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; } } } } }