3 * Copyright(c) 2006-2009 Ext JS, LLC
5 * http://www.extjs.com/license
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
16 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
\r
20 * @cfg {Object} chartStyle
\r
21 * Sets styles for this chart. Contains a number of default values. Modifying this property will override
\r
22 * the base styles on the chart.
\r
26 animationEnabled: true,
\r
53 * The url to load the chart from. This defaults to Ext.chart.Chart.CHART_URL, which should
\r
54 * be modified to point to the local charts resource.
\r
58 * @cfg {Object} extraStyle
\r
59 * Contains extra styles that will be added or overwritten to the default chartStyle. Defaults to <tt>null</tt>.
\r
64 * @cfg {Boolean} disableCaching
\r
65 * True to add a "cache buster" to the end of the chart url. Defaults to true for Opera and IE.
\r
67 disableCaching: Ext.isIE || Ext.isOpera,
\r
68 disableCacheParam: '_dc',
\r
70 initComponent : function(){
\r
71 Ext.chart.Chart.superclass.initComponent.call(this);
\r
73 this.url = Ext.chart.Chart.CHART_URL;
\r
75 if(this.disableCaching){
\r
76 this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
\r
87 this.store = Ext.StoreMgr.lookup(this.store);
\r
91 * Sets a single style value on the Chart instance.
\r
93 * @param name {String} Name of the Chart style value to change.
\r
94 * @param value {Object} New value to pass to the Chart style.
\r
96 setStyle: function(name, value){
\r
97 this.swf.setStyle(name, Ext.encode(value));
\r
101 * Resets all styles on the Chart instance.
\r
103 * @param styles {Object} Initializer for all Chart styles.
\r
105 setStyles: function(styles){
\r
106 this.swf.setStyles(Ext.encode(styles));
\r
110 * Sets the styles on all series in the Chart.
\r
112 * @param styles {Array} Initializer for all Chart series styles.
\r
114 setSeriesStyles: function(styles){
\r
116 Ext.each(styles, function(style){
\r
117 s.push(Ext.encode(style));
\r
119 this.swf.setSeriesStyles(s);
\r
122 setCategoryNames : function(names){
\r
123 this.swf.setCategoryNames(names);
\r
126 setTipRenderer : function(fn){
\r
128 this.tipFnName = this.createFnProxy(function(item, index, series){
\r
129 var record = chart.store.getAt(index);
\r
130 return fn(chart, record, index, series);
\r
131 }, this.tipFnName);
\r
132 this.swf.setDataTipFunction(this.tipFnName);
\r
135 setSeries : function(series){
\r
136 this.series = series;
\r
141 * Changes the data store bound to this chart and refreshes it.
\r
142 * @param {Store} store The store to bind to this chart
\r
144 bindStore : function(store, initial){
\r
145 if(!initial && this.store){
\r
146 if(store !== this.store && this.store.autoDestroy){
\r
147 this.store.destroy();
\r
149 this.store.un("datachanged", this.refresh, this);
\r
150 this.store.un("add", this.delayRefresh, this);
\r
151 this.store.un("remove", this.delayRefresh, this);
\r
152 this.store.un("update", this.delayRefresh, this);
\r
153 this.store.un("clear", this.refresh, this);
\r
157 store = Ext.StoreMgr.lookup(store);
\r
160 datachanged: this.refresh,
\r
161 add: this.delayRefresh,
\r
162 remove: this.delayRefresh,
\r
163 update: this.delayRefresh,
\r
164 clear: this.refresh
\r
167 this.store = store;
\r
168 if(store && !initial){
\r
173 onSwfReady : function(isReset){
\r
174 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
\r
175 this.swf.setType(this.type);
\r
177 if(this.chartStyle){
\r
178 this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
\r
181 if(this.categoryNames){
\r
182 this.setCategoryNames(this.categoryNames);
\r
185 if(this.tipRenderer){
\r
186 this.setTipRenderer(this.tipRenderer);
\r
189 this.bindStore(this.store, true);
\r
191 this.refresh.defer(10, this);
\r
194 delayRefresh : function(){
\r
195 if(!this.refreshTask){
\r
196 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
\r
198 this.refreshTask.delay(this.refreshBuffer);
\r
201 refresh : function(){
\r
202 var styleChanged = false;
\r
203 // convert the store data into something YUI charts can understand
\r
204 var data = [], rs = this.store.data.items;
\r
205 for(var j = 0, len = rs.length; j < len; j++){
\r
206 data[j] = rs[j].data;
\r
208 //make a copy of the series definitions so that we aren't
\r
209 //editing them directly.
\r
210 var dataProvider = [];
\r
211 var seriesCount = 0;
\r
212 var currentSeries = null;
\r
215 seriesCount = this.series.length;
\r
216 for(i = 0; i < seriesCount; i++){
\r
217 currentSeries = this.series[i];
\r
218 var clonedSeries = {};
\r
219 for(var prop in currentSeries){
\r
220 if(prop == "style" && currentSeries.style !== null){
\r
221 clonedSeries.style = Ext.encode(currentSeries.style);
\r
222 styleChanged = true;
\r
223 //we don't want to modify the styles again next time
\r
224 //so null out the style property.
\r
225 // this causes issues
\r
226 // currentSeries.style = null;
\r
228 clonedSeries[prop] = currentSeries[prop];
\r
231 dataProvider.push(clonedSeries);
\r
235 if(seriesCount > 0){
\r
236 for(i = 0; i < seriesCount; i++){
\r
237 currentSeries = dataProvider[i];
\r
238 if(!currentSeries.type){
\r
239 currentSeries.type = this.type;
\r
241 currentSeries.dataProvider = data;
\r
244 dataProvider.push({type: this.type, dataProvider: data});
\r
246 this.swf.setDataProvider(dataProvider);
\r
249 createFnProxy : function(fn, old){
\r
251 delete window[old];
\r
253 var fnName = "extFnProxy" + (++Ext.chart.Chart.PROXY_FN_ID);
\r
254 window[fnName] = fn;
\r
258 onDestroy: function(){
\r
259 Ext.chart.Chart.superclass.onDestroy.call(this);
\r
260 this.bindStore(null);
\r
261 var tip = this.tipFnName;
\r
262 if(!Ext.isEmpty(tip)){
\r
263 delete window[tip];
\r
267 Ext.reg('chart', Ext.chart.Chart);
\r
268 Ext.chart.Chart.PROXY_FN_ID = 0;
\r
271 * Sets the url to load the chart from. This should be set to a local resource.
\r
275 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.7.0/build/charts/assets/charts.swf';
\r
278 * @class Ext.chart.PieChart
\r
279 * @extends Ext.chart.Chart
\r
283 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
\r
286 onSwfReady : function(isReset){
\r
287 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
\r
289 this.setDataField(this.dataField);
\r
290 this.setCategoryField(this.categoryField);
\r
293 setDataField : function(field){
\r
294 this.dataField = field;
\r
295 this.swf.setDataField(field);
\r
298 setCategoryField : function(field){
\r
299 this.categoryField = field;
\r
300 this.swf.setCategoryField(field);
\r
303 Ext.reg('piechart', Ext.chart.PieChart);
\r
306 * @class Ext.chart.CartesianChart
\r
307 * @extends Ext.chart.Chart
\r
309 * @xtype cartesianchart
\r
311 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
\r
312 onSwfReady : function(isReset){
\r
313 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
\r
316 this.setXField(this.xField);
\r
319 this.setYField(this.yField);
\r
322 this.setXAxis(this.xAxis);
\r
325 this.setYAxis(this.yAxis);
\r
329 setXField : function(value){
\r
330 this.xField = value;
\r
331 this.swf.setHorizontalField(value);
\r
334 setYField : function(value){
\r
335 this.yField = value;
\r
336 this.swf.setVerticalField(value);
\r
339 setXAxis : function(value){
\r
340 this.xAxis = this.createAxis('xAxis', value);
\r
341 this.swf.setHorizontalAxis(this.xAxis);
\r
344 setYAxis : function(value){
\r
345 this.yAxis = this.createAxis('yAxis', value);
\r
346 this.swf.setVerticalAxis(this.yAxis);
\r
349 createAxis : function(axis, value){
\r
350 var o = Ext.apply({}, value), oldFn = null;
\r
352 oldFn = this[axis].labelFunction;
\r
354 if(o.labelRenderer){
\r
355 var fn = o.labelRenderer;
\r
356 o.labelFunction = this.createFnProxy(function(v){
\r
359 delete o.labelRenderer;
\r
364 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
\r
367 * @class Ext.chart.LineChart
\r
368 * @extends Ext.chart.CartesianChart
\r
372 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
\r
375 Ext.reg('linechart', Ext.chart.LineChart);
\r
378 * @class Ext.chart.ColumnChart
\r
379 * @extends Ext.chart.CartesianChart
\r
381 * @xtype columnchart
\r
383 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
\r
386 Ext.reg('columnchart', Ext.chart.ColumnChart);
\r
389 * @class Ext.chart.StackedColumnChart
\r
390 * @extends Ext.chart.CartesianChart
\r
392 * @xtype stackedcolumnchart
\r
394 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
\r
395 type: 'stackcolumn'
\r
397 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
\r
400 * @class Ext.chart.BarChart
\r
401 * @extends Ext.chart.CartesianChart
\r
405 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
\r
408 Ext.reg('barchart', Ext.chart.BarChart);
\r
411 * @class Ext.chart.StackedBarChart
\r
412 * @extends Ext.chart.CartesianChart
\r
414 * @xtype stackedbarchart
\r
416 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
\r
419 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
\r
424 * @class Ext.chart.Axis
\r
425 * Defines a CartesianChart's vertical or horizontal axis.
\r
428 Ext.chart.Axis = function(config){
\r
429 Ext.apply(this, config);
\r
432 Ext.chart.Axis.prototype =
\r
435 * The type of axis.
\r
443 * The direction in which the axis is drawn. May be "horizontal" or "vertical".
\r
445 * @property orientation
\r
448 orientation: "horizontal",
\r
451 * If true, the items on the axis will be drawn in opposite direction.
\r
453 * @property reverse
\r
459 * A string reference to the globally-accessible function that may be called to
\r
460 * determine each of the label values for this axis.
\r
462 * @property labelFunction
\r
465 labelFunction: null,
\r
468 * If true, labels that overlap previously drawn labels on the axis will be hidden.
\r
470 * @property hideOverlappingLabels
\r
473 hideOverlappingLabels: true
\r
477 * @class Ext.chart.NumericAxis
\r
478 * @extends Ext.chart.Axis
\r
479 * A type of axis whose units are measured in numeric values.
\r
482 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
\r
486 * The minimum value drawn by the axis. If not set explicitly, the axis minimum
\r
487 * will be calculated automatically.
\r
489 * @property minimum
\r
495 * The maximum value drawn by the axis. If not set explicitly, the axis maximum
\r
496 * will be calculated automatically.
\r
498 * @property maximum
\r
504 * The spacing between major intervals on this axis.
\r
506 * @property majorUnit
\r
512 * The spacing between minor intervals on this axis.
\r
514 * @property minorUnit
\r
520 * If true, the labels, ticks, gridlines, and other objects will snap to
\r
521 * the nearest major or minor unit. If false, their position will be based
\r
522 * on the minimum value.
\r
524 * @property snapToUnits
\r
530 * If true, and the bounds are calculated automatically, either the minimum or
\r
531 * maximum will be set to zero.
\r
533 * @property alwaysShowZero
\r
536 alwaysShowZero: true,
\r
539 * The scaling algorithm to use on this axis. May be "linear" or "logarithmic".
\r
548 * @class Ext.chart.TimeAxis
\r
549 * @extends Ext.chart.Axis
\r
550 * A type of axis whose units are measured in time-based values.
\r
553 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
\r
557 * The minimum value drawn by the axis. If not set explicitly, the axis minimum
\r
558 * will be calculated automatically.
\r
560 * @property minimum
\r
566 * The maximum value drawn by the axis. If not set explicitly, the axis maximum
\r
567 * will be calculated automatically.
\r
569 * @property maximum
\r
575 * The spacing between major intervals on this axis.
\r
577 * @property majorUnit
\r
583 * The time unit used by the majorUnit.
\r
585 * @property majorTimeUnit
\r
588 majorTimeUnit: null,
\r
591 * The spacing between minor intervals on this axis.
\r
593 * @property majorUnit
\r
599 * The time unit used by the minorUnit.
\r
601 * @property majorTimeUnit
\r
604 minorTimeUnit: null,
\r
607 * If true, the labels, ticks, gridlines, and other objects will snap to
\r
608 * the nearest major or minor unit. If false, their position will be based
\r
609 * on the minimum value.
\r
611 * @property snapToUnits
\r
618 * @class Ext.chart.CategoryAxis
\r
619 * @extends Ext.chart.Axis
\r
620 * A type of axis that displays items in categories.
\r
623 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
\r
627 * A list of category names to display along this axis.
\r
629 * @property categoryNames
\r
632 categoryNames: null
\r
636 * @class Ext.chart.Series
\r
637 * Series class for the charts widget.
\r
640 Ext.chart.Series = function(config) { Ext.apply(this, config); };
\r
642 Ext.chart.Series.prototype =
\r
645 * The type of series.
\r
653 * The human-readable name of the series.
\r
655 * @property displayName
\r
662 * @class Ext.chart.CartesianSeries
\r
663 * @extends Ext.chart.Series
\r
664 * CartesianSeries class for the charts widget.
\r
667 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
\r
669 * The field used to access the x-axis value from the items from the data source.
\r
677 * The field used to access the y-axis value from the items from the data source.
\r
686 * @class Ext.chart.ColumnSeries
\r
687 * @extends Ext.chart.CartesianSeries
\r
688 * ColumnSeries class for the charts widget.
\r
691 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
696 * @class Ext.chart.LineSeries
\r
697 * @extends Ext.chart.CartesianSeries
\r
698 * LineSeries class for the charts widget.
\r
701 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
706 * @class Ext.chart.BarSeries
\r
707 * @extends Ext.chart.CartesianSeries
\r
708 * BarSeries class for the charts widget.
\r
711 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
717 * @class Ext.chart.PieSeries
\r
718 * @extends Ext.chart.Series
\r
719 * PieSeries class for the charts widget.
\r
722 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
\r
725 categoryField: null
\r