DataPointSet.as
DataPoint.as


/*
author: Sammy Joe Osborne
date: 09/15/06
DataPoint Class
*/

import mx.transitions.Tween;
import mx.transitions.easing.*;
import flash.geom.*;


class DataPoint extends MovieClip{
        
        
        //private instance variables
        private var _graphXCoord:Number = 0; //the coordinate on the graph (not the pixel coordinates)  ----> accessed by xcoord getter/setter functions
        private var _graphYCoord:Number = 0; //the coordinate on the graph (not the pixel coordinates)  ----> accessed by ycoord getter/setter functions
        private var graphStats:Object; //an object containing 4 properties of the graph: xMargin, yMargin, xUnit, yUnit
        private var _color:String;//The color used for this point
        
        
        //constructor
        public function DataPoint(){
                //do nothing
        }
        
        public function init(graphXCoord:Number, graphYCoord:Number, _color:String, _graphStats:Object):DataPoint{
                this.graphStats = _graphStats;
                this.ycoord = graphYCoord;
                this.xcoord = graphXCoord;
                
                this._color = _color;
                this._visible = false;
                
                
                this.createEmptyMovieClip("circle_mc", this.getNextHighestDepth());
                //circle_mc._x = 0;
                //circle_mc._y = 0;
                drawCircle(this["circle_mc"],3.6, Number(this._color), 100);
                
                
                //update number of points created
                _global.pointCount++;
                return this;
        }
        
        
        
        private function drawCircle(target_mc:MovieClip, radius:Number, fillColor:Number, fillAlpha:Number):Void {
                var x:Number = 0;
                var y:Number = 0;
                var fillColor1 = calcGradient(fillColor, 130);
                var fillColor2 = calcGradient(fillColor, 90);
                with (target_mc) {
                        
                        lineStyle(.5, 0x000000, 100, false, "none", "none");
                        colors = [fillColor1, fillColor2];
                        fillType = "radial";
                        alphas = [100, 100];
                        ratios = [35, 200];
                        spreadMethod = "pad";
                        interpolationMethod = "RGB";
                        focalPointRatio = 0;
                        matrix = new Matrix();
                        matrix.createGradientBox(radius*2, radius*2, 0, -(radius), -(radius));
                        beginGradientFill(fillType, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPointRatio);
                        
                        moveTo(x + radius, y);
                        curveTo(radius + x, Math.tan(Math.PI / 8) * radius + y, Math.sin(Math.PI / 4) * radius + x, Math.sin(Math.PI / 4) * radius + y);
                        curveTo(Math.tan(Math.PI / 8) * radius + x, radius + y, x, radius + y);
                        curveTo(-Math.tan(Math.PI / 8) * radius + x, radius+ y, -Math.sin(Math.PI / 4) * radius + x, Math.sin(Math.PI / 4) * radius + y);
                        curveTo(-radius + x, Math.tan(Math.PI / 8) * radius + y, -radius + x, y);
                        curveTo(-radius + x, -Math.tan(Math.PI / 8) * radius + y, -Math.sin(Math.PI / 4) * radius + x, -Math.sin(Math.PI / 4) * radius + y);
                        curveTo(-Math.tan(Math.PI / 8) * radius + x, -radius + y, x, -radius + y);
                        curveTo(Math.tan(Math.PI / 8) * radius + x, -radius + y, Math.sin(Math.PI / 4) * radius + x, -Math.sin(Math.PI / 4) * radius + y);
                        curveTo(radius + x, -Math.tan(Math.PI / 8) * radius + y, radius + x, y);
                        endFill();
                        
                }
        }
        
        private function translateCoordinates(xCoordinate:Number, yCoordinate:Number):Object{
                var pixelCoordinates:Object = new Object();
                pixelCoordinates.xCoordinate = graphStats.xMargin + xCoordinate * graphStats.xUnit;
                pixelCoordinates.yCoordinate = (graphStats.graphHeight - graphStats.yMargin) - yCoordinate * graphStats.yUnit;
                
                return pixelCoordinates;
        }
        
        //Setter functions
        public function set xcoord(value:Number):Void {
                this._graphXCoord = value;
                this._x = translateCoordinates(_graphXCoord, _graphYCoord).xCoordinate;
        }
        
        public function set ycoord(value:Number):Void {
                this._graphYCoord = value;
                this._y = translateCoordinates(_graphXCoord, _graphYCoord).yCoordinate;
        }
        
        public function set color(value:String):Void {
                this._color = value;
                this.createEmptyMovieClip("circle_mc", this["circle_mc"].getDepth());
                drawCircle(this["circle_mc"],3.6, Number(this._color), 100);
        }
        
        
        
        //Getter functions
        public function get xcoord():Number {
                return this._graphXCoord;
        }
        
        public function get ycoord():Number {
                return this._graphYCoord;
        }
        
        public function get color():String {
                return this._color;
        }
        
        public function get graphXCoord():Number{
                return _graphXCoord;
        }
        
        public function get graphYCoord():Number{
                return _graphYCoord;
        }
        
        //animate dot to a new x and y value
        public function animateTo(newX:Number, newY:Number){
                new Tween(this, "xcoord", Regular.easeInOut, this.xcoord, newX, 4, true);
                new Tween(this, "ycoord", Regular.easeInOut, this.ycoord, newY, 4, true);
        }
        
        public function toString():String{
                return ("Graph Coords: (" + _graphXCoord + ", " + _graphYCoord + ")\nPixel Coords: (" + _x + ", " + _y);
        }
        
        
        //--------------- gradient color calculation functions.  included here because they clutter this up and #include won't work in custom classes ------------------------------
        private function hexToRGB ( hex:Number ):Object{
                var returnObj:Object = new Object();
                returnObj.r = hex >> 16;
                var temp = hex ^ returnObj.r << 16;
                returnObj.g = temp >> 8;
                returnObj.b = temp ^ returnObj.g << 8;
                
                return returnObj;
        }
        
        
        private function RGBToHex (r, g, b ){
                var hex = r << 16 ^ g << 8 ^ b;
                return hex;
        }
        
        
        
        private function RGBToHLS(r,g,b):Object {
                var h,l,s;
                var max = (Math.max(Math.max(r, g), b))/255;
                var min = (Math.min(Math.min(r, g), b))/255;
                var delta = max-min;
                l = (max+min)/2;
                s = (max == min) ? 0 : ((l <= 0.5) ? delta/l/2 : delta/(2-l*2));
                if(r/255 == max) h = (g-b)/delta/255;
                else if(g/255 == max) h = 2+(b-r)/delta/255;
                else if(b/255 == max) h = 4+(r-g)/delta/255;
                h *= 40;
                if(h < 0) h += 240;
                h = Math.round(h);
                return {h:((isNaN(h)) ? 0 : h), l:Math.round(l*240), s:Math.round(s*240)};
        }
        
        private function HLSToRGB(h,l,s):Object {
                var r,g,b;
                if(s == 0) {
                        r = g = b = Math.round(l/240*255);
                } else {
                        h /= 240; l /= 240; s /= 240;
                        var temp4,temp3;
                        var temp2 = (l < 0.5) ? l*(s+1) : l+s-l*s;
                        var temp1 = l*2 - temp2;
                        for(var i=0; i<3; i++) {
                                switch(i) {
                                        case 0: temp3 = h+1/3; break;
                                        case 1: temp3 = h; break;
                                        case 2: temp3 = h-1/3; break;
                                }
                                if(temp3 < 0) temp3++;
                                else if(temp3 > 1) temp3--;
                                if(temp3*6 < 1) temp4 = temp1+(temp2-temp1)*6*temp3;
                                else if(temp3*2 < 1) temp4 = temp2;
                                else if(temp3*3 < 2) temp4 = temp1+(temp2-temp1)*((2/3)-temp3)*6;
                                else temp4 = temp1;
                                switch(i) {
                                        case 0: r = Math.round(temp4*255); break;
                                        case 1: g = Math.round(temp4*255); break;
                                        case 2: b = Math.round(temp4*255); break;
                                }
                        }
                }
                return {r:r, g:g, b:b};
        }
        
        private function calcGradient(hex:Number, percent:Number):Number{
                var rgb = hexToRGB(hex);
                var hls = RGBToHLS(rgb.r, rgb.g, rgb.b);
                hls.l = (hls.l)*(percent/100);
                if(hls.l > 240) hls.l = 240;
                if(hls.l < 0) hls.l = 0;
                rgb = HLSToRGB(hls.h, hls.l, hls.s);
                return RGBToHex(rgb.r, rgb.g, rgb.b);
        }
        
        
}