Parent Directory
|
Revision Log
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 |