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 this.store.un("datachanged", this.refresh, this);
\r
147 this.store.un("add", this.delayRefresh, this);
\r
148 this.store.un("remove", this.delayRefresh, this);
\r
149 this.store.un("update", this.delayRefresh, this);
\r
150 this.store.un("clear", this.refresh, this);
\r
151 if(store !== this.store && this.store.autoDestroy){
\r
152 this.store.destroy();
\r
156 store = Ext.StoreMgr.lookup(store);
\r
159 datachanged: this.refresh,
\r
160 add: this.delayRefresh,
\r
161 remove: this.delayRefresh,
\r
162 update: this.delayRefresh,
\r
163 clear: this.refresh
\r
166 this.store = store;
\r
167 if(store && !initial){
\r
172 onSwfReady : function(isReset){
\r
173 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
\r
174 this.swf.setType(this.type);
\r
176 if(this.chartStyle){
\r
177 this.setStyles(Ext.apply(this.extraStyle || {}, this.chartStyle));
\r
180 if(this.categoryNames){
\r
181 this.setCategoryNames(this.categoryNames);
\r
184 if(this.tipRenderer){
\r
185 this.setTipRenderer(this.tipRenderer);
\r
188 this.bindStore(this.store, true);
\r
190 this.refresh.defer(10, this);
\r
193 delayRefresh : function(){
\r
194 if(!this.refreshTask){
\r
195 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
\r
197 this.refreshTask.delay(this.refreshBuffer);
\r
200 refresh : function(){
\r
201 var styleChanged = false;
\r
202 // convert the store data into something YUI charts can understand
\r
203 var data = [], rs = this.store.data.items;
\r
204 for(var j = 0, len = rs.length; j < len; j++){
\r
205 data[j] = rs[j].data;
\r
207 //make a copy of the series definitions so that we aren't
\r
208 //editing them directly.
\r
209 var dataProvider = [];
\r
210 var seriesCount = 0;
\r
211 var currentSeries = null;
\r
214 seriesCount = this.series.length;
\r
215 for(i = 0; i < seriesCount; i++){
\r
216 currentSeries = this.series[i];
\r
217 var clonedSeries = {};
\r
218 for(var prop in currentSeries){
\r
219 if(prop == "style" && currentSeries.style !== null){
\r
220 clonedSeries.style = Ext.encode(currentSeries.style);
\r
221 styleChanged = true;
\r
222 //we don't want to modify the styles again next time
\r
223 //so null out the style property.
\r
224 // this causes issues
\r
225 // currentSeries.style = null;
\r
227 clonedSeries[prop] = currentSeries[prop];
\r
230 dataProvider.push(clonedSeries);
\r
234 if(seriesCount > 0){
\r
235 for(i = 0; i < seriesCount; i++){
\r
236 currentSeries = dataProvider[i];
\r
237 if(!currentSeries.type){
\r
238 currentSeries.type = this.type;
\r
240 currentSeries.dataProvider = data;
\r
243 dataProvider.push({type: this.type, dataProvider: data});
\r
245 this.swf.setDataProvider(dataProvider);
\r
248 createFnProxy : function(fn, old){
\r
250 delete window[old];
\r
252 var fnName = "extFnProxy" + (++Ext.chart.Chart.PROXY_FN_ID);
\r
253 window[fnName] = fn;
\r
257 onDestroy: function(){
\r
258 Ext.chart.Chart.superclass.onDestroy.call(this);
\r
259 delete window[this.tipFnName];
\r
262 Ext.reg('chart', Ext.chart.Chart);
\r
263 Ext.chart.Chart.PROXY_FN_ID = 0;
\r
266 * Sets the url to load the chart from. This should be set to a local resource.
\r
270 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.7.0/build/charts/assets/charts.swf';
\r
273 * @class Ext.chart.PieChart
\r
274 * @extends Ext.chart.Chart
\r
278 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
\r
281 onSwfReady : function(isReset){
\r
282 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
\r
284 this.setDataField(this.dataField);
\r
285 this.setCategoryField(this.categoryField);
\r
288 setDataField : function(field){
\r
289 this.dataField = field;
\r
290 this.swf.setDataField(field);
\r
293 setCategoryField : function(field){
\r
294 this.categoryField = field;
\r
295 this.swf.setCategoryField(field);
\r
298 Ext.reg('piechart', Ext.chart.PieChart);
\r
301 * @class Ext.chart.CartesianChart
\r
302 * @extends Ext.chart.Chart
\r
304 * @xtype cartesianchart
\r
306 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
\r
307 onSwfReady : function(isReset){
\r
308 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
\r
311 this.setXField(this.xField);
\r
314 this.setYField(this.yField);
\r
317 this.setXAxis(this.xAxis);
\r
320 this.setYAxis(this.yAxis);
\r
324 setXField : function(value){
\r
325 this.xField = value;
\r
326 this.swf.setHorizontalField(value);
\r
329 setYField : function(value){
\r
330 this.yField = value;
\r
331 this.swf.setVerticalField(value);
\r
334 setXAxis : function(value){
\r
335 this.xAxis = this.createAxis('xAxis', value);
\r
336 this.swf.setHorizontalAxis(this.xAxis);
\r
339 setYAxis : function(value){
\r
340 this.yAxis = this.createAxis('yAxis', value);
\r
341 this.swf.setVerticalAxis(this.yAxis);
\r
344 createAxis : function(axis, value){
\r
345 var o = Ext.apply({}, value), oldFn = null;
\r
347 oldFn = this[axis].labelFunction;
\r
349 if(o.labelRenderer){
\r
350 var fn = o.labelRenderer;
\r
351 o.labelFunction = this.createFnProxy(function(v){
\r
354 delete o.labelRenderer;
\r
359 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
\r
362 * @class Ext.chart.LineChart
\r
363 * @extends Ext.chart.CartesianChart
\r
367 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
\r
370 Ext.reg('linechart', Ext.chart.LineChart);
\r
373 * @class Ext.chart.ColumnChart
\r
374 * @extends Ext.chart.CartesianChart
\r
376 * @xtype columnchart
\r
378 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
\r
381 Ext.reg('columnchart', Ext.chart.ColumnChart);
\r
384 * @class Ext.chart.StackedColumnChart
\r
385 * @extends Ext.chart.CartesianChart
\r
387 * @xtype stackedcolumnchart
\r
389 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
\r
390 type: 'stackcolumn'
\r
392 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
\r
395 * @class Ext.chart.BarChart
\r
396 * @extends Ext.chart.CartesianChart
\r
400 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
\r
403 Ext.reg('barchart', Ext.chart.BarChart);
\r
406 * @class Ext.chart.StackedBarChart
\r
407 * @extends Ext.chart.CartesianChart
\r
409 * @xtype stackedbarchart
\r
411 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
\r
414 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
\r
419 * @class Ext.chart.Axis
\r
420 * Defines a CartesianChart's vertical or horizontal axis.
\r
423 Ext.chart.Axis = function(config){
\r
424 Ext.apply(this, config);
\r
427 Ext.chart.Axis.prototype =
\r
430 * The type of axis.
\r
438 * The direction in which the axis is drawn. May be "horizontal" or "vertical".
\r
440 * @property orientation
\r
443 orientation: "horizontal",
\r
446 * If true, the items on the axis will be drawn in opposite direction.
\r
448 * @property reverse
\r
454 * A string reference to the globally-accessible function that may be called to
\r
455 * determine each of the label values for this axis.
\r
457 * @property labelFunction
\r
460 labelFunction: null,
\r
463 * If true, labels that overlap previously drawn labels on the axis will be hidden.
\r
465 * @property hideOverlappingLabels
\r
468 hideOverlappingLabels: true
\r
472 * @class Ext.chart.NumericAxis
\r
473 * @extends Ext.chart.Axis
\r
474 * A type of axis whose units are measured in numeric values.
\r
477 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
\r
481 * The minimum value drawn by the axis. If not set explicitly, the axis minimum
\r
482 * will be calculated automatically.
\r
484 * @property minimum
\r
490 * The maximum value drawn by the axis. If not set explicitly, the axis maximum
\r
491 * will be calculated automatically.
\r
493 * @property maximum
\r
499 * The spacing between major intervals on this axis.
\r
501 * @property majorUnit
\r
507 * The spacing between minor intervals on this axis.
\r
509 * @property minorUnit
\r
515 * If true, the labels, ticks, gridlines, and other objects will snap to
\r
516 * the nearest major or minor unit. If false, their position will be based
\r
517 * on the minimum value.
\r
519 * @property snapToUnits
\r
525 * If true, and the bounds are calculated automatically, either the minimum or
\r
526 * maximum will be set to zero.
\r
528 * @property alwaysShowZero
\r
531 alwaysShowZero: true,
\r
534 * The scaling algorithm to use on this axis. May be "linear" or "logarithmic".
\r
543 * @class Ext.chart.TimeAxis
\r
544 * @extends Ext.chart.Axis
\r
545 * A type of axis whose units are measured in time-based values.
\r
548 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
\r
552 * The minimum value drawn by the axis. If not set explicitly, the axis minimum
\r
553 * will be calculated automatically.
\r
555 * @property minimum
\r
561 * The maximum value drawn by the axis. If not set explicitly, the axis maximum
\r
562 * will be calculated automatically.
\r
564 * @property maximum
\r
570 * The spacing between major intervals on this axis.
\r
572 * @property majorUnit
\r
578 * The time unit used by the majorUnit.
\r
580 * @property majorTimeUnit
\r
583 majorTimeUnit: null,
\r
586 * The spacing between minor intervals on this axis.
\r
588 * @property majorUnit
\r
594 * The time unit used by the minorUnit.
\r
596 * @property majorTimeUnit
\r
599 minorTimeUnit: null,
\r
602 * If true, the labels, ticks, gridlines, and other objects will snap to
\r
603 * the nearest major or minor unit. If false, their position will be based
\r
604 * on the minimum value.
\r
606 * @property snapToUnits
\r
613 * @class Ext.chart.CategoryAxis
\r
614 * @extends Ext.chart.Axis
\r
615 * A type of axis that displays items in categories.
\r
618 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
\r
622 * A list of category names to display along this axis.
\r
624 * @property categoryNames
\r
627 categoryNames: null
\r
631 * @class Ext.chart.Series
\r
632 * Series class for the charts widget.
\r
635 Ext.chart.Series = function(config) { Ext.apply(this, config); };
\r
637 Ext.chart.Series.prototype =
\r
640 * The type of series.
\r
648 * The human-readable name of the series.
\r
650 * @property displayName
\r
657 * @class Ext.chart.CartesianSeries
\r
658 * @extends Ext.chart.Series
\r
659 * CartesianSeries class for the charts widget.
\r
662 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
\r
664 * The field used to access the x-axis value from the items from the data source.
\r
672 * The field used to access the y-axis value from the items from the data source.
\r
681 * @class Ext.chart.ColumnSeries
\r
682 * @extends Ext.chart.CartesianSeries
\r
683 * ColumnSeries class for the charts widget.
\r
686 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
691 * @class Ext.chart.LineSeries
\r
692 * @extends Ext.chart.CartesianSeries
\r
693 * LineSeries class for the charts widget.
\r
696 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
701 * @class Ext.chart.BarSeries
\r
702 * @extends Ext.chart.CartesianSeries
\r
703 * BarSeries class for the charts widget.
\r
706 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
712 * @class Ext.chart.PieSeries
\r
713 * @extends Ext.chart.Series
\r
714 * PieSeries class for the charts widget.
\r
717 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
\r
720 categoryField: null
\r