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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1, Tue Jul 1 15:30:02 2008 WST revision 1.2, Tue Jul 15 03:27:17 2008 WST

By dservos:

CONTRIB-497 Cleaned up some of the code for report/visual and the flex based application for viewing the visualizations. Improved the UI of the visualization. Added documentation to both the php and actionscript 3 (flex) code. Removed some unneeded files. TODO: *Add more visualizations. *Add printer firendly version. *Make flex appplications settings less hardcoded and loaded from moodle. *Load lang files from moodle to flex for full language support. *Add a settings page for the report.

# Line 1  Line 1 
1    ///////////////////////////////////////////////////////////////////////////
2    //                                                                       //
3    // NOTICE OF COPYRIGHT                                                   //
4    //                                                                       //
5    // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
6    //          http://moodle.org                                            //
7    //                                                                       //
8    // Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
9    //                                                                       //
10    // This program is free software; you can redistribute it and/or modify  //
11    // it under the terms of the GNU General Public License as published by  //
12    // the Free Software Foundation; either version 2 of the License, or     //
13    // (at your option) any later version.                                   //
14    //                                                                       //
15    // This program is distributed in the hope that it will be useful,       //
16    // but WITHOUT ANY WARRANTY; without even the implied warranty of        //
17    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
18    // GNU General Public License for more details:                          //
19    //                                                                       //
20    //          http://www.gnu.org/copyleft/gpl.html                         //
21    //                                                                       //
22    ///////////////////////////////////////////////////////////////////////////
23    
24     /**
25     * This is the flex with flare based visualizer for the Moodle 2.x visual
26     * grade book plug-in. This should load the grade book data for a given
27     * visualization from the report/visual plug-in based on a set of flashvars
28     * passed to it from Moodle and display a visual repersenation.
29     */
30  package {  package {
31      import flare.animate.Sequence;          //Flare imports
32      import flare.animate.Transitioner;      import flare.animate.Transitioner;
33      import flare.data.DataSet;      import flare.data.DataSet;
34      import flare.data.DataSource;      import flare.data.DataSource;
# Line 10  Line 38 
38      import flare.vis.data.Data;      import flare.vis.data.Data;
39      import flare.vis.data.DataSprite;      import flare.vis.data.DataSprite;
40      import flare.vis.legend.Legend;      import flare.vis.legend.Legend;
41        import flare.vis.legend.LegendItem;
42      import flare.vis.operator.encoder.ColorEncoder;      import flare.vis.operator.encoder.ColorEncoder;
43      import flare.vis.operator.encoder.ShapeEncoder;      import flare.vis.operator.encoder.ShapeEncoder;
44      import flare.vis.operator.layout.AxisLayout;      import flare.vis.operator.layout.AxisLayout;
# Line 27  Line 56 
56      import flash.text.TextFormat;      import flash.text.TextFormat;
57    
58      [SWF(width="800", height="600", backgroundColor="#ffffff", frameRate="30")]      [SWF(width="800", height="600", backgroundColor="#ffffff", frameRate="30")]
59        /**
60        * Main class for handling grade book data and greatating a visualization.
61        */
62      public class flare_visualization extends Sprite      public class flare_visualization extends Sprite
63      {      {
64            /**
65             * The visualization object to be used in creating the visualization.
66             */
67          private var vis:Visualization;          private var vis:Visualization;
68    
69            /**
70             * A refernce to the currently displayed dialog box. If null no dialog
71             * box is currently being displayed.
72             */
73          private var lastBox:Sprite = null;          private var lastBox:Sprite = null;
74    
75            /**
76             * A refernce to the data sprite witch contains the data for witch the
77             * currently displayed dialog box is based on and a child of.
78             */
79          private var lastBoxData:DataSprite = null;          private var lastBoxData:DataSprite = null;
80    
81            /**
82             * The data feild the X axis is based on.
83             * @default data.student
84             */
85          private var axisX:String = "data.student";          private var axisX:String = "data.student";
86    
87            /**
88             * The data field the Y axis is based on.
89             * @default data.grade
90             */
91          private var axisY:String = "data.grade";          private var axisY:String = "data.grade";
92    
93            /**
94             * A container for the legends witch will be displayed on the righ hand
95             * side.
96             */
97            private var legends:Sprite;
98    
99            /**
100             * The hover control for the dialog box.
101             */
102            private var boxhc:HoverControl = new HoverControl();
103    
104            /**
105             * The constucter for the flare_visualization class.
106             * Calls on harvest_data and sets up the varibles from the flashvars.
107             */
108          public function flare_visualization()          public function flare_visualization()
109          {          {
110                  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']));                  // Call harvest_data, loading needed visualization data from moodle.
111                  //harvest_data('http://localhost/moodle/grade/report/visual/json_data.php?id=3&sessioncookie=&sessionid=ebb79f5984c0fa4c9b0d85814c573a81&sessiontest=jHKFJhsOPf');                  // The Moodle wwwroot, course id, users sessionid, users session cookie
112                    // and session test data are needed to get the data from moodle are
113                    // loaded threw flashvars.
114                    harvest_data(loaderInfo.parameters['wwwroot'] + '/grade/report/visual/data.php?id=' +   escape(loaderInfo.parameters['courseid']) + '&sessioncookie=' +  escape(loaderInfo.parameters['sessioncookie']) + '&sessionid=' +  escape(loaderInfo.parameters['sessionid']) + '&sessiontest=' + escape(loaderInfo.parameters['sessiontest']));
115                    //harvest_data('http://localhost/moodle/grade/report/visual/data.php?id=3&sessioncookie=&sessionid=ebb79f5984c0fa4c9b0d85814c573a81&sessiontest=jHKFJhsOPf');
116          }          }
117    
118            /**
119            * Harvests the data from Moodle and calls on buildVis to build the
120            * visualization once the data has been loaded.
121            * TODO: Add a loading bar and more feed back about the loading process.
122            * @param url The url from witch to load the tab formated data for the visualization.
123            */
124          public function harvest_data(url:String):void          public function harvest_data(url:String):void
125          {          {
126                  var ds:DataSource = new DataSource(url, "tab");                  var ds:DataSource = new DataSource(url, "tab");
# Line 51  Line 131 
131              });              });
132          }          }
133    
134            /**
135             * Find the max width between a container and all of it's decendence
136             * This dose not find the width of a container but the greatest width
137             * of an invdual component in it's decenedences.
138             * @param d The display container to find the max width of.
139             * @return the max width value of the display objects.
140             */
141          private function getMaxWidth(d:DisplayObjectContainer):int {          private function getMaxWidth(d:DisplayObjectContainer):int {
142                  var max:int = d.width;                  var max:int = d.width;
143    
144              for(var k:uint; k < d.numChildren; k++ ) {              for(var k:uint = 0; k < d.numChildren; k++ ) {
145                  var width:int = 0;                  var width:int = 0;
146    
147                  if(d.getChildAt(k) is DisplayObjectContainer) {                  if(d.getChildAt(k) is DisplayObjectContainer) {
# Line 71  Line 158 
158              return max;              return max;
159          }          }
160    
161            /**
162             * Simple function to retrun the greatest of two ints.
163             * @param num1 the first number to test
164             * @param num2 the second number to test
165             * @return the largest value between num1 and num2.
166             */
167          private function max(num1:int, num2:int):int {          private function max(num1:int, num2:int):int {
168                  if(num1 > num2) {                  if(num1 > num2) {
169                          return num1;                          return num1;
# Line 79  Line 172 
172                  }                  }
173          }          }
174    
175            /**
176             * Find the max height between a container and all of it's decendence
177             * This dose not find the width of a container but the greatest height
178             * of an invdual component in it's decenedences.
179             * @param d The display container to find the max height of.
180             * @return the max height value of the display objects.
181             */
182          private function getMaxHeight(d:DisplayObjectContainer):int {          private function getMaxHeight(d:DisplayObjectContainer):int {
183                  var max:int = d.height;                  var max:int = d.height;
184    
185              for(var k:uint; k < d.numChildren; k++ ) {              for(var k:uint = 0; k < d.numChildren; k++ ) {
186                  var height:int = 0;                  var height:int = 0;
187    
188                  if(d.getChildAt(k) is DisplayObjectContainer) {                  if(d.getChildAt(k) is DisplayObjectContainer) {
# Line 99  Line 199 
199              return max;              return max;
200          }          }
201    
202            /**
203             * Builds the visualization based on the loaded data.
204             * Also sets up the legends, buttons and controls.
205             * @param data The data that was loaded in from moodle.
206             */
207          private function buildVis(data:Data):void          private function buildVis(data:Data):void
208          {          {
209              vis = new Visualization(data);              vis = new Visualization(data);
210                legends = new Sprite();
211    
212                // Set the functions to be called when a dialog box is hovered over.
213                boxhc.onRollOver = boxRollOver;
214                            boxhc.onRollOut = boxRollOut;
215    
216                            // Set up the encoders and layout
217                          var colorEncoder:ColorEncoder = new ColorEncoder("data.item", Data.NODES, "lineColor", ScaleType.CATEGORIES);                          var colorEncoder:ColorEncoder = new ColorEncoder("data.item", Data.NODES, "lineColor", ScaleType.CATEGORIES);
218                          var shapeEncoder:ShapeEncoder = new ShapeEncoder("data.group");                          var shapeEncoder:ShapeEncoder = new ShapeEncoder("data.group");
219                          var al:AxisLayout = new AxisLayout(axisX, axisY);                          var al:AxisLayout = new AxisLayout(axisX, axisY);
220    
221                            // Add the encoders and layout to the visualization.
222                          vis.operators.add(al);                          vis.operators.add(al);
223              vis.operators.add(colorEncoder);              vis.operators.add(colorEncoder);
224              vis.operators.add(shapeEncoder);              vis.operators.add(shapeEncoder);
225    
226                // Set up the layout of the axes.
227              vis.xyAxes.xAxis.horizontalAnchor = TextSprite.LEFT;              vis.xyAxes.xAxis.horizontalAnchor = TextSprite.LEFT;
228                          vis.xyAxes.xAxis.verticalAnchor = TextSprite.MIDDLE;                          vis.xyAxes.xAxis.verticalAnchor = TextSprite.MIDDLE;
229                          vis.xyAxes.xAxis.labelAngle = Math.PI / 2;                          vis.xyAxes.xAxis.labelAngle = Math.PI / 2;
230                          vis.xyAxes.xAxis.fixLabelOverlap = false;                          vis.xyAxes.xAxis.fixLabelOverlap = false;
231                          vis.xyAxes.yAxis.fixLabelOverlap = false;                          vis.xyAxes.yAxis.fixLabelOverlap = false;
232    
233                // Update the visualization so the widths and other values are correct.
234              vis.update();              vis.update();
235    
236                            // Initalize the X and Y axis labels and the visualizations title.
237                          var labelX:TextSprite = new TextSprite("Student", new TextFormat("mono", 20));                          var labelX:TextSprite = new TextSprite("Student", new TextFormat("mono", 20));
238                          var labelY:TextSprite = new TextSprite("Grade", new TextFormat("mono", 20));                          var labelY:TextSprite = new TextSprite("Grade", new TextFormat("mono", 20));
239                          var title:TextSprite = new TextSprite("Normalized Grades vs Students", new TextFormat("mono", 25));                          var title:TextSprite = new TextSprite("Normalized Grades vs Students", new TextFormat("mono", 25));
240    
241                            // Find the largest width out of the X axis labels so it can used for positing sprites.
242                    var xLabelsHeight:int = getMaxHeight(vis.xyAxes.xAxis.labels);
243                var yLabelsWidth:int = getMaxWidth(vis.xyAxes.yAxis.labels);
244    
245                            // Position the visualization.
246                          vis.y = title.height + 10;                          vis.y = title.height + 10;
247              vis.x = labelY.height + -vis.xyAxes.yAxis.labelOffsetX + getMaxWidth(vis.xyAxes.yAxis.labels);              vis.x = labelY.height + -vis.xyAxes.yAxis.labelOffsetX + yLabelsWidth;
248    
249                            // Set up the legends.
250                          var itemLegend:Legend = new Legend("data.item", colorEncoder.scale, colorEncoder.colors, null, null);                          var itemLegend:Legend = new Legend("data.item", colorEncoder.scale, colorEncoder.colors, null, null);
251              var groupLegend:Legend = new Legend("data.group", shapeEncoder.scale, null, shapeEncoder.shapes, null);              var groupLegend:Legend = new Legend("data.group", shapeEncoder.scale, null, shapeEncoder.shapes, null);
252    
253                  var xLabelsHeight:int = getMaxHeight(vis.xyAxes.xAxis.labels);              // Set the bounds of the visualization based on the hieght and width of the flash application,
254                // and the other components so the visualization is takes up the unused space.
255              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));              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));
256    
257                // Add the visualization to the main sprite.
258              addChild(vis);              addChild(vis);
259    
260                // Set up the properitys of the data sprites and add a eventlistener to check for
261                // clicks on them.
262              vis.data.visit(function(d:DataSprite):void {              vis.data.visit(function(d:DataSprite):void {
263                                  d.fillColor = 0x018888ff;                                  d.fillColor = 0x018888ff;
264                                  d.fillAlpha = 0.2;                                  d.fillAlpha = 0.2;
# Line 142  Line 266 
266                                  d.addEventListener(MouseEvent.CLICK, mouseClicked);                                  d.addEventListener(MouseEvent.CLICK, mouseClicked);
267                          });                          });
268    
269              itemLegend.x = vis.bounds.width + 10;              // Position the legends.
270                legends.x = vis.bounds.width + 10;
271                itemLegend.x = 0;
272              itemLegend.y = 0;              itemLegend.y = 0;
273              groupLegend.x = vis.bounds.width + 10;              groupLegend.x = 0;
274              groupLegend.y = itemLegend.y + itemLegend.height;              groupLegend.y = itemLegend.y + itemLegend.height;
275    
276                // Add a listener for mouse clicks on the legends.
277                itemLegend.items.addEventListener(MouseEvent.CLICK, legendClick);
278                groupLegend.items.addEventListener(MouseEvent.CLICK, legendClick);
279    
280                // Add the legends to the legends container.
281                legends.addChild(itemLegend);
282                legends.addChild(groupLegend);
283    
284                // Set up and add a hover control to each legend.
285                var itemHC:HoverControl = new HoverControl(itemLegend.items);
286                itemHC.onRollOver = legendRollOver;
287                            itemHC.onRollOut = legendRollOut;
288                var groupHC:HoverControl = new HoverControl(groupLegend.items);
289                groupHC.onRollOver = legendRollOver;
290                            groupHC.onRollOut = legendRollOut;
291    
292    
293                // Position and add the labels and title to the axes.
294                          labelX.x = vis.bounds.width/2 - labelX.width/2;                          labelX.x = vis.bounds.width/2 - labelX.width/2;
295                          labelX.y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + xLabelsHeight;                          labelX.y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + xLabelsHeight;
296              vis.xyAxes.xAxis.addChild(labelX);              vis.xyAxes.xAxis.addChild(labelX);
# Line 161  Line 304 
304                          title.y = -vis.y;                          title.y = -vis.y;
305                          vis.xyAxes.addChild(title);                          vis.xyAxes.addChild(title);
306    
307              vis.addChild(itemLegend);                  // Add the legeneds container to the visualization.
308              vis.addChild(groupLegend);              vis.addChild(legends);
             vis.setChildIndex(vis.marks, vis.numChildren - 1);  
309    
310                // Set up the hovercontrol for the marks on the chart
311              var hc:HoverControl = new HoverControl(vis, Filters.isDataSprite);              var hc:HoverControl = new HoverControl(vis, Filters.isDataSprite);
312              hc.onRollOver = rollOver;              hc.onRollOver = rollOver;
313                          hc.onRollOut = rollOut;                          hc.onRollOut = rollOut;
314    
315                          var bInvert:Button = new Button("Invert Axis");                          // Set up the buttons and a container for them.
316                            var controls:Sprite = new Sprite();
317                            var bInvert:Button = new Button("Invert Axes");
318                            var bHideAxis:Button = new Button("Hide Axes");
319                            var bHideXLabel:Button = new Button("Hide X Labels");
320                            var bHideYLabel:Button = new Button("Hide Y Labels");
321    
322                            var hideXLabelTransitioner:Transitioner = new Transitioner(2);
323                            bHideXLabel.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
324                                    if(!hideXLabelTransitioner.running) {
325                                            hideXLabelTransitioner.reset();
326    
327                                            if(bHideXLabel.text == "Show X Labels") {
328                                                    bHideXLabel.text = "Hide X Labels";
329                                                    vis.xyAxes.xAxis.showLabels = true;
330                                                    vis.bounds = new Rectangle(0, 0, loaderInfo.width - (legends.width + 15 + vis.x), loaderInfo.height - (vis.y + xLabelsHeight + labelX.height + vis.xyAxes.xAxis.labelOffsetY));
331                                            } else {
332                                                    bHideXLabel.text = "Show X Labels";
333                                                    vis.xyAxes.xAxis.showLabels = false;
334                                                    vis.bounds = new Rectangle(0, 0, loaderInfo.width - (legends.width + 15 + vis.x), loaderInfo.height - (vis.y + labelX.height));
335                                            }
336    
337                                            hideXLabelTransitioner.$(labelY).x = -vis.x;
338                                            hideXLabelTransitioner.$(labelY).y = vis.bounds.height/2 - labelY.height/2;
339    
340                                            vis.update(hideXLabelTransitioner).play();
341                                    }
342                            });
343    
344                            var hideYLabelTransitioner:Transitioner = new Transitioner(2);
345                            bHideYLabel.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
346                                    if(!hideYLabelTransitioner.running) {
347                                            var t:Transitioner = new Transitioner(2);
348                                            var newX:int;
349    
350                                            hideYLabelTransitioner.reset();
351    
352                                            if(bHideYLabel.text == "Show Y Labels") {
353                                                    bHideYLabel.text = "Hide Y Labels";
354                                                    vis.xyAxes.yAxis.showLabels = true;
355                                                    newX = labelY.width + -vis.xyAxes.yAxis.labelOffsetX + yLabelsWidth;
356                                            } else {
357                                                    bHideYLabel.text = "Show Y Labels";
358                                                    vis.xyAxes.yAxis.showLabels = false;
359                                                    newX = labelY.width;
360                                            }
361    
362                                            t.$(vis).x = newX;
363                                            vis.bounds = new Rectangle(0, 0, loaderInfo.width - (legends.width + 15 + newX), loaderInfo.height - (vis.y + xLabelsHeight + labelX.height + vis.xyAxes.xAxis.labelOffsetY));
364    
365                                            // Reposition the labels and title.
366                                            t.$(title).x = vis.bounds.width/2 - title.width/2;
367                                            t.$(labelX).x = vis.bounds.width/2 - labelX.width/2;
368                                            t.$(labelX).y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + xLabelsHeight;
369                                            t.$(labelY).x = -newX;
370                                            t.$(labelY).y = vis.bounds.height/2 - labelY.height/2;
371    
372                                            // Keep the legends in there place.
373                                            t.$(legends).x = vis.bounds.width + 10;
374    
375                                            t.play();
376                                            vis.update(hideYLabelTransitioner).play();
377                                    }
378                            });
379    
380                            // Set up the transitioner to be used when inverting the axes
381                            var updateTransitioner:Transitioner = new Transitioner(2);
382                            updateTransitioner.onEnd = function():void {
383                                    updateMarkVisiblity();
384                                    vis.xyAxes.xAxis.labels.visible = true;
385                                    vis.xyAxes.yAxis.labels.visible = true;
386                            };
387                updateTransitioner.onStart = function():void {
388                    updateMarkVisiblity();
389                    vis.xyAxes.xAxis.labels.visible = false;
390                                    vis.xyAxes.yAxis.labels.visible = false;
391                }
392    
393                            // The function to invert the axes.
394                          bInvert.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {                          bInvert.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
395                                  var t1:Transitioner = new Transitioner(2);                                  // If we are not allready in the process of inverting the axes.
396                                  var t2:Transitioner = new Transitioner(2);                                  if(!updateTransitioner.running) {
397                                  var t3:Transitioner = new Transitioner(2);                                          var t:Transitioner = new Transitioner(2);
                                 var t4:Transitioner = new Transitioner(2);  
                                 var t5:Transitioner = new Transitioner(2);  
                                 var t6:Transitioner = new Transitioner(2);  
398                                  var tempText:String = labelX.text;                                  var tempText:String = labelX.text;
399                                  var tempOffset:int = vis.xyAxes.xAxis.labelOffsetX;                                  var tempOffset:int = vis.xyAxes.xAxis.labelOffsetX;
400                                  var tempWidth:uint = vis.bounds.width;                                  var tempWidth:uint = vis.bounds.width;
                                 var xLabelsHeight:int = getMaxWidth(vis.xyAxes.yAxis.labels);  
401    
402                                            var tempLabels:int = xLabelsHeight;
403                                            var currentXLabelsHeight:int = getMaxWidth(vis.xyAxes.yAxis.labels);
404    
405                                            var tempShowLabels:Boolean = vis.xyAxes.xAxis.showLabels;
406    
407                                            // Rest the transitioner for a clean transition.
408                                            updateTransitioner.reset();
409    
410                                            // Flip the axis feilds.
411                                  al.xField = axisY;                                  al.xField = axisY;
412                                  al.yField = axisX;                                  al.yField = axisX;
413                                  axisX = al.xField;                                  axisX = al.xField;
414                                  axisY = al.yField;                                  axisY = al.yField;
415    
416                                            xLabelsHeight = yLabelsWidth;
417                                            yLabelsWidth = tempLabels;
418    
419                                            vis.xyAxes.xAxis.showLabels = vis.xyAxes.yAxis.showLabels;
420                                            vis.xyAxes.yAxis.showLabels = tempShowLabels;
421    
422                                            if(vis.xyAxes.yAxis.showLabels) {
423                                                    bHideYLabel.text = "Hide Y Labels";
424                                            } else {
425                                                    bHideYLabel.text = "Show Y Labels";
426                                            }
427    
428                                            if(vis.xyAxes.xAxis.showLabels) {
429                                                    bHideXLabel.text = "Hide X Labels";
430                                            } else {
431                                                    bHideXLabel.text = "Show X Labels";
432                                            }
433    
434    
435                                            // Flip the labels
436                                  labelX.text = labelY.text;                                  labelX.text = labelY.text;
437                                  labelY.text = tempText;                                  labelY.text = tempText;
438    
439                                            // Find the new X value for the visualization.
440                                  var newX:int = labelY.width + vis.xyAxes.xAxis.labelOffsetY + getMaxHeight(vis.xyAxes.xAxis.labels);                                  var newX:int = labelY.width + vis.xyAxes.xAxis.labelOffsetY + getMaxHeight(vis.xyAxes.xAxis.labels);
441    
442                                  t1.$(vis).x = newX;                                          // Reposition and set the bounds of the visualization.
443                                  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));                                          t.$(vis).x = newX;
444                                            vis.bounds = new Rectangle(0, 0, loaderInfo.width - (legends.width + 15 + newX), loaderInfo.height - (vis.y + currentXLabelsHeight + labelX.height + vis.xyAxes.xAxis.labelOffsetY));
445    
446                                            // Reposition the labels and title.
447                                            t.$(title).x = vis.bounds.width/2 - title.width/2;
448                                            t.$(labelX).x = vis.bounds.width/2 - labelX.width/2;
449                                            t.$(labelX).y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + currentXLabelsHeight;
450                                            t.$(labelY).x = -newX;
451                                            t.$(labelY).y = vis.bounds.height/2 - labelY.width/2;
452    
453                                            // Keep the legends in there place.
454                                            t.$(legends).x = vis.bounds.width + 10;
455    
456                                            //Play the transition.
457                            t.play();
458                            vis.update(updateTransitioner).play();
459                            }
460                            });
461    
462                                  t1.$(title).x = vis.bounds.width/2 - title.width/2;                          // Set up the transitioner for the hide axes button.
463                            var hideAxisTrans:Transitioner = new Transitioner(1);
464    
465                                  t1.$(labelX).x = vis.bounds.width/2 - labelX.width/2;                          // Function for hidding the axes.
466                                  t1.$(labelX).y = vis.bounds.height + vis.xyAxes.xAxis.labelOffsetY + xLabelsHeight;                          bHideAxis.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
467                                  t1.$(labelY).x = -newX;                                  // If we are not allready in the process of hidding the axes
468                                  t1.$(labelY).y = vis.bounds.height/2 - labelY.width/2;                                  if(!hideAxisTrans.running) {
469                                            // Reset the transitoner for a clean transiton.
470                                            hideAxisTrans.reset();
471    
472                                            // Hide or show the axes.
473                                            if(bHideAxis.text == "Show Axes") {
474                                                    hideAxisTrans.$(bHideAxis).text = "Hide Axes";
475                                                    al.showAxes(hideAxisTrans).play();
476                                            } else {
477                                                    hideAxisTrans.$(bHideAxis).text = "Show Axes";
478                                                    al.hideAxes(hideAxisTrans).play();
479                                            }
480                                    }
481                            });
482    
483                                  t1.$(itemLegend).x = vis.bounds.width + 10;                          // Position the buttons inside there container.
484                  t1.$(groupLegend).x = vis.bounds.width + 10;                          bHideXLabel.x = 0;
485                            bHideXLabel.y = 0;
486    
487                            bHideAxis.x = legends.width - bHideAxis.width - 5;
488                            bHideAxis.y = bHideXLabel.y;
489    
490                            bInvert.x = legends.width - bInvert.width - 5;
491                            bInvert.y = bHideXLabel.y + bHideXLabel.height + 2;
492    
493                            bHideYLabel.x = 0;
494                            bHideYLabel.y = bHideXLabel.y + bHideXLabel.height + 2;
495    
496                            // Poistion the buttons container.
497                            controls.x = legends.x + vis.x;
498                            controls.y = legends.y + legends.height + vis.y + 20;
499    
500                            // Add the buttons to the container and the container to the main sprite.
501                            controls.addChild(bInvert);
502                            controls.addChild(bHideAxis);
503                            controls.addChild(bHideXLabel);
504                            controls.addChild(bHideYLabel);
505                            addChild(controls);
506    
507                  t1.play()                          // Set the marks on the chart to the higest deepth.
508                  vis.update(new Transitioner(2)).play();              vis.setChildIndex(vis.marks, vis.numChildren - 1);
                         });  
                         addChild(bInvert);  
509    
510                            // Update.
511                          vis.update();                          vis.update();
512                            updateMarkVisiblity();
513          }          }
514    
515            /**
516            * Roll over function witch makes the object 0.5 units bigger and adds a glow filter.
517            * @param ob the object witch was rolled over.
518            */
519          private function rollOver(ob:Object):void {          private function rollOver(ob:Object):void {
520                  ob.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)];                  ob.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)];
521                    ob.size += 0.5;
522          }          }
523    
524            /**
525            * Roll out function witch removes the filters and makes the object 0.5 units smaller.
526            * @param ob the object witch was rolled out of.
527            */
528          private function rollOut(ob:Object):void {          private function rollOut(ob:Object):void {
529                  ob.filters = null;                  ob.filters = null;
530                    ob.size -= 0.5;
531          }          }
532    
533            /**
534            * Roll over function for the dialog box.
535            * Adds a glow filter to the curently active dialog box.
536            * @param ob a child of the dialog box.
537            */
538          private function boxRollOver(ob:Object):void {          private function boxRollOver(ob:Object):void {
539                  if(lastBoxData != null) {                  if(lastBoxData != null) {
540                          lastBoxData.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)];                          lastBoxData.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)];
541                  }                  }
542          }          }
543    
544            /**
545            * Roll out function for the dialog box.
546            * Removes filters on the curently active dialog box.
547            * @param ob a child of the dialog box.
548            */
549          private function boxRollOut(ob:Object):void {          private function boxRollOut(ob:Object):void {
550                  if(lastBoxData != null) {                  if(lastBoxData != null) {
551                          lastBoxData.filters = null;                          lastBoxData.filters = null;
552                  }                  }
553          }          }
554    
555            /**
556            * Finds the Legend belonging to the LegendItem passed.
557            * TODO: See if this can be replaced by a .parent call.
558            * @param item a LegendItem to find the Legend of.
559            * @return the Legend that contains the passed LegendItem.
560            */
561            private function findLegendByItem(item:LegendItem):Legend {
562                    for(var i:uint = 0; i < legends.numChildren; i++ ) {
563                            if(Legend(legends.getChildAt(i)).items.contains(item)) {
564                                    return Legend(legends.getChildAt(i));
565                            }
566                    }
567    
568                    return null;
569            }
570    
571            /**
572            * Roll over function for legends.
573            * Adds a glow filter to the legend's item aswell as all the markers on the chart
574            * that are realted to the legend item and incrases there size by 1 unit.
575            * @param ob the LegendItem being rolled over.
576            */
577            private function legendRollOver(ob:LegendItem):void {
578                    var legend:Legend = findLegendByItem(ob);
579                    var dataName:String = legend.dataField.substr(legend.dataField.lastIndexOf('.') + 1);
580    
581                    ob.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)];
582    
583                    vis.data.visit(function(d:DataSprite):void {
584                                    if(d.data.hasOwnProperty(dataName) && ob.value == d.data[dataName]) {
585                                            d.filters = [new GlowFilter(0xFFFF55, 0.8, 6, 6, 10)];
586                                            d.size += 1;
587                                    }
588                            }, 3, Filters.isDataSprite);
589            }
590    
591            /**
592            * Roll out function for legends.
593            * Removes filters to the legend's item aswell as all the markers on the chart
594            * that are realted to the legend item and decrases there size by 1 unit.
595            * @param ob the LegendItem being rolled out of.
596            */
597            private function legendRollOut(ob:LegendItem):void {
598                    var legend:Legend = findLegendByItem(ob);
599                    var dataName:String = legend.dataField.substr(legend.dataField.lastIndexOf('.') + 1);
600    
601                    ob.filters = null;
602    
603                    vis.data.visit(function(d:DataSprite):void {
604                                    if(d.data.hasOwnProperty(dataName) && ob.value == d.data[dataName]) {
605                                            d.filters = null;
606                                            d.size -= 1;
607                                    }
608                            }, 3, Filters.isDataSprite);
609            }
610    
611            /**
612            * Creates and returns a dialog box containing information on the passed data sprite.
613            * @param data the DataSprite containing the information to display.
614            * @returns the Sprite containing the dialog box.
615            */
616          private function dataDialogBox(data:DataSprite):Sprite {          private function dataDialogBox(data:DataSprite):Sprite {
617                  var box:Sprite = new Sprite;                  var box:Sprite = new Sprite;
618    
# Line 241  Line 621 
621                  backGround.graphics.lineStyle(3, 0x0000ff, 0.3);                  backGround.graphics.lineStyle(3, 0x0000ff, 0.3);
622    
623                  var text:Sprite = new Sprite;                  var text:Sprite = new Sprite;
624                  var name:TextSprite = new TextSprite(data.data.student, new TextFormat("mono", 20, null, true));                  var x:int = 5;
625                    var y:int = 0;
626    
627                    for(var property:Object in data.data) {
628                            var temp:TextSprite = new TextSprite(property.toString() + ": " + data.data[property], new TextFormat("mono", 12, null, true));
629                            temp.x = x;
630                            temp.y = y;
631                            text.addChild(temp);
632                            y += temp.height;
633                    }
634    
635                    /*var name:TextSprite = new TextSprite(data.data.student, new TextFormat("mono", 20, null, true));
636                  var item:TextSprite = new TextSprite("Item: " + data.data.item, new TextFormat("mono", 12, null, true));                  var item:TextSprite = new TextSprite("Item: " + data.data.item, new TextFormat("mono", 12, null, true));
637                  var grade:TextSprite = new TextSprite("Grade: " + data.data.grade + "%", new TextFormat("mono", 12, null, true));                  var grade:TextSprite = new TextSprite("Grade: " + data.data.grade + "%", new TextFormat("mono", 12, null, true));
638                  var group:TextSprite = new TextSprite("Group: " + data.data.group, new TextFormat("mono", 12, null, true));                  var group:TextSprite = new TextSprite("Group: " + data.data.group, new TextFormat("mono", 12, null, true));
# Line 258  Line 649 
649                  name.y = 0;                  name.y = 0;
650                  item.y = name.y + name.height;                  item.y = name.y + name.height;
651                  group.y = item.y + item.height;                  group.y = item.y + item.height;
652                  grade.y = group.y + group.height;                  grade.y = group.y + group.height;*/
653    
654                  backGround.graphics.drawRoundRect(0, 0, text.width + 5, text.height, 30, 30);                  backGround.graphics.drawRoundRect(0, 0, text.width + 10, text.height, 30, 30);
655    
656                  box.addChild(backGround);                  box.addChild(backGround);
657                  box.addChild(text);                  box.addChild(text);
# Line 268  Line 659 
659                  return box;                  return box;
660          }          }
661    
662            /**
663            * Check if a mark on the chart is visible based on the related LegendItems states.
664            * @param d the DataSprite to check the visiblility of.
665            * @returns true if the mark is visible.
666            */
667            private function markIsVisible(d:DataSprite):Boolean {
668                    var items:Array = getLegendItems(d);
669    
670                    for each(var item:LegendItem in items) {
671                            if(item.alpha != 1) {
672                                    return false;
673                            }
674                    }
675    
676                    return true;
677            }
678    
679            /**
680            * Gets all LegenedItems realted to a given DataSprite/mark.
681            * @params d the DataSprite on the chart.
682            * @returns Array of LegendItems that are realted to the given DataSprite.
683            */
684            private function getLegendItems(d:DataSprite):Array {
685                    var items:Array = new Array();
686    
687                    for(var i:uint = 0; i < legends.numChildren; i++) {
688                            var legend:Legend = Legend(legends.getChildAt(i));
689    
690                            for(var k:uint = 0; k < legend.items.numChildren; k++) {
691                                    var item:LegendItem = LegendItem(legend.items.getChildAt(k));
692    
693                                    if(d.data[legend.dataField.substr(legend.dataField.lastIndexOf('.') + 1)] == item.value) {
694                                            items.push(item);
695                                            break;
696                                    }
697                            }
698                    }
699    
700                    return items;
701            }
702    
703            /**
704            * Sets the visible atrubute of the marks/DataSprites based on the status of the LegendItems realted to it.
705            * @param item if set, only updates marks for that LegendItem. Otherwise updates all marks.
706            */
707            private function updateMarkVisiblity(item:LegendItem=null):void {
708                    var legend:Legend;
709                    var dataName:String;
710    
711                    if(item != null) {
712                            legend = findLegendByItem(item);
713                            dataName = legend.dataField.substr(legend.dataField.lastIndexOf('.') + 1);
714                    }
715    
716                    vis.data.visit(function(d:DataSprite):void {
717                                    if(item == null || (d.data.hasOwnProperty(dataName) && item.value == d.data[dataName])) {
718                                            if(markIsVisible(d)) {
719                                                    //d.alpha = 1.0;
720                                                    d.visible = true;
721                                            } else {
722                                                    //d.alpha = 0.0;
723                                                    d.visible = false;
724                                            }
725                                    }
726                            }, 3, Filters.isDataSprite);
727            }
728    
729            /**
730            * Function to be called when a LegendItem is clicked.
731            * Changes the legendItems alpah value and updates mark visiblity.
732            * @param evt the mouse event.
733            */
734            private function legendClick(evt:MouseEvent):void {
735                    var item:LegendItem = LegendItem(evt.target);
736    
737                    if(item.alpha == 1) {
738                            item.alpha = 0.4;
739                    } else {
740                            item.alpha = 1.0;
741                    }
742    
743                    updateMarkVisiblity(item);
744            }
745    
746            /**
747            * Function called when a click happens on a mark on the chart.
748            * Creates and adds a dialog box for that mark/DataSprite when clicked or removes the dialog box if
749            * the mark allready has one.
750            * @param the mouse event.
751            */
752          private function mouseClicked(evt:MouseEvent):void {          private function mouseClicked(evt:MouseEvent):void {
753                  if(DisplayObject(evt.target).parent == vis.marks) {                  if(DisplayObject(evt.target).parent == vis.marks) {
754                          if(lastBox != null && lastBoxData != null) {                          if(lastBox != null && lastBoxData != null) {
755                                  lastBoxData.removeChild(lastBox);                                  lastBoxData.removeChild(lastBox);
756                                    boxhc.detach();
757                          }                          }
758    
759                          if(evt.target != lastBoxData) {                          if(evt.target != lastBoxData) {
# Line 279  Line 761 
761                                  lastBoxData = DataSprite(evt.target);                                  lastBoxData = DataSprite(evt.target);
762                                  Sprite(evt.target).addChild(lastBox);                                  Sprite(evt.target).addChild(lastBox);
763                                  vis.marks.setChildIndex(Sprite(evt.target), vis.marks.numChildren - 1);                                  vis.marks.setChildIndex(Sprite(evt.target), vis.marks.numChildren - 1);
764                                  var hc:HoverControl = new HoverControl(Sprite(evt.target), null);                                  boxhc.attach(Sprite(evt.target));
                         hc.onRollOver = boxRollOver;  
                                         hc.onRollOut = boxRollOut;  
765                          } else {                          } else {
766                                  lastBoxData = null;                                  lastBoxData = null;
767                                  lastBox = null;                                  lastBox = null;

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

Moodle CVS Admin
ViewVC Help
Powered by ViewVC 1.0.7