[moodle] / contrib / plugins / grade / report / visual / flare_visualization / flare_visualization.as Repository:

View of /contrib/plugins/grade/report/visual/flare_visualization/flare_visualization.as

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (download) (annotate)
Tue Jul 1 15:30:02 2008 WST (16 months, 3 weeks ago) by dservos
Branch: MAIN
CONTRIB-497
Start of the grade/report/visual plug-in for displaying charts and graphs using flare as part of the GSoC animated grade statistics report project.

Currently only one visualization has been added and it is still in a rough state.

The code for the swf can be found in the flare_visualization dir.

Lots more work ahead to get the plug-in 100%.

package {
    import flare.animate.Sequence;
    import flare.animate.Transitioner;
    import flare.data.DataSet;
    import flare.data.DataSource;
    import flare.display.TextSprite;
    import flare.vis.Visualization;
    import flare.vis.controls.HoverControl;
    import flare.vis.data.Data;
    import flare.vis.data.DataSprite;
    import flare.vis.legend.Legend;
    import flare.vis.operator.encoder.ColorEncoder;
    import flare.vis.operator.encoder.ShapeEncoder;
    import flare.vis.operator.layout.AxisLayout;
    import flare.vis.scale.ScaleType;
    import flare.vis.util.Filters;
    
    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.GlowFilter;
    import flash.geom.Rectangle;
    import flash.net.URLLoader;
    import flash.text.TextFormat;

    [SWF(width="800", height="600", backgroundColor="#ffffff", frameRate="30")]
    public class flare_visualization extends Sprite
    {   
    	private var vis:Visualization;
    	private var lastBox:Sprite = null;
    	private var lastBoxData:DataSprite = null;
    	private var axisX:String = "data.student";
    	private var axisY:String = "data.grade";    	
    	 	
        public function flare_visualization()
        {
        	harvest_data(loaderInfo.parameters['wwwroot'] + '/grade/report/visual/json_data.php?id=' +   escape(loaderInfo.parameters['courseid']) + '&sessioncookie=' +  escape(loaderInfo.parameters['sessioncookie']) + '&sessionid=' +  escape(loaderInfo.parameters['sessionid']) + '&sessiontest=' + escape(loaderInfo.parameters['sessiontest']));
        	//harvest_data('http://localhost/moodle/grade/report/visual/json_data.php?id=3&sessioncookie=&sessionid=ebb79f5984c0fa4c9b0d85814c573a81&sessiontest=jHKFJhsOPf');
        }
        
        public function harvest_data(url:String):void
        {
        	var ds:DataSource = new DataSource(url, "tab");
            var loader:URLLoader = ds.load();
            loader.addEventListener(Event.COMPLETE, function(evt:Event):void {
                var ds:DataSet = loader.data as DataSet;
                buildVis(Data.fromDataSet(ds));
            });
        }
     
     	private function getMaxWidth(d:DisplayObjectContainer):int {
     		var max:int = d.width;
     		  
            for(var k:uint; k < d.numChildren; k++ ) {  
            	var width:int = 0;
            	
                if(d.getChildAt(k) is DisplayObjectContainer) {
                	width = getMaxWidth(DisplayObjectContainer(d.getChildAt(k)));  
                } else {
                	width = d.getChildAt(k).width;
                }
  				
  				if(width > max) {
  					max = width;
  				}
            }
            
            return max;
        }
     
     	private function max(num1:int, num2:int):int {
     		if(num1 > num2) {
     			return num1;
     		} else {
     			return num2;
     		}
     	}
     
     	private function getMaxHeight(d:DisplayObjectContainer):int {
     		var max:int = d.height;
     		  
            for(var k:uint; k < d.numChildren; k++ ) {  
            	var height:int = 0;
            	
                if(d.getChildAt(k) is DisplayObjectContainer) {
                	height = getMaxHeight(DisplayObjectContainer(d.getChildAt(k)));  
                } else {
                	height = d.getChildAt(k).height;
                }
  				
  				if(height > max) {
  					max = height;
  				}
            }
            
            return max;
        }  
     
     	private function buildVis(data:Data):void
        {
            vis = new Visualization(data);
            
			var colorEncoder:ColorEncoder = new ColorEncoder("data.item", Data.NODES, "lineColor", ScaleType.CATEGORIES);
			var shapeEncoder:ShapeEncoder = new ShapeEncoder("data.group");
			var al:AxisLayout = new AxisLayout(axisX, axisY);
			
			vis.operators.add(al);
            vis.operators.add(colorEncoder);
            vis.operators.add(shapeEncoder);
            
            vis.xyAxes.xAxis.horizontalAnchor = TextSprite.LEFT; 
			vis.xyAxes.xAxis.verticalAnchor = TextSprite.MIDDLE; 
			vis.xyAxes.xAxis.labelAngle = Math.PI / 2;
			vis.xyAxes.xAxis.fixLabelOverlap = false;
			vis.xyAxes.yAxis.fixLabelOverlap = false;
			
            
            vis.update();
			
			var labelX:TextSprite = new TextSprite("Student", new TextFormat("mono", 20)); 
			var labelY:TextSprite = new TextSprite("Grade", new TextFormat("mono", 20));
			var title:TextSprite = new TextSprite("Normalized Grades vs Students", new TextFormat("mono", 25));
			
			
			vis.y = title.height + 10;
            vis.x = labelY.height + -vis.xyAxes.yAxis.labelOffsetX + getMaxWidth(vis.xyAxes.yAxis.labels);
			
			var itemLegend:Legend = new Legend("data.item", colorEncoder.scale, colorEncoder.colors, null, null);
            var groupLegend:Legend = new Legend("data.group", shapeEncoder.scale, null, shapeEncoder.shapes, null);
           	
           	var xLabelsHeight:int = getMaxHeight(vis.xyAxes.xAxis.labels);
            vis.bounds = new Rectangle(0, 0, loaderInfo.width - (max(itemLegend.width, groupLegend.width) + 15 + vis.x), loaderInfo.height - (vis.y + xLabelsHeight + labelX.height + vis.xyAxes.xAxis.labelOffsetY)); 
            addChild(vis);
            
            vis.data.visit(function(d:DataSprite):void {
				d.fillColor = 0x018888ff;
				d.fillAlpha = 0.2;
				d.lineWidth = 2;
				d.addEventListener(MouseEvent.CLICK, mouseClicked);
			});
             
            itemLegend.x = vis.bounds.width + 10;
            itemLegend.y = 0;
            groupLegend.x = vis.bounds.width + 10;
            groupLegend.y = itemLegend.y + itemLegend.height;
            
            
			labelX.x = vis.bounds.width/2 - labelX.width/2;
			labelX.y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + xLabelsHeight;
            vis.xyAxes.xAxis.addChild(labelX);
            
			labelY.x = -vis.x;
			labelY.y = vis.bounds.height/2 - labelY.width/2;
			labelY.rotation = -90;
			vis.xyAxes.yAxis.addChild(labelY);
			
			title.x = vis.bounds.width/2 - title.width/2;
			title.y = -vis.y;
			vis.xyAxes.addChild(title);
            
            vis.addChild(itemLegend);
            vis.addChild(groupLegend);
            vis.setChildIndex(vis.marks, vis.numChildren - 1);
            
            var hc:HoverControl = new HoverControl(vis, Filters.isDataSprite);
            hc.onRollOver = rollOver;
			hc.onRollOut = rollOut;
			
			var bInvert:Button = new Button("Invert Axis");
			bInvert.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
				var t1:Transitioner = new Transitioner(2);
				var t2:Transitioner = new Transitioner(2);
				var t3:Transitioner = new Transitioner(2);
				var t4:Transitioner = new Transitioner(2);
				var t5:Transitioner = new Transitioner(2);
				var t6:Transitioner = new Transitioner(2);
				var tempText:String = labelX.text;
				var tempOffset:int = vis.xyAxes.xAxis.labelOffsetX;
				var tempWidth:uint = vis.bounds.width;
				var xLabelsHeight:int = getMaxWidth(vis.xyAxes.yAxis.labels);
				
				al.xField = axisY;
				al.yField = axisX;
				axisX = al.xField;
				axisY = al.yField;
				
				labelX.text = labelY.text;
				labelY.text = tempText;
				
				var newX:int = labelY.width + vis.xyAxes.xAxis.labelOffsetY + getMaxHeight(vis.xyAxes.xAxis.labels);
				
				t1.$(vis).x = newX;
				vis.bounds = new Rectangle(0, 0, loaderInfo.width - (max(itemLegend.width, groupLegend.width) + 15 + newX), loaderInfo.height - (vis.y + xLabelsHeight + labelX.height + vis.xyAxes.xAxis.labelOffsetY));
				
				t1.$(title).x = vis.bounds.width/2 - title.width/2;
				
				t1.$(labelX).x = vis.bounds.width/2 - labelX.width/2;
				t1.$(labelX).y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + xLabelsHeight;
				t1.$(labelY).x = -newX;
				t1.$(labelY).y = vis.bounds.height/2 - labelY.width/2;
				
				t1.$(itemLegend).x = vis.bounds.width + 10;
            	t1.$(groupLegend).x = vis.bounds.width + 10;
            	
            	t1.play()
            	vis.update(new Transitioner(2)).play();
			});
			addChild(bInvert);
			
			vis.update();
        }
        
        private function rollOver(ob:Object):void {
        	ob.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)];
        }
        
        private function rollOut(ob:Object):void {
        	ob.filters = null;
        }
        
        private function boxRollOver(ob:Object):void {
        	if(lastBoxData != null) {
        		lastBoxData.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)];
        	}
        }
        
        private function boxRollOut(ob:Object):void {
        	if(lastBoxData != null) {
        		lastBoxData.filters = null;
        	}
        }
        
        private function dataDialogBox(data:DataSprite):Sprite {
        	var box:Sprite = new Sprite;
        	
        	var backGround:Sprite = new Sprite;	
        	backGround.graphics.beginFill(0x7777ff, 0.60);
        	backGround.graphics.lineStyle(3, 0x0000ff, 0.3);
        	 
        	var text:Sprite = new Sprite;
        	var name:TextSprite = new TextSprite(data.data.student, new TextFormat("mono", 20, null, true));
        	var item:TextSprite = new TextSprite("Item: " + data.data.item, new TextFormat("mono", 12, null, true));
        	var grade:TextSprite = new TextSprite("Grade: " + data.data.grade + "%", new TextFormat("mono", 12, null, true));
        	var group:TextSprite = new TextSprite("Group: " + data.data.group, new TextFormat("mono", 12, null, true));
        	text.addChild(name);
        	text.addChild(item);
        	text.addChild(group);
        	text.addChild(grade);
        	
        	name.x = text.width/2 - name.width/2;
        	item.x = 5;
        	grade.x = 5;
        	group.x = 5;
        	
        	name.y = 0;
        	item.y = name.y + name.height;
        	group.y = item.y + item.height;
        	grade.y = group.y + group.height;
   
        	backGround.graphics.drawRoundRect(0, 0, text.width + 5, text.height, 30, 30);     	
        	
        	box.addChild(backGround);
        	box.addChild(text);
        	
        	return box;
        }
        
        private function mouseClicked(evt:MouseEvent):void {
        	if(DisplayObject(evt.target).parent == vis.marks) {
        		if(lastBox != null && lastBoxData != null) {
        			lastBoxData.removeChild(lastBox);
        		}
        		
        		if(evt.target != lastBoxData) {
        			lastBox = dataDialogBox(DataSprite(evt.target));
        			lastBoxData = DataSprite(evt.target);
        			Sprite(evt.target).addChild(lastBox);
    				vis.marks.setChildIndex(Sprite(evt.target), vis.marks.numChildren - 1);
    				var hc:HoverControl = new HoverControl(Sprite(evt.target), null);
            		hc.onRollOver = boxRollOver;
					hc.onRollOut = boxRollOut;
        		} else {
        			lastBoxData = null;
        			lastBox = null;
        		}
        	}
        }
    }
}

Moodle CVS Admin
ViewVC Help
Powered by ViewVC 1.0.7