Upgrade to ExtJS 3.1.1 - Released 02/08/2010
[extjs.git] / src / widgets / chart / Chart.js
1 /*!
2  * Ext JS Library 3.1.1
3  * Copyright(c) 2006-2010 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**\r
8  * @class Ext.chart.Chart\r
9  * @extends Ext.FlashComponent\r
10  * The Ext.chart package provides the capability to visualize data with flash based charting.\r
11  * Each chart binds directly to an Ext.data.Store enabling automatic updates of the chart.\r
12  * To change the look and feel of a chart, see the {@link #chartStyle} and {@link #extraStyle} config options.\r
13  * @constructor\r
14  * @xtype chart\r
15  */\r
16  \r
17  Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {\r
18     refreshBuffer: 100,\r
19     \r
20     /**\r
21      * @cfg {String} backgroundColor\r
22      * @hide\r
23      */\r
24 \r
25     /**\r
26      * @cfg {Object} chartStyle\r
27      * Sets styles for this chart. This contains default styling, so modifying this property will <b>override</b>\r
28      * the built in styles of the chart. Use {@link #extraStyle} to add customizations to the default styling. \r
29      */\r
30     chartStyle: {\r
31         padding: 10,\r
32         animationEnabled: true,\r
33         font: {\r
34             name: 'Tahoma',\r
35             color: 0x444444,\r
36             size: 11\r
37         },\r
38         dataTip: {\r
39             padding: 5,\r
40             border: {\r
41                 color: 0x99bbe8,\r
42                 size:1\r
43             },\r
44             background: {\r
45                 color: 0xDAE7F6,\r
46                 alpha: .9\r
47             },\r
48             font: {\r
49                 name: 'Tahoma',\r
50                 color: 0x15428B,\r
51                 size: 10,\r
52                 bold: true\r
53             }\r
54         }\r
55     },\r
56     \r
57     /**\r
58      * @cfg {String} url\r
59      * The url to load the chart from. This defaults to Ext.chart.Chart.CHART_URL, which should\r
60      * be modified to point to the local charts resource.\r
61      */\r
62     \r
63     /**\r
64      * @cfg {Object} extraStyle\r
65      * Contains extra styles that will be added or overwritten to the default chartStyle. Defaults to <tt>null</tt>.\r
66      * For a detailed list of the options available, visit the YUI Charts site \r
67      * at <a href="http://developer.yahoo.com/yui/charts/#basicstyles">http://developer.yahoo.com/yui/charts/#basicstyles</a><br/>\r
68      * Some of the options availabe:<br />\r
69      * <ul style="padding:5px;padding-left:16px;list-style-type:inherit;">\r
70      * <li><b>padding</b> - The space around the edge of the chart's contents. Padding does not increase the size of the chart.</li>\r
71      * <li><b>animationEnabled</b> - A Boolean value that specifies whether marker animations are enabled or not. Enabled by default.</li>\r
72      * <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/>\r
73      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
74      *      <li><b>name</b> - font name</li>\r
75      *      <li><b>color</b> - font color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>\r
76      *      <li><b>size</b> - font size in points (numeric portion only, ie: 11)</li>\r
77      *      <li><b>bold</b> - boolean</li>\r
78      *      <li><b>italic</b> - boolean</li>\r
79      *      <li><b>underline</b> - boolean</li>\r
80      *  </ul>\r
81      * </li>\r
82      * <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/>\r
83      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
84      *      <li><b>color</b> - border color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>\r
85      *      <li><b>size</b> - border size in pixels (numeric portion only, ie: 1)</li>\r
86      *  </ul>\r
87      * </li>\r
88      * <li><b>background</b> - An object defining the background style of the chart.<br/>\r
89      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
90      *      <li><b>color</b> - border color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>\r
91      *      <li><b>image</b> - an image URL. May be relative to the current document or absolute.</li>\r
92      *  </ul>\r
93      * </li>\r
94      * <li><b>legend</b> - An object defining the legend style<br/>\r
95      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
96      *      <li><b>display</b> - location of the legend. Possible values are "none", "left", "right", "top", and "bottom".</li>\r
97      *      <li><b>spacing</b> - an image URL. May be relative to the current document or absolute.</li>\r
98      *      <li><b>padding, border, background, font</b> - same options as described above.</li>\r
99      *  </ul></li>\r
100      * <li><b>dataTip</b> - An object defining the style of the data tip (tooltip).<br/>\r
101      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
102      *      <li><b>padding, border, background, font</b> - same options as described above.</li>\r
103      *  </ul></li>\r
104      * <li><b>xAxis and yAxis</b> - An object defining the style of the style of either axis.<br/>\r
105      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
106      *      <li><b>color</b> - same option as described above.</li>\r
107      *      <li><b>size</b> - same option as described above.</li>\r
108      *      <li><b>showLabels</b> - boolean</li>\r
109      *      <li><b>labelRotation</b> - a value in degrees from -90 through 90. Default is zero.</li>\r
110      *  </ul></li>\r
111      * <li><b>majorGridLines and minorGridLines</b> - An object defining the style of the style of the grid lines.<br/>\r
112      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
113      *      <li><b>color, size</b> - same options as described above.</li>\r
114      *  </ul></li></li>\r
115      * <li><b>zeroGridLine</b> - An object defining the style of the style of the zero grid line.<br/>\r
116      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
117      *      <li><b>color, size</b> - same options as described above.</li>\r
118      *  </ul></li></li>\r
119      * <li><b>majorTicks and minorTicks</b> - An object defining the style of the style of ticks in the chart.<br/>\r
120      *  <ul style="padding:5px;padding-left:26px;list-style-type:circle;">\r
121      *      <li><b>color, size</b> - same options as described above.</li>\r
122      *      <li><b>length</b> - the length of each tick in pixels extending from the axis.</li>\r
123      *      <li><b>display</b> - how the ticks are drawn. Possible values are "none", "inside", "outside", and "cross".</li>\r
124      *  </ul></li></li>\r
125      * </ul>\r
126      */\r
127     extraStyle: null,\r
128     \r
129     /**\r
130      * @cfg {Object} seriesStyles\r
131      * Contains styles to apply to the series after a refresh. Defaults to <tt>null</tt>.\r
132      */\r
133     seriesStyles: null,\r
134     \r
135     /**\r
136      * @cfg {Boolean} disableCaching\r
137      * True to add a "cache buster" to the end of the chart url. Defaults to true for Opera and IE.\r
138      */\r
139     disableCaching: Ext.isIE || Ext.isOpera,\r
140     disableCacheParam: '_dc',\r
141 \r
142     initComponent : function(){\r
143         Ext.chart.Chart.superclass.initComponent.call(this);\r
144         if(!this.url){\r
145             this.url = Ext.chart.Chart.CHART_URL;\r
146         }\r
147         if(this.disableCaching){\r
148             this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));\r
149         }\r
150         this.addEvents(\r
151             'itemmouseover',\r
152             'itemmouseout',\r
153             'itemclick',\r
154             'itemdoubleclick',\r
155             'itemdragstart',\r
156             'itemdrag',\r
157             'itemdragend',\r
158             /**\r
159              * @event beforerefresh\r
160              * Fires before a refresh to the chart data is called.  If the beforerefresh handler returns\r
161              * <tt>false</tt> the {@link #refresh} action will be cancelled.\r
162              * @param {Chart} this\r
163              */\r
164             'beforerefresh',\r
165             /**\r
166              * @event refresh\r
167              * Fires after the chart data has been refreshed.\r
168              * @param {Chart} this\r
169              */\r
170             'refresh'\r
171         );\r
172         this.store = Ext.StoreMgr.lookup(this.store);\r
173     },\r
174 \r
175     /**\r
176      * Sets a single style value on the Chart instance.\r
177      *\r
178      * @param name {String} Name of the Chart style value to change.\r
179      * @param value {Object} New value to pass to the Chart style.\r
180      */\r
181      setStyle: function(name, value){\r
182          this.swf.setStyle(name, Ext.encode(value));\r
183      },\r
184 \r
185     /**\r
186      * Resets all styles on the Chart instance.\r
187      *\r
188      * @param styles {Object} Initializer for all Chart styles.\r
189      */\r
190     setStyles: function(styles){\r
191         this.swf.setStyles(Ext.encode(styles));\r
192     },\r
193 \r
194     /**\r
195      * Sets the styles on all series in the Chart.\r
196      *\r
197      * @param styles {Array} Initializer for all Chart series styles.\r
198      */\r
199     setSeriesStyles: function(styles){\r
200         this.seriesStyles = styles;\r
201         var s = [];\r
202         Ext.each(styles, function(style){\r
203             s.push(Ext.encode(style));\r
204         });\r
205         this.swf.setSeriesStyles(s);\r
206     },\r
207 \r
208     setCategoryNames : function(names){\r
209         this.swf.setCategoryNames(names);\r
210     },\r
211 \r
212     setTipRenderer : function(fn){\r
213         var chart = this;\r
214         this.tipFnName = this.createFnProxy(function(item, index, series){\r
215             var record = chart.store.getAt(index);\r
216             return fn(chart, record, index, series);\r
217         }, this.tipFnName);\r
218         this.swf.setDataTipFunction(this.tipFnName);\r
219     },\r
220 \r
221     setSeries : function(series){\r
222         this.series = series;\r
223         this.refresh();\r
224     },\r
225 \r
226     /**\r
227      * Changes the data store bound to this chart and refreshes it.\r
228      * @param {Store} store The store to bind to this chart\r
229      */\r
230     bindStore : function(store, initial){\r
231         if(!initial && this.store){\r
232             if(store !== this.store && this.store.autoDestroy){\r
233                 this.store.destroy();\r
234             }else{\r
235                 this.store.un("datachanged", this.refresh, this);\r
236                 this.store.un("add", this.delayRefresh, this);\r
237                 this.store.un("remove", this.delayRefresh, this);\r
238                 this.store.un("update", this.delayRefresh, this);\r
239                 this.store.un("clear", this.refresh, this);\r
240             }\r
241         }\r
242         if(store){\r
243             store = Ext.StoreMgr.lookup(store);\r
244             store.on({\r
245                 scope: this,\r
246                 datachanged: this.refresh,\r
247                 add: this.delayRefresh,\r
248                 remove: this.delayRefresh,\r
249                 update: this.delayRefresh,\r
250                 clear: this.refresh\r
251             });\r
252         }\r
253         this.store = store;\r
254         if(store && !initial){\r
255             this.refresh();\r
256         }\r
257     },\r
258 \r
259     onSwfReady : function(isReset){\r
260         Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);\r
261         this.swf.setType(this.type);\r
262 \r
263         if(this.chartStyle){\r
264             this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));\r
265         }\r
266 \r
267         if(this.categoryNames){\r
268             this.setCategoryNames(this.categoryNames);\r
269         }\r
270 \r
271         if(this.tipRenderer){\r
272             this.setTipRenderer(this.tipRenderer);\r
273         }\r
274         if(!isReset){\r
275             this.bindStore(this.store, true);\r
276         }\r
277         this.refresh.defer(10, this);\r
278     },\r
279 \r
280     delayRefresh : function(){\r
281         if(!this.refreshTask){\r
282             this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);\r
283         }\r
284         this.refreshTask.delay(this.refreshBuffer);\r
285     },\r
286 \r
287     refresh : function(){\r
288         if(this.fireEvent('beforerefresh', this) !== false){\r
289                 var styleChanged = false;\r
290                 // convert the store data into something YUI charts can understand\r
291                 var data = [], rs = this.store.data.items;\r
292                 for(var j = 0, len = rs.length; j < len; j++){\r
293                     data[j] = rs[j].data;\r
294                 }\r
295                 //make a copy of the series definitions so that we aren't\r
296                 //editing them directly.\r
297                 var dataProvider = [];\r
298                 var seriesCount = 0;\r
299                 var currentSeries = null;\r
300                 var i = 0;\r
301                 if(this.series){\r
302                     seriesCount = this.series.length;\r
303                     for(i = 0; i < seriesCount; i++){\r
304                         currentSeries = this.series[i];\r
305                         var clonedSeries = {};\r
306                         for(var prop in currentSeries){\r
307                             if(prop == "style" && currentSeries.style !== null){\r
308                                 clonedSeries.style = Ext.encode(currentSeries.style);\r
309                                 styleChanged = true;\r
310                                 //we don't want to modify the styles again next time\r
311                                 //so null out the style property.\r
312                                 // this causes issues\r
313                                 // currentSeries.style = null;\r
314                             } else{\r
315                                 clonedSeries[prop] = currentSeries[prop];\r
316                             }\r
317                         }\r
318                         dataProvider.push(clonedSeries);\r
319                     }\r
320                 }\r
321         \r
322                 if(seriesCount > 0){\r
323                     for(i = 0; i < seriesCount; i++){\r
324                         currentSeries = dataProvider[i];\r
325                         if(!currentSeries.type){\r
326                             currentSeries.type = this.type;\r
327                         }\r
328                         currentSeries.dataProvider = data;\r
329                     }\r
330                 } else{\r
331                     dataProvider.push({type: this.type, dataProvider: data});\r
332                 }\r
333                 this.swf.setDataProvider(dataProvider);\r
334                 if(this.seriesStyles){\r
335                     this.setSeriesStyles(this.seriesStyles);\r
336                 }\r
337             this.fireEvent('refresh', this);\r
338         }\r
339     },\r
340 \r
341     createFnProxy : function(fn, old){\r
342         if(old){\r
343             delete window[old];\r
344         }\r
345         var fnName = "extFnProxy" + (++Ext.chart.Chart.PROXY_FN_ID);\r
346         window[fnName] = fn;\r
347         return fnName;\r
348     },\r
349     \r
350     onDestroy: function(){\r
351         Ext.chart.Chart.superclass.onDestroy.call(this);\r
352         this.bindStore(null);\r
353         var tip = this.tipFnName;\r
354         if(!Ext.isEmpty(tip)){\r
355             delete window[tip];\r
356         }\r
357     }\r
358 });\r
359 Ext.reg('chart', Ext.chart.Chart);\r
360 Ext.chart.Chart.PROXY_FN_ID = 0;\r
361 \r
362 /**\r
363  * Sets the url to load the chart from. This should be set to a local resource.\r
364  * @static\r
365  * @type String\r
366  */\r
367 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.7.0/build/charts/assets/charts.swf';\r
368 \r
369 /**\r
370  * @class Ext.chart.PieChart\r
371  * @extends Ext.chart.Chart\r
372  * @constructor\r
373  * @xtype piechart\r
374  */\r
375 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {\r
376     type: 'pie',\r
377 \r
378     onSwfReady : function(isReset){\r
379         Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);\r
380 \r
381         this.setDataField(this.dataField);\r
382         this.setCategoryField(this.categoryField);\r
383     },\r
384 \r
385     setDataField : function(field){\r
386         this.dataField = field;\r
387         this.swf.setDataField(field);\r
388     },\r
389 \r
390     setCategoryField : function(field){\r
391         this.categoryField = field;\r
392         this.swf.setCategoryField(field);\r
393     }\r
394 });\r
395 Ext.reg('piechart', Ext.chart.PieChart);\r
396 \r
397 /**\r
398  * @class Ext.chart.CartesianChart\r
399  * @extends Ext.chart.Chart\r
400  * @constructor\r
401  * @xtype cartesianchart\r
402  */\r
403 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {\r
404     onSwfReady : function(isReset){\r
405         Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);\r
406 \r
407         if(this.xField){\r
408             this.setXField(this.xField);\r
409         }\r
410         if(this.yField){\r
411             this.setYField(this.yField);\r
412         }\r
413         if(this.xAxis){\r
414             this.setXAxis(this.xAxis);\r
415         }\r
416         if(this.yAxis){\r
417             this.setYAxis(this.yAxis);\r
418         }\r
419     },\r
420 \r
421     setXField : function(value){\r
422         this.xField = value;\r
423         this.swf.setHorizontalField(value);\r
424     },\r
425 \r
426     setYField : function(value){\r
427         this.yField = value;\r
428         this.swf.setVerticalField(value);\r
429     },\r
430 \r
431     setXAxis : function(value){\r
432         this.xAxis = this.createAxis('xAxis', value);\r
433         this.swf.setHorizontalAxis(this.xAxis);\r
434     },\r
435 \r
436     setYAxis : function(value){\r
437         this.yAxis = this.createAxis('yAxis', value);\r
438         this.swf.setVerticalAxis(this.yAxis);\r
439     },\r
440 \r
441     createAxis : function(axis, value){\r
442         var o = Ext.apply({}, value), oldFn = null;\r
443         if(this[axis]){\r
444             oldFn = this[axis].labelFunction;\r
445         }\r
446         if(o.labelRenderer){\r
447             var fn = o.labelRenderer;\r
448             o.labelFunction = this.createFnProxy(function(v){\r
449                 return fn(v);\r
450             }, oldFn);\r
451             delete o.labelRenderer;\r
452         }\r
453         return o;\r
454     }\r
455 });\r
456 Ext.reg('cartesianchart', Ext.chart.CartesianChart);\r
457 \r
458 /**\r
459  * @class Ext.chart.LineChart\r
460  * @extends Ext.chart.CartesianChart\r
461  * @constructor\r
462  * @xtype linechart\r
463  */\r
464 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {\r
465     type: 'line'\r
466 });\r
467 Ext.reg('linechart', Ext.chart.LineChart);\r
468 \r
469 /**\r
470  * @class Ext.chart.ColumnChart\r
471  * @extends Ext.chart.CartesianChart\r
472  * @constructor\r
473  * @xtype columnchart\r
474  */\r
475 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {\r
476     type: 'column'\r
477 });\r
478 Ext.reg('columnchart', Ext.chart.ColumnChart);\r
479 \r
480 /**\r
481  * @class Ext.chart.StackedColumnChart\r
482  * @extends Ext.chart.CartesianChart\r
483  * @constructor\r
484  * @xtype stackedcolumnchart\r
485  */\r
486 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {\r
487     type: 'stackcolumn'\r
488 });\r
489 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);\r
490 \r
491 /**\r
492  * @class Ext.chart.BarChart\r
493  * @extends Ext.chart.CartesianChart\r
494  * @constructor\r
495  * @xtype barchart\r
496  */\r
497 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {\r
498     type: 'bar'\r
499 });\r
500 Ext.reg('barchart', Ext.chart.BarChart);\r
501 \r
502 /**\r
503  * @class Ext.chart.StackedBarChart\r
504  * @extends Ext.chart.CartesianChart\r
505  * @constructor\r
506  * @xtype stackedbarchart\r
507  */\r
508 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {\r
509     type: 'stackbar'\r
510 });\r
511 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);\r
512 \r
513 \r
514 \r
515 /**\r
516  * @class Ext.chart.Axis\r
517  * Defines a CartesianChart's vertical or horizontal axis.\r
518  * @constructor\r
519  */\r
520 Ext.chart.Axis = function(config){\r
521     Ext.apply(this, config);\r
522 };\r
523 \r
524 Ext.chart.Axis.prototype =\r
525 {\r
526     /**\r
527      * The type of axis.\r
528      *\r
529      * @property type\r
530      * @type String\r
531      */\r
532     type: null,\r
533 \r
534     /**\r
535      * The direction in which the axis is drawn. May be "horizontal" or "vertical".\r
536      *\r
537      * @property orientation\r
538      * @type String\r
539      */\r
540     orientation: "horizontal",\r
541 \r
542     /**\r
543      * If true, the items on the axis will be drawn in opposite direction.\r
544      *\r
545      * @property reverse\r
546      * @type Boolean\r
547      */\r
548     reverse: false,\r
549 \r
550     /**\r
551      * A string reference to the globally-accessible function that may be called to\r
552      * determine each of the label values for this axis.\r
553      *\r
554      * @property labelFunction\r
555      * @type String\r
556      */\r
557     labelFunction: null,\r
558 \r
559     /**\r
560      * If true, labels that overlap previously drawn labels on the axis will be hidden.\r
561      *\r
562      * @property hideOverlappingLabels\r
563      * @type Boolean\r
564      */\r
565     hideOverlappingLabels: true\r
566 };\r
567 \r
568 /**\r
569  * @class Ext.chart.NumericAxis\r
570  * @extends Ext.chart.Axis\r
571  * A type of axis whose units are measured in numeric values.\r
572  * @constructor\r
573  */\r
574 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {\r
575     type: "numeric",\r
576 \r
577     /**\r
578      * The minimum value drawn by the axis. If not set explicitly, the axis minimum\r
579      * will be calculated automatically.\r
580      *\r
581      * @property minimum\r
582      * @type Number\r
583      */\r
584     minimum: NaN,\r
585 \r
586     /**\r
587      * The maximum value drawn by the axis. If not set explicitly, the axis maximum\r
588      * will be calculated automatically.\r
589      *\r
590      * @property maximum\r
591      * @type Number\r
592      */\r
593     maximum: NaN,\r
594 \r
595     /**\r
596      * The spacing between major intervals on this axis.\r
597      *\r
598      * @property majorUnit\r
599      * @type Number\r
600      */\r
601     majorUnit: NaN,\r
602 \r
603     /**\r
604      * The spacing between minor intervals on this axis.\r
605      *\r
606      * @property minorUnit\r
607      * @type Number\r
608      */\r
609     minorUnit: NaN,\r
610 \r
611     /**\r
612      * If true, the labels, ticks, gridlines, and other objects will snap to\r
613      * the nearest major or minor unit. If false, their position will be based\r
614      * on the minimum value.\r
615      *\r
616      * @property snapToUnits\r
617      * @type Boolean\r
618      */\r
619     snapToUnits: true,\r
620 \r
621     /**\r
622      * If true, and the bounds are calculated automatically, either the minimum or\r
623      * maximum will be set to zero.\r
624      *\r
625      * @property alwaysShowZero\r
626      * @type Boolean\r
627      */\r
628     alwaysShowZero: true,\r
629 \r
630     /**\r
631      * The scaling algorithm to use on this axis. May be "linear" or "logarithmic".\r
632      *\r
633      * @property scale\r
634      * @type String\r
635      */\r
636     scale: "linear"\r
637 });\r
638 \r
639 /**\r
640  * @class Ext.chart.TimeAxis\r
641  * @extends Ext.chart.Axis\r
642  * A type of axis whose units are measured in time-based values.\r
643  * @constructor\r
644  */\r
645 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {\r
646     type: "time",\r
647 \r
648     /**\r
649      * The minimum value drawn by the axis. If not set explicitly, the axis minimum\r
650      * will be calculated automatically.\r
651      *\r
652      * @property minimum\r
653      * @type Date\r
654      */\r
655     minimum: null,\r
656 \r
657     /**\r
658      * The maximum value drawn by the axis. If not set explicitly, the axis maximum\r
659      * will be calculated automatically.\r
660      *\r
661      * @property maximum\r
662      * @type Number\r
663      */\r
664     maximum: null,\r
665 \r
666     /**\r
667      * The spacing between major intervals on this axis.\r
668      *\r
669      * @property majorUnit\r
670      * @type Number\r
671      */\r
672     majorUnit: NaN,\r
673 \r
674     /**\r
675      * The time unit used by the majorUnit.\r
676      *\r
677      * @property majorTimeUnit\r
678      * @type String\r
679      */\r
680     majorTimeUnit: null,\r
681 \r
682     /**\r
683      * The spacing between minor intervals on this axis.\r
684      *\r
685      * @property majorUnit\r
686      * @type Number\r
687      */\r
688     minorUnit: NaN,\r
689 \r
690     /**\r
691      * The time unit used by the minorUnit.\r
692      *\r
693      * @property majorTimeUnit\r
694      * @type String\r
695      */\r
696     minorTimeUnit: null,\r
697 \r
698     /**\r
699      * If true, the labels, ticks, gridlines, and other objects will snap to\r
700      * the nearest major or minor unit. If false, their position will be based\r
701      * on the minimum value.\r
702      *\r
703      * @property snapToUnits\r
704      * @type Boolean\r
705      */\r
706     snapToUnits: true\r
707 });\r
708 \r
709 /**\r
710  * @class Ext.chart.CategoryAxis\r
711  * @extends Ext.chart.Axis\r
712  * A type of axis that displays items in categories.\r
713  * @constructor\r
714  */\r
715 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {\r
716     type: "category",\r
717 \r
718     /**\r
719      * A list of category names to display along this axis.\r
720      *\r
721      * @property categoryNames\r
722      * @type Array\r
723      */\r
724     categoryNames: null\r
725 });\r
726 \r
727 /**\r
728  * @class Ext.chart.Series\r
729  * Series class for the charts widget.\r
730  * @constructor\r
731  */\r
732 Ext.chart.Series = function(config) { Ext.apply(this, config); };\r
733 \r
734 Ext.chart.Series.prototype =\r
735 {\r
736     /**\r
737      * The type of series.\r
738      *\r
739      * @property type\r
740      * @type String\r
741      */\r
742     type: null,\r
743 \r
744     /**\r
745      * The human-readable name of the series.\r
746      *\r
747      * @property displayName\r
748      * @type String\r
749      */\r
750     displayName: null\r
751 };\r
752 \r
753 /**\r
754  * @class Ext.chart.CartesianSeries\r
755  * @extends Ext.chart.Series\r
756  * CartesianSeries class for the charts widget.\r
757  * @constructor\r
758  */\r
759 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {\r
760     /**\r
761      * The field used to access the x-axis value from the items from the data source.\r
762      *\r
763      * @property xField\r
764      * @type String\r
765      */\r
766     xField: null,\r
767 \r
768     /**\r
769      * The field used to access the y-axis value from the items from the data source.\r
770      *\r
771      * @property yField\r
772      * @type String\r
773      */\r
774     yField: null\r
775 });\r
776 \r
777 /**\r
778  * @class Ext.chart.ColumnSeries\r
779  * @extends Ext.chart.CartesianSeries\r
780  * ColumnSeries class for the charts widget.\r
781  * @constructor\r
782  */\r
783 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {\r
784     type: "column"\r
785 });\r
786 \r
787 /**\r
788  * @class Ext.chart.LineSeries\r
789  * @extends Ext.chart.CartesianSeries\r
790  * LineSeries class for the charts widget.\r
791  * @constructor\r
792  */\r
793 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {\r
794     type: "line"\r
795 });\r
796 \r
797 /**\r
798  * @class Ext.chart.BarSeries\r
799  * @extends Ext.chart.CartesianSeries\r
800  * BarSeries class for the charts widget.\r
801  * @constructor\r
802  */\r
803 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {\r
804     type: "bar"\r
805 });\r
806 \r
807 \r
808 /**\r
809  * @class Ext.chart.PieSeries\r
810  * @extends Ext.chart.Series\r
811  * PieSeries class for the charts widget.\r
812  * @constructor\r
813  */\r
814 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {\r
815     type: "pie",\r
816     dataField: null,\r
817     categoryField: null\r
818 });