Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Chart.html
index cdba6c2..6846ddb 100644 (file)
+<!DOCTYPE html>
 <html>
 <head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>The source code</title>
-    <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
-    <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
+  <script type="text/javascript" src="../prettify/prettify.js"></script>
+  <style type="text/css">
+    .highlight { display: block; background-color: #ddd; }
+  </style>
+  <script type="text/javascript">
+    function highlight() {
+      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+    }
+  </script>
 </head>
-<body  onload="prettyPrint();">
-    <pre class="prettyprint lang-js">/*!
- * Ext JS Library 3.2.1
- * Copyright(c) 2006-2010 Ext JS, Inc.
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
-<div id="cls-Ext.chart.Chart"></div>/**
- * @class Ext.chart.Chart
- * @extends Ext.FlashComponent
- * The Ext.chart package provides the capability to visualize data with flash based charting.
+<body onload="prettyPrint(); highlight();">
+  <pre class="prettyprint lang-js"><span id='Ext-chart-Chart'>/**
+</span> * @class Ext.chart.Chart
+ * @extends Ext.draw.Component
+ *
+ * The Ext.chart package provides the capability to visualize data.
  * Each chart binds directly to an Ext.data.Store enabling automatic updates of the chart.
- * To change the look and feel of a chart, see the {@link #chartStyle} and {@link #extraStyle} config options.
- * @constructor
- * @xtype chart
+ * A chart configuration object has some overall styling options as well as an array of axes
+ * and series. A chart instance example could look like:
+ *
+  &lt;pre&gt;&lt;code&gt;
+    Ext.create('Ext.chart.Chart', {
+        renderTo: Ext.getBody(),
+        width: 800,
+        height: 600,
+        animate: true,
+        store: store1,
+        shadow: true,
+        theme: 'Category1',
+        legend: {
+            position: 'right'
+        },
+        axes: [ ...some axes options... ],
+        series: [ ...some series options... ]
+    });
+  &lt;/code&gt;&lt;/pre&gt;
+ *
+ * In this example we set the `width` and `height` of the chart, we decide whether our series are
+ * animated or not and we select a store to be bound to the chart. We also turn on shadows for all series,
+ * select a color theme `Category1` for coloring the series, set the legend to the right part of the chart and
+ * then tell the chart to render itself in the body element of the document. For more information about the axes and
+ * series configurations please check the documentation of each series (Line, Bar, Pie, etc).
  */
+Ext.define('Ext.chart.Chart', {
+
+    /* Begin Definitions */
+
+    alias: 'widget.chart',
 
- Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
-    refreshBuffer: 100,
+    extend: 'Ext.draw.Component',
+    
+    mixins: {
+        themeManager: 'Ext.chart.theme.Theme',
+        mask: 'Ext.chart.Mask',
+        navigation: 'Ext.chart.Navigation'
+    },
+
+    requires: [
+        'Ext.util.MixedCollection',
+        'Ext.data.StoreManager',
+        'Ext.chart.Legend',
+        'Ext.util.DelayedTask'
+    ],
+
+    /* End Definitions */
 
-    <div id="cfg-Ext.chart.Chart-backgroundColor"></div>/**
-     * @cfg {String} backgroundColor
-     * @hide
+    // @private
+    viewBox: false,
+
+<span id='Ext-chart-Chart-cfg-theme'>    /**
+</span>     * @cfg {String} theme (optional) The name of the theme to be used. A theme defines the colors and
+     * other visual displays of tick marks on axis, text, title text, line colors, marker colors and styles, etc.
+     * Possible theme values are 'Base', 'Green', 'Sky', 'Red', 'Purple', 'Blue', 'Yellow' and also six category themes
+     * 'Category1' to 'Category6'. Default value is 'Base'.
      */
 
-    <div id="cfg-Ext.chart.Chart-chartStyle"></div>/**
-     * @cfg {Object} chartStyle
-     * Sets styles for this chart. This contains default styling, so modifying this property will <b>override</b>
-     * the built in styles of the chart. Use {@link #extraStyle} to add customizations to the default styling.
+<span id='Ext-chart-Chart-cfg-animate'>    /**
+</span>     * @cfg {Boolean/Object} animate (optional) true for the default animation (easing: 'ease' and duration: 500)
+     * or a standard animation config object to be used for default chart animations. Defaults to false.
      */
-    chartStyle: {
-        padding: 10,
-        animationEnabled: true,
-        font: {
-            name: 'Tahoma',
-            color: 0x444444,
-            size: 11
-        },
-        dataTip: {
-            padding: 5,
-            border: {
-                color: 0x99bbe8,
-                size:1
-            },
-            background: {
-                color: 0xDAE7F6,
-                alpha: .9
-            },
-            font: {
-                name: 'Tahoma',
-                color: 0x15428B,
-                size: 10,
-                bold: true
-            }
-        }
-    },
+    animate: false,
 
-    <div id="cfg-Ext.chart.Chart-url"></div>/**
-     * @cfg {String} url
-     * The url to load the chart from. This defaults to Ext.chart.Chart.CHART_URL, which should
-     * be modified to point to the local charts resource.
+<span id='Ext-chart-Chart-cfg-legend'>    /**
+</span>     * @cfg {Boolean/Object} legend (optional) true for the default legend display or a legend config object. Defaults to false.
      */
+    legend: false,
 
-    <div id="cfg-Ext.chart.Chart-extraStyle"></div>/**
-     * @cfg {Object} extraStyle
-     * Contains extra styles that will be added or overwritten to the default chartStyle. Defaults to <tt>null</tt>.
-     * For a detailed list of the options available, visit the YUI Charts site
-     * at <a href="http://developer.yahoo.com/yui/charts/#basicstyles">http://developer.yahoo.com/yui/charts/#basicstyles</a><br/>
-     * Some of the options availabe:<br />
-     * <ul style="padding:5px;padding-left:16px;list-style-type:inherit;">
-     * <li><b>padding</b> - The space around the edge of the chart's contents. Padding does not increase the size of the chart.</li>
-     * <li><b>animationEnabled</b> - A Boolean value that specifies whether marker animations are enabled or not. Enabled by default.</li>
-     * <li><b>font</b> - An Object defining the font style to be used in the chart. Defaults to <tt>{ name: 'Tahoma', color: 0x444444, size: 11 }</tt><br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>name</b> - font name</li>
-     *      <li><b>color</b> - font color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
-     *      <li><b>size</b> - font size in points (numeric portion only, ie: 11)</li>
-     *      <li><b>bold</b> - boolean</li>
-     *      <li><b>italic</b> - boolean</li>
-     *      <li><b>underline</b> - boolean</li>
-     *  </ul>
-     * </li>
-     * <li><b>border</b> - An object defining the border style around the chart. The chart itself will decrease in dimensions to accomodate the border.<br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>color</b> - border color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
-     *      <li><b>size</b> - border size in pixels (numeric portion only, ie: 1)</li>
-     *  </ul>
-     * </li>
-     * <li><b>background</b> - An object defining the background style of the chart.<br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>color</b> - border color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
-     *      <li><b>image</b> - an image URL. May be relative to the current document or absolute.</li>
-     *  </ul>
-     * </li>
-     * <li><b>legend</b> - An object defining the legend style<br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>display</b> - location of the legend. Possible values are "none", "left", "right", "top", and "bottom".</li>
-     *      <li><b>spacing</b> - an image URL. May be relative to the current document or absolute.</li>
-     *      <li><b>padding, border, background, font</b> - same options as described above.</li>
-     *  </ul></li>
-     * <li><b>dataTip</b> - An object defining the style of the data tip (tooltip).<br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>padding, border, background, font</b> - same options as described above.</li>
-     *  </ul></li>
-     * <li><b>xAxis and yAxis</b> - An object defining the style of the style of either axis.<br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>color</b> - same option as described above.</li>
-     *      <li><b>size</b> - same option as described above.</li>
-     *      <li><b>showLabels</b> - boolean</li>
-     *      <li><b>labelRotation</b> - a value in degrees from -90 through 90. Default is zero.</li>
-     *  </ul></li>
-     * <li><b>majorGridLines and minorGridLines</b> - An object defining the style of the style of the grid lines.<br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>color, size</b> - same options as described above.</li>
-     *  </ul></li></li>
-     * <li><b>zeroGridLine</b> - An object defining the style of the style of the zero grid line.<br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>color, size</b> - same options as described above.</li>
-     *  </ul></li></li>
-     * <li><b>majorTicks and minorTicks</b> - An object defining the style of the style of ticks in the chart.<br/>
-     *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
-     *      <li><b>color, size</b> - same options as described above.</li>
-     *      <li><b>length</b> - the length of each tick in pixels extending from the axis.</li>
-     *      <li><b>display</b> - how the ticks are drawn. Possible values are "none", "inside", "outside", and "cross".</li>
-     *  </ul></li></li>
-     * </ul>
+<span id='Ext-chart-Chart-cfg-insetPadding'>    /**
+</span>     * @cfg {integer} insetPadding (optional) Set the amount of inset padding in pixels for the chart. Defaults to 10.
      */
-    extraStyle: null,
+    insetPadding: 10,
 
-    <div id="cfg-Ext.chart.Chart-seriesStyles"></div>/**
-     * @cfg {Object} seriesStyles
-     * Contains styles to apply to the series after a refresh. Defaults to <tt>null</tt>.
+<span id='Ext-chart-Chart-cfg-enginePriority'>    /**
+</span>     * @cfg {Array} enginePriority
+     * Defines the priority order for which Surface implementation to use. The first
+     * one supported by the current environment will be used.
      */
-    seriesStyles: null,
+    enginePriority: ['Svg', 'Vml'],
+
+<span id='Ext-chart-Chart-cfg-background'>    /**
+</span>     * @cfg {Object|Boolean} background (optional) Set the chart background. This can be a gradient object, image, or color.
+     * Defaults to false for no background.
+     *
+     * For example, if `background` were to be a color we could set the object as
+     *
+     &lt;pre&gt;&lt;code&gt;
+        background: {
+            //color string
+            fill: '#ccc'
+        }
+     &lt;/code&gt;&lt;/pre&gt;
+
+     You can specify an image by using:
+
+     &lt;pre&gt;&lt;code&gt;
+        background: {
+            image: 'http://path.to.image/'
+        }
+     &lt;/code&gt;&lt;/pre&gt;
+
+     Also you can specify a gradient by using the gradient object syntax:
+
+     &lt;pre&gt;&lt;code&gt;
+        background: {
+            gradient: {
+                id: 'gradientId',
+                angle: 45,
+                stops: {
+                    0: {
+                        color: '#555'
+                    }
+                    100: {
+                        color: '#ddd'
+                    }
+                }
+            }
+        }
+     &lt;/code&gt;&lt;/pre&gt;
+     */
+    background: false,
+
+<span id='Ext-chart-Chart-cfg-gradients'>    /**
+</span>     * @cfg {Array} gradients (optional) Define a set of gradients that can be used as `fill` property in sprites.
+     * The gradients array is an array of objects with the following properties:
+     *
+     * &lt;ul&gt;
+     * &lt;li&gt;&lt;strong&gt;id&lt;/strong&gt; - string - The unique name of the gradient.&lt;/li&gt;
+     * &lt;li&gt;&lt;strong&gt;angle&lt;/strong&gt; - number, optional - The angle of the gradient in degrees.&lt;/li&gt;
+     * &lt;li&gt;&lt;strong&gt;stops&lt;/strong&gt; - object - An object with numbers as keys (from 0 to 100) and style objects
+     * as values&lt;/li&gt;
+     * &lt;/ul&gt;
+     *
+
+     For example:
+
+     &lt;pre&gt;&lt;code&gt;
+        gradients: [{
+            id: 'gradientId',
+            angle: 45,
+            stops: {
+                0: {
+                    color: '#555'
+                },
+                100: {
+                    color: '#ddd'
+                }
+            }
+        },  {
+            id: 'gradientId2',
+            angle: 0,
+            stops: {
+                0: {
+                    color: '#590'
+                },
+                20: {
+                    color: '#599'
+                },
+                100: {
+                    color: '#ddd'
+                }
+            }
+        }]
+     &lt;/code&gt;&lt;/pre&gt;
+
+     Then the sprites can use `gradientId` and `gradientId2` by setting the fill attributes to those ids, for example:
+
+     &lt;pre&gt;&lt;code&gt;
+        sprite.setAttributes({
+            fill: 'url(#gradientId)'
+        }, true);
+     &lt;/code&gt;&lt;/pre&gt;
 
-    <div id="cfg-Ext.chart.Chart-disableCaching"></div>/**
-     * @cfg {Boolean} disableCaching
-     * True to add a "cache buster" to the end of the chart url. Defaults to true for Opera and IE.
      */
-    disableCaching: Ext.isIE || Ext.isOpera,
-    disableCacheParam: '_dc',
 
-    initComponent : function(){
-        Ext.chart.Chart.superclass.initComponent.call(this);
-        if(!this.url){
-            this.url = Ext.chart.Chart.CHART_URL;
+
+    constructor: function(config) {
+        var me = this,
+            defaultAnim;
+        me.initTheme(config.theme || me.theme);
+        if (me.gradients) {
+            Ext.apply(config, { gradients: me.gradients });
         }
-        if(this.disableCaching){
-            this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
+        if (me.background) {
+            Ext.apply(config, { background: me.background });
+        }
+        if (config.animate) {
+            defaultAnim = {
+                easing: 'ease',
+                duration: 500
+            };
+            if (Ext.isObject(config.animate)) {
+                config.animate = Ext.applyIf(config.animate, defaultAnim);
+            }
+            else {
+                config.animate = defaultAnim;
+            }
         }
-        this.addEvents(
+        me.mixins.mask.constructor.call(me, config);
+        me.mixins.navigation.constructor.call(me, config);
+        me.callParent([config]);
+    },
+
+    initComponent: function() {
+        var me = this,
+            axes,
+            series;
+        me.callParent();
+        me.addEvents(
+            'itemmousedown',
+            'itemmouseup',
             'itemmouseover',
             'itemmouseout',
             'itemclick',
             'itemdragstart',
             'itemdrag',
             'itemdragend',
-            <div id="event-Ext.chart.Chart-beforerefresh"></div>/**
-             * @event beforerefresh
-             * Fires before a refresh to the chart data is called.  If the beforerefresh handler returns
-             * <tt>false</tt> the {@link #refresh} action will be cancelled.
-             * @param {Chart} this
-             */
+<span id='Ext-chart-Chart-event-beforerefresh'>            /**
+</span>                 * @event beforerefresh
+                 * Fires before a refresh to the chart data is called.  If the beforerefresh handler returns
+                 * &lt;tt&gt;false&lt;/tt&gt; the {@link #refresh} action will be cancelled.
+                 * @param {Chart} this
+                 */
             'beforerefresh',
-            <div id="event-Ext.chart.Chart-refresh"></div>/**
-             * @event refresh
-             * Fires after the chart data has been refreshed.
-             * @param {Chart} this
-             */
+<span id='Ext-chart-Chart-event-refresh'>            /**
+</span>                 * @event refresh
+                 * Fires after the chart data has been refreshed.
+                 * @param {Chart} this
+                 */
             'refresh'
         );
-        this.store = Ext.StoreMgr.lookup(this.store);
-    },
-
-    <div id="method-Ext.chart.Chart-setStyle"></div>/**
-     * Sets a single style value on the Chart instance.
-     *
-     * @param name {String} Name of the Chart style value to change.
-     * @param value {Object} New value to pass to the Chart style.
-     */
-     setStyle: function(name, value){
-         this.swf.setStyle(name, Ext.encode(value));
-     },
-
-    <div id="method-Ext.chart.Chart-setStyles"></div>/**
-     * Resets all styles on the Chart instance.
-     *
-     * @param styles {Object} Initializer for all Chart styles.
-     */
-    setStyles: function(styles){
-        this.swf.setStyles(Ext.encode(styles));
-    },
+        Ext.applyIf(me, {
+            zoom: {
+                width: 1,
+                height: 1,
+                x: 0,
+                y: 0
+            }
+        });
+        me.maxGutter = [0, 0];
+        me.store = Ext.data.StoreManager.lookup(me.store);
+        axes = me.axes;
+        me.axes = Ext.create('Ext.util.MixedCollection', false, function(a) { return a.position; });
+        if (axes) {
+            me.axes.addAll(axes);
+        }
+        series = me.series;
+        me.series = Ext.create('Ext.util.MixedCollection', false, function(a) { return a.seriesId || (a.seriesId = Ext.id(null, 'ext-chart-series-')); });
+        if (series) {
+            me.series.addAll(series);
+        }
+        if (me.legend !== false) {
+            me.legend = Ext.create('Ext.chart.Legend', Ext.applyIf({chart:me}, me.legend));
+        }
 
-    <div id="method-Ext.chart.Chart-setSeriesStyles"></div>/**
-     * Sets the styles on all series in the Chart.
-     *
-     * @param styles {Array} Initializer for all Chart series styles.
-     */
-    setSeriesStyles: function(styles){
-        this.seriesStyles = styles;
-        var s = [];
-        Ext.each(styles, function(style){
-            s.push(Ext.encode(style));
+        me.on({
+            mousemove: me.onMouseMove,
+            mouseleave: me.onMouseLeave,
+            mousedown: me.onMouseDown,
+            mouseup: me.onMouseUp,
+            scope: me
         });
-        this.swf.setSeriesStyles(s);
     },
 
-    setCategoryNames : function(names){
-        this.swf.setCategoryNames(names);
+    // @private overrides the component method to set the correct dimensions to the chart.
+    afterComponentLayout: function(width, height) {
+        var me = this;
+        if (Ext.isNumber(width) &amp;&amp; Ext.isNumber(height)) {
+            me.curWidth = width;
+            me.curHeight = height;
+            me.redraw(true);
+        }
+        this.callParent(arguments);
     },
 
-    setLegendRenderer : function(fn, scope){
-        var chart = this;
-        scope = scope || chart;
-        chart.removeFnProxy(chart.legendFnName);
-        chart.legendFnName = chart.createFnProxy(function(name){
-            return fn.call(scope, name);
+<span id='Ext-chart-Chart-cfg-resize'>    /**
+</span>     * Redraw the chart. If animations are set this will animate the chart too.
+     * @cfg {boolean} resize Optional flag which changes the default origin points of the chart for animations.
+     */
+    redraw: function(resize) {
+        var me = this,
+            chartBBox = me.chartBBox = {
+                x: 0,
+                y: 0,
+                height: me.curHeight,
+                width: me.curWidth
+            },
+            legend = me.legend;
+        me.surface.setSize(chartBBox.width, chartBBox.height);
+        // Instantiate Series and Axes
+        me.series.each(me.initializeSeries, me);
+        me.axes.each(me.initializeAxis, me);
+        //process all views (aggregated data etc) on stores
+        //before rendering.
+        me.axes.each(function(axis) {
+            axis.processView();
         });
-        chart.swf.setLegendLabelFunction(chart.legendFnName);
-    },
-
-    setTipRenderer : function(fn, scope){
-        var chart = this;
-        scope = scope || chart;
-        chart.removeFnProxy(chart.tipFnName);
-        chart.tipFnName = chart.createFnProxy(function(item, index, series){
-            var record = chart.store.getAt(index);
-            return fn.call(scope, chart, record, index, series);
+        me.axes.each(function(axis) {
+            axis.drawAxis(true);
         });
-        chart.swf.setDataTipFunction(chart.tipFnName);
-    },
-
-    setSeries : function(series){
-        this.series = series;
-        this.refresh();
-    },
 
-    <div id="method-Ext.chart.Chart-bindStore"></div>/**
-     * Changes the data store bound to this chart and refreshes it.
-     * @param {Store} store The store to bind to this chart
-     */
-    bindStore : function(store, initial){
-        if(!initial && this.store){
-            if(store !== this.store && this.store.autoDestroy){
-                this.store.destroy();
-            }else{
-                this.store.un("datachanged", this.refresh, this);
-                this.store.un("add", this.delayRefresh, this);
-                this.store.un("remove", this.delayRefresh, this);
-                this.store.un("update", this.delayRefresh, this);
-                this.store.un("clear", this.refresh, this);
-            }
-        }
-        if(store){
-            store = Ext.StoreMgr.lookup(store);
-            store.on({
-                scope: this,
-                datachanged: this.refresh,
-                add: this.delayRefresh,
-                remove: this.delayRefresh,
-                update: this.delayRefresh,
-                clear: this.refresh
-            });
-        }
-        this.store = store;
-        if(store && !initial){
-            this.refresh();
+        // Create legend if not already created
+        if (legend !== false) {
+            legend.create();
         }
-    },
 
-    onSwfReady : function(isReset){
-        Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
-        var ref;
-        this.swf.setType(this.type);
+        // Place axes properly, including influence from each other
+        me.alignAxes();
 
-        if(this.chartStyle){
-            this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
+        // Reposition legend based on new axis alignment
+        if (me.legend !== false) {
+            legend.updatePosition();
         }
 
-        if(this.categoryNames){
-            this.setCategoryNames(this.categoryNames);
-        }
+        // Find the max gutter
+        me.getMaxGutter();
 
-        if(this.tipRenderer){
-            ref = this.getFunctionRef(this.tipRenderer);
-            this.setTipRenderer(ref.fn, ref.scope);
-        }
-        if(this.legendRenderer){
-            ref = this.getFunctionRef(this.legendRenderer);
-            this.setLegendRenderer(ref.fn, ref.scope);
+        // Draw axes and series
+        me.resizing = !!resize;
+
+        me.axes.each(me.drawAxis, me);
+        me.series.each(me.drawCharts, me);
+        me.resizing = false;
+    },
+
+    // @private set the store after rendering the chart.
+    afterRender: function() {
+        var ref,
+            me = this;
+        this.callParent();
+
+        if (me.categoryNames) {
+            me.setCategoryNames(me.categoryNames);
         }
-        if(!isReset){
-            this.bindStore(this.store, true);
+
+        if (me.tipRenderer) {
+            ref = me.getFunctionRef(me.tipRenderer);
+            me.setTipRenderer(ref.fn, ref.scope);
         }
-        this.refresh.defer(10, this);
+        me.bindStore(me.store, true);
+        me.refresh();
     },
 
-    delayRefresh : function(){
-        if(!this.refreshTask){
-            this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
-        }
-        this.refreshTask.delay(this.refreshBuffer);
+    // @private get x and y position of the mouse cursor.
+    getEventXY: function(e) {
+        var me = this,
+            box = this.surface.getRegion(),
+            pageXY = e.getXY(),
+            x = pageXY[0] - box.left,
+            y = pageXY[1] - box.top;
+        return [x, y];
     },
 
-    refresh : function(){
-        if(this.fireEvent('beforerefresh', this) !== false){
-            var styleChanged = false;
-            // convert the store data into something YUI charts can understand
-            var data = [], rs = this.store.data.items;
-            for(var j = 0, len = rs.length; j < len; j++){
-                data[j] = rs[j].data;
-            }
-            //make a copy of the series definitions so that we aren't
-            //editing them directly.
-            var dataProvider = [];
-            var seriesCount = 0;
-            var currentSeries = null;
-            var i = 0;
-            if(this.series){
-                seriesCount = this.series.length;
-                for(i = 0; i < seriesCount; i++){
-                    currentSeries = this.series[i];
-                    var clonedSeries = {};
-                    for(var prop in currentSeries){
-                        if(prop == "style" && currentSeries.style !== null){
-                            clonedSeries.style = Ext.encode(currentSeries.style);
-                            styleChanged = true;
-                            //we don't want to modify the styles again next time
-                            //so null out the style property.
-                            // this causes issues
-                            // currentSeries.style = null;
-                        } else{
-                            clonedSeries[prop] = currentSeries[prop];
-                        }
+    // @private wrap the mouse down position to delegate the event to the series.
+    onClick: function(e) {
+        var me = this,
+            position = me.getEventXY(e),
+            item;
+
+        // Ask each series if it has an item corresponding to (not necessarily exactly
+        // on top of) the current mouse coords. Fire itemclick event.
+        me.series.each(function(series) {
+            if (Ext.draw.Draw.withinBox(position[0], position[1], series.bbox)) {
+                if (series.getItemForPoint) {
+                    item = series.getItemForPoint(position[0], position[1]);
+                    if (item) {
+                        series.fireEvent('itemclick', item);
                     }
-                    dataProvider.push(clonedSeries);
                 }
             }
+        }, me);
+    },
+
+    // @private wrap the mouse down position to delegate the event to the series.
+    onMouseDown: function(e) {
+        var me = this,
+            position = me.getEventXY(e),
+            item;
 
-            if(seriesCount > 0){
-                for(i = 0; i < seriesCount; i++){
-                    currentSeries = dataProvider[i];
-                    if(!currentSeries.type){
-                        currentSeries.type = this.type;
+        if (me.mask) {
+            me.mixins.mask.onMouseDown.call(me, e);
+        }
+        // Ask each series if it has an item corresponding to (not necessarily exactly
+        // on top of) the current mouse coords. Fire mousedown event.
+        me.series.each(function(series) {
+            if (Ext.draw.Draw.withinBox(position[0], position[1], series.bbox)) {
+                if (series.getItemForPoint) {
+                    item = series.getItemForPoint(position[0], position[1]);
+                    if (item) {
+                        series.fireEvent('itemmousedown', item);
                     }
-                    currentSeries.dataProvider = data;
                 }
-            } else{
-                dataProvider.push({type: this.type, dataProvider: data});
             }
-            this.swf.setDataProvider(dataProvider);
-            if(this.seriesStyles){
-                this.setSeriesStyles(this.seriesStyles);
-            }
-            this.fireEvent('refresh', this);
-        }
+        }, me);
     },
 
-    // private
-    createFnProxy : function(fn){
-        var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
-        Ext.chart.Chart.proxyFunction[fnName] = fn;
-        return 'Ext.chart.Chart.proxyFunction.' + fnName;
-    },
+    // @private wrap the mouse up event to delegate it to the series.
+    onMouseUp: function(e) {
+        var me = this,
+            position = me.getEventXY(e),
+            item;
 
-    // private
-    removeFnProxy : function(fn){
-        if(!Ext.isEmpty(fn)){
-            fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
-            delete Ext.chart.Chart.proxyFunction[fn];
+        if (me.mask) {
+            me.mixins.mask.onMouseUp.call(me, e);
         }
+        // Ask each series if it has an item corresponding to (not necessarily exactly
+        // on top of) the current mouse coords. Fire mousedown event.
+        me.series.each(function(series) {
+            if (Ext.draw.Draw.withinBox(position[0], position[1], series.bbox)) {
+                if (series.getItemForPoint) {
+                    item = series.getItemForPoint(position[0], position[1]);
+                    if (item) {
+                        series.fireEvent('itemmouseup', item);
+                    }
+                }
+            }
+        }, me);
     },
 
-    // private
-    getFunctionRef : function(val){
-        if(Ext.isFunction(val)){
-            return {
-                fn: val,
-                scope: this
-            };
-        }else{
-            return {
-                fn: val.fn,
-                scope: val.scope || this
-            }
+    // @private wrap the mouse move event so it can be delegated to the series.
+    onMouseMove: function(e) {
+        var me = this,
+            position = me.getEventXY(e),
+            item, last, storeItem, storeField;
+
+        if (me.mask) {
+            me.mixins.mask.onMouseMove.call(me, e);
         }
+        // Ask each series if it has an item corresponding to (not necessarily exactly
+        // on top of) the current mouse coords. Fire itemmouseover/out events.
+        me.series.each(function(series) {
+            if (Ext.draw.Draw.withinBox(position[0], position[1], series.bbox)) {
+                if (series.getItemForPoint) {
+                    item = series.getItemForPoint(position[0], position[1]);
+                    last = series._lastItemForPoint;
+                    storeItem = series._lastStoreItem;
+                    storeField = series._lastStoreField;
+
+
+                    if (item !== last || item &amp;&amp; (item.storeItem != storeItem || item.storeField != storeField)) {
+                        if (last) {
+                            series.fireEvent('itemmouseout', last);
+                            delete series._lastItemForPoint;
+                            delete series._lastStoreField;
+                            delete series._lastStoreItem;
+                        }
+                        if (item) {
+                            series.fireEvent('itemmouseover', item);
+                            series._lastItemForPoint = item;
+                            series._lastStoreItem = item.storeItem;
+                            series._lastStoreField = item.storeField;
+                        }
+                    }
+                }
+            } else {
+                last = series._lastItemForPoint;
+                if (last) {
+                    series.fireEvent('itemmouseout', last);
+                    delete series._lastItemForPoint;
+                    delete series._lastStoreField;
+                    delete series._lastStoreItem;
+                }
+            }
+        }, me);
     },
 
-    // private
-    onDestroy: function(){
-        if (this.refreshTask && this.refreshTask.cancel){
-            this.refreshTask.cancel();
+    // @private handle mouse leave event.
+    onMouseLeave: function(e) {
+        var me = this;
+        if (me.mask) {
+            me.mixins.mask.onMouseLeave.call(me, e);
         }
-        Ext.chart.Chart.superclass.onDestroy.call(this);
-        this.bindStore(null);
-        this.removeFnProxy(this.tipFnName);
-        this.removeFnProxy(this.legendFnName);
-    }
-});
-Ext.reg('chart', Ext.chart.Chart);
-Ext.chart.Chart.PROXY_FN_ID = 0;
-Ext.chart.Chart.proxyFunction = {};
-
-<div id="prop-Ext.chart.Chart-CHART_URL"></div>/**
- * Sets the url to load the chart from. This should be set to a local resource.
- * @static
- * @type String
- */
-Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.0/build/charts/assets/charts.swf';
-
-<div id="cls-Ext.chart.PieChart"></div>/**
- * @class Ext.chart.PieChart
- * @extends Ext.chart.Chart
- * @constructor
- * @xtype piechart
- */
-Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
-    type: 'pie',
-
-    onSwfReady : function(isReset){
-        Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
-
-        this.setDataField(this.dataField);
-        this.setCategoryField(this.categoryField);
+        me.series.each(function(series) {
+            delete series._lastItemForPoint;
+        });
     },
 
-    setDataField : function(field){
-        this.dataField = field;
-        this.swf.setDataField(field);
+    // @private buffered refresh for when we update the store
+    delayRefresh: function() {
+        var me = this;
+        if (!me.refreshTask) {
+            me.refreshTask = Ext.create('Ext.util.DelayedTask', me.refresh, me);
+        }
+        me.refreshTask.delay(me.refreshBuffer);
     },
 
-    setCategoryField : function(field){
-        this.categoryField = field;
-        this.swf.setCategoryField(field);
-    }
-});
-Ext.reg('piechart', Ext.chart.PieChart);
+    // @private
+    refresh: function() {
+        var me = this;
+        if (me.rendered &amp;&amp; me.curWidth != undefined &amp;&amp; me.curHeight != undefined) {
+            if (me.fireEvent('beforerefresh', me) !== false) {
+                me.redraw();
+                me.fireEvent('refresh', me);
+            }
+        }
+    },
 
-<div id="cls-Ext.chart.CartesianChart"></div>/**
- * @class Ext.chart.CartesianChart
- * @extends Ext.chart.Chart
- * @constructor
- * @xtype cartesianchart
- */
-Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
-    onSwfReady : function(isReset){
-        Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
-        this.labelFn = [];
-        if(this.xField){
-            this.setXField(this.xField);
+<span id='Ext-chart-Chart-method-bindStore'>    /**
+</span>     * Changes the data store bound to this chart and refreshes it.
+     * @param {Store} store The store to bind to this chart
+     */
+    bindStore: function(store, initial) {
+        var me = this;
+        if (!initial &amp;&amp; me.store) {
+            if (store !== me.store &amp;&amp; me.store.autoDestroy) {
+                me.store.destroy();
+            }
+            else {
+                me.store.un('datachanged', me.refresh, me);
+                me.store.un('add', me.delayRefresh, me);
+                me.store.un('remove', me.delayRefresh, me);
+                me.store.un('update', me.delayRefresh, me);
+                me.store.un('clear', me.refresh, me);
+            }
         }
-        if(this.yField){
-            this.setYField(this.yField);
+        if (store) {
+            store = Ext.data.StoreManager.lookup(store);
+            store.on({
+                scope: me,
+                datachanged: me.refresh,
+                add: me.delayRefresh,
+                remove: me.delayRefresh,
+                update: me.delayRefresh,
+                clear: me.refresh
+            });
         }
-        if(this.xAxis){
-            this.setXAxis(this.xAxis);
+        me.store = store;
+        if (store &amp;&amp; !initial) {
+            me.refresh();
         }
-        if(this.xAxes){
-            this.setXAxes(this.xAxes);
+    },
+
+    // @private Create Axis
+    initializeAxis: function(axis) {
+        var me = this,
+            chartBBox = me.chartBBox,
+            w = chartBBox.width,
+            h = chartBBox.height,
+            x = chartBBox.x,
+            y = chartBBox.y,
+            themeAttrs = me.themeAttrs,
+            config = {
+                chart: me
+            };
+        if (themeAttrs) {
+            config.axisStyle = Ext.apply({}, themeAttrs.axis);
+            config.axisLabelLeftStyle = Ext.apply({}, themeAttrs.axisLabelLeft);
+            config.axisLabelRightStyle = Ext.apply({}, themeAttrs.axisLabelRight);
+            config.axisLabelTopStyle = Ext.apply({}, themeAttrs.axisLabelTop);
+            config.axisLabelBottomStyle = Ext.apply({}, themeAttrs.axisLabelBottom);
+            config.axisTitleLeftStyle = Ext.apply({}, themeAttrs.axisTitleLeft);
+            config.axisTitleRightStyle = Ext.apply({}, themeAttrs.axisTitleRight);
+            config.axisTitleTopStyle = Ext.apply({}, themeAttrs.axisTitleTop);
+            config.axisTitleBottomStyle = Ext.apply({}, themeAttrs.axisTitleBottom);
         }
-        if(this.yAxis){
-            this.setYAxis(this.yAxis);
+        switch (axis.position) {
+            case 'top':
+                Ext.apply(config, {
+                    length: w,
+                    width: h,
+                    x: x,
+                    y: y
+                });
+            break;
+            case 'bottom':
+                Ext.apply(config, {
+                    length: w,
+                    width: h,
+                    x: x,
+                    y: h
+                });
+            break;
+            case 'left':
+                Ext.apply(config, {
+                    length: h,
+                    width: w,
+                    x: x,
+                    y: h
+                });
+            break;
+            case 'right':
+                Ext.apply(config, {
+                    length: h,
+                    width: w,
+                    x: w,
+                    y: h
+                });
+            break;
         }
-        if(this.yAxes){
-            this.setYAxes(this.yAxes);
+        if (!axis.chart) {
+            Ext.apply(config, axis);
+            axis = me.axes.replace(Ext.createByAlias('axis.' + axis.type.toLowerCase(), config));
         }
-        if(Ext.isDefined(this.constrainViewport)){
-            this.swf.setConstrainViewport(this.constrainViewport);
+        else {
+            Ext.apply(axis, config);
         }
     },
 
-    setXField : function(value){
-        this.xField = value;
-        this.swf.setHorizontalField(value);
-    },
 
-    setYField : function(value){
-        this.yField = value;
-        this.swf.setVerticalField(value);
-    },
-
-    setXAxis : function(value){
-        this.xAxis = this.createAxis('xAxis', value);
-        this.swf.setHorizontalAxis(this.xAxis);
-    },
+<span id='Ext-chart-Chart-method-alignAxes'>    /**
+</span>     * @private Adjust the dimensions and positions of each axis and the chart body area after accounting
+     * for the space taken up on each side by the axes and legend.
+     */
+    alignAxes: function() {
+        var me = this,
+            axes = me.axes,
+            legend = me.legend,
+            edges = ['top', 'right', 'bottom', 'left'],
+            chartBBox,
+            insetPadding = me.insetPadding,
+            insets = {
+                top: insetPadding,
+                right: insetPadding,
+                bottom: insetPadding,
+                left: insetPadding
+            };
 
-    setXAxes : function(value){
-        var axis;
-        for(var i = 0; i < value.length; i++) {
-            axis = this.createAxis('xAxis' + i, value[i]);
-            this.swf.setHorizontalAxis(axis);
+        function getAxis(edge) {
+            var i = axes.findIndex('position', edge);
+            return (i &lt; 0) ? null : axes.getAt(i);
         }
-    },
 
-    setYAxis : function(value){
-        this.yAxis = this.createAxis('yAxis', value);
-        this.swf.setVerticalAxis(this.yAxis);
-    },
+        // Find the space needed by axes and legend as a positive inset from each edge
+        Ext.each(edges, function(edge) {
+            var isVertical = (edge === 'left' || edge === 'right'),
+                axis = getAxis(edge),
+                bbox;
+
+            // Add legend size if it's on this edge
+            if (legend !== false) {
+                if (legend.position === edge) {
+                    bbox = legend.getBBox();
+                    insets[edge] += (isVertical ? bbox.width : bbox.height) + insets[edge];
+                }
+            }
 
-    setYAxes : function(value){
-        var axis;
-        for(var i = 0; i < value.length; i++) {
-            axis = this.createAxis('yAxis' + i, value[i]);
-            this.swf.setVerticalAxis(axis);
-        }
+            // Add axis size if there's one on this edge only if it has been
+            //drawn before.
+            if (axis &amp;&amp; axis.bbox) {
+                bbox = axis.bbox;
+                insets[edge] += (isVertical ? bbox.width : bbox.height);
+            }
+        });
+        // Build the chart bbox based on the collected inset values
+        chartBBox = {
+            x: insets.left,
+            y: insets.top,
+            width: me.curWidth - insets.left - insets.right,
+            height: me.curHeight - insets.top - insets.bottom
+        };
+        me.chartBBox = chartBBox;
+
+        // Go back through each axis and set its length and position based on the
+        // corresponding edge of the chartBBox
+        axes.each(function(axis) {
+            var pos = axis.position,
+                isVertical = (pos === 'left' || pos === 'right');
+
+            axis.x = (pos === 'right' ? chartBBox.x + chartBBox.width : chartBBox.x);
+            axis.y = (pos === 'top' ? chartBBox.y : chartBBox.y + chartBBox.height);
+            axis.width = (isVertical ? chartBBox.width : chartBBox.height);
+            axis.length = (isVertical ? chartBBox.height : chartBBox.width);
+        });
     },
 
-    createAxis : function(axis, value){
-        var o = Ext.apply({}, value),
-            ref,
-            old;
-
-        if(this[axis]){
-            old = this[axis].labelFunction;
-            this.removeFnProxy(old);
-            this.labelFn.remove(old);
+    // @private initialize the series.
+    initializeSeries: function(series, idx) {
+        var me = this,
+            themeAttrs = me.themeAttrs,
+            seriesObj, markerObj, seriesThemes, st,
+            markerThemes, colorArrayStyle = [],
+            i = 0, l,
+            config = {
+                chart: me,
+                seriesId: series.seriesId
+            };
+        if (themeAttrs) {
+            seriesThemes = themeAttrs.seriesThemes;
+            markerThemes = themeAttrs.markerThemes;
+            seriesObj = Ext.apply({}, themeAttrs.series);
+            markerObj = Ext.apply({}, themeAttrs.marker);
+            config.seriesStyle = Ext.apply(seriesObj, seriesThemes[idx % seriesThemes.length]);
+            config.seriesLabelStyle = Ext.apply({}, themeAttrs.seriesLabel);
+            config.markerStyle = Ext.apply(markerObj, markerThemes[idx % markerThemes.length]);
+            if (themeAttrs.colors) {
+                config.colorArrayStyle = themeAttrs.colors;
+            } else {
+                colorArrayStyle = [];
+                for (l = seriesThemes.length; i &lt; l; i++) {
+                    st = seriesThemes[i];
+                    if (st.fill || st.stroke) {
+                        colorArrayStyle.push(st.fill || st.stroke);
+                    }
+                }
+                if (colorArrayStyle.length) {
+                    config.colorArrayStyle = colorArrayStyle;
+                }
+            }
+            config.seriesIdx = idx;
         }
-        if(o.labelRenderer){
-            ref = this.getFunctionRef(o.labelRenderer);
-            o.labelFunction = this.createFnProxy(function(v){
-                return ref.fn.call(ref.scope, v);
-            });
-            delete o.labelRenderer;
-            this.labelFn.push(o.labelFunction);
+        if (series instanceof Ext.chart.series.Series) {
+            Ext.apply(series, config);
+        } else {
+            Ext.applyIf(config, series);
+            series = me.series.replace(Ext.createByAlias('series.' + series.type.toLowerCase(), config));
         }
-        if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
-            o.position = 'bottom';
+        if (series.initialize) {
+            series.initialize();
         }
-        return o;
     },
 
-    onDestroy : function(){
-        Ext.chart.CartesianChart.superclass.onDestroy.call(this);
-        Ext.each(this.labelFn, function(fn){
-            this.removeFnProxy(fn);
-        }, this);
-    }
-});
-Ext.reg('cartesianchart', Ext.chart.CartesianChart);
-
-<div id="cls-Ext.chart.LineChart"></div>/**
- * @class Ext.chart.LineChart
- * @extends Ext.chart.CartesianChart
- * @constructor
- * @xtype linechart
- */
-Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
-    type: 'line'
-});
-Ext.reg('linechart', Ext.chart.LineChart);
-
-<div id="cls-Ext.chart.ColumnChart"></div>/**
- * @class Ext.chart.ColumnChart
- * @extends Ext.chart.CartesianChart
- * @constructor
- * @xtype columnchart
- */
-Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
-    type: 'column'
-});
-Ext.reg('columnchart', Ext.chart.ColumnChart);
-
-<div id="cls-Ext.chart.StackedColumnChart"></div>/**
- * @class Ext.chart.StackedColumnChart
- * @extends Ext.chart.CartesianChart
- * @constructor
- * @xtype stackedcolumnchart
- */
-Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
-    type: 'stackcolumn'
-});
-Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
-
-<div id="cls-Ext.chart.BarChart"></div>/**
- * @class Ext.chart.BarChart
- * @extends Ext.chart.CartesianChart
- * @constructor
- * @xtype barchart
- */
-Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
-    type: 'bar'
-});
-Ext.reg('barchart', Ext.chart.BarChart);
-
-<div id="cls-Ext.chart.StackedBarChart"></div>/**
- * @class Ext.chart.StackedBarChart
- * @extends Ext.chart.CartesianChart
- * @constructor
- * @xtype stackedbarchart
- */
-Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
-    type: 'stackbar'
-});
-Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
-
-
-
-<div id="cls-Ext.chart.Axis"></div>/**
- * @class Ext.chart.Axis
- * Defines a CartesianChart's vertical or horizontal axis.
- * @constructor
- */
-Ext.chart.Axis = function(config){
-    Ext.apply(this, config);
-};
-
-Ext.chart.Axis.prototype =
-{
-    <div id="prop-Ext.chart.Axis-type"></div>/**
-     * The type of axis.
-     *
-     * @property type
-     * @type String
-     */
-    type: null,
-
-    <div id="prop-Ext.chart.Axis-orientation"></div>/**
-     * The direction in which the axis is drawn. May be "horizontal" or "vertical".
-     *
-     * @property orientation
-     * @type String
-     */
-    orientation: "horizontal",
-
-    <div id="prop-Ext.chart.Axis-reverse"></div>/**
-     * If true, the items on the axis will be drawn in opposite direction.
-     *
-     * @property reverse
-     * @type Boolean
-     */
-    reverse: false,
-
-    <div id="prop-Ext.chart.Axis-labelFunction"></div>/**
-     * A string reference to the globally-accessible function that may be called to
-     * determine each of the label values for this axis.
-     *
-     * @property labelFunction
-     * @type String
-     */
-    labelFunction: null,
-
-    <div id="prop-Ext.chart.Axis-hideOverlappingLabels"></div>/**
-     * If true, labels that overlap previously drawn labels on the axis will be hidden.
-     *
-     * @property hideOverlappingLabels
-     * @type Boolean
-     */
-    hideOverlappingLabels: true,
-
-    <div id="prop-Ext.chart.Axis-labelSpacing"></div>/**
-     * The space, in pixels, between labels on an axis.
-     *
-     * @property labelSpacing
-     * @type Number
-     */
-    labelSpacing: 2
-};
-
-<div id="cls-Ext.chart.NumericAxis"></div>/**
- * @class Ext.chart.NumericAxis
- * @extends Ext.chart.Axis
- * A type of axis whose units are measured in numeric values.
- * @constructor
- */
-Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
-    type: "numeric",
-
-    <div id="prop-Ext.chart.NumericAxis-minimum"></div>/**
-     * The minimum value drawn by the axis. If not set explicitly, the axis
-     * minimum will be calculated automatically.
-     *
-     * @property minimum
-     * @type Number
-     */
-    minimum: NaN,
-
-    <div id="prop-Ext.chart.NumericAxis-maximum"></div>/**
-     * The maximum value drawn by the axis. If not set explicitly, the axis
-     * maximum will be calculated automatically.
-     *
-     * @property maximum
-     * @type Number
-     */
-    maximum: NaN,
-
-    <div id="prop-Ext.chart.NumericAxis-majorUnit"></div>/**
-     * The spacing between major intervals on this axis.
-     *
-     * @property majorUnit
-     * @type Number
-     */
-    majorUnit: NaN,
-
-    <div id="prop-Ext.chart.NumericAxis-minorUnit"></div>/**
-     * The spacing between minor intervals on this axis.
-     *
-     * @property minorUnit
-     * @type Number
-     */
-    minorUnit: NaN,
-
-    <div id="prop-Ext.chart.NumericAxis-snapToUnits"></div>/**
-     * If true, the labels, ticks, gridlines, and other objects will snap to the
-     * nearest major or minor unit. If false, their position will be based on
-     * the minimum value.
-     *
-     * @property snapToUnits
-     * @type Boolean
-     */
-    snapToUnits: true,
-
-    <div id="prop-Ext.chart.NumericAxis-alwaysShowZero"></div>/**
-     * If true, and the bounds are calculated automatically, either the minimum
-     * or maximum will be set to zero.
-     *
-     * @property alwaysShowZero
-     * @type Boolean
-     */
-    alwaysShowZero: true,
-
-    <div id="prop-Ext.chart.NumericAxis-scale"></div>/**
-     * The scaling algorithm to use on this axis. May be "linear" or
-     * "logarithmic".
-     *
-     * @property scale
-     * @type String
-     */
-    scale: "linear",
-
-    <div id="prop-Ext.chart.NumericAxis-roundMajorUnit"></div>/**
-     * Indicates whether to round the major unit.
-     *
-     * @property roundMajorUnit
-     * @type Boolean
-     */
-    roundMajorUnit: true,
-
-    <div id="prop-Ext.chart.NumericAxis-calculateByLabelSize"></div>/**
-     * Indicates whether to factor in the size of the labels when calculating a
-     * major unit.
-     *
-     * @property calculateByLabelSize
-     * @type Boolean
-     */
-    calculateByLabelSize: true,
-
-    <div id="prop-Ext.chart.NumericAxis-position"></div>/**
-     * Indicates the position of the axis relative to the chart
-     *
-     * @property position
-     * @type String
-     */
-    position: 'left',
-
-    <div id="prop-Ext.chart.NumericAxis-adjustMaximumByMajorUnit"></div>/**
-     * Indicates whether to extend maximum beyond data's maximum to the nearest
-     * majorUnit.
-     *
-     * @property adjustMaximumByMajorUnit
-     * @type Boolean
-     */
-    adjustMaximumByMajorUnit: true,
-
-    <div id="prop-Ext.chart.NumericAxis-adjustMinimumByMajorUnit"></div>/**
-     * Indicates whether to extend the minimum beyond data's minimum to the
-     * nearest majorUnit.
-     *
-     * @property adjustMinimumByMajorUnit
-     * @type Boolean
-     */
-    adjustMinimumByMajorUnit: true
-
-});
-
-<div id="cls-Ext.chart.TimeAxis"></div>/**
- * @class Ext.chart.TimeAxis
- * @extends Ext.chart.Axis
- * A type of axis whose units are measured in time-based values.
- * @constructor
- */
-Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
-    type: "time",
-
-    <div id="prop-Ext.chart.TimeAxis-minimum"></div>/**
-     * The minimum value drawn by the axis. If not set explicitly, the axis
-     * minimum will be calculated automatically.
-     *
-     * @property minimum
-     * @type Date
-     */
-    minimum: null,
-
-    <div id="prop-Ext.chart.TimeAxis-maximum"></div>/**
-     * The maximum value drawn by the axis. If not set explicitly, the axis
-     * maximum will be calculated automatically.
-     *
-     * @property maximum
-     * @type Number
-     */
-    maximum: null,
-
-    <div id="prop-Ext.chart.TimeAxis-majorUnit"></div>/**
-     * The spacing between major intervals on this axis.
-     *
-     * @property majorUnit
-     * @type Number
-     */
-    majorUnit: NaN,
-
-    <div id="prop-Ext.chart.TimeAxis-majorTimeUnit"></div>/**
-     * The time unit used by the majorUnit.
-     *
-     * @property majorTimeUnit
-     * @type String
-     */
-    majorTimeUnit: null,
-
-    <div id="prop-Ext.chart.TimeAxis-majorUnit"></div>/**
-     * The spacing between minor intervals on this axis.
-     *
-     * @property majorUnit
-     * @type Number
-     */
-    minorUnit: NaN,
-
-    <div id="prop-Ext.chart.TimeAxis-majorTimeUnit"></div>/**
-     * The time unit used by the minorUnit.
-     *
-     * @property majorTimeUnit
-     * @type String
-     */
-    minorTimeUnit: null,
-
-    <div id="prop-Ext.chart.TimeAxis-snapToUnits"></div>/**
-     * If true, the labels, ticks, gridlines, and other objects will snap to the
-     * nearest major or minor unit. If false, their position will be based on
-     * the minimum value.
-     *
-     * @property snapToUnits
-     * @type Boolean
-     */
-    snapToUnits: true,
-
-    <div id="prop-Ext.chart.TimeAxis-stackingEnabled"></div>/**
-     * Series that are stackable will only stack when this value is set to true.
-     *
-     * @property stackingEnabled
-     * @type Boolean
-     */
-    stackingEnabled: false,
-
-    <div id="prop-Ext.chart.TimeAxis-calculateByLabelSize"></div>/**
-     * Indicates whether to factor in the size of the labels when calculating a
-     * major unit.
-     *
-     * @property calculateByLabelSize
-     * @type Boolean
-     */
-    calculateByLabelSize: true
-
-});
-
-<div id="cls-Ext.chart.CategoryAxis"></div>/**
- * @class Ext.chart.CategoryAxis
- * @extends Ext.chart.Axis
- * A type of axis that displays items in categories.
- * @constructor
- */
-Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
-    type: "category",
-
-    <div id="prop-Ext.chart.CategoryAxis-categoryNames"></div>/**
-     * A list of category names to display along this axis.
-     *
-     * @property categoryNames
-     * @type Array
-     */
-    categoryNames: null,
-
-    <div id="prop-Ext.chart.CategoryAxis-calculateCategoryCount"></div>/**
-     * Indicates whether or not to calculate the number of categories (ticks and
-     * labels) when there is not enough room to display all labels on the axis.
-     * If set to true, the axis will determine the number of categories to plot.
-     * If not, all categories will be plotted.
-     *
-     * @property calculateCategoryCount
-     * @type Boolean
-     */
-    calculateCategoryCount: false
-
-});
-
-<div id="cls-Ext.chart.Series"></div>/**
- * @class Ext.chart.Series
- * Series class for the charts widget.
- * @constructor
- */
-Ext.chart.Series = function(config) { Ext.apply(this, config); };
-
-Ext.chart.Series.prototype =
-{
-    <div id="prop-Ext.chart.Series-type"></div>/**
-     * The type of series.
-     *
-     * @property type
-     * @type String
-     */
-    type: null,
-
-    <div id="prop-Ext.chart.Series-displayName"></div>/**
-     * The human-readable name of the series.
-     *
-     * @property displayName
-     * @type String
-     */
-    displayName: null
-};
-
-<div id="cls-Ext.chart.CartesianSeries"></div>/**
- * @class Ext.chart.CartesianSeries
- * @extends Ext.chart.Series
- * CartesianSeries class for the charts widget.
- * @constructor
- */
-Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
-    <div id="prop-Ext.chart.CartesianSeries-xField"></div>/**
-     * The field used to access the x-axis value from the items from the data
-     * source.
-     *
-     * @property xField
-     * @type String
-     */
-    xField: null,
-
-    <div id="prop-Ext.chart.CartesianSeries-yField"></div>/**
-     * The field used to access the y-axis value from the items from the data
-     * source.
-     *
-     * @property yField
-     * @type String
-     */
-    yField: null,
-
-    <div id="prop-Ext.chart.CartesianSeries-showInLegend"></div>/**
-     * False to not show this series in the legend. Defaults to <tt>true</tt>.
-     *
-     * @property showInLegend
-     * @type Boolean
-     */
-    showInLegend: true,
-
-    <div id="prop-Ext.chart.CartesianSeries-axis"></div>/**
-     * Indicates which axis the series will bind to
-     *
-     * @property axis
-     * @type String
-     */
-    axis: 'primary'
-});
+    // @private
+    getMaxGutter: function() {
+        var me = this,
+            maxGutter = [0, 0];
+        me.series.each(function(s) {
+            var gutter = s.getGutters &amp;&amp; s.getGutters() || [0, 0];
+            maxGutter[0] = Math.max(maxGutter[0], gutter[0]);
+            maxGutter[1] = Math.max(maxGutter[1], gutter[1]);
+        });
+        me.maxGutter = maxGutter;
+    },
 
-<div id="cls-Ext.chart.ColumnSeries"></div>/**
- * @class Ext.chart.ColumnSeries
- * @extends Ext.chart.CartesianSeries
- * ColumnSeries class for the charts widget.
- * @constructor
- */
-Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
-    type: "column"
-});
+    // @private draw axis.
+    drawAxis: function(axis) {
+        axis.drawAxis();
+    },
 
-<div id="cls-Ext.chart.LineSeries"></div>/**
- * @class Ext.chart.LineSeries
- * @extends Ext.chart.CartesianSeries
- * LineSeries class for the charts widget.
- * @constructor
- */
-Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
-    type: "line"
-});
+    // @private draw series.
+    drawCharts: function(series) {
+        series.triggerafterrender = false;
+        series.drawSeries();
+        if (!this.animate) {
+            series.fireEvent('afterrender');
+        }
+    },
 
-<div id="cls-Ext.chart.BarSeries"></div>/**
- * @class Ext.chart.BarSeries
- * @extends Ext.chart.CartesianSeries
- * BarSeries class for the charts widget.
- * @constructor
- */
-Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
-    type: "bar"
+    // @private remove gently.
+    destroy: function() {
+        this.surface.destroy();
+        this.bindStore(null);
+        this.callParent(arguments);
+    }
 });
-
-
-<div id="cls-Ext.chart.PieSeries"></div>/**
- * @class Ext.chart.PieSeries
- * @extends Ext.chart.Series
- * PieSeries class for the charts widget.
- * @constructor
- */
-Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
-    type: "pie",
-    dataField: null,
-    categoryField: null
-});</pre>    
+</pre>
 </body>
-</html>
\ No newline at end of file
+</html>