/* ----------------------------------------------------- */
/* coding: timor kodal [pulsar-network] */
/* copyright by: (c) 2010 timor kodal */
/* ----------------------------------------------------- */
/* contact: [http://pulsar.cc | timor [at] kodal.de */
/* ----------------------------------------------------- */
/* to see this and other scripts in action, please visit */
/* http://pulsar.cc */
/* ----------------------------------------------------- */
/* you are free to use my scripts */
/* according to the creative commons licence cc-nc-by */
/* ----------------------------------------------------- */
/* more information: http://creativecommons.org */
/* ----------------------------------------------------- */
package pflash.widget
{
import flash.display.*;
import flash.events.Event;
import flash.geom.*;
import flash.text.TextField;
import flash.text.TextFormat;
public class Flowchart extends MovieClip {
public var data : Object;
public var graph : Array;
public var range : Object;
public var colors : Array;
public var captionDuration = 400;
public var captionPosition : String = "final";
public var mcGrid : MovieClip;
public var mcStats : MovieClip;
public var w : Number = 200;
public var h : Number = 80;
public var invertX : Boolean = false;
public var invertY : Boolean = true;
public var dateX : Boolean = false;
public var dateY : Boolean = false;
public var intervalX : Number = 5;
public var intervalY : Number = 5;
public var highlightX : Number = 4;
public var highlightY : Number = 4;
public var meterX : Number = 1;
public var meterY : Number = 1;
public var textFormat : TextFormat = null;
/* CONSTRUCTOR */
public function Flowchart (data = false) {
this.data = new Object();
this.graph = new Array();
this.range = new Object();
this.colors = new Array();
this.colors['default'] = [uint(0xff8888),uint(0x44ff44)];
this.colors['gridX'] = uint(0x888888);
this.colors['gridY'] = uint(0x888888);
this.colors['meterX'] = uint(0x444444);
this.colors['meterY'] = uint(0x444444);
if (data)
this.importArray(data);
}
public function createGradient(colors,alphas:Array = null,ratios:Array = null):Object {
var gradient = new Object();
gradient.colors = colors;
if (alphas)
gradient.alphas = alphas;
else
gradient.alphas = [0.6,0.2];
if (ratios)
gradient.ratios = ratios;
else
gradient.ratios = [0x00,0xff];
return gradient;
}
private function drawStats (): Sprite {
var stats = new Sprite();
var dots = new Sprite();
stats.addChild(dots);
var realx;
var point:Point;
var nextPoint:Point;
var color;
var x1,x2,y1,y2: Number;
var first = new Array();
var last = new Array();
var typecount = 0;
var that = this;
for (var type in this.graph) {
if (this.colors[type]) {
color = this.colors[type];
} else if (typeof this.colors['default']=="number") {
color = this.colors['default'];
} else if (this.colors['default'][typecount%this.colors['default'].length]) {
color = this.colors['default'][typecount%this.colors['default'].length];
}
var label = new MovieClip();
if (typeof(color)=="object") {
stats.graphics.lineStyle(2,color.colors[0],0.8);
dots.graphics.lineStyle(2,color.colors[0],1);
label.graphics.beginFill(this.colors[type].colors[0]);
if (!color.matrix) {
color.matrix = new Matrix();
color.matrix.createGradientBox(this.h,80,Math.PI / 2,10,0);
}
stats.graphics.beginGradientFill(GradientType.LINEAR, color.colors, color.alphas, color.ratios, color.matrix, SpreadMethod.PAD);
} else {
stats.graphics.lineStyle(2,color,0.8);
dots.graphics.lineStyle(2,color,1);
stats.graphics.beginFill(color,0.4);
label.graphics.beginFill(color,0.8);
}
for (var x in this.graph[type]) {
point = this.graph[type][x];
x1 = (point.x-this.range.minx)/(this.range.maxx-this.range.minx)*this.w;
if (this.invertX)
x1 = this.w-x1;
y1 = (point.y-this.range.miny)/(this.range.maxy-this.range.miny)*this.h;
if (this.invertY)
y1 = this.h-y1;
if (!first[type]) {
first[type] = new Point(x1,y1);
stats.graphics.moveTo(x1,y1);
}
stats.graphics.lineTo(x1,y1);
dots.graphics.drawCircle(x1,y1,1);
if (this.graph[type][x+1]) {
nextPoint = this.graph[type][x+1];
trace(Math.floor(x1)+"x"+Math.floor(y1)+":"+Math.floor(x2)+"x"+Math.floor(y2));
} else {
nextPoint = new Point(point.x,this.range.miny);
if (that.captionDuration!=="permanent") {
label.addEventListener(Event.ENTER_FRAME,labelView);
var count = 0;
function labelView(e: Event) {
count++;
if (count>that.captionDuration)
e.target.alpha/=1.1;
}
}
var textfield = new TextField();
textfield.htmlText = ""+type+"";
textfield.selectable = false;
label.graphics.drawRect(0, 2, textfield.textWidth+3,textfield.textHeight);
label.graphics.endFill();
if (this.captionPosition=="final") {
label.y=y1-5;
label.x=x1+5;
} else {
label.y=0+typecount*(textfield.textHeight+1);
label.x=this.w+5;
}
if (label.x+textfield.textWidth>this.w-10)
label.x-=textfield.textWidth+12;
label.addChild(textfield);
label.alpha=0.8;
stats.addChild(label);
}
x2 = (nextPoint.x-this.range.minx)/(this.range.maxx-this.range.minx)*this.w;
if (this.invertX)
x2 = this.w-x2;
y2 = (nextPoint.y-this.range.miny)/(this.range.maxy-this.range.miny)*this.h;
if (this.invertY)
y2 = this.h-y2;
stats.graphics.lineTo(x2,y2);
last[type]=new Point(x2,y2);
}
stats.graphics.lineTo(last[type].x,this.h);
stats.graphics.lineTo(first[type].x,this.h);
stats.graphics.endFill();
typecount++;
}
return stats;
}
private function drawGrid (data = false): Sprite {
if (data)
this.importArray(data);
var grid = new Sprite();
var labels = new MovieClip();
if (this.intervalX<2)
this.intervalX=2;
if (this.intervalY<2)
this.intervalY=2;
var realx;
var realy;
for (var x=0;x<=this.w;x+=this.intervalX) {
realx = x;
if (!this.invertX)
realx = this.w-x;
if (realx/this.intervalX%this.highlightX==0) {
grid.graphics.lineStyle(1,this.colors['gridX']);
var num = Math.floor((this.w-x)/this.w*(this.range.maxx-this.range.minx)+this.range.minx);
var tfcontainer = new MovieClip();
var textfield = new TextField();
if (this.dateX) {
var d = new Date(num*1000);
num = Number(d.getMonth()+1)+" "+d.getFullYear();
}
if (this.textFormat) {
textfield.defaultTextFormat = this.textFormat;
textfield.embedFonts = true;
textfield.text = num;
textfield.rotation=90;
} else {
textfield.htmlText = ""+num+"";
}
//textfield.text = num;
textfield.selectable = false;
tfcontainer.addChild(textfield);
tfcontainer.y=this.h;
tfcontainer.x=realx+textfield.textHeight/2+2;
labels.addChild(tfcontainer);
} else
grid.graphics.lineStyle(1,this.colors['gridX'],0.5);
grid.graphics.moveTo(realx,0);
grid.graphics.lineTo(realx,this.h);
}
for (var y=0;y<=this.h;y+=this.intervalY) {
realy = y;
if (this.invertY)
realy = this.h-y;
if (realy/this.intervalY%this.highlightY==0) {
grid.graphics.lineStyle(1,this.colors['gridY']);
var num = Math.floor(y/this.h*(this.range.maxy-this.range.miny)+this.range.miny);
var textfield = new TextField();
if (this.dateY) {
var d = new Date(num*1000);
num = Number(d.getMonth()+1)+" "+d.getFullYear();
}
if (this.textFormat) {
textfield.defaultTextFormat = this.textFormat;
textfield.embedFonts = true;
textfield.text = num;
} else {
textfield.htmlText = ""+num+"";
}
textfield.selectable = false;
textfield.y=realy-textfield.textHeight/2-2;
textfield.x=this.w+2;
labels.addChild(textfield);
} else
grid.graphics.lineStyle(1,this.colors['gridY'],0.5);
grid.graphics.moveTo(0,realy);
grid.graphics.lineTo(this.w,realy);
}
grid.addChild(labels);
grid.alpha=0.5;
return grid;
}
public function draw (data = false) {
if (data)
this.importArray(data);
var mc = new MovieClip();
mc.addChild(this.drawGrid());
mc.addChild(this.drawStats());
mc.x=0;
mc.y=0;
this.addChild(mc);
}
public function importArray (data) {
this.data = data;
this.graph = new Array();
var buf;
var y; /* y-value */
var x; /* x-value */
var t; /* type */
var point:Point;
for(var t in this.data) {
if (!this.graph[t])
this.graph[t] = new Array();
var keys : Array = [];
for( var key : String in this.data[t] ) keys.push( key );
keys.sort();
for(var key in keys) {
x=keys[key];
y=this.data[t][x];
this.graph[t].push(new Point(x,y));
if (!this.range.hasOwnProperty('minx') || xthis.range['maxx'])
this.range.maxx=Number(x);
if (!this.range.hasOwnProperty('miny') || ythis.range['maxy'])
this.range.maxy=Number(y);
trace("statistics ("+this.graph[t].length+"): "+t+" :"+x+"/"+y);
}
}
trace(this.range.minx+" "+this.range.maxx+"/"+this.range.miny+" "+this.range.maxy);
}
public function importObjects (data) {
this.data = data;
this.graph = new Array();
var buf;
var y; /* y-value */
var x; /* x-value */
var t; /* type */
var point:Point;
for(var t in this.data) {
if (!this.graph[t])
this.graph[t] = new Array();
for(var key in this.data[t]) {
x=this.data[t][key].x;
y=this.data[t][key].y;
this.graph[t].push(new Point(x,y));
if (!this.range.hasOwnProperty('minx') || xthis.range['maxx'])
this.range.maxx=Number(x);
if (!this.range.hasOwnProperty('miny') || ythis.range['maxy'])
this.range.maxy=Number(y);
trace("statistics ("+this.graph[t].length+"): "+t+" :"+x+"/"+y);
}
}
trace(this.range.minx+" "+this.range.maxx+"/"+this.range.miny+" "+this.range.maxy);
}
}
}