DataPointSet.as |
/* author: Sammy Joe Osborne date: 09/21/06 DataPointSet is a linked list implementation I ported from Java to Actionscript 2.0. It is used to link together DataPoint objects. The Node class is also used in this implementation. Each Node contains data (the actual DataPoint object), a nextNode, and a previousNode which simply contain (or point to) the Node before or after itself in the chain. FUNCTIONS: DataPointSet() //The constructor addDataPoint(o:Object) //Recieves a DataPoint object and adds a node to the set with this DataPoint as it's data removeDataPoint() //Removes the current node isEmpty() //Returns a boolean if the list is empty or not getDataPoint() //Returns the DataPoint object contained in the current node getNextDataPoint() //Returns the DataPoint object contained in the node after current atEnd() //Returns a boolean true or false if the current node is at the end of the list advance() //Iterates the DataPointSet to move to the next node in the chain reset() //Sets currentPoint back to the beginning of the DataPointSet (the head node) display() drawPoints() //draws all points in the dataSet to the stage drawLines() NOTES: An onEnterFrame function in the Graph class continually calls the drawLine function in this class to move them with the dots when they move. Depth management to keep the dots on top of the lines is done within this class. Depth management to keep DataPointSets on top of each other will have to be done in the Graph class. */ import mx.transitions.Tween; import mx.transitions.easing.*; class DataPointSet extends MovieClip{ //current, previous, and next nodes var headPoint:Node; var currentPoint:Node; var previousPoint:Node; var nextPoint:Node; var pointCount:Number; var linesDrawn:Boolean; var varName:String; var myColor:Object; function DataPointSet(){ //do nothing } //_color sent as an object just incase I emplement other forms of color later.......? right now its a string. public function init(_color:Object){ headPoint = null; currentPoint = null; previousPoint = null; nextPoint = null; pointCount = 0; linesDrawn = false; varName = this._name; myColor = _color; trace("The constructor just ran"); return this; } //adds a new point to the list //it actually adds the attached movie clip into the linked list. Attach movie actually returns a movieClip object, so I had the init() function return a DataPoint object, which is just an extended MovieClip object. public function addDataPoint(_xCoordinate:Number, _yCoordinate:Number, _graphStats:Object):Void{ pointCount++; //create movieclips the points and lines will exist on if(this["Points"]._x == undefined){ this.createEmptyMovieClip(("Points"), 2); this.createEmptyMovieClip(("Lines"), 1); } var n:Node = new Node(this["Points"].attachMovie("DataPoint", varName + pointCount, pointCount,{}).init(_xCoordinate, _yCoordinate, myColor, _graphStats), null); if(headPoint == null) headPoint = n; else{ reset(); gotoEndingPoint();//go to last point in the list to add new point after it (just incase list has been reset) currentPoint.nextNode = n; previousPoint = currentPoint; } currentPoint = n; } //remove a point from the list public function removeDataPoint():Void{ if(headPoint != null){ if(previousPoint == null) headPoint = headPoint.nextNode; else previousPoint.nextNode = currentPoint.nextNode; currentPoint = currentPoint.nextNode; } pointCount--; } //determine if the DataPointSet is empty public function isEmpty():Boolean{ if(headPoint == null) return true; return false; } //returns the DataPoint object in the current position; returns null if the current element is null public function getDataPoint():Object{ if(currentPoint != null) return currentPoint.dataObject; return null; } //returns the next DataPoint object held in the node pointed to by the current node, but doesn't change current public function getNextDataPoint():Object{ if(currentPoint != null) return currentPoint.nextNode.dataObject; return null; } //determines if we are at the end of the list of points (if we are on the last point) public function atEnd():Boolean{ return currentPoint == null; } //sets currentPoint to the ending point in the list public function gotoEndingPoint():Void{ while(currentPoint.nextNode != null){ advance(); } } //Advances currentPoint to be the next DataPoint in the chain public function advance():Void{ if(!atEnd()){ previousPoint = currentPoint; currentPoint = currentPoint.nextNode; } } //resets to the beginning of the list public function reset():Void{ previousPoint = null; currentPoint = headPoint; } //From the first point, outputs all x,y graph coords of points public function display():Void{ reset(); if(headPoint != null){ do{ trace("x:" + getDataPoint().xcoord + " y:" + getDataPoint().ycoord); advance(); }while(!atEnd()); } } //returns an array of all the points in this set in the form of a DataProvider so it can populate a DataGrid component public function getDataProvider():Array{ reset(); var DP:Array = new Array(); var i = 0; if(headPoint != null){ do{ DP[i] = ({X:(""+getDataPoint().xcoord), Y:(""+getDataPoint().ycoord)}); advance(); i++; }while(!atEnd()); } return DP; } //makes all points (dots) visible public function drawPoints():Void{ reset(); var i = 1; do{ this["Points"][varName+i]._visible = true; i++; advance(); }while(i<=pointCount); } //Simply draws a fat black line, then draws another thinner line of color over it to give appareance if black outlines with a fill public function drawLines():Void{ reset(); this["Lines"].clear(); if(headPoint != null){ while(getNextDataPoint() != null){ this["Lines"].lineStyle(3.8, 0x000000, 100); this["Lines"].moveTo(getDataPoint()._x, getDataPoint()._y); this["Lines"].lineTo(getNextDataPoint()._x, getNextDataPoint()._y); this["Lines"].lineStyle(2, Number(myColor), 100); this["Lines"].moveTo(getDataPoint()._x, getDataPoint()._y); this["Lines"].lineTo(getNextDataPoint()._x, getNextDataPoint()._y); advance(); updateAfterEvent(); } } } /*public function drawLines_Old(customLine:String):Void{ reset(); var i = 1; var lineName; if(_parent[varName + "Lines"]._x == undefined){ _parent.createEmptyMovieClip((varName + "Lines"), 1); } while(getNextDataPoint() != undefined){ lineName = varName + customLine + i; if(_parent[varName + "Lines"][lineName]._x == undefined){ _parent[varName + "Lines"].attachMovie(customLine, lineName, _parent[varName + "Lines"].getNextHighestDepth()); } _parent[varName + "Lines"][lineName]._rotation = 0; _parent[varName + "Lines"][lineName]._width = getDistance(_parent[varName + "Points"][varName + i], _parent[varName + "Points"][varName + (i + 1)]); _parent[varName + "Lines"][lineName]._rotation = getAngle(_parent[varName + "Points"][varName + i], _parent[varName + "Points"][varName + (i + 1)]); _parent[varName + "Lines"][lineName]._x = _parent[varName + "Points"][varName + i]._x; _parent[varName + "Lines"][lineName]._y = _parent[varName + "Points"][varName + i]._y; advance(); i++; } }*/ //Returns the distance between two points. Used for drawing a line between the two points. public function getDistance(point1, point2):Number{ var a, b, c; a = Math.abs(point2._x - point1._x); b = Math.abs(point2._y - point1._y); c = Math.sqrt(a*a + b*b); return c; } //Returns an angle in degrees public function getAngle(point1, point2):Number{ var a, b, c, angle; a = point2._x - point1._x; b = point2._y - point1._y; //c = Math.sqrt(a*a + b*b); angle = Math.atan(b/a); //this is in radians angle = angle*180/Math.PI; //converts radians to degrees return angle; } public function animateDots(goalsPassed:DataPointSet):Void{ reset(); var goals:DataPointSet = goalsPassed; goals.reset(); var newX, newY; var i = 1; var instanceName:String; if(headPoint != null){ do{ instanceName = varName + i; newX = goals.getDataPoint().xcoord; newY = goals.getDataPoint().ycoord; this["Points"][instanceName].animateTo(newX, newY); advance(); goals.advance(); i++; }while(!goals.atEnd()); } } public function changeColor(newColor:Object):Void{ myColor = newColor; reset(); while(getDataPoint() != undefined){ getDataPoint().color = newColor; advance(); } drawLines(); } public function set color(value:Object):Void{ myColor = value; } public function get color():Object{ return myColor; } public function toString():String{ return (pointCount + " points in chain"); } }