Parent Directory
|
Revision Log
Revision 1.1 - (view) (download)
| 1 : | dservos | 1.1 | |
| 2 : | package { | ||
| 3 : | import flare.animate.Sequence; | ||
| 4 : | import flare.animate.Transitioner; | ||
| 5 : | import flare.data.DataSet; | ||
| 6 : | import flare.data.DataSource; | ||
| 7 : | import flare.display.TextSprite; | ||
| 8 : | import flare.vis.Visualization; | ||
| 9 : | import flare.vis.controls.HoverControl; | ||
| 10 : | import flare.vis.data.Data; | ||
| 11 : | import flare.vis.data.DataSprite; | ||
| 12 : | import flare.vis.legend.Legend; | ||
| 13 : | import flare.vis.operator.encoder.ColorEncoder; | ||
| 14 : | import flare.vis.operator.encoder.ShapeEncoder; | ||
| 15 : | import flare.vis.operator.layout.AxisLayout; | ||
| 16 : | import flare.vis.scale.ScaleType; | ||
| 17 : | import flare.vis.util.Filters; | ||
| 18 : | |||
| 19 : | import flash.display.DisplayObject; | ||
| 20 : | import flash.display.DisplayObjectContainer; | ||
| 21 : | import flash.display.Sprite; | ||
| 22 : | import flash.events.Event; | ||
| 23 : | import flash.events.MouseEvent; | ||
| 24 : | import flash.filters.GlowFilter; | ||
| 25 : | import flash.geom.Rectangle; | ||
| 26 : | import flash.net.URLLoader; | ||
| 27 : | import flash.text.TextFormat; | ||
| 28 : | |||
| 29 : | [SWF(width="800", height="600", backgroundColor="#ffffff", frameRate="30")] | ||
| 30 : | public class flare_visualization extends Sprite | ||
| 31 : | { | ||
| 32 : | private var vis:Visualization; | ||
| 33 : | private var lastBox:Sprite = null; | ||
| 34 : | private var lastBoxData:DataSprite = null; | ||
| 35 : | private var axisX:String = "data.student"; | ||
| 36 : | private var axisY:String = "data.grade"; | ||
| 37 : | |||
| 38 : | public function flare_visualization() | ||
| 39 : | { | ||
| 40 : | 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'])); | ||
| 41 : | //harvest_data('http://localhost/moodle/grade/report/visual/json_data.php?id=3&sessioncookie=&sessionid=ebb79f5984c0fa4c9b0d85814c573a81&sessiontest=jHKFJhsOPf'); | ||
| 42 : | } | ||
| 43 : | |||
| 44 : | public function harvest_data(url:String):void | ||
| 45 : | { | ||
| 46 : | var ds:DataSource = new DataSource(url, "tab"); | ||
| 47 : | var loader:URLLoader = ds.load(); | ||
| 48 : | loader.addEventListener(Event.COMPLETE, function(evt:Event):void { | ||
| 49 : | var ds:DataSet = loader.data as DataSet; | ||
| 50 : | buildVis(Data.fromDataSet(ds)); | ||
| 51 : | }); | ||
| 52 : | } | ||
| 53 : | |||
| 54 : | private function getMaxWidth(d:DisplayObjectContainer):int { | ||
| 55 : | var max:int = d.width; | ||
| 56 : | |||
| 57 : | for(var k:uint; k < d.numChildren; k++ ) { | ||
| 58 : | var width:int = 0; | ||
| 59 : | |||
| 60 : | if(d.getChildAt(k) is DisplayObjectContainer) { | ||
| 61 : | width = getMaxWidth(DisplayObjectContainer(d.getChildAt(k))); | ||
| 62 : | } else { | ||
| 63 : | width = d.getChildAt(k).width; | ||
| 64 : | } | ||
| 65 : | |||
| 66 : | if(width > max) { | ||
| 67 : | max = width; | ||
| 68 : | } | ||
| 69 : | } | ||
| 70 : | |||
| 71 : | return max; | ||
| 72 : | } | ||
| 73 : | |||
| 74 : | private function max(num1:int, num2:int):int { | ||
| 75 : | if(num1 > num2) { | ||
| 76 : | return num1; | ||
| 77 : | } else { | ||
| 78 : | return num2; | ||
| 79 : | } | ||
| 80 : | } | ||
| 81 : | |||
| 82 : | private function getMaxHeight(d:DisplayObjectContainer):int { | ||
| 83 : | var max:int = d.height; | ||
| 84 : | |||
| 85 : | for(var k:uint; k < d.numChildren; k++ ) { | ||
| 86 : | var height:int = 0; | ||
| 87 : | |||
| 88 : | if(d.getChildAt(k) is DisplayObjectContainer) { | ||
| 89 : | height = getMaxHeight(DisplayObjectContainer(d.getChildAt(k))); | ||
| 90 : | } else { | ||
| 91 : | height = d.getChildAt(k).height; | ||
| 92 : | } | ||
| 93 : | |||
| 94 : | if(height > max) { | ||
| 95 : | max = height; | ||
| 96 : | } | ||
| 97 : | } | ||
| 98 : | |||
| 99 : | return max; | ||
| 100 : | } | ||
| 101 : | |||
| 102 : | private function buildVis(data:Data):void | ||
| 103 : | { | ||
| 104 : | vis = new Visualization(data); | ||
| 105 : | |||
| 106 : | var colorEncoder:ColorEncoder = new ColorEncoder("data.item", Data.NODES, "lineColor", ScaleType.CATEGORIES); | ||
| 107 : | var shapeEncoder:ShapeEncoder = new ShapeEncoder("data.group"); | ||
| 108 : | var al:AxisLayout = new AxisLayout(axisX, axisY); | ||
| 109 : | |||
| 110 : | vis.operators.add(al); | ||
| 111 : | vis.operators.add(colorEncoder); | ||
| 112 : | vis.operators.add(shapeEncoder); | ||
| 113 : | |||
| 114 : | vis.xyAxes.xAxis.horizontalAnchor = TextSprite.LEFT; | ||
| 115 : | vis.xyAxes.xAxis.verticalAnchor = TextSprite.MIDDLE; | ||
| 116 : | vis.xyAxes.xAxis.labelAngle = Math.PI / 2; | ||
| 117 : | vis.xyAxes.xAxis.fixLabelOverlap = false; | ||
| 118 : | vis.xyAxes.yAxis.fixLabelOverlap = false; | ||
| 119 : | |||
| 120 : | |||
| 121 : | vis.update(); | ||
| 122 : | |||
| 123 : | var labelX:TextSprite = new TextSprite("Student", new TextFormat("mono", 20)); | ||
| 124 : | var labelY:TextSprite = new TextSprite("Grade", new TextFormat("mono", 20)); | ||
| 125 : | var title:TextSprite = new TextSprite("Normalized Grades vs Students", new TextFormat("mono", 25)); | ||
| 126 : | |||
| 127 : | |||
| 128 : | vis.y = title.height + 10; | ||
| 129 : | vis.x = labelY.height + -vis.xyAxes.yAxis.labelOffsetX + getMaxWidth(vis.xyAxes.yAxis.labels); | ||
| 130 : | |||
| 131 : | var itemLegend:Legend = new Legend("data.item", colorEncoder.scale, colorEncoder.colors, null, null); | ||
| 132 : | var groupLegend:Legend = new Legend("data.group", shapeEncoder.scale, null, shapeEncoder.shapes, null); | ||
| 133 : | |||
| 134 : | var xLabelsHeight:int = getMaxHeight(vis.xyAxes.xAxis.labels); | ||
| 135 : | 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)); | ||
| 136 : | addChild(vis); | ||
| 137 : | |||
| 138 : | vis.data.visit(function(d:DataSprite):void { | ||
| 139 : | d.fillColor = 0x018888ff; | ||
| 140 : | d.fillAlpha = 0.2; | ||
| 141 : | d.lineWidth = 2; | ||
| 142 : | d.addEventListener(MouseEvent.CLICK, mouseClicked); | ||
| 143 : | }); | ||
| 144 : | |||
| 145 : | itemLegend.x = vis.bounds.width + 10; | ||
| 146 : | itemLegend.y = 0; | ||
| 147 : | groupLegend.x = vis.bounds.width + 10; | ||
| 148 : | groupLegend.y = itemLegend.y + itemLegend.height; | ||
| 149 : | |||
| 150 : | |||
| 151 : | labelX.x = vis.bounds.width/2 - labelX.width/2; | ||
| 152 : | labelX.y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + xLabelsHeight; | ||
| 153 : | vis.xyAxes.xAxis.addChild(labelX); | ||
| 154 : | |||
| 155 : | labelY.x = -vis.x; | ||
| 156 : | labelY.y = vis.bounds.height/2 - labelY.width/2; | ||
| 157 : | labelY.rotation = -90; | ||
| 158 : | vis.xyAxes.yAxis.addChild(labelY); | ||
| 159 : | |||
| 160 : | title.x = vis.bounds.width/2 - title.width/2; | ||
| 161 : | title.y = -vis.y; | ||
| 162 : | vis.xyAxes.addChild(title); | ||
| 163 : | |||
| 164 : | vis.addChild(itemLegend); | ||
| 165 : | vis.addChild(groupLegend); | ||
| 166 : | vis.setChildIndex(vis.marks, vis.numChildren - 1); | ||
| 167 : | |||
| 168 : | var hc:HoverControl = new HoverControl(vis, Filters.isDataSprite); | ||
| 169 : | hc.onRollOver = rollOver; | ||
| 170 : | hc.onRollOut = rollOut; | ||
| 171 : | |||
| 172 : | var bInvert:Button = new Button("Invert Axis"); | ||
| 173 : | bInvert.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void { | ||
| 174 : | var t1:Transitioner = new Transitioner(2); | ||
| 175 : | var t2:Transitioner = new Transitioner(2); | ||
| 176 : | var t3:Transitioner = new Transitioner(2); | ||
| 177 : | var t4:Transitioner = new Transitioner(2); | ||
| 178 : | var t5:Transitioner = new Transitioner(2); | ||
| 179 : | var t6:Transitioner = new Transitioner(2); | ||
| 180 : | var tempText:String = labelX.text; | ||
| 181 : | var tempOffset:int = vis.xyAxes.xAxis.labelOffsetX; | ||
| 182 : | var tempWidth:uint = vis.bounds.width; | ||
| 183 : | var xLabelsHeight:int = getMaxWidth(vis.xyAxes.yAxis.labels); | ||
| 184 : | |||
| 185 : | al.xField = axisY; | ||
| 186 : | al.yField = axisX; | ||
| 187 : | axisX = al.xField; | ||
| 188 : | axisY = al.yField; | ||
| 189 : | |||
| 190 : | labelX.text = labelY.text; | ||
| 191 : | labelY.text = tempText; | ||
| 192 : | |||
| 193 : | var newX:int = labelY.width + vis.xyAxes.xAxis.labelOffsetY + getMaxHeight(vis.xyAxes.xAxis.labels); | ||
| 194 : | |||
| 195 : | t1.$(vis).x = newX; | ||
| 196 : | 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)); | ||
| 197 : | |||
| 198 : | t1.$(title).x = vis.bounds.width/2 - title.width/2; | ||
| 199 : | |||
| 200 : | t1.$(labelX).x = vis.bounds.width/2 - labelX.width/2; | ||
| 201 : | t1.$(labelX).y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + xLabelsHeight; | ||
| 202 : | t1.$(labelY).x = -newX; | ||
| 203 : | t1.$(labelY).y = vis.bounds.height/2 - labelY.width/2; | ||
| 204 : | |||
| 205 : | t1.$(itemLegend).x = vis.bounds.width + 10; | ||
| 206 : | t1.$(groupLegend).x = vis.bounds.width + 10; | ||
| 207 : | |||
| 208 : | t1.play() | ||
| 209 : | vis.update(new Transitioner(2)).play(); | ||
| 210 : | }); | ||
| 211 : | addChild(bInvert); | ||
| 212 : | |||
| 213 : | vis.update(); | ||
| 214 : | } | ||
| 215 : | |||
| 216 : | private function rollOver(ob:Object):void { | ||
| 217 : | ob.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)]; | ||
| 218 : | } | ||
| 219 : | |||
| 220 : | private function rollOut(ob:Object):void { | ||
| 221 : | ob.filters = null; | ||
| 222 : | } | ||
| 223 : | |||
| 224 : | private function boxRollOver(ob:Object):void { | ||
| 225 : | if(lastBoxData != null) { | ||
| 226 : | lastBoxData.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)]; | ||
| 227 : | } | ||
| 228 : | } | ||
| 229 : | |||
| 230 : | private function boxRollOut(ob:Object):void { | ||
| 231 : | if(lastBoxData != null) { | ||
| 232 : | lastBoxData.filters = null; | ||
| 233 : | } | ||
| 234 : | } | ||
| 235 : | |||
| 236 : | private function dataDialogBox(data:DataSprite):Sprite { | ||
| 237 : | var box:Sprite = new Sprite; | ||
| 238 : | |||
| 239 : | var backGround:Sprite = new Sprite; | ||
| 240 : | backGround.graphics.beginFill(0x7777ff, 0.60); | ||
| 241 : | backGround.graphics.lineStyle(3, 0x0000ff, 0.3); | ||
| 242 : | |||
| 243 : | var text:Sprite = new Sprite; | ||
| 244 : | var name:TextSprite = new TextSprite(data.data.student, new TextFormat("mono", 20, null, true)); | ||
| 245 : | var item:TextSprite = new TextSprite("Item: " + data.data.item, new TextFormat("mono", 12, null, true)); | ||
| 246 : | var grade:TextSprite = new TextSprite("Grade: " + data.data.grade + "%", new TextFormat("mono", 12, null, true)); | ||
| 247 : | var group:TextSprite = new TextSprite("Group: " + data.data.group, new TextFormat("mono", 12, null, true)); | ||
| 248 : | text.addChild(name); | ||
| 249 : | text.addChild(item); | ||
| 250 : | text.addChild(group); | ||
| 251 : | text.addChild(grade); | ||
| 252 : | |||
| 253 : | name.x = text.width/2 - name.width/2; | ||
| 254 : | item.x = 5; | ||
| 255 : | grade.x = 5; | ||
| 256 : | group.x = 5; | ||
| 257 : | |||
| 258 : | name.y = 0; | ||
| 259 : | item.y = name.y + name.height; | ||
| 260 : | group.y = item.y + item.height; | ||
| 261 : | grade.y = group.y + group.height; | ||
| 262 : | |||
| 263 : | backGround.graphics.drawRoundRect(0, 0, text.width + 5, text.height, 30, 30); | ||
| 264 : | |||
| 265 : | box.addChild(backGround); | ||
| 266 : | box.addChild(text); | ||
| 267 : | |||
| 268 : | return box; | ||
| 269 : | } | ||
| 270 : | |||
| 271 : | private function mouseClicked(evt:MouseEvent):void { | ||
| 272 : | if(DisplayObject(evt.target).parent == vis.marks) { | ||
| 273 : | if(lastBox != null && lastBoxData != null) { | ||
| 274 : | lastBoxData.removeChild(lastBox); | ||
| 275 : | } | ||
| 276 : | |||
| 277 : | if(evt.target != lastBoxData) { | ||
| 278 : | lastBox = dataDialogBox(DataSprite(evt.target)); | ||
| 279 : | lastBoxData = DataSprite(evt.target); | ||
| 280 : | Sprite(evt.target).addChild(lastBox); | ||
| 281 : | vis.marks.setChildIndex(Sprite(evt.target), vis.marks.numChildren - 1); | ||
| 282 : | var hc:HoverControl = new HoverControl(Sprite(evt.target), null); | ||
| 283 : | hc.onRollOver = boxRollOver; | ||
| 284 : | hc.onRollOut = boxRollOut; | ||
| 285 : | } else { | ||
| 286 : | lastBoxData = null; | ||
| 287 : | lastBox = null; | ||
| 288 : | } | ||
| 289 : | } | ||
| 290 : | } | ||
| 291 : | } | ||
| 292 : | } |
| Moodle CVS Admin | ViewVC Help |
| Powered by ViewVC 1.0.7 |