Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Chart.html
index ec59f43..6846ddb 100644 (file)
-<html>\r
-<head>\r
-  <title>The source code</title>\r
-    <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
-    <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
-</head>\r
-<body  onload="prettyPrint();">\r
-    <pre class="prettyprint lang-js"><div id="cls-Ext.chart.Chart"></div>/**\r
- * @class Ext.chart.Chart\r
- * @extends Ext.FlashComponent\r
- * The Ext.chart package provides the capability to visualize data with flash based charting.\r
- * Each chart binds directly to an Ext.data.Store enabling automatic updates of the chart.\r
- * @constructor\r
- * @xtype chart\r
- */\r
\r
- Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {\r
-    refreshBuffer: 100,\r
-\r
-    <div id="cfg-Ext.chart.Chart-chartStyle"></div>/**\r
-     * @cfg {Object} chartStyle\r
-     * Sets styles for this chart. Contains a number of default values. Modifying this property will override\r
-     * the base styles on the chart.\r
-     */\r
-    chartStyle: {\r
-        padding: 10,\r
-        animationEnabled: true,\r
-        font: {\r
-            name: 'Tahoma',\r
-            color: 0x444444,\r
-            size: 11\r
-        },\r
-        dataTip: {\r
-            padding: 5,\r
-            border: {\r
-                color: 0x99bbe8,\r
-                size:1\r
-            },\r
-            background: {\r
-                color: 0xDAE7F6,\r
-                alpha: .9\r
-            },\r
-            font: {\r
-                name: 'Tahoma',\r
-                color: 0x15428B,\r
-                size: 10,\r
-                bold: true\r
-            }\r
-        }\r
-    },\r
-    \r
-    <div id="cfg-Ext.chart.Chart-url"></div>/**\r
-     * @cfg {String} url\r
-     * The url to load the chart from. This defaults to Ext.chart.Chart.CHART_URL, which should\r
-     * be modified to point to the local charts resource.\r
-     */\r
-    \r
-    <div id="cfg-Ext.chart.Chart-extraStyle"></div>/**\r
-     * @cfg {Object} extraStyle\r
-     * Contains extra styles that will be added or overwritten to the default chartStyle. Defaults to <tt>null</tt>.\r
-     */\r
-    extraStyle: null,\r
-    \r
-    <div id="cfg-Ext.chart.Chart-disableCaching"></div>/**\r
-     * @cfg {Boolean} disableCaching\r
-     * True to add a "cache buster" to the end of the chart url. Defaults to true for Opera and IE.\r
-     */\r
-    disableCaching: Ext.isIE || Ext.isOpera,\r
-    disableCacheParam: '_dc',\r
-\r
-    initComponent : function(){\r
-        Ext.chart.Chart.superclass.initComponent.call(this);\r
-        if(!this.url){\r
-            this.url = Ext.chart.Chart.CHART_URL;\r
-        }\r
-        if(this.disableCaching){\r
-            this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));\r
-        }\r
-        this.addEvents(\r
-            'itemmouseover',\r
-            'itemmouseout',\r
-            'itemclick',\r
-            'itemdoubleclick',\r
-            'itemdragstart',\r
-            'itemdrag',\r
-            'itemdragend'\r
-        );\r
-        this.store = Ext.StoreMgr.lookup(this.store);\r
-    },\r
-\r
-    <div id="method-Ext.chart.Chart-setStyle"></div>/**\r
-     * Sets a single style value on the Chart instance.\r
-     *\r
-     * @param name {String} Name of the Chart style value to change.\r
-     * @param value {Object} New value to pass to the Chart style.\r
-     */\r
-     setStyle: function(name, value){\r
-         this.swf.setStyle(name, Ext.encode(value));\r
-     },\r
-\r
-    <div id="method-Ext.chart.Chart-setStyles"></div>/**\r
-     * Resets all styles on the Chart instance.\r
-     *\r
-     * @param styles {Object} Initializer for all Chart styles.\r
-     */\r
-    setStyles: function(styles){\r
-        this.swf.setStyles(Ext.encode(styles));\r
-    },\r
-\r
-    <div id="method-Ext.chart.Chart-setSeriesStyles"></div>/**\r
-     * Sets the styles on all series in the Chart.\r
-     *\r
-     * @param styles {Array} Initializer for all Chart series styles.\r
-     */\r
-    setSeriesStyles: function(styles){\r
-        var s = [];\r
-        Ext.each(styles, function(style){\r
-            s.push(Ext.encode(style));\r
-        });\r
-        this.swf.setSeriesStyles(s);\r
-    },\r
-\r
-    setCategoryNames : function(names){\r
-        this.swf.setCategoryNames(names);\r
-    },\r
-\r
-    setTipRenderer : function(fn){\r
-        var chart = this;\r
-        this.tipFnName = this.createFnProxy(function(item, index, series){\r
-            var record = chart.store.getAt(index);\r
-            return fn(chart, record, index, series);\r
-        }, this.tipFnName);\r
-        this.swf.setDataTipFunction(this.tipFnName);\r
-    },\r
-\r
-    setSeries : function(series){\r
-        this.series = series;\r
-        this.refresh();\r
-    },\r
-\r
-    <div id="method-Ext.chart.Chart-bindStore"></div>/**\r
-     * Changes the data store bound to this chart and refreshes it.\r
-     * @param {Store} store The store to bind to this chart\r
-     */\r
-    bindStore : function(store, initial){\r
-        if(!initial && this.store){\r
-            this.store.un("datachanged", this.refresh, this);\r
-            this.store.un("add", this.delayRefresh, this);\r
-            this.store.un("remove", this.delayRefresh, this);\r
-            this.store.un("update", this.delayRefresh, this);\r
-            this.store.un("clear", this.refresh, this);\r
-            if(store !== this.store && this.store.autoDestroy){\r
-                this.store.destroy();\r
-            }\r
-        }\r
-        if(store){\r
-            store = Ext.StoreMgr.lookup(store);\r
-            store.on({\r
-                scope: this,\r
-                datachanged: this.refresh,\r
-                add: this.delayRefresh,\r
-                remove: this.delayRefresh,\r
-                update: this.delayRefresh,\r
-                clear: this.refresh\r
-            });\r
-        }\r
-        this.store = store;\r
-        if(store && !initial){\r
-            this.refresh();\r
-        }\r
-    },\r
-\r
-    onSwfReady : function(isReset){\r
-        Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);\r
-        this.swf.setType(this.type);\r
-\r
-        if(this.chartStyle){\r
-            this.setStyles(Ext.apply(this.extraStyle || {}, this.chartStyle));\r
-        }\r
-\r
-        if(this.categoryNames){\r
-            this.setCategoryNames(this.categoryNames);\r
-        }\r
-\r
-        if(this.tipRenderer){\r
-            this.setTipRenderer(this.tipRenderer);\r
-        }\r
-        if(!isReset){\r
-            this.bindStore(this.store, true);\r
-        }\r
-        this.refresh.defer(10, this);\r
-    },\r
-\r
-    delayRefresh : function(){\r
-        if(!this.refreshTask){\r
-            this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);\r
-        }\r
-        this.refreshTask.delay(this.refreshBuffer);\r
-    },\r
-\r
-    refresh : function(){\r
-        var styleChanged = false;\r
-        // convert the store data into something YUI charts can understand\r
-        var data = [], rs = this.store.data.items;\r
-        for(var j = 0, len = rs.length; j < len; j++){\r
-            data[j] = rs[j].data;\r
-        }\r
-        //make a copy of the series definitions so that we aren't\r
-        //editing them directly.\r
-        var dataProvider = [];\r
-        var seriesCount = 0;\r
-        var currentSeries = null;\r
-        var i = 0;\r
-        if(this.series){\r
-            seriesCount = this.series.length;\r
-            for(i = 0; i < seriesCount; i++){\r
-                currentSeries = this.series[i];\r
-                var clonedSeries = {};\r
-                for(var prop in currentSeries){\r
-                    if(prop == "style" && currentSeries.style !== null){\r
-                        clonedSeries.style = Ext.encode(currentSeries.style);\r
-                        styleChanged = true;\r
-                        //we don't want to modify the styles again next time\r
-                        //so null out the style property.\r
-                        // this causes issues\r
-                        // currentSeries.style = null;\r
-                    } else{\r
-                        clonedSeries[prop] = currentSeries[prop];\r
-                    }\r
-                }\r
-                dataProvider.push(clonedSeries);\r
-            }\r
-        }\r
-\r
-        if(seriesCount > 0){\r
-            for(i = 0; i < seriesCount; i++){\r
-                currentSeries = dataProvider[i];\r
-                if(!currentSeries.type){\r
-                    currentSeries.type = this.type;\r
-                }\r
-                currentSeries.dataProvider = data;\r
-            }\r
-        } else{\r
-            dataProvider.push({type: this.type, dataProvider: data});\r
-        }\r
-        this.swf.setDataProvider(dataProvider);\r
-    },\r
-\r
-    createFnProxy : function(fn, old){\r
-        if(old){\r
-            delete window[old];\r
-        }\r
-        var fnName = "extFnProxy" + (++Ext.chart.Chart.PROXY_FN_ID);\r
-        window[fnName] = fn;\r
-        return fnName;\r
-    },\r
-    \r
-    onDestroy: function(){\r
-        Ext.chart.Chart.superclass.onDestroy.call(this);\r
-        delete window[this.tipFnName];\r
-    }\r
-});\r
-Ext.reg('chart', Ext.chart.Chart);\r
-Ext.chart.Chart.PROXY_FN_ID = 0;\r
-\r
-<div id="prop-Ext.chart.Chart-CHART_URL"></div>/**\r
- * Sets the url to load the chart from. This should be set to a local resource.\r
- * @static\r
- * @type String\r
- */\r
-Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.7.0/build/charts/assets/charts.swf';\r
-\r
-<div id="cls-Ext.chart.PieChart"></div>/**\r
- * @class Ext.chart.PieChart\r
- * @extends Ext.chart.Chart\r
- * @constructor\r
- * @xtype piechart\r
- */\r
-Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {\r
-    type: 'pie',\r
-\r
-    onSwfReady : function(isReset){\r
-        Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);\r
-\r
-        this.setDataField(this.dataField);\r
-        this.setCategoryField(this.categoryField);\r
-    },\r
-\r
-    setDataField : function(field){\r
-        this.dataField = field;\r
-        this.swf.setDataField(field);\r
-    },\r
-\r
-    setCategoryField : function(field){\r
-        this.categoryField = field;\r
-        this.swf.setCategoryField(field);\r
-    }\r
-});\r
-Ext.reg('piechart', Ext.chart.PieChart);\r
-\r
-<div id="cls-Ext.chart.CartesianChart"></div>/**\r
- * @class Ext.chart.CartesianChart\r
- * @extends Ext.chart.Chart\r
- * @constructor\r
- * @xtype cartesianchart\r
- */\r
-Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {\r
-    onSwfReady : function(isReset){\r
-        Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);\r
-\r
-        if(this.xField){\r
-            this.setXField(this.xField);\r
-        }\r
-        if(this.yField){\r
-            this.setYField(this.yField);\r
-        }\r
-        if(this.xAxis){\r
-            this.setXAxis(this.xAxis);\r
-        }\r
-        if(this.yAxis){\r
-            this.setYAxis(this.yAxis);\r
-        }\r
-    },\r
-\r
-    setXField : function(value){\r
-        this.xField = value;\r
-        this.swf.setHorizontalField(value);\r
-    },\r
-\r
-    setYField : function(value){\r
-        this.yField = value;\r
-        this.swf.setVerticalField(value);\r
-    },\r
-\r
-    setXAxis : function(value){\r
-        this.xAxis = this.createAxis('xAxis', value);\r
-        this.swf.setHorizontalAxis(this.xAxis);\r
-    },\r
-\r
-    setYAxis : function(value){\r
-        this.yAxis = this.createAxis('yAxis', value);\r
-        this.swf.setVerticalAxis(this.yAxis);\r
-    },\r
-\r
-    createAxis : function(axis, value){\r
-        var o = Ext.apply({}, value), oldFn = null;\r
-        if(this[axis]){\r
-            oldFn = this[axis].labelFunction;\r
-        }\r
-        if(o.labelRenderer){\r
-            var fn = o.labelRenderer;\r
-            o.labelFunction = this.createFnProxy(function(v){\r
-                return fn(v);\r
-            }, oldFn);\r
-            delete o.labelRenderer;\r
-        }\r
-        return o;\r
-    }\r
-});\r
-Ext.reg('cartesianchart', Ext.chart.CartesianChart);\r
-\r
-<div id="cls-Ext.chart.LineChart"></div>/**\r
- * @class Ext.chart.LineChart\r
- * @extends Ext.chart.CartesianChart\r
- * @constructor\r
- * @xtype linechart\r
- */\r
-Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {\r
-    type: 'line'\r
-});\r
-Ext.reg('linechart', Ext.chart.LineChart);\r
-\r
-<div id="cls-Ext.chart.ColumnChart"></div>/**\r
- * @class Ext.chart.ColumnChart\r
- * @extends Ext.chart.CartesianChart\r
- * @constructor\r
- * @xtype columnchart\r
- */\r
-Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {\r
-    type: 'column'\r
-});\r
-Ext.reg('columnchart', Ext.chart.ColumnChart);\r
-\r
-<div id="cls-Ext.chart.StackedColumnChart"></div>/**\r
- * @class Ext.chart.StackedColumnChart\r
- * @extends Ext.chart.CartesianChart\r
- * @constructor\r
- * @xtype stackedcolumnchart\r
- */\r
-Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {\r
-    type: 'stackcolumn'\r
-});\r
-Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);\r
-\r
-<div id="cls-Ext.chart.BarChart"></div>/**\r
- * @class Ext.chart.BarChart\r
- * @extends Ext.chart.CartesianChart\r
- * @constructor\r
- * @xtype barchart\r
- */\r
-Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {\r
-    type: 'bar'\r
-});\r
-Ext.reg('barchart', Ext.chart.BarChart);\r
-\r
-<div id="cls-Ext.chart.StackedBarChart"></div>/**\r
- * @class Ext.chart.StackedBarChart\r
- * @extends Ext.chart.CartesianChart\r
- * @constructor\r
- * @xtype stackedbarchart\r
- */\r
-Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {\r
-    type: 'stackbar'\r
-});\r
-Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);\r
-\r
-\r
-\r
-<div id="cls-Ext.chart.Axis"></div>/**\r
- * @class Ext.chart.Axis\r
- * Defines a CartesianChart's vertical or horizontal axis.\r
- * @constructor\r
- */\r
-Ext.chart.Axis = function(config){\r
-    Ext.apply(this, config);\r
-};\r
-\r
-Ext.chart.Axis.prototype =\r
-{\r
-    <div id="prop-Ext.chart.Axis-type"></div>/**\r
-     * The type of axis.\r
-     *\r
-     * @property type\r
-     * @type String\r
-     */\r
-    type: null,\r
-\r
-    <div id="prop-Ext.chart.Axis-orientation"></div>/**\r
-     * The direction in which the axis is drawn. May be "horizontal" or "vertical".\r
-     *\r
-     * @property orientation\r
-     * @type String\r
-     */\r
-    orientation: "horizontal",\r
-\r
-    <div id="prop-Ext.chart.Axis-reverse"></div>/**\r
-     * If true, the items on the axis will be drawn in opposite direction.\r
-     *\r
-     * @property reverse\r
-     * @type Boolean\r
-     */\r
-    reverse: false,\r
-\r
-    <div id="prop-Ext.chart.Axis-labelFunction"></div>/**\r
-     * A string reference to the globally-accessible function that may be called to\r
-     * determine each of the label values for this axis.\r
-     *\r
-     * @property labelFunction\r
-     * @type String\r
-     */\r
-    labelFunction: null,\r
-\r
-    <div id="prop-Ext.chart.Axis-hideOverlappingLabels"></div>/**\r
-     * If true, labels that overlap previously drawn labels on the axis will be hidden.\r
-     *\r
-     * @property hideOverlappingLabels\r
-     * @type Boolean\r
-     */\r
-    hideOverlappingLabels: true\r
-};\r
-\r
-<div id="cls-Ext.chart.NumericAxis"></div>/**\r
- * @class Ext.chart.NumericAxis\r
- * @extends Ext.chart.Axis\r
- * A type of axis whose units are measured in numeric values.\r
- * @constructor\r
- */\r
-Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {\r
-    type: "numeric",\r
-\r
-    <div id="prop-Ext.chart.NumericAxis-minimum"></div>/**\r
-     * The minimum value drawn by the axis. If not set explicitly, the axis minimum\r
-     * will be calculated automatically.\r
-     *\r
-     * @property minimum\r
-     * @type Number\r
-     */\r
-    minimum: NaN,\r
-\r
-    <div id="prop-Ext.chart.NumericAxis-maximum"></div>/**\r
-     * The maximum value drawn by the axis. If not set explicitly, the axis maximum\r
-     * will be calculated automatically.\r
-     *\r
-     * @property maximum\r
-     * @type Number\r
-     */\r
-    maximum: NaN,\r
-\r
-    <div id="prop-Ext.chart.NumericAxis-majorUnit"></div>/**\r
-     * The spacing between major intervals on this axis.\r
-     *\r
-     * @property majorUnit\r
-     * @type Number\r
-     */\r
-    majorUnit: NaN,\r
-\r
-    <div id="prop-Ext.chart.NumericAxis-minorUnit"></div>/**\r
-     * The spacing between minor intervals on this axis.\r
-     *\r
-     * @property minorUnit\r
-     * @type Number\r
-     */\r
-    minorUnit: NaN,\r
-\r
-    <div id="prop-Ext.chart.NumericAxis-snapToUnits"></div>/**\r
-     * If true, the labels, ticks, gridlines, and other objects will snap to\r
-     * the nearest major or minor unit. If false, their position will be based\r
-     * on the minimum value.\r
-     *\r
-     * @property snapToUnits\r
-     * @type Boolean\r
-     */\r
-    snapToUnits: true,\r
-\r
-    <div id="prop-Ext.chart.NumericAxis-alwaysShowZero"></div>/**\r
-     * If true, and the bounds are calculated automatically, either the minimum or\r
-     * maximum will be set to zero.\r
-     *\r
-     * @property alwaysShowZero\r
-     * @type Boolean\r
-     */\r
-    alwaysShowZero: true,\r
-\r
-    <div id="prop-Ext.chart.NumericAxis-scale"></div>/**\r
-     * The scaling algorithm to use on this axis. May be "linear" or "logarithmic".\r
-     *\r
-     * @property scale\r
-     * @type String\r
-     */\r
-    scale: "linear"\r
-});\r
-\r
-<div id="cls-Ext.chart.TimeAxis"></div>/**\r
- * @class Ext.chart.TimeAxis\r
- * @extends Ext.chart.Axis\r
- * A type of axis whose units are measured in time-based values.\r
- * @constructor\r
- */\r
-Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {\r
-    type: "time",\r
-\r
-    <div id="prop-Ext.chart.TimeAxis-minimum"></div>/**\r
-     * The minimum value drawn by the axis. If not set explicitly, the axis minimum\r
-     * will be calculated automatically.\r
-     *\r
-     * @property minimum\r
-     * @type Date\r
-     */\r
-    minimum: null,\r
-\r
-    <div id="prop-Ext.chart.TimeAxis-maximum"></div>/**\r
-     * The maximum value drawn by the axis. If not set explicitly, the axis maximum\r
-     * will be calculated automatically.\r
-     *\r
-     * @property maximum\r
-     * @type Number\r
-     */\r
-    maximum: null,\r
-\r
-    <div id="prop-Ext.chart.TimeAxis-majorUnit"></div>/**\r
-     * The spacing between major intervals on this axis.\r
-     *\r
-     * @property majorUnit\r
-     * @type Number\r
-     */\r
-    majorUnit: NaN,\r
-\r
-    <div id="prop-Ext.chart.TimeAxis-majorTimeUnit"></div>/**\r
-     * The time unit used by the majorUnit.\r
-     *\r
-     * @property majorTimeUnit\r
-     * @type String\r
-     */\r
-    majorTimeUnit: null,\r
-\r
-    <div id="prop-Ext.chart.TimeAxis-majorUnit"></div>/**\r
-     * The spacing between minor intervals on this axis.\r
-     *\r
-     * @property majorUnit\r
-     * @type Number\r
-     */\r
-    minorUnit: NaN,\r
-\r
-    <div id="prop-Ext.chart.TimeAxis-majorTimeUnit"></div>/**\r
-     * The time unit used by the minorUnit.\r
-     *\r
-     * @property majorTimeUnit\r
-     * @type String\r
-     */\r
-    minorTimeUnit: null,\r
-\r
-    <div id="prop-Ext.chart.TimeAxis-snapToUnits"></div>/**\r
-     * If true, the labels, ticks, gridlines, and other objects will snap to\r
-     * the nearest major or minor unit. If false, their position will be based\r
-     * on the minimum value.\r
-     *\r
-     * @property snapToUnits\r
-     * @type Boolean\r
-     */\r
-    snapToUnits: true\r
-});\r
-\r
-<div id="cls-Ext.chart.CategoryAxis"></div>/**\r
- * @class Ext.chart.CategoryAxis\r
- * @extends Ext.chart.Axis\r
- * A type of axis that displays items in categories.\r
- * @constructor\r
- */\r
-Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {\r
-    type: "category",\r
-\r
-    <div id="prop-Ext.chart.CategoryAxis-categoryNames"></div>/**\r
-     * A list of category names to display along this axis.\r
-     *\r
-     * @property categoryNames\r
-     * @type Array\r
-     */\r
-    categoryNames: null\r
-});\r
-\r
-<div id="cls-Ext.chart.Series"></div>/**\r
- * @class Ext.chart.Series\r
- * Series class for the charts widget.\r
- * @constructor\r
- */\r
-Ext.chart.Series = function(config) { Ext.apply(this, config); };\r
-\r
-Ext.chart.Series.prototype =\r
-{\r
-    <div id="prop-Ext.chart.Series-type"></div>/**\r
-     * The type of series.\r
-     *\r
-     * @property type\r
-     * @type String\r
-     */\r
-    type: null,\r
-\r
-    <div id="prop-Ext.chart.Series-displayName"></div>/**\r
-     * The human-readable name of the series.\r
-     *\r
-     * @property displayName\r
-     * @type String\r
-     */\r
-    displayName: null\r
-};\r
-\r
-<div id="cls-Ext.chart.CartesianSeries"></div>/**\r
- * @class Ext.chart.CartesianSeries\r
- * @extends Ext.chart.Series\r
- * CartesianSeries class for the charts widget.\r
- * @constructor\r
- */\r
-Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {\r
-    <div id="prop-Ext.chart.CartesianSeries-xField"></div>/**\r
-     * The field used to access the x-axis value from the items from the data source.\r
-     *\r
-     * @property xField\r
-     * @type String\r
-     */\r
-    xField: null,\r
-\r
-    <div id="prop-Ext.chart.CartesianSeries-yField"></div>/**\r
-     * The field used to access the y-axis value from the items from the data source.\r
-     *\r
-     * @property yField\r
-     * @type String\r
-     */\r
-    yField: null\r
-});\r
-\r
-<div id="cls-Ext.chart.ColumnSeries"></div>/**\r
- * @class Ext.chart.ColumnSeries\r
- * @extends Ext.chart.CartesianSeries\r
- * ColumnSeries class for the charts widget.\r
- * @constructor\r
- */\r
-Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {\r
-    type: "column"\r
-});\r
-\r
-<div id="cls-Ext.chart.LineSeries"></div>/**\r
- * @class Ext.chart.LineSeries\r
- * @extends Ext.chart.CartesianSeries\r
- * LineSeries class for the charts widget.\r
- * @constructor\r
- */\r
-Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {\r
-    type: "line"\r
-});\r
-\r
-<div id="cls-Ext.chart.BarSeries"></div>/**\r
- * @class Ext.chart.BarSeries\r
- * @extends Ext.chart.CartesianSeries\r
- * BarSeries class for the charts widget.\r
- * @constructor\r
- */\r
-Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {\r
-    type: "bar"\r
-});\r
-\r
-\r
-<div id="cls-Ext.chart.PieSeries"></div>/**\r
- * @class Ext.chart.PieSeries\r
- * @extends Ext.chart.Series\r
- * PieSeries class for the charts widget.\r
- * @constructor\r
- */\r
-Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {\r
-    type: "pie",\r
-    dataField: null,\r
-    categoryField: null\r
-});</pre>    \r
-</body>\r
-</html>
\ No newline at end of file
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>The source code</title>
+  <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(); 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.
+ * 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',
+
+    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 */
+
+    // @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'.
+     */
+
+<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.
+     */
+    animate: false,
+
+<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,
+
+<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.
+     */
+    insetPadding: 10,
+
+<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.
+     */
+    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;
+
+     */
+
+
+    constructor: function(config) {
+        var me = this,
+            defaultAnim;
+        me.initTheme(config.theme || me.theme);
+        if (me.gradients) {
+            Ext.apply(config, { gradients: me.gradients });
+        }
+        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;
+            }
+        }
+        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',
+            'itemdoubleclick',
+            'itemdragstart',
+            'itemdrag',
+            'itemdragend',
+<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',
+<span id='Ext-chart-Chart-event-refresh'>            /**
+</span>                 * @event refresh
+                 * Fires after the chart data has been refreshed.
+                 * @param {Chart} this
+                 */
+            'refresh'
+        );
+        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));
+        }
+
+        me.on({
+            mousemove: me.onMouseMove,
+            mouseleave: me.onMouseLeave,
+            mousedown: me.onMouseDown,
+            mouseup: me.onMouseUp,
+            scope: me
+        });
+    },
+
+    // @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);
+    },
+
+<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();
+        });
+        me.axes.each(function(axis) {
+            axis.drawAxis(true);
+        });
+
+        // Create legend if not already created
+        if (legend !== false) {
+            legend.create();
+        }
+
+        // Place axes properly, including influence from each other
+        me.alignAxes();
+
+        // Reposition legend based on new axis alignment
+        if (me.legend !== false) {
+            legend.updatePosition();
+        }
+
+        // Find the max gutter
+        me.getMaxGutter();
+
+        // 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 (me.tipRenderer) {
+            ref = me.getFunctionRef(me.tipRenderer);
+            me.setTipRenderer(ref.fn, ref.scope);
+        }
+        me.bindStore(me.store, true);
+        me.refresh();
+    },
+
+    // @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];
+    },
+
+    // @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);
+                    }
+                }
+            }
+        }, 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 (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);
+                    }
+                }
+            }
+        }, me);
+    },
+
+    // @private wrap the mouse up event to delegate it to the series.
+    onMouseUp: function(e) {
+        var me = this,
+            position = me.getEventXY(e),
+            item;
+
+        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 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 handle mouse leave event.
+    onMouseLeave: function(e) {
+        var me = this;
+        if (me.mask) {
+            me.mixins.mask.onMouseLeave.call(me, e);
+        }
+        me.series.each(function(series) {
+            delete series._lastItemForPoint;
+        });
+    },
+
+    // @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);
+    },
+
+    // @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);
+            }
+        }
+    },
+
+<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 (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
+            });
+        }
+        me.store = store;
+        if (store &amp;&amp; !initial) {
+            me.refresh();
+        }
+    },
+
+    // @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);
+        }
+        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 (!axis.chart) {
+            Ext.apply(config, axis);
+            axis = me.axes.replace(Ext.createByAlias('axis.' + axis.type.toLowerCase(), config));
+        }
+        else {
+            Ext.apply(axis, config);
+        }
+    },
+
+
+<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
+            };
+
+        function getAxis(edge) {
+            var i = axes.findIndex('position', edge);
+            return (i &lt; 0) ? null : axes.getAt(i);
+        }
+
+        // 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];
+                }
+            }
+
+            // 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);
+        });
+    },
+
+    // @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 (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 (series.initialize) {
+            series.initialize();
+        }
+    },
+
+    // @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;
+    },
+
+    // @private draw axis.
+    drawAxis: function(axis) {
+        axis.drawAxis();
+    },
+
+    // @private draw series.
+    drawCharts: function(series) {
+        series.triggerafterrender = false;
+        series.drawSeries();
+        if (!this.animate) {
+            series.fireEvent('afterrender');
+        }
+    },
+
+    // @private remove gently.
+    destroy: function() {
+        this.surface.destroy();
+        this.bindStore(null);
+        this.callParent(arguments);
+    }
+});
+</pre>
+</body>
+</html>