Transferred from the Adobe Open Source Subversion Repository

Revision: 12850
Author:   jimurphy@adobe.com
Date:     2009-12-11T14:57:14.623098Z

Log Message:
-----------
add 6 new DMV projects to the SDK:
automation
automation_air
automation_dmv
automation_flashflexkit
automation_spark
datavisualization

These projects are setup to build in an ant main call.  There are currently several warnings in the datavisualization project that will be cleaned up.  No checkintests exist for these projects as of yet.

I also modified the exisitng projects build files for easier management of the localization targets, bundle and fat-swc. If the projects that I updated:airframework,airspark,framework,playerglobal,rpc,and spark.  All the new projects have been implemented this same way.

QE notes: DMV folks should run through their tests
Doc notes: probably
Bugs: nope
Reviewer:
Tests run: ran the following targets: compile,checkintests,other.locales and doc
Is noteworthy for integration: no

Modified Paths:
--------------
1404 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1252938 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/charts/src/mx/charts/chartClasses/BoundedValue.as
+++ frameworks/projects/charts/src/mx/charts/chartClasses/BoundedValue.as
@@ -0,0 +1,126 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2009 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.charts.chartClasses
+{
+
+/**
+ *  A bounded value is used to represent a datapoint
+ *  that a chart element intends to render on screen.
+ *  ChartElements report BoundedValues, describing their data
+ *  to an Axis object. The axis computes autogenerated ranges.
+ *  A BoundedValue encapsulates both the value of the datapoint
+ *  in a particualr dimension, as well as a margin, in pixels,
+ *  that a ChartElement needs above or below the value
+ *  in order to render it.
+ *  Plots on a plot chart, for example, report their data
+ *  with margins to accomodate the size of the plots.
+ *  A column chart might report a margin in the Y axis
+ *  to accomodate a label rendered above the chart.
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public class BoundedValue
+{
+    include "../../core/Version.as";
+
+	//--------------------------------------------------------------------------
+	//
+	//  Constructor
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  Constructor.
+	 *
+	 *  @param value The value to be rendered.
+	 *
+	 *  @param lowerMargin The lower margin.
+	 *
+	 *  @param upperMargin The upper margin.
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public function BoundedValue(value:Number,
+								 lowerMargin:Number = 0,
+								 upperMargin:Number = 0)
+	{
+		super();
+
+		this.value = value;
+		this.lowerMargin = lowerMargin;
+		this.upperMargin = upperMargin;
+	}
+
+	//--------------------------------------------------------------------------
+	//
+	//  Properties
+	//
+	//--------------------------------------------------------------------------
+
+	//----------------------------------
+	//  lowerMargin
+	//----------------------------------
+
+	[Inspectable(environment="none")]
+
+	/**
+	 *  The margin, in pixels, required below the value
+	 *  in order to render properly.
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public var lowerMargin:Number;
+
+	//----------------------------------
+	//  upperMargin
+	//----------------------------------
+
+	[Inspectable(environment="none")]
+
+	/**
+	 *  The margin, in pixels, required above the value
+	 *  in order to render properly.
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public var upperMargin:Number;
+
+	//----------------------------------
+	//  value
+	//----------------------------------
+
+	[Inspectable(environment="none")]
+
+	/**
+	 *  The value to be rendered.
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public var value:Number;
+}
+
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 6443
Author:   rfrishbe@adobe.com
Date:     2009-04-30T22:46:07.257552Z

Log Message:
-----------
Renaming SkinnableComponent's loadSkin() and unloadSkin() skinning lifecycle methods to createSkin() and destroySkin() as no loading actually occurs here.

Also fixing up a few ASDoc bugs in the videoplayer stuff.  Also, checking in modifications to TrackBase, which was a file I missed yesterday when checking in.  The changes add 3 new events to TrackBase and clean it up so the setters don't do any extra work if it's being set to the same value as it was before.

QE Notes: -
Doc Notes: -
Bugs: SDK-19779
Reviewer: Jason
tests: checkintests, mustella SkinnableComponent tests

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/Scroller.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/primitives/VideoElement.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/VideoPlayerScrubBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/VideoPlayerVolumeBarMuteButton.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/supportClasses/TrackBase.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/VideoPlayerVolumeBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/airframework/src/spark/components/windowClasses/TitleBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/VideoPlayer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/supportClasses/SkinnableComponent.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1281878 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/mediaClasses/ScrubBar.as
+++ frameworks/projects/spark/src/spark/components/mediaClasses/ScrubBar.as
@@ -53,30 +53,6 @@
         dataTipFormatFunction = formatTimeValue;
     }

-    protected function formatTimeValue(value:Number):String
-    {
-        // default format: hours:minutes:seconds
-        var hours:uint = Math.floor(value/3600) % 24;
-        var minutes:uint = Math.floor(value/60) % 60;
-        var seconds:uint = Math.round(value) % 60;
-
-        var result:String = "";
-        if (hours != 0)
-            result = hours + ":";
-
-        if (result && minutes < 10)
-            result += "0" + minutes + ":";
-        else
-            result += minutes + ":";
-
-        if (seconds < 10)
-            result += "0" + seconds;
-        else
-            result += seconds;
-
-        return result;
-    }
-
     //--------------------------------------------------------------------------
     //
     //  Skin Parts
@@ -254,5 +230,32 @@
         if (playedArea)
             DisplayObject(playedArea).width = Math.round(playedAreaSize);
     }
+
+    /**
+     *  @private
+     */
+    private function formatTimeValue(value:Number):String
+    {
+        // default format: hours:minutes:seconds
+        var hours:uint = Math.floor(value/3600) % 24;
+        var minutes:uint = Math.floor(value/60) % 60;
+        var seconds:uint = Math.round(value) % 60;
+
+        var result:String = "";
+        if (hours != 0)
+            result = hours + ":";
+
+        if (result && minutes < 10)
+            result += "0" + minutes + ":";
+        else
+            result += minutes + ":";
+
+        if (seconds < 10)
+            result += "0" + seconds;
+        else
+            result += seconds;
+
+        return result;
+    }
 }
 }


Applied the changes to the original FlexUnitCIPrinter class

--- asunit-4.0/src/asunit/printers/FlexUnitCIPrinter.as
+++ asunit-4.0/src/asunit/printers/FlexUnitCIPrinter.as
@@ -1,285 +1,197 @@
 package asunit.printers {
+	import asunit.framework.IResult;
+	import asunit.framework.IRunListener;
+	import asunit.framework.ITestFailure;
+	import asunit.framework.ITestSuccess;
+	import asunit.framework.ITestWarning;
+	import asunit.framework.Method;

-    import asunit.framework.IResult;
-    import asunit.framework.IRunListener;
-    import asunit.framework.ITestFailure;
-    import asunit.framework.ITestSuccess;
-    import asunit.framework.ITestWarning;
-    import asunit.framework.Method;
+	import flash.events.DataEvent;
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.IOErrorEvent;
+	import flash.events.SecurityErrorEvent;
+	import flash.events.TimerEvent;
+	import flash.net.XMLSocket;
+	import flash.system.fscommand;
+	import flash.utils.Timer;
+	import flash.utils.getQualifiedClassName;
+	import flash.utils.getTimer;
+
+	public class FlexUnitCIPrinter extends EventDispatcher implements IRunListener
+	{
+		protected static const DEFAULT_SERVER:String = "127.0.0.1";
+		protected static const DEFAULT_PORT:uint = 1024;

-    import flash.events.DataEvent;
-    import flash.events.Event;
-    import flash.events.EventDispatcher;
-    import flash.events.IOErrorEvent;
-    import flash.events.SecurityErrorEvent;
-    import flash.events.TimerEvent;
-    import flash.net.XMLSocket;
-    import flash.system.fscommand;
-    import flash.utils.Timer;
-    import flash.utils.getQualifiedClassName;
-    import flash.utils.getTimer;
+		public var port:uint;
+		public var server:String; //this is local host. same machine

-    public class FlexUnitCIPrinter extends EventDispatcher implements IRunListener
-    {
-        protected static const DEFAULT_PORT: uint = 1024;
-        protected static const DEFAULT_SERVER: String = "127.0.0.1";
-        private static const SUCCESS: String = "success";
-        private static const ERROR: String = "error";
-        private static const FAILURE: String = "failure";
-        private static const IGNORE: String = "ignore";
-
-        private var messageQueue: Array = [];
-
-        private var _ready: Boolean = false;
-
+		private static const SUCCESS:String = "success";
+		private static const ERROR:String = "error";
+		private static const FAILURE:String = "failure";
+		private static const IGNORE:String = "ignore";
+
         private static const END_OF_TEST_ACK: String ="<endOfTestRunAck/>";
         private static const END_OF_TEST_RUN: String = "<endOfTestRun/>";
         private static const START_OF_TEST_RUN_ACK: String = "<startOfTestRunAck/>";
+
+		private var socket:XMLSocket;
+		private var connectTimeout:Timer;
+
+		protected var messageQueue:Array;
+
+		private var startTime : int;
+
+		public function FlexUnitCIPrinter()
+		{
+			this.port = port;
+			this.server = server;
+			messageQueue = [];
+
+			socket = new XMLSocket();
+			socket.addEventListener(Event.CONNECT, onConnect);
+			socket.addEventListener(DataEvent.DATA, onData);
+			socket.addEventListener(IOErrorEvent.IO_ERROR, onErrorEvent);
+			socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onErrorEvent);
+   	   		socket.addEventListener(Event.CLOSE, onErrorEvent);
+
+			connectTimeout = new Timer(5000, 1);
+			connectTimeout.addEventListener(TimerEvent.TIMER_COMPLETE, onConnectTimeout);
+			connectTimeout.start();

-        private var socket: XMLSocket;
+			connect();
+		}
+
+		protected function connect(ip:String = DEFAULT_SERVER, port:uint = DEFAULT_PORT):void {
+   	   		try {
+   	   			socket.connect(ip, port);
+   	   		}
+			catch (e:Error) {
+   	   			trace('## Error connecting to socket: ' + e.message);
+   	   		}
+		}
+
+		private function onConnectTimeout(event:TimerEvent):void {
+			throw new Error('Timed out waiting to connect to socket.');
+		}
+
+		public function onTestIgnored(method:Method):void {
+			var xmlMessageIgnore:String = "<testcase classname='" + getQualifiedClassName(method.scope)
+				+ "' name='" + method.name + "' time='0' status='"+IGNORE+"'>"
+				+ "<skipped />"
+				+ "</testcase>";
+			sendMessage(xmlMessageIgnore);
+		}
+
+		protected static function xmlEscapeMessage(message:String):String {
+			if (!message) return '';
+
+			var escape:XML = <escape/>;
+			escape.setChildren( message );
+			return escape.children()[0].toXMLString();
+		}
+
+		public function onTestFailure(failure:ITestFailure):void {
+			sendMessage(getFailureMessage(failure));
+		}

-        public var port: uint;
+		protected function getFailureMessage(failure:ITestFailure):String {
+			var status:String = failure.isFailure ? FAILURE : ERROR;
+//			var stackTrace:String = xmlEscapeMessage(failure.thrownException.getStackTrace());
+			var stackTrace:String = failure.thrownException.getStackTrace();
+			var xml:String =
+				"<testcase classname='" + getQualifiedClassName(failure.failedTest)
+				+ "' name='" + failure.failedMethod
+				+ "' time='0' status='" + status + "'>"
+
+					+ "<error message='" + xmlEscapeMessage(failure.exceptionMessage)
+					+ "' type='"+ getQualifiedClassName(failure.thrownException) +"' >"
+						+ "<![CDATA[" + stackTrace + "]]>"
+					+ "</error>"
+
+				+ "</testcase>";

-        public var server: String; //this is local host. same machine
+			return xml;
+		}
+
+		protected function sendMessage(message:String):void {
+			if (!socket.connected) {
+				messageQueue.push(message);
+				return;
+			}
+
+			socket.send(message);
+			trace(message);
+		}
+
+		protected function onConnect(event:Event):void {
+			connectTimeout.stop();
+		}
+
+		protected function sendQueuedMessages():void {
+		    trace("sendQueuedMessages()");
+			while (messageQueue.length) {
+				sendMessage(messageQueue.shift());
+			}
+		}
+
+		protected function serverReady(): void
+		{
+            // now that we are connectd lets send all the test results which are already available
+		    sendQueuedMessages();
+		}

-        private var timeOut: Timer;
-        private var lastTestTime: Number = 0;
-        private var startTime: Number;
-
-        /**
-         *
-         */
-        public function FlexUnitCIPrinter(port: uint = DEFAULT_PORT, server: String = DEFAULT_SERVER)
-        {
-            this.port = port;
-            this.server = server;
-
-            messageQueue = [];
-
-            socket = new XMLSocket ();
-            socket.addEventListener( DataEvent.DATA, dataHandler );
-            socket.addEventListener( Event.CONNECT, handleConnect );
-            socket.addEventListener( IOErrorEvent.IO_ERROR, errorHandler);
-            socket.addEventListener( SecurityErrorEvent.SECURITY_ERROR,errorHandler);
-            socket.addEventListener( Event.CLOSE,errorHandler);
-
-            timeOut = new Timer( 2000, 1 );
-            timeOut.addEventListener(TimerEvent.TIMER_COMPLETE, declareBroken, false, 0, true );
-            timeOut.start();
-
-            try
-            {
-                socket.connect( server, port );
-                timeOut.stop();
-            } catch (e:Error) {
-                //This needs to be more than a trace
-                trace (e.message);
-            }
-        }
-
-        /**
-         * Invoked when the timeout has been met, cancel everything
-         */
-        private function declareBroken( event:TimerEvent ):void {
-            errorHandler( new Event( "broken") );
-        }
-
-        /**
-         *
-         */
-        protected function sendResults(msg:String):void
-        {
-            if(socket.connected)
-            {
-                trace("sending message")
-                socket.send( msg );
-            } else {
-                // queue to message for when we are connected to the server
-                trace("sendResults(): Queuing message: " + msg);
-                messageQueue.push(msg);
-            }
-
-            trace(msg);
-        }
-
-        /**
-         *
-         */
-        private function handleConnect(event:Event):void
-        {
-            trace("handleConnect()");
-        }
-
-        private function sendQueueTestResults(): void
-        {
-            trace("sendQueueTestResults()");
-            for each ( var message: String in messageQueue )
-            {
-                trace("sendQueueTestResults(): msg=" + message);
-                sendResults(message);
-            }
-        }
-
-        /**
-         *
-         */
-        private function errorHandler(event:Event):void
-        {
-            trace("errorHandler()");
-            if ( !ready ) {
-                //If we are not yet ready and received this, just inform the core so it can move on
-//              dispatchEvent( new Event( AsyncListenerWatcher.LISTENER_FAILED ) );
-            } else {
-                //If on the other hand we were ready once, then the core is counting on us... so, if something goes
-                //wrong now, we are likely hung up. For now we are simply going to bail out of this process
-                exit();
-            }
-        }
-
-        /**
-         *
-         */
-        private function dataHandler( event : DataEvent ) : void
-        {
+		private function onData( event : DataEvent ) : void
+		{
             var data : String = event.data;
-            trace("FlexUnitCIPrinter#dataHandler: " + data);

             // If we received an acknowledgement on startup, the java server is read and we can start sending.
             if ( data == START_OF_TEST_RUN_ACK ) {
-                setStatusReady();
+                serverReady();
             } else if ( data == END_OF_TEST_ACK ) {
                 // If we received an acknowledgement finish-up.
                 // Close the socket.
                 socket.close();
                 exit();
             }
+		}
+
+		protected function onErrorEvent(event:Event):void {
+			trace('FlexUnitCIPrinter::onErrorEvent() - event: ' + event);
+			//throw new Error('FlashBuilderPrinter::onErrorEvent() - event: ' + event);
+		}
+
+		public function onRunStarted():void {
+		}
+
+        public function onTestStarted(test:Object):void {
+            startTime = getTimer();
         }
+
+        public function onTestCompleted(test:Object):void {
+//            testTimes.push({test:test, duration:duration});
+        }
+
+		public function onTestSuccess(success:ITestSuccess):void
+		{
+			//TODO: move test time into ITestSuccess
+            var testTime:Number = (getTimer() - startTime); // flexunit doesn't accept float numbers
+            var className: String = getQualifiedClassName(success.test);
+            var methodName: String = success.method;
+            var xmlMessageSuccess:String = "<testcase classname=\"" + className +"\" name=\"" + methodName +"\" time=\"" + testTime +"\" status=\"success\" />";
+			sendMessage(xmlMessageSuccess);
+		}
+
+		public function onRunCompleted(result:IResult):void {
+			sendMessage(END_OF_TEST_RUN);
+		}
+
+		protected function exit():void
+		{
+			fscommand("quit");
+		}

-        public function get ready():Boolean
-        {
-            return _ready;
-        }
-
-        protected function setStatusReady(): void
-        {
-            trace("FlexUnitCIPrinter#setStatusReady()");
-            _ready = true;
-
-            clientConnected();
-        }
-
-        protected function clientConnected(): void
-        {
-            trace("FlexUnitCIPrinter#clientConnected()");
-
-            // now that we are connectd lets send all the test results which are already available
-            sendQueueTestResults();
-        }
-
-        protected function exit(): void
-        {
-            trace("FlexUnitCIPrinter#exit()");
-            fscommand("quit");
-        }
-
-        ///////////
-
-        public function onRunStarted(): void
-        {
-            trace("onRunStarted()");
-        }
-
-        public function onTestStarted(test:Object):void
-        {
-            trace("onTestStarted()");
-            startTime = getTimer();
-            lastTestTime = getTimer(); // for the first test being run
-        }
-
-        public function onTestCompleted(test:Object):void
-        {
-            var duration:Number = getTimer() - startTime;
-            var className: String = getQualifiedClassName(test);
-
-            trace("onTestCompleted(): className=" + className + " duration=" + duration);
-        }
-
-        public function onTestFailure(failure:ITestFailure):void
-        {
-            trace("onTestFailure()");
-			sendResults(getFailureMessage(failure));
-            lastTestTime = getTimer();
-
-        }
-
-        private function getFailureMessage(failure:ITestFailure): String
-        {
-            var duration:Number = getTimer() - startTime;
-			var status:String = failure.isFailure ? FAILURE : ERROR;
-			var stackTrace:String = failure.thrownException.getStackTrace();
-			var xml:String =
-				"<testcase classname='" + getQualifiedClassName(failure.failedTest)
-				+ "' name='" + failure.failedMethod
-				+ "' time='" + duration + "' status='" + status + "'>"
-
-					+ "<error message='" + xmlEscapeMessage(failure.exceptionMessage)
-					+ "' type='"+ getQualifiedClassName(failure.thrownException) +"' >"
-						+ "<![CDATA[" + stackTrace + "]]>"
-					+ "</error>"
-
-				+ "</testcase>";
-
-			return xml;
-        }
-
-        protected static function xmlEscapeMessage(message:String):String {
-			if (!message) return '';
-
-			var escape:XML = <escape/>;
-			escape.setChildren( message );
-			return escape.children()[0].toXMLString();
-        }
-
-        public function onTestSuccess(success:ITestSuccess):void
-        {
-            var duration:Number = getTimer() - lastTestTime;
-            var methodName: String = success.method;
-            var featureName: String = success.feature;
-            var className: String = getQualifiedClassName(success.test);
-
-            trace("onTestSuccess(): methodName=" +methodName + " featureName=" + featureName + " className=" + className + " duration=" + duration);
-
-            sendResults("<testcase classname=\"" + className +"\" name=\"" + methodName +"\" time=\"" + duration +"\" status=\"success\" />");
-
-
-            lastTestTime = getTimer();
-        }
-
-        public function onTestIgnored(method:Method):void
-        {
-            trace("onTestIgnored()");
-            var duration:Number = getTimer() - lastTestTime;
-            var methodName: String = method.name;
-            var className: String = getQualifiedClassName(method.scope);
-
-            var xml:String =
-            				"<testcase classname=\""+className+"\" name=\""+methodName+"\" time=\"" + duration  + "\" status=\""+IGNORE+"\">"
-            				+ "<skipped />"
-            				+ "</testcase>";
-            sendResults(xml);
-
-            lastTestTime = getTimer();
-        }
-
-        public function onWarning(warning:ITestWarning):void
-        {
-            trace("onWarning()");
-        }
-
-        public function onRunCompleted(result:IResult):void
-        {
-            trace("onRunCompleted()");
-			sendResults(END_OF_TEST_RUN);
-        }
-    }
+		public function onWarning(warning:ITestWarning) : void {
+		}
+	}
 }


Transferred from the Adobe Open Source Subversion Repository

Revision: 12850
Author:   jimurphy@adobe.com
Date:     2009-12-11T14:57:14.623098Z

Log Message:
-----------
add 6 new DMV projects to the SDK:
automation
automation_air
automation_dmv
automation_flashflexkit
automation_spark
datavisualization

These projects are setup to build in an ant main call.  There are currently several warnings in the datavisualization project that will be cleaned up.  No checkintests exist for these projects as of yet.

I also modified the exisitng projects build files for easier management of the localization targets, bundle and fat-swc. If the projects that I updated:airframework,airspark,framework,playerglobal,rpc,and spark.  All the new projects have been implemented this same way.

QE notes: DMV folks should run through their tests
Doc notes: probably
Bugs: nope
Reviewer:
Tests run: ran the following targets: compile,checkintests,other.locales and doc
Is noteworthy for integration: no

Modified Paths:
--------------
1404 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1252960 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/charts/src/mx/charts/chartClasses/CartesianDataCanvas.as
+++ frameworks/projects/charts/src/mx/charts/chartClasses/CartesianDataCanvas.as
@@ -0,0 +1,2022 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2009 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+//  Adobe Patent or Adobe Patent Pending Invention Included Within this File
+//  Adobe patent application tracking B503, entitled Charting Data Graphics -
+//  graphics drawing API that allows to draw in data space, inventors Ely Greenfield.
+//  AdobePatentID="B503"
+//
+////////////////////////////////////////////////////////////////////////////////
+package mx.charts.chartClasses
+{
+
+import flash.display.BitmapData;
+import flash.display.DisplayObject;
+import flash.display.Graphics;
+import flash.events.Event;
+import flash.geom.Matrix;
+import flash.geom.Point;
+import flash.utils.Dictionary;
+import mx.core.mx_internal;
+import mx.core.IFlexDisplayObject;
+import mx.core.IUIComponent;
+
+use namespace mx_internal;
+
+[DefaultProperty("dataChildren")]
+
+/**
+ * This class lets you use add graphical elements such as lines, ellipses, and other shapes
+ * by using a graphics API. The values that you pass to the graphics API are in data
+ * coordinates rather than screen coordinates. You can also add any DisplaObject to the canvas,
+ * in the same way that you add children to containers.
+ *
+ *
The drawing region for the canvas is determined by the verticalAxis
+ * and horizontalAxis, if they are specified. Otherwise,
+ * the canvas uses the default axes of the chart to compute the drawing region.

+ *
+ *
The data coordinates passed as parameters to the drawing APIs can be
+ * actual values of the data coordinate or an object of type CartesianCanvasValue,
+ * which can hold a data coordinate value and an offset, in pixels.

+ *
+ * @mxml
+ *
+ *
The <mx:CartesianDataCanvas> tag inherits all the
+ *  properties of its parent classes and adds the following properties:

+ *
+ *

+ *  <mx:CartesianDataCanvas
+ *    Properties
+ *    dataChildren="No default"
+ *    horizontalAxis="No default"
+ *    includeInRanges="false"
+ *    verticalAxis="No default"
+ *  />
+ *

+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public class CartesianDataCanvas extends ChartElement implements IDataCanvas
+{
+    include "../../core/Version.as";
+
+    //----------------------------------------------
+    //
+    // Constructor
+    //
+    //----------------------------------------------
+
+    /**
+     * Constructor.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function CartesianDataCanvas()
+    {
+        super();
+
+        dataTransform = new CartesianTransform();
+    }
+
+    //-----------------------------------------------
+    //
+    // Variables
+    //
+    //-----------------------------------------------
+
+    private var _data:*;
+    private var _offset:Number;
+    private var _xMap:Dictionary;
+    private var _yMap:Dictionary;
+    private var _hDataDesc:DataDescription = new DataDescription();
+    private var _vDataDesc:DataDescription = new DataDescription();
+
+    private var _dataCache:CartesianDataCache;
+    private var _dataCacheDirty:Boolean = true;
+    private var _mappingDirty:Boolean = true;
+    private var _filterDirty:Boolean = true;
+    private var _transformDirty:Boolean = true;
+    private var _oldUW:Number;
+    private var _oldUH:Number;
+    private var borderWidth:Number = 0;
+    private var _bAxesDirty:Boolean = false;
+    private var _childMap:Dictionary = new Dictionary(true);
+
+    //----------------------------------------------
+    //
+    // Overridden Properties
+    //
+    //----------------------------------------------
+
+    //----------------------------------
+    //  dataTransform
+    //----------------------------------
+
+    /**
+     *  @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function set dataTransform(value:DataTransform):void
+    {
+        if (value)
+        {
+            super.dataTransform = value;
+        }
+        else
+        {
+            for (var p:String in dataTransform.axes)
+            {
+                dataTransform.getAxis(p).unregisterDataTransform(dataTransform);
+            }
+        }
+    }
+
+
+    //----------------------------------------------
+    //
+    // Properties
+    //
+    //----------------------------------------------
+
+    //-----------------------------------------
+    //  dataChildren
+    //-----------------------------------------
+
+    /**
+     * @private
+     * Storage for dataChildren property
+     */
+    private var _dataChildren:Array /* of DisplayObject */ = [];
+    [Inspectable(category="General")]
+
+    /**
+     * An array of child objects.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get dataChildren():Array /* of DisplayObject */
+    {
+        return _dataChildren;
+    }
+
+    /**
+     * @private
+     */
+    public function set dataChildren(value:Array /* of DisplayObject */):void
+    {
+        for (var p:* in _childMap)
+        {
+            removeChild(_childMap[p].child);
+        }
+        _childMap = new Dictionary(true);
+        _dataChildren = value;
+        var n:int = value.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            var dc:CartesianDataChild;
+            if (value[i] is CartesianDataChild)
+                dc = value[i];
+            else
+                dc = new CartesianDataChild(value[i]);
+
+            _childMap[dc.child] = dc;
+            dc.addEventListener("change",dataChildChangeHandler,false,0,true);
+            super.addChild(dc.child);
+        }
+        invalidateOpCodes();
+    }
+
+    //----------------------------------
+    //  horizontalAxis
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the horizontalAxis property.
+     */
+    private var _horizontalAxis:IAxis;
+
+    [Inspectable(category="Data")]
+
+    /**
+     *  Defines the labels, tick marks, and data position
+     *  for items on the x-axis.
+     *  Use either the LinearAxis class or the CategoryAxis class
+     *  to set the properties of the horizontal axis as a child tag in MXML
+     *  or create a LinearAxis or CategoryAxis object in ActionScript.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get horizontalAxis():IAxis
+    {
+        return _horizontalAxis;
+    }
+
+    /**
+     * @private
+     */
+    public function set horizontalAxis(value:IAxis):void
+    {
+        _horizontalAxis = value;
+        _bAxesDirty = true;
+
+        invalidateData();
+        invalidateProperties();
+    }
+
+    //----------------------------------
+    //  includeInRanges
+    //----------------------------------
+
+    /**
+     * @private
+     * Storage for includeInRanges property
+     */
+    private var _includeInRanges:Boolean = false;
+    [Inspectable(category="General")]
+
+    /**
+     * If true, the computed range of the chart is affected by this
+     * canvas.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+
+    public function get includeInRanges():Boolean
+    {
+        return _includeInRanges;
+    }
+
+    /**
+     * @private
+     */
+    public function set includeInRanges(value:Boolean):void
+    {
+        if (_includeInRanges == value)
+            return;
+        _includeInRanges = value;
+        dataChanged();
+    }
+
+    //--------------------------------------------
+    // opCodes
+    //--------------------------------------------
+    /**
+     * @private
+     * Storage for opCodes property
+     */
+    private var _opCodes:Array /* of CartesianOpCode */ = [];
+
+    [ArrayElementType("CartesianOpCode")]
+
+    /**
+     * @private
+     */
+
+    private function get opCodes():Array /* of CartesianOpCode */
+    {
+        return _opCodes;
+    }
+
+    /**
+     * @private
+     */
+    private function set opCodes(value:Array /* of CartesianOpCode */):void
+    {
+        _opCodes = value;
+        invalidateOpCodes();
+    }
+
+
+    //----------------------------------
+    //  verticalAxis
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the verticalAxis property.
+     */
+    private var _verticalAxis:IAxis;
+
+    [Inspectable(category="Data")]
+
+    /**
+     *  Defines the labels, tick marks, and data position
+     *  for items on the y-axis.
+     *  Use either the LinearAxis class or the CategoryAxis class
+     *  to set the properties of the vertical axis as a child tag in MXML
+     *  or create a LinearAxis or CategoryAxis object in ActionScript.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get verticalAxis():IAxis
+    {
+        return _verticalAxis;
+    }
+
+    /**
+     *  @private
+     */
+    public function set verticalAxis(value:IAxis):void
+    {
+        _verticalAxis = value;
+        _bAxesDirty = true;
+        invalidateData();
+        invalidateProperties();
+    }
+
+
+    //----------------------------------------------
+    //
+    // Overridden Methods
+    //
+    //----------------------------------------------
+
+    /**
+     * @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function addChild(child:DisplayObject):DisplayObject
+    {
+        var dc:CartesianDataChild = new CartesianDataChild(child);
+        _childMap[child] = dc;
+        _dataChildren.push(dc);
+        dc.addEventListener("change",dataChildChangeHandler,false,0,true);
+        invalidateOpCodes();
+        return super.addChild(child);
+    }
+
+    /**
+     * @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function addChildAt(child:DisplayObject,index:int):DisplayObject
+    {
+        var dc:CartesianDataChild = new CartesianDataChild(child);
+        _childMap[child] = dc;
+        _dataChildren.push(dc);
+        dc.addEventListener("change",dataChildChangeHandler,false,0,true);
+        invalidateOpCodes();
+        return super.addChildAt(child,index);
+    }
+
+    /**
+     *  @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override protected function commitProperties():void
+    {
+        super.commitProperties();
+
+        if (_bAxesDirty)
+        {
+            if (dataTransform)
+            {
+                if (_horizontalAxis)
+                {
+                    _horizontalAxis.chartDataProvider = dataProvider;
+                    CartesianTransform(dataTransform).setAxis(
+                        CartesianTransform.HORIZONTAL_AXIS,_horizontalAxis);
+                }
+
+                if (_verticalAxis)
+                {
+                    _verticalAxis.chartDataProvider = dataProvider;
+                    CartesianTransform(dataTransform).setAxis(
+                        CartesianTransform.VERTICAL_AXIS, _verticalAxis);
+                }
+            }
+            _bAxesDirty = false;
+        }
+
+        var c:CartesianChart = CartesianChart(chart);
+        if (c)
+        {
+            if (!_horizontalAxis)
+            {
+                if (dataTransform.axes[CartesianTransform.HORIZONTAL_AXIS] != c.horizontalAxis)
+                        CartesianTransform(dataTransform).setAxis(
+                            CartesianTransform.HORIZONTAL_AXIS,c.horizontalAxis);
+            }
+
+            if (!_verticalAxis)
+            {
+                if (dataTransform.axes[CartesianTransform.VERTICAL_AXIS] != c.verticalAxis)
+                        CartesianTransform(dataTransform).setAxis(
+                            CartesianTransform.VERTICAL_AXIS, c.verticalAxis);
+            }
+        }
+        dataTransform.elements = [this];
+        invalidateOpCodes();
+    }
+
+
+    /**
+     * @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function removeChild(child:DisplayObject):DisplayObject
+    {
+        super.removeChild(child);
+        if (child in _childMap)
+            delete _childMap[child];
+        _dataChildren.splice(_dataChildren.indexOf(child),1);
+        return child;
+    }
+
+    /**
+     * @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function removeChildAt(index:int):DisplayObject
+    {
+        var child:DisplayObject = super.removeChildAt(index);
+        if (child in _childMap)
+            delete _childMap[child];
+        _dataChildren.splice(index,1);
+        return child;
+    }
+
+    /**
+     * @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+
+    override protected function updateDisplayList(unscaledWidth:Number,
+                                                  unscaledHeight:Number):void
+    {
+
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+
+
+        validateData();
+
+        var updated:Boolean = validateTransform();
+
+        if (updated)
+        {
+            var g:Graphics = graphics;
+
+            g.clear();
+            var n:int = _opCodes.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                _opCodes[i].render(this,_dataCache);
+            }
+            positionChildren();
+        }
+    }
+
+    /**
+     *  @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function invalidateDisplayList():void
+    {
+        _dataCacheDirty = true;
+        _mappingDirty = true;
+        _filterDirty = true;
+        _transformDirty = true;
+        super.invalidateDisplayList();
+    }
+
+    /**
+     *  @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function dataToLocal(... dataValues):Point
+    {
+        var data:Object = {};
+        var da:Array /* of Object */ = [ data ];
+        var n:int = dataValues.length;
+
+        if (n > 0)
+        {
+            data["d0"] = dataValues[0];
+            dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).
+                mapCache(da, "d0", "v0");
+        }
+
+        if (n > 1)
+        {
+            data["d1"] = dataValues[1];
+            dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).
+                mapCache(da, "d1", "v1");
+        }
+
+        dataTransform.transformCache(da,"v0","s0","v1","s1");
+
+        return new Point(data.s0 + this.x,
+                         data.s1 + this.y);
+    }
+
+    /**
+     *  @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function localToData(v:Point):Array /* of Object */
+    {
+        var values:Array /* of Object */ = dataTransform.invertTransform(
+                                            v.x - this.x,
+                                            v.y - this.y);
+        return values;
+    }
+
+    /**
+     * @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function describeData(dimension:String,
+                                          requiredFields:uint):Array /* of DataDescription */
+    {
+        updateMapping();
+        var result:Array /* of DataDescription */ = [];
+
+        if (_includeInRanges)
+        {
+            if (dimension == CartesianTransform.VERTICAL_AXIS)
+            {
+                if (_dataCache.xCache.length > 0)
+                    result.push(_vDataDesc);
+            }
+            else if (dimension == CartesianTransform.HORIZONTAL_AXIS)
+            {
+                if (_dataCache.yCache.length > 0)
+                    result.push(_hDataDesc);
+            }
+        }
+
+        return result;
+    }
+
+    //----------------------------------------------
+    //
+    // Methods
+    //
+    //----------------------------------------------
+
+    mx_internal function dataChildChangeHandler(event:Event):void
+    {
+        dataChildren = dataChildren;
+    }
+
+    /**
+     * Adds the specified display object as a child to the current canvas.
+     *
+     * @param child     The display object that is to be added as a child to current canvas.
+     * @param left      Left x-coordinate of the child in data coordinates.
+     * @param top       Top y-coordinate of the child in data coordinates.
+     * @param right     Right x-coordinate of the child in data coordinates.
+     * @param bottom    Bottom y-coordinate of the child in data coordinates.
+     * @param hCenter   Middle x-coordinate of the child in data coordinates.
+     * @param vCenter   Middle y-coordinate of the child in data coordinates.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function addDataChild(child:DisplayObject,left:* = undefined, top:* = undefined, right:* = undefined,
+                                 bottom:* = undefined , hCenter:* = undefined, vCenter:* = undefined):void
+    {
+        var dc:CartesianDataChild = new CartesianDataChild(child,left,top,right,bottom);
+        dc.addEventListener("change",dataChildChangeHandler,false,0,true);
+        addChild(child);
+        updateDataChild(child,left,top,right,bottom,hCenter,vCenter);
+        invalidateOpCodes();
+    }
+
+    /**
+     * Removes all data children (DisplayObject instances) of the canvas.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function removeAllChildren():void
+    {
+        var n:int = _dataChildren.length;
+        for (var i:int = n - 1; i >= 0; i--)
+        {
+            removeChildAt(i);
+        }
+    }
+
+    /**
+     * Updates the position of any child to current canvas.
+     *
+     * @param child     The display object that is to be updated.
+     * @param left      Left x coordinate of the child, in data coordinates.
+     * @param top       Top y coordinate of the child, in data coordinates.
+     * @param right     Right x coordinate of the child, in data coordinates.
+     * @param bottom    Bottom y coordinate of the child, in data coordinates.
+     * @param hCenter   Middle x coordinate of the child, in data coordinates.
+     * @param vCenter   Middle y coordinate of the child, in data coordinates.
+     *
+     *
For example:
+     *

+     *      var lbl:Label = new Label();
+     *      lbl.text = "Last Month";
+     *      canvas.addChild(lbl);
+     *      canvas.updateDataChild(lbl,"Feb",200);
+     *

+     *

+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function updateDataChild(child:DisplayObject,left:* = undefined, top:* = undefined, right:* = undefined,
+                                    bottom:* = undefined, hCenter:* = undefined, vCenter:* = undefined):void
+    {
+        var dc:CartesianDataChild = _childMap[child];
+        dc.left = left;
+        dc.top = top;
+        dc.right = right;
+        dc.bottom = bottom;
+        dc.horizontalCenter = hCenter;
+        dc.verticalCenter = vCenter;
+        invalidateOpCodes();
+    }
+
+    /**
+     * @copy flash.display.Graphics#clear()
+     * @see flash.display.Graphics
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function clear():void
+    {
+        _opCodes = [];
+        invalidateOpCodes();
+    }
+
+    /**
+     * Note: With the exception of the beginGradientFill() and beginShaderFill() methods, the following information
+     * from the flash.display.Graphics class's beginFill() method applies to this method:
+     *
+     * @copy flash.display.Graphics#beginFill()
+     * @see flash.display.Graphics
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function beginFill(color:uint , alpha:Number = 1):void
+    {
+        pushOp(CartesianOpCode.BEGIN_FILL, { color: color, alpha: alpha} );
+    }
+
+    /**
+     * Fills a drawing area with a bitmap image. The coordinates that you pass to this method are relative to
+     * the canvas's horizontal axis and vertical axis.
+     *
+     *
The usage and parameters of this method are identical to the beginBitmapFill() method of the
+     * flash.display.Graphics class.

+     *
+     * @param bitmap A transparent or opaque bitmap image that contains the bits to be displayed.
+     *
+     * @param x The x coordinate of the fill.
+     *
+     * @param y The y coordinate of the fill.
+     *
+     * @param matrix A matrix object (of the flash.geom.Matrix class),
+     * which you can use to define transformations on the bitmap.
+     *
+     * @param repeat If true, the bitmap image repeats in a tiled pattern.
+     * If false, the bitmap image does not repeat, and the edges of
+     * the bitmap are used for any fill area that extends beyond the bitmap.
+     *
+     * @param smooth If false, upscaled bitmap images are rendered
+     * by using a nearest-neighbor algorithm and look pixelated.
+     * If true, upscaled bitmap images are rendered by using a bilinear algorithm.
+     * Rendering by using the nearest neighbor algorithm is faster.
+     *
+     * @see flash.display.Graphics#beginBitmapFill()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function beginBitmapFill(bitmap:BitmapData, x:* = undefined,
+                                    y:* = undefined, matrix:Matrix = null,
+                                    repeat:Boolean = true, smooth:Boolean = true):void
+    {
+        pushOp(CartesianOpCode.BEGIN_BITMAP_FILL, { bitmap:bitmap, x:x, y:y, repeat:repeat, smooth:smooth, matrix:matrix });
+    }
+
+    /**
+     * Draws a curve using the current line style from the current drawing position to (anchorX, anchorY) and using the
+     * control point that (controlX, controlY) specifies. The coordinates that you pass to this method are in terms of
+     * chart data rather than screen coordinates.
+     *
+     *
The usage and parameters of this method are identical to the curveTo() method of the
+     * flash.display.Graphics class.

+     *
+     * @param controlX The x coordinate of the control point.
+     *
+     * @param controlY The y coordinate of the control point.
+     *
+     * @param anchorX The x coordinate of the anchor point.
+     *
+     * @param anchorY The y coordinate of the anchor point.
+     *
+     * @see flash.display.Graphics#curveTo()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function curveTo(controlX:*, controlY:*, anchorX:*, anchorY:*):void
+    {
+        pushOp(CartesianOpCode.CURVE_TO, { controlX: controlX, controlY:controlY, anchorX:anchorX, anchorY:anchorY, borderWidth: borderWidth } );
+    }
+
+    /**
+     * Draws a circle.
+     * Set the line style, fill, or both before you call the drawCircle() method,
+     * by calling the linestyle(), lineGradientStyle(),
+     * beginFill(), beginGradientFill(), or beginBitmapFill() method.
+     * The coordinates that you pass to this method are in terms of chart data rather than screen coordinates.
+     *
+     * @param x The x location of the center of the circle (in pixels).
+     *
+     * @param y The y location of the center of the circle (in pixels).
+     *
+     * @param radius The radius of the circle (in pixels).
+     *
+     * @see flash.display.Graphics
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function drawCircle(x:*, y:*, radius:Number):void
+    {
+        pushOp(CartesianOpCode.DRAW_CIRCLE, { x: x, y: y, radius: radius, borderWidth: borderWidth });
+    }
+
+    /**
+     * Draws an ellipse.
+     * Set the line style, fill, or both before you call the drawEllipse() method,
+     * by calling the linestyle(), lineGradientStyle(),
+     * beginFill(), beginGradientFill(), or beginBitmapFill() method.
+     * The coordinates that you pass to this method are in terms of chart data rather than screen coordinates.
+     *
+     * @param left The x location of the top-left corner of the bounding-box of the ellipse.
+     *
+     * @param top The y location of the top-left corner of the bounding-box of the ellipse.
+     *
+     * @param right The x location of the bottom-right corner of the bounding-box of the ellipse.
+     *
+     * @param bottom The y location of the bottom-right corner of the bounding-box of the ellipse.
+     *
+     * @see flash.display.Graphics#drawEllipse()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function drawEllipse(left:*, top:*, right:*, bottom:*):void
+    {
+        pushOp(CartesianOpCode.DRAW_ELLIPSE, { left: left, top: top, right: right, bottom: bottom, borderWidth: borderWidth });
+    }
+
+    /**
+     * Draws a rectangle.
+     * Set the line style, fill, or both before you call the drawRect() method,
+     * by calling the linestyle(), lineGradientStyle(),
+     * beginFill(), beginGradientFill(), or beginBitmapFill() method.
+     * The coordinates that you pass to this method are in terms of chart data rather than screen coordinates.
+     *
+     * @param left The x location of the top-left corner of the rectangle.
+     *
+     * @param top The y location of the top-left corner of the rectangle.
+     *
+     * @param right The x location of the bottom-right corner of the rectangle.
+     *
+     * @param bottom The y location of the bottom-right corner of the rectangle.
+     *
+     * @see flash.display.Graphics#drawRect()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function drawRect(left:*, top:*, right:*, bottom:*):void
+    {
+        pushOp(CartesianOpCode.DRAW_RECT, { left: left, top: top, right: right, bottom: bottom, borderWidth: borderWidth });
+    }
+
+    /**
+     * Draws a rounded rectangle.
+     * Set the line style, fill, or both before you call the drawRoundRect() method,
+     * by calling the linestyle(), lineGradientStyle(),
+     * beginFill(), beginGradientFill(), or beginBitmapFill() method.
+     * The coordinates that you pass to this method are in terms of chart data rather than screen coordinates.
+     *
+     * @param left The x location of the top-left corner of the rectangle.
+     *
+     * @param top The y location of the top-left corner of the rectangle.
+     *
+     * @param right The x location of the bottom-right corner of the rectangle.
+     *
+     * @param bottom The y location of the bottom-right corner of the rectangle.
+     *
+     * @param cornerRadius The radius of the corners, in pixels.
+     *
+     * @see flash.display.Graphics#drawRoundRect()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function drawRoundedRect(left:*, top:*, right:*, bottom:*, cornerRadius:Number):void
+    {
+        pushOp(CartesianOpCode.DRAW_ROUNDRECT, { left: left, top: top, right: right, bottom: bottom,
+                                    borderWidth: borderWidth,
+                                    cornerRadius: cornerRadius });
+    }
+
+    /**
+     * Note: With the exception of the beginGradientFill() method, the following information
+     * from the flash.display.Graphics class's endFill() applies to this method:
+     *
+     * @copy flash.display.Graphics#endFill()
+     * @see flash.display.Graphics
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function endFill():void
+    {
+        pushOp(CartesianOpCode.END_FILL);
+    }
+
+    /**
+     * Specifies a line style that Flash uses for subsequent calls to other Graphics methods (such as lineTo()
+     * or drawCircle()) for the object.
+     *
+     *
The usage and parameters of this method are identical to the lineStyle() method of the
+     * flash.display.Graphics class.

+     *
+     * @param thickness An integer that indicates the thickness of the line in points; valid values are 0-255.
+     * If a number is not specified, or if the parameter is undefined, a line is not drawn.
+     * If a value of less than 0 is passed, the default is 0.
+     * The value 0 indicates hairline thickness; the maximum thickness is 255.
+     * If a value greater than 255 is passed, the default is 255.
+     *
+     * @param color A hexadecimal color value of the line; for example, red is 0xFF0000, blue is 0x0000FF, and so on.
+     * If a value is not indicated, the default is 0x000000 (black).
+     *
+     * @param alpha A number that indicates the alpha value of the color of the line; valid values are 0 to 1.
+     * If a value is not indicated, the default is 1 (solid).
+     * If the value is less than 0, the default is 0.
+     * If the value is greater than 1, the default is 1.
+     *
+     * @param pixelHinting A Boolean value that specifies whether to hint strokes to full pixels.
+     * This affects both the position of anchors of a curve and the line stroke size itself.
+     * With pixelHinting set to true, line widths are adjusted to full pixel widths.
+     * With pixelHinting set to false, disjoints can appear for curves and straight lines.
+     *
+     * @param scaleMode A value from the flash.display.LineScaleMode class that specifies which scale mode to use:
+     *
+     *

+     *
LineScaleMode.NORMAL: Always scale the line thickness when the object is scaled (the default).

+     *
LineScaleMode.NONE: Never scale the line thickness.

+     *
LineScaleMode.VERTICAL: Do not scale the line thickness if the object is scaled vertically only.

+     *
LineScaleMode.HORIZONTAL: Do not scale the line thickness if the object is scaled horizontally only.

+     *

+     *
+     * @param caps A value from the flash.display.CapsStyle class that specifies the type of
+     * caps at the end of lines.
+     * Valid values are: CapsStyle.NONE, CapsStyle.ROUND,
+     * and CapsStyle.SQUARE. If a value is not indicated, use round caps.
+     *
+     * @param joints A value from the flash.display.JointStyle class that specifies the type of
+     * joint appearance used at angles.
+     * Valid values are: JointStyle.BEVEL, JointStyle.MITER, and JointStyle.ROUND.
+     * If a value is not indicated, use round joints.
+     *
+     * @param miterLimit A number that indicates the limit at which a miter is cut off.
+     * Valid values range from 1 to 255 (and values outside that range are rounded to 1 or 255).
+     * This value is only used if the jointStyle is set to "miter".
+     * The miterLimit value represents the length that a miter can extend beyond the point at which
+     * the lines meet to form a joint.
+     * The value expresses a factor of the line thickness.
+     * For example, with a miterLimit factor of 2.5 and a thickness of 10 pixels, the miter is cut off at 25 pixels.
+     *
+     * @see flash.display.Graphics#lineStyle()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function lineStyle(thickness:Number, color:uint = 0, alpha:Number = 1.0,
+                              pixelHinting:Boolean = false, scaleMode:String = "normal",
+                              caps:String = null, joints:String = null, miterLimit:Number = 3):void
+    {
+        borderWidth = thickness;
+        pushOp(CartesianOpCode.LINE_STYLE, { thickness: thickness, color: color, alpha: alpha, pixelHinting: pixelHinting, scaleMode: scaleMode,
+                                    caps: caps, joints: joints, miterLimit: miterLimit });
+    }
+
+    /**
+     * Draws a line using the current line style from the current drawing position to (x, y);
+     * the current drawing position is then set to (x, y).
+     * If the display object in which you are drawing contains content that was created
+     * with the Flash drawing tools, calls to the lineTo() method are drawn underneath the content.
+     * If you call lineTo() before any calls to the moveTo() method, the default position
+     * for the current drawing is (0, 0).
+     * If any of the parameters are missing, this method fails and the current drawing
+     * position is not changed. Coordinates are in terms of data rather than screen coordinates.
+     * The coordinates that you pass to this method are in terms of chart data rather than screen coordinates.
+     *
+     * @param x The x coordinate of the drawing position.
+     *
+     * @param y The y coordinate of the drawing position.
+     *
+     * @see flash.display.Graphics#lineTo()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function lineTo(x:*, y:*):void
+    {
+        pushOp(CartesianOpCode.LINE_TO, { x: x, y:y, borderWidth: borderWidth });
+    }
+
+    /**
+     * Moves the current drawing position to (x, y).
+     * If any of the parameters are missing, this method fails and the current
+     * drawing position is not changed.
+     * The coordinates that you pass to this method are in terms of chart data rather than screen coordinates.
+     *
+     * @param x The x coordinate of the drawing position.
+     *
+     * @param y The y coordinate of the drawing position.
+     *
+     * @see flash.display.Graphics#moveTo()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function moveTo(x:*, y:*):void
+    {
+        pushOp(CartesianOpCode.MOVE_TO, { x: x, y:y, borderWidth: borderWidth });
+    }
+
+
+    /**
+     *  Calls the updateTransform() method of the canvas, if necessary.
+     *  This method is called automatically by the canvas
+     *  during the commitProperties() method, as necessary,
+     *  but a derived canvas might call it explicitly
+     *  if the generated values are needed at an explicit time.
+     *  Filtering and transforming of data relies on specific values
+     *  being calculated by the axes, which can in turn
+     *  depend on the data that is displayed in the chart.
+     *  Calling this function at the wrong time might result
+     *  in extra work being done, if those values are updated.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected function validateTransform():Boolean
+    {
+        var updated:Boolean = false;
+        if (dataTransform && _transformDirty)
+        {
+            updated = updateTransform();
+        }
+        return updated;
+    }
+
+    /**
+     *  Calls the updateMapping()
+     *  and updateFilter() methods of the canvas, if necessary.
+     *  This method is called automatically by the canvas
+     *  from the commitProperties() method, as necessary,
+     *  but a derived canvas might call it explicitly
+     *  if the generated values are needed at an explicit time.
+     *  Loading and mapping data against the axes is designed
+     *  to be acceptable by the axes at any time.
+     *  It is safe this method explicitly at any point.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected function validateData():void
+    {
+        if (dataTransform)
+        {
+            if (_mappingDirty)
+            {
+                updateMapping();
+            }
+            if (_filterDirty)
+            {
+                updateFilter();
+            }
+        }
+    }
+
+    /**
+     *  Called when the underlying data the canvas represents
+     *  needs to be filtered against the ranges represented by the axes
+     *  of the associated data transform.
+     *  This can happen either because the underlying data has changed
+     *  or because the range of the associated axes has changed.
+     *  If you implement a custom canvas type, you should override this method
+     *  and filter out any outlying data using the filterCache()
+     *  method of the axes managed by its associated data transform.
+     *  The filterCache() method converts any values
+     *  that are out of range to NaN.
+     *  You must be sure to call the super.updateFilter() method
+     *  in your subclass.
+     *  You should not generally call this method directly.
+     *  Instead, if you need to guarantee that your data has been filtered
+     *  at a given point, call the validateTransform() method
+     *  of the CartesianDataCanvas class.
+     *  You can generally assume that your updateData()
+     *  and updateMapping() methods have been called
+     *  prior to this method, if necessary.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+
+    protected function updateFilter():void
+    {
+        dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).filterCache(_dataCache.yCache,"mappedValue","filteredValue");
+        dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).filterCache(_dataCache.xCache,"mappedValue","filteredValue");
+
+        var n:int = _dataCache.xCache.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            if (isNaN(_dataCache.xCache[i].filteredValue))
+                delete _dataCache.xMap[_dataCache.xCache[i].value];
+        }
+
+        n = _dataCache.yCache.length;
+        for (i = 0; i < n; i++)
+        {
+            if (isNaN(_dataCache.yCache[i].filteredValue))
+                delete _dataCache.yMap[_dataCache.yCache[i].value];
+        }
+        stripNaNs(_dataCache.xCache,"filteredValue");
+        stripNaNs(_dataCache.yCache,"filteredValue");
+        _filterDirty = false;
+    }
+
+    /**
+     * @private
+     */
+    private function mapChildren():void
+    {
+        var width:Number;
+        var height:Number;
+        for (var p:* in _childMap)
+        {
+            var dc:CartesianDataChild = _childMap[p];
+            if (dc.horizontalCenter != undefined)
+            {
+                width = widthFor(dc.child);
+                split(dc.horizontalCenter)
+                _dataCache.storeX(_data,width/2 - _offset,width/2 + _offset);
+            }
+            else if (dc.right == undefined)
+            {
+                split(dc.left);
+                _dataCache.storeX(_data,- _offset,widthFor(dc.child) + _offset);
+            }
+            else if (dc.left == undefined)
+            {
+                split(dc.right);
+                _dataCache.storeX(_data,widthFor(dc.child) - _offset,_offset);
+            }
+            else
+            {
+                split(dc.left);
+                _dataCache.storeX(_data,-_offset,_offset);
+                split(dc.right);
+                _dataCache.storeX(_data,-_offset,_offset);
+            }
+            if (dc.verticalCenter != undefined)
+            {
+                height = heightFor(dc.child);
+                split(dc.verticalCenter);
+                _dataCache.storeY(_data,height/2 - _offset,height/2 + _offset);
+            }
+            else if (dc.bottom== undefined)
+            {
+                split(dc.top);
+                _dataCache.storeY(_data,- _offset,heightFor(dc.child) + _offset);
+            }
+            else if (dc.top == undefined)
+            {
+                split(dc.bottom);
+                _dataCache.storeY(_data,heightFor(dc.child) - _offset,_offset);
+            }
+            else
+            {
+                split(dc.top);
+                _dataCache.storeY(_data,-_offset,_offset);
+                split(dc.bottom);
+                _dataCache.storeY(_data,-_offset,_offset);
+            }
+        }
+    }
+
+    /**
+     *  Removes any item from the provided cache whose field
+     *  property is NaN.
+     *  Derived classes can call this method from their updateFilter()
+     * implementation to remove any ChartItems filtered out by the axes.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected function stripNaNs(cache:Array /* of Object */, field:String):void
+    {
+        var len:int = cache.length;
+        var start:int = -1;
+        var end:int = -1;
+        var i:int;
+        var n:int;
+
+        if (field == "")
+        {
+            n = cache.length;
+            for (i = n - 1; i >= 0; i--)
+            {
+                if (isNaN(cache[i]))
+                {
+                    if (start < 0)
+                    {
+                        start = end = i;
+                    }
+                    else if (end - 1 == i)
+                    {
+                        end = i;
+                    }
+                    else
+                    {
+                        cache.splice(end, start - end + 1);
+                        start = end = i;
+                    }
+                }
+            }
+        }
+        else
+        {
+            n = cache.length;
+            for (i = n - 1; i >= 0; i--)
+            {
+                if (isNaN(cache[i][field]))
+                {
+                    if (start < 0)
+                    {
+                        start = end = i;
+                    }
+                    else if (end - 1 == i)
+                    {
+                        end = i;
+                    }
+                    else
+                    {
+                        cache.splice(end, start - end + 1);
+                        start = end = i;
+                    }
+                }
+            }
+        }
+
+        if (start >= 0)
+            cache.splice(end, start - end + 1);
+    }
+
+    /**
+     *  Informs the canvas that the underlying data
+     *  in the data provider has changed.
+     *  This method triggers calls to the updateMapping()
+     *  and updateTransform() methods on the next call
+     *  to the commitProperties() method.
+     *
+     *  @param invalid true if the data provider's data has changed.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    protected function invalidateData(invalid:Boolean = true):void
+    {
+        if (invalid)
+        {
+            invalidateDisplayList();
+        }
+    }
+
+    /**
+     * @private
+     * Takes our data values and converts them into pixel values.
+     */
+    protected function updateMapping():void
+    {
+        if (_dataCacheDirty)
+        {
+            _dataCache = new CartesianDataCache();
+
+            var p:*;
+            var record:*;
+            var value:*;
+            var boundedValue:BoundedValue;
+
+            var n:int = _opCodes.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                _opCodes[i].collectValues(_dataCache);
+            }
+
+            mapChildren();
+
+            _dataCache.xCache = [];
+            _dataCache.yCache = [];
+            _hDataDesc.min = Number.MAX_VALUE;
+            _hDataDesc.max = Number.MIN_VALUE;
+            _vDataDesc.min = Number.MAX_VALUE;
+            _vDataDesc.max = Number.MIN_VALUE;
+            for (p in _dataCache.xMap)
+            {
+                value = _dataCache.xMap[p];
+                _dataCache.xCache.push({ value: value });
+            }
+            for (p in _dataCache.yMap)
+            {
+                value = _dataCache.yMap[p];
+                _dataCache.yCache.push({ value: value });
+            }
+            _dataCacheDirty = false;
+            _mappingDirty = true;
+        }
+        if (_mappingDirty)
+        {
+            dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).mapCache(_dataCache.yCache,"value","mappedValue",true);
+            dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).mapCache(_dataCache.xCache,"value","mappedValue",true);
+            _transformDirty = true;
+            _mappingDirty = false;
+            _filterDirty = true;
+            var boundedValues:Array /* of BoundedValue */ = [];
+
+            n = _dataCache.xCache.length;
+            for (i = 0; i < n; i++)
+            {
+                value = _dataCache.xCache[i];
+                boundedValue = _dataCache.xBoundedValues[value.value];
+                if (boundedValue)
+                {
+                    boundedValue.value = value.mappedValue;
+                    boundedValues.push(boundedValue);
+                }
+            }
+            if (boundedValues.length > 0)
+            {
+                _hDataDesc.boundedValues = boundedValues;
+                boundedValues = [];
+            }
+
+            n = _dataCache.yCache.length;
+            for (i = 0; i < n; i++)
+            {
+                value = _dataCache.yCache[i];
+                boundedValue = _dataCache.yBoundedValues[value.value];
+                if (boundedValue)
+                {
+                    boundedValue.value = value.mappedValue;
+                    boundedValues.push(boundedValue);
+                }
+            }
+            if (boundedValues.length > 0)
+            {
+                _vDataDesc.boundedValues = boundedValues;
+            }
+
+            n = _dataCache.yCache.length;
+            for (i = 0; i < n; i++)
+            {
+                record = _dataCache.yCache[i];
+                _vDataDesc.min = Math.min(_vDataDesc.min, record.mappedValue);
+                _vDataDesc.max = Math.max(_vDataDesc.max, record.mappedValue);
+            }
+
+            n = _dataCache.xCache.length;
+            for (i = 0; i < n; i++)
+            {
+                record = _dataCache.xCache[i];
+                _hDataDesc.min = Math.min(_hDataDesc.min, record.mappedValue);
+                _hDataDesc.max = Math.max(_hDataDesc.max, record.mappedValue);
+            }
+
+        }
+    }
+
+    /**
+     * @private
+     */
+    protected function updateTransform():Boolean
+    {
+        var record:Object;
+        var updated:Boolean = false;
+        if (_transformDirty == false)
+        {
+            if (unscaledHeight != _oldUW || unscaledWidth != _oldUW)
+            {
+                _transformDirty = true;
+                _oldUW = unscaledWidth;
+                _oldUH = unscaledHeight;
+            }
+        }
+
+        if (_transformDirty)
+        {
+            updated = true;
+            _transformDirty = false;
+            dataTransform.transformCache(_dataCache.xCache,"mappedValue","pixelValue",null,null);
+            dataTransform.transformCache(_dataCache.yCache,null,null,"mappedValue","pixelValue");
+
+            var n:int = _dataCache.xCache.length;
+            for (var i:int = 0; i < n; i++)
+            {
+                record = _dataCache.xCache[i];
+                _dataCache.xMap[record.value] = record.pixelValue;
+            }
+
+            n = _dataCache.yCache.length;
+            for (i = 0; i < n; i++)
+            {
+                record = _dataCache.yCache[i];
+                _dataCache.yMap[record.value] = record.pixelValue;
+            }
+        }
+        return updated;
+    }
+
+    /**
+     * @private
+     * Retrieves value and offset from given data
+     */
+    private function split(v:*):void
+    {
+        if (v is CartesianCanvasValue)
+        {
+            _data = v.value;
+            _offset = v.offset;
+            if (isNaN(_offset))
+                _offset = 0;
+        }
+        else
+        {
+            _data = v;
+            _offset = 0;
+        }
+    }
+
+    /**
+     * @private
+     * Retrieves value from given data
+     */
+    private function data(v:*):*
+    {
+        if (v is CartesianCanvasValue)
+            return v.value;
+        else
+            return v;
+    }
+
+    /**
+     * @private
+     * Retrieves offset from given data
+     */
+    private function offset(v:*):*
+    {
+        if (v is CartesianCanvasValue)
+            return v.offset;
+        else
+            return 0;
+    }
+
+    /**
+     * @inheritDoc
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    // this function is called by the charting package when the axes that affect this element change their mapping some how.
+    // that means we need to call the mapCache function again to get new mappings.
+    override public function mappingChanged():void
+    {
+        invalidateDisplayList();
+    }
+
+    /**
+     * @private
+     */
+    private function widthFor(child:DisplayObject):Number
+    {
+        return  (child is IUIComponent)? IUIComponent(child).getExplicitOrMeasuredWidth() + 2:
+                (child is IFlexDisplayObject)? IFlexDisplayObject(child).measuredWidth + 2:
+                child.width;
+    }
+
+    /**
+     * @private
+     */
+    private function heightFor(child:DisplayObject):Number
+    {
+        return  (child is IUIComponent)? IUIComponent(child).getExplicitOrMeasuredHeight() + 2:
+                (child is IFlexDisplayObject)? IFlexDisplayObject(child).measuredHeight + 2:
+                child.height;
+    }
+
+    /**
+     * private
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    private function positionChildren():void
+    {
+        for (var p:* in _childMap)
+        {
+            var dc:CartesianDataChild = _childMap[p];
+            var left:Number;
+            var right:Number;
+            var top:Number;
+            var bottom:Number;
+            var hCenter:Number;
+            var vCenter:Number;
+            var width:Number;
+            var height:Number;
+
+            if (dc.horizontalCenter != undefined)
+            {
+                hCenter = _dataCache.x(data(dc.horizontalCenter)) + offset(dc.horizontalCenter);
+                width = widthFor(dc.child);
+                left = hCenter - width/2;
+                right = hCenter + width/2;
+            }
+            else if (dc.right == undefined)
+            {
+                left = _dataCache.x(data(dc.left)) + offset(dc.left);
+                right = left + widthFor(dc.child);
+            }
+            else if (dc.left == undefined)
+            {
+                right = _dataCache.x(data(dc.right)) + offset(dc.right);
+                left = right - widthFor(dc.child);
+            }
+            else
+            {
+                left = _dataCache.x(data(dc.left)) + offset(dc.left);
+                right = _dataCache.x(data(dc.right)) + offset(dc.right);
+            }
+
+            if (dc.verticalCenter != undefined)
+            {
+                vCenter = _dataCache.y(data(dc.verticalCenter)) + offset(dc.verticalCenter);
+                height = heightFor(dc.child);
+                top = vCenter - height/2;
+                bottom= vCenter + height/2;
+            }
+            else if (dc.bottom == undefined)
+            {
+                top = _dataCache.y(data(dc.top)) + offset(dc.top);
+                bottom = top + heightFor(dc.child);
+            }
+            else if (dc.top == undefined)
+            {
+                bottom = _dataCache.y(data(dc.bottom)) + offset(dc.bottom);
+                top = bottom - heightFor(dc.child);
+            }
+            else
+            {
+                top = _dataCache.y(data(dc.top)) + offset(dc.top);
+                bottom = _dataCache.y(data(dc.bottom)) + offset(dc.bottom);
+            }
+            if (isNaN(left) || isNaN(right) || isNaN(top) || isNaN(bottom))
+            {
+                removeChild(p);
+                continue;
+            }
+            if (dc.child is IFlexDisplayObject)
+            {
+                IFlexDisplayObject(dc.child).setActualSize(right-left,bottom-top);
+                IFlexDisplayObject(dc.child).move(left, top);
+            }
+            else
+            {
+                dc.child.width = right - left;
+                dc.child.height = bottom - top;
+                dc.child.x = left;
+                dc.child.y = top;
+            }
+        }
+    }
+
+    /**
+     * @private
+     */
+    private function invalidateOpCodes():void
+    {
+        dataChanged();
+        invalidateDisplayList();
+    }
+
+    /**
+     * @private
+     */
+    private function pushOp(code:int, params:Object = null):CartesianOpCode
+    {
+        var op:CartesianOpCode = new CartesianOpCode(this,code,params);
+        _opCodes.push(op);
+        invalidateOpCodes();
+        return op;
+    }
+}
+
+}
+
+import mx.charts.chartClasses.CartesianDataCanvas;
+import flash.utils.Dictionary;
+import mx.charts.chartClasses.BoundedValue;
+import flash.geom.Matrix;
+import flash.display.Graphics;
+import mx.charts.chartClasses.CartesianCanvasValue;
+import mx.core.mx_internal;
+
+use namespace mx_internal;
+
+class CartesianOpCode
+{
+    public var canvas:CartesianDataCanvas;
+    public var code:int;
+    public var params:Object;
+
+    public function CartesianOpCode(canvas:CartesianDataCanvas,code:int, params:Object = null):void
+    {
+        this.canvas = canvas;
+        this.code = code;
+        this.params = (params == null) ? {} : params;
+    }
+
+    public static const BEGIN_BITMAP_FILL:int =     0;
+    public static const BEGIN_FILL:int =            1;
+    public static const CURVE_TO:int =              2;
+    public static const DRAW_CIRCLE:int =           3;
+    public static const DRAW_ELLIPSE:int =          4;
+    public static const DRAW_RECT:int =             5;
+    public static const DRAW_ROUNDRECT:int =        6;
+    public static const END_FILL:int =              7;
+    public static const LINE_STYLE:int =            8;
+    public static const LINE_TO:int =               9;
+    public static const MOVE_TO:int =               10;
+
+    private var _data:*;
+    private var _offset:Number;
+
+    private function split(v:*):void
+    {
+        if (v is CartesianCanvasValue)
+        {
+            _data = v.value;
+            _offset = v.offset;
+            if (isNaN(_offset))
+                _offset = 0;
+        }
+        else
+        {
+            _data = v;
+            _offset = 0;
+        }
+    }
+
+    private function data(v:*):*
+    {
+        if (v is CartesianCanvasValue)
+            return v.value;
+        else
+            return v;
+    }
+
+    private function offset(v:*):*
+    {
+        if (v is CartesianCanvasValue)
+            return v.offset;
+        else
+            return 0;
+    }
+
+    mx_internal function collectValues(cache:CartesianDataCache):void
+    {
+        switch (code)
+        {
+            case BEGIN_BITMAP_FILL:
+                split(params.x);
+                if (_data != undefined)
+                    cache.storeX(_data,-_offset,_offset);
+                split(params.y);
+                if (_data != undefined)
+                    cache.storeY(_data,-_offset,_offset);
+                break;
+            case CURVE_TO:
+                split(params.anchorX);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.anchorY);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.controlX);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.controlY);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                break;
+            case DRAW_CIRCLE:
+                split(params.x);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.y);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                break;
+            case MOVE_TO:
+            case LINE_TO:
+                split(params.x);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.y);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                break;
+            case DRAW_ELLIPSE:
+                split(params.left);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.top);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.right);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.bottom);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                break;
+            case DRAW_RECT:
+                split(params.left);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.top);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.right);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.bottom);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                break;
+            case DRAW_ROUNDRECT:
+                split(params.left);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.top);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.right);
+                cache.storeX(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                split(params.bottom);
+                cache.storeY(_data,-_offset+params.borderWidth/2,_offset+params.borderWidth/2);
+                break;
+        }
+    }
+
+    mx_internal function render(target:CartesianDataCanvas,cache:CartesianDataCache):void
+    {
+        var left:Number;
+        var top:Number;
+        var right:Number;
+        var bottom:Number;
+        var controlX:Number;
+        var controlY:Number;
+        var anchorX:Number;
+        var anchorY:Number;
+        var x:Number;
+        var y:Number;
+
+        var g:Graphics = target.graphics;
+            switch (code)
+        {
+            case BEGIN_BITMAP_FILL:
+                var m:Matrix;
+                if (!(params.matrix))
+                    m = new Matrix();
+                else
+                    m = params.matrix.clone();
+
+                var d:* = data(params.x);
+                if (d != undefined)
+                    m.tx = cache.x(d);
+                m.tx  += offset(params.x);
+                d = data(params.y);
+                if (d != undefined)
+                    m.ty = cache.y(d);
+                m.ty += offset(params.y);
+                g.beginBitmapFill(params.bitmap, m, params.repeat, params.smooth);
+                break;
+
+            case BEGIN_FILL:
+                g.beginFill(params.color, params.alpha);
+                break;
+
+            case CURVE_TO:
+                controlX = cache.x(data(params.controlX)) + offset(params.controlX);
+                controlY = cache.y(data(params.controlY)) + offset(params.controlY);
+                anchorX = cache.x(data(params.anchorX)) + offset(params.anchorX);
+                anchorY = cache.y(data(params.anchorY)) + offset(params.anchorY);
+                if (isNaN(controlX) || isNaN(controlY) || isNaN(anchorX) || isNaN(anchorY))
+                    return;
+                g.curveTo(controlX, controlY, anchorX, anchorY);
+                break;
+
+            case DRAW_CIRCLE:
+                x = cache.x(data(params.x)) + offset(params.x);
+                y = cache.y(data(params.y)) + offset(params.y);
+                if (isNaN(x) || isNaN(y))
+                    return;
+                 g.drawCircle(x, y, params.radius);
+                break;
+
+            case DRAW_ELLIPSE:
+                left = cache.x(data(params.left)) + offset(params.left);
+                top = cache.y(data(params.top)) + offset(params.top);
+                right = cache.x(data(params.right)) + offset(params.right);
+                bottom = cache.y(data(params.bottom)) + offset(params.bottom);
+                if (isNaN(left) || isNaN(top) || isNaN(right) || isNaN(bottom))
+                    return;
+                g.drawEllipse(left, top,
+                            right - left,bottom - top);
+                break;
+
+            case DRAW_RECT:
+                left = cache.x(data(params.left)) + offset(params.left);
+                top = cache.y(data(params.top)) + offset(params.top);
+                right = cache.x(data(params.right)) + offset(params.right);
+                bottom = cache.y(data(params.bottom)) + offset(params.bottom);
+                if (isNaN(left) || isNaN(top) || isNaN(right) || isNaN(bottom))
+                    return;
+                g.drawRect(left, top,
+                            right - left,bottom - top);
+                break;
+
+            case DRAW_ROUNDRECT:
+                left = cache.x(data(params.left)) + offset(params.left);
+                top = cache.y(data(params.top)) + offset(params.top);
+                right = cache.x(data(params.right)) + offset(params.right);
+                bottom = cache.y(data(params.bottom)) + offset(params.bottom);
+                if (isNaN(left) || isNaN(top) || isNaN(right) || isNaN(bottom))
+                    return;
+                g.drawRoundRect(left, top,
+                            right - left,bottom - top,params.cornerRadius,params.cornerRadius);
+                break;
+
+            case END_FILL:
+                g.endFill();
+                break;
+
+            case LINE_STYLE:
+                g.lineStyle(params.thickness,params.color,params.alpha,params.pixleHinting,params.scaleMode,params.caps,params.joints,params.miterLimit);
+                break;
+
+            case MOVE_TO:
+                x = cache.x(data(params.x)) + offset(params.x);
+                y = cache.y(data(params.y)) + offset(params.y);
+                if (isNaN(x) || isNaN(y))
+                    return;
+                g.moveTo(x , y);
+                break;
+
+            case LINE_TO:
+                x = cache.x(data(params.x)) + offset(params.x);
+                y = cache.y(data(params.y)) + offset(params.y);
+                if (isNaN(x) || isNaN(y))
+                    return;
+                g.lineTo(x,y);
+                break;
+        }
+    }
+}
+
+import mx.core.mx_internal;
+
+use namespace mx_internal;
+
+class CartesianDataCache
+{
+    public var xCache:Array /* of Object */;
+    public var yCache:Array /* of Object */;
+
+    public var xBoundedValues:Dictionary;
+    public var yBoundedValues:Dictionary;
+    public var xMap:Dictionary;
+    public var yMap:Dictionary;
+
+    public function CartesianDataCache():void
+    {
+        xMap = new Dictionary(true);
+        yMap = new Dictionary(true);
+        xCache = [];
+        yCache = [];
+        xBoundedValues = new Dictionary(true);
+        yBoundedValues = new Dictionary(true);
+    }
+
+    mx_internal function storeX(value:*,leftMargin:Number = 0, rightMargin:Number = 0):void
+    {
+        var bounds:BoundedValue;
+
+        if (leftMargin < 0)
+            leftMargin = 0;
+        if (rightMargin < 0)
+            rightMargin = 0;
+
+        xMap[value] = value;
+        if (leftMargin != 0 || rightMargin != 0)
+        bounds = xBoundedValues[value];
+        if (leftMargin > 0)
+            leftMargin += 2;
+        if (rightMargin > 0)
+            rightMargin += 2;
+
+        if (!bounds)
+        {
+            xBoundedValues[value] = bounds = new BoundedValue(0,leftMargin,rightMargin);
+        }
+        else
+        {
+            bounds.lowerMargin = Math.max(bounds.lowerMargin,leftMargin);
+            bounds.upperMargin = Math.max(bounds.upperMargin,rightMargin);
+        }
+    }
+
+    mx_internal function storeY(value:*,topMargin:Number = 0,bottomMargin:Number = 0):void
+    {
+        var bounds:BoundedValue;
+
+        yMap[value] = value;
+        if (topMargin != 0 || bottomMargin != 0)
+        {
+            bounds = yBoundedValues[value];
+            if (!bounds)
+            {
+                yBoundedValues[value] = bounds = new BoundedValue(0,bottomMargin,topMargin);
+            }
+            else
+            {
+                bounds.lowerMargin = Math.max(bounds.lowerMargin,bottomMargin);
+                bounds.upperMargin = Math.max(bounds.upperMargin,topMargin);
+            }
+        }
+    }
+
+    mx_internal function x(value:*):Number
+    {
+        return Number(xMap[value]);
+    }
+
+    mx_internal function y(value:*):Number
+    {
+        return Number(yMap[value]);
+    }
+}
+
+import flash.display.DisplayObject;
+import flash.events.EventDispatcher;
+import flash.events.Event;
+use namespace mx_internal;
+
+[DefaultProperty("content")]
+[Event("change")]
+
+class CartesianDataChild extends EventDispatcher
+{
+    public function CartesianDataChild(child:DisplayObject = null,left:* = undefined, top:* = undefined, right:* = undefined, bottom:* = undefined,
+    horizontalCenter:* = undefined, verticalCenter:* = undefined):void
+    {
+        this.child = child;
+        this.left = left;
+        this.top = top;
+        this.bottom = bottom;
+        this.right = right;
+    }
+
+    public var child:DisplayObject;
+    public var left:*;
+    public var right:*;
+    public var top:*;
+    public var bottom:*;
+    public var horizontalCenter:*;
+    public var verticalCenter:*;
+
+    public function set content(value:*):void
+    {
+        if (value is DisplayObject)
+            child = value;
+        else if (value is Class)
+            child = new value();
+        dispatchEvent(new Event("change"));
+    }
+}


use Vector.<Function> instead of Array in Signal to get a ~10% performance boost

--- src/aerys/minko/type/Signal.as
+++ src/aerys/minko/type/Signal.as
@@ -2,16 +2,16 @@
 {
 	public final class Signal
 	{
-		private var _name			: String	= null;
+		private var _name			: String;

-		private var _callbacks		: Array		= [];
-		private var _numCallbacks	: uint		= 0;
+		private var _callbacks		: Vector.<Function>;
+		private var _numCallbacks	: uint;

-		private var _executed		: Boolean	= false;
-		private var _numAdded		: uint		= 0;
-		private var _toAdd			: Array		= null;
-		private var _numRemoved		: uint		= 0;
-		private var _toRemove		: Array		= null;
+		private var _executed		: Boolean;
+		private var _numAdded		: uint;
+		private var _toAdd			: Vector.<Function>;
+		private var _numRemoved		: uint;
+		private var _toRemove		: Vector.<Function>;

 		public function get numCallbacks() : uint
 		{
@@ -21,6 +21,7 @@
 		public function Signal(name : String)
 		{
 			_name = name;
+            _callbacks = new <Function>[];
 		}

 		public function add(callback : Function) : void
@@ -33,7 +34,7 @@
 				if (_toAdd)
 					_toAdd.push(callback);
 				else
-					_toAdd = [callback];
+					_toAdd = new <Function>[callback];
 				++_numAdded;

 				return ;
@@ -55,7 +56,7 @@
 				if (_toRemove)
 					_toRemove.push(callback);
 				else
-					_toRemove = [callback];
+					_toRemove = new <Function>[callback];
 				++_numRemoved;

 				return ;
@@ -77,7 +78,7 @@
 			{
 				_executed = true;
 				for (var i : uint = 0; i < _numCallbacks; ++i)
-					(_callbacks[i] as Function).apply(null, params);
+					_callbacks[i].apply(null, params);
 				_executed = false;

 				for (i = 0; i < _numAdded; ++i)


Transferred from the Adobe Open Source Subversion Repository

Revision: 12339
Author:   clucier@adobe.com
Date:     2009-12-01T22:28:31.107685Z

Log Message:
-----------
Reducing some of the event dispatching noise in the SDK.  Seeing pretty good results in our runtime performance tests and startup times... 5%-15% improvement over all.  This is about all we'll be able to commit to for Flex 4.0.  Added hasEventListener test before dispatching more of our lifecycle events.  Modified compiler binding code-gen to do the same.  Documented all public facing events where applicable to denote that they are no longer capturable by default.

QE notes: No
Doc notes: No
Bugs: SDK-24249
Reviewer: Alex
Tests run: Mustella, Checkin
Is noteworthy for integration: Yes

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/skins/spark/BorderContainerSkin.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/primitives/supportClasses/GraphicElement.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/Group.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/styles/StyleManagerImpl.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/SolidColorStroke.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/events/FlexEvent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/managers/LayoutManager.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/SolidColor.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/airframework/src/mx/managers/WindowedSystemManager.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/Container.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/managers/systemClasses/ChildManager.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/GradientEntry.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/states/State.as</path>
<path kind="file" action="M">/flex/sdk/trunk/modules/compiler/src/java/flex2/compiler/as3/binding/BindableSecondPassEvaluator.java</path>
<path kind="file" action="M">/flex/sdk/trunk/modules/compiler/src/java/flex2/compiler/as3/binding/BindableProperty.vm</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1262029 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/framework/src/mx/managers/systemClasses/ChildManager.as
+++ frameworks/projects/framework/src/mx/managers/systemClasses/ChildManager.as
@@ -182,7 +182,8 @@
 	 */
 	public function childAdded(child:DisplayObject):void
 	{
-		child.dispatchEvent(new FlexEvent(FlexEvent.ADD));
+        if (child.hasEventListener(FlexEvent.ADD))
+		    child.dispatchEvent(new FlexEvent(FlexEvent.ADD));

 		if (child is IUIComponent)
 			IUIComponent(child).initialize(); // calls child.createChildren()
@@ -193,7 +194,8 @@
      */
 	public function removingChild(child:DisplayObject):void
 	{
-		child.dispatchEvent(new FlexEvent(FlexEvent.REMOVE));
+        if (child.hasEventListener(FlexEvent.REMOVE))
+		    child.dispatchEvent(new FlexEvent(FlexEvent.REMOVE));
 	}

 	/**


Transferred from the Adobe Open Source Subversion Repository

Revision: 23243
Author:   cframpto@adobe.com
Date:     2011-12-20T00:59:57.384047Z

Log Message:
-----------
In frameworks, remove Adobe headers from all files except xml/mxml file types.  There are also a few .txt files that are license files that I didn't touch yet.

Modified Paths:
--------------
2361 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1265278 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mobiletheme/src/spark/skins/mobile/DefaultButtonSkin.as
+++ frameworks/projects/mobiletheme/src/spark/skins/mobile/DefaultButtonSkin.as
@@ -1,13 +1,3 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  ADOBE SYSTEMS INCORPORATED
-//  Copyright 2010 Adobe Systems Incorporated
-//  All Rights Reserved.
-//
-//  NOTICE: Adobe permits you to use, modify, and distribute this file
-//  in accordance with the terms of the license agreement accompanying it.
-//
-////////////////////////////////////////////////////////////////////////////////

 package spark.skins.mobile
 {