3 <title>The source code</title>
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 <body onload="prettyPrint();">
8 <pre class="prettyprint lang-js">/*!
10 * Copyright(c) 2006-2009 Ext JS, LLC
12 * http://www.extjs.com/license
14 <div id="cls-Ext.chart.Chart"></div>/**
\r
15 * @class Ext.chart.Chart
\r
16 * @extends Ext.FlashComponent
\r
17 * The Ext.chart package provides the capability to visualize data with flash based charting.
\r
18 * Each chart binds directly to an Ext.data.Store enabling automatic updates of the chart.
\r
23 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
\r
26 <div id="cfg-Ext.chart.Chart-chartStyle"></div>/**
\r
27 * @cfg {Object} chartStyle
\r
28 * Sets styles for this chart. Contains a number of default values. Modifying this property will override
\r
29 * the base styles on the chart.
\r
33 animationEnabled: true,
\r
58 <div id="cfg-Ext.chart.Chart-url"></div>/**
\r
60 * The url to load the chart from. This defaults to Ext.chart.Chart.CHART_URL, which should
\r
61 * be modified to point to the local charts resource.
\r
64 <div id="cfg-Ext.chart.Chart-extraStyle"></div>/**
\r
65 * @cfg {Object} extraStyle
\r
66 * Contains extra styles that will be added or overwritten to the default chartStyle. Defaults to <tt>null</tt>.
\r
70 <div id="cfg-Ext.chart.Chart-disableCaching"></div>/**
\r
71 * @cfg {Boolean} disableCaching
\r
72 * True to add a "cache buster" to the end of the chart url. Defaults to true for Opera and IE.
\r
74 disableCaching: Ext.isIE || Ext.isOpera,
\r
75 disableCacheParam: '_dc',
\r
77 initComponent : function(){
\r
78 Ext.chart.Chart.superclass.initComponent.call(this);
\r
80 this.url = Ext.chart.Chart.CHART_URL;
\r
82 if(this.disableCaching){
\r
83 this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
\r
94 this.store = Ext.StoreMgr.lookup(this.store);
\r
97 <div id="method-Ext.chart.Chart-setStyle"></div>/**
\r
98 * Sets a single style value on the Chart instance.
\r
100 * @param name {String} Name of the Chart style value to change.
\r
101 * @param value {Object} New value to pass to the Chart style.
\r
103 setStyle: function(name, value){
\r
104 this.swf.setStyle(name, Ext.encode(value));
\r
107 <div id="method-Ext.chart.Chart-setStyles"></div>/**
\r
108 * Resets all styles on the Chart instance.
\r
110 * @param styles {Object} Initializer for all Chart styles.
\r
112 setStyles: function(styles){
\r
113 this.swf.setStyles(Ext.encode(styles));
\r
116 <div id="method-Ext.chart.Chart-setSeriesStyles"></div>/**
\r
117 * Sets the styles on all series in the Chart.
\r
119 * @param styles {Array} Initializer for all Chart series styles.
\r
121 setSeriesStyles: function(styles){
\r
123 Ext.each(styles, function(style){
\r
124 s.push(Ext.encode(style));
\r
126 this.swf.setSeriesStyles(s);
\r
129 setCategoryNames : function(names){
\r
130 this.swf.setCategoryNames(names);
\r
133 setTipRenderer : function(fn){
\r
135 this.tipFnName = this.createFnProxy(function(item, index, series){
\r
136 var record = chart.store.getAt(index);
\r
137 return fn(chart, record, index, series);
\r
138 }, this.tipFnName);
\r
139 this.swf.setDataTipFunction(this.tipFnName);
\r
142 setSeries : function(series){
\r
143 this.series = series;
\r
147 <div id="method-Ext.chart.Chart-bindStore"></div>/**
\r
148 * Changes the data store bound to this chart and refreshes it.
\r
149 * @param {Store} store The store to bind to this chart
\r
151 bindStore : function(store, initial){
\r
152 if(!initial && this.store){
\r
153 if(store !== this.store && this.store.autoDestroy){
\r
154 this.store.destroy();
\r
156 this.store.un("datachanged", this.refresh, this);
\r
157 this.store.un("add", this.delayRefresh, this);
\r
158 this.store.un("remove", this.delayRefresh, this);
\r
159 this.store.un("update", this.delayRefresh, this);
\r
160 this.store.un("clear", this.refresh, this);
\r
164 store = Ext.StoreMgr.lookup(store);
\r
167 datachanged: this.refresh,
\r
168 add: this.delayRefresh,
\r
169 remove: this.delayRefresh,
\r
170 update: this.delayRefresh,
\r
171 clear: this.refresh
\r
174 this.store = store;
\r
175 if(store && !initial){
\r
180 onSwfReady : function(isReset){
\r
181 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
\r
182 this.swf.setType(this.type);
\r
184 if(this.chartStyle){
\r
185 this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
\r
188 if(this.categoryNames){
\r
189 this.setCategoryNames(this.categoryNames);
\r
192 if(this.tipRenderer){
\r
193 this.setTipRenderer(this.tipRenderer);
\r
196 this.bindStore(this.store, true);
\r
198 this.refresh.defer(10, this);
\r
201 delayRefresh : function(){
\r
202 if(!this.refreshTask){
\r
203 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
\r
205 this.refreshTask.delay(this.refreshBuffer);
\r
208 refresh : function(){
\r
209 var styleChanged = false;
\r
210 // convert the store data into something YUI charts can understand
\r
211 var data = [], rs = this.store.data.items;
\r
212 for(var j = 0, len = rs.length; j < len; j++){
\r
213 data[j] = rs[j].data;
\r
215 //make a copy of the series definitions so that we aren't
\r
216 //editing them directly.
\r
217 var dataProvider = [];
\r
218 var seriesCount = 0;
\r
219 var currentSeries = null;
\r
222 seriesCount = this.series.length;
\r
223 for(i = 0; i < seriesCount; i++){
\r
224 currentSeries = this.series[i];
\r
225 var clonedSeries = {};
\r
226 for(var prop in currentSeries){
\r
227 if(prop == "style" && currentSeries.style !== null){
\r
228 clonedSeries.style = Ext.encode(currentSeries.style);
\r
229 styleChanged = true;
\r
230 //we don't want to modify the styles again next time
\r
231 //so null out the style property.
\r
232 // this causes issues
\r
233 // currentSeries.style = null;
\r
235 clonedSeries[prop] = currentSeries[prop];
\r
238 dataProvider.push(clonedSeries);
\r
242 if(seriesCount > 0){
\r
243 for(i = 0; i < seriesCount; i++){
\r
244 currentSeries = dataProvider[i];
\r
245 if(!currentSeries.type){
\r
246 currentSeries.type = this.type;
\r
248 currentSeries.dataProvider = data;
\r
251 dataProvider.push({type: this.type, dataProvider: data});
\r
253 this.swf.setDataProvider(dataProvider);
\r
256 createFnProxy : function(fn, old){
\r
258 delete window[old];
\r
260 var fnName = "extFnProxy" + (++Ext.chart.Chart.PROXY_FN_ID);
\r
261 window[fnName] = fn;
\r
265 onDestroy: function(){
\r
266 Ext.chart.Chart.superclass.onDestroy.call(this);
\r
267 this.bindStore(null);
\r
268 var tip = this.tipFnName;
\r
269 if(!Ext.isEmpty(tip)){
\r
270 delete window[tip];
\r
274 Ext.reg('chart', Ext.chart.Chart);
\r
275 Ext.chart.Chart.PROXY_FN_ID = 0;
\r
277 <div id="prop-Ext.chart.Chart-CHART_URL"></div>/**
\r
278 * Sets the url to load the chart from. This should be set to a local resource.
\r
282 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.7.0/build/charts/assets/charts.swf';
\r
284 <div id="cls-Ext.chart.PieChart"></div>/**
\r
285 * @class Ext.chart.PieChart
\r
286 * @extends Ext.chart.Chart
\r
290 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
\r
293 onSwfReady : function(isReset){
\r
294 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
\r
296 this.setDataField(this.dataField);
\r
297 this.setCategoryField(this.categoryField);
\r
300 setDataField : function(field){
\r
301 this.dataField = field;
\r
302 this.swf.setDataField(field);
\r
305 setCategoryField : function(field){
\r
306 this.categoryField = field;
\r
307 this.swf.setCategoryField(field);
\r
310 Ext.reg('piechart', Ext.chart.PieChart);
\r
312 <div id="cls-Ext.chart.CartesianChart"></div>/**
\r
313 * @class Ext.chart.CartesianChart
\r
314 * @extends Ext.chart.Chart
\r
316 * @xtype cartesianchart
\r
318 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
\r
319 onSwfReady : function(isReset){
\r
320 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
\r
323 this.setXField(this.xField);
\r
326 this.setYField(this.yField);
\r
329 this.setXAxis(this.xAxis);
\r
332 this.setYAxis(this.yAxis);
\r
336 setXField : function(value){
\r
337 this.xField = value;
\r
338 this.swf.setHorizontalField(value);
\r
341 setYField : function(value){
\r
342 this.yField = value;
\r
343 this.swf.setVerticalField(value);
\r
346 setXAxis : function(value){
\r
347 this.xAxis = this.createAxis('xAxis', value);
\r
348 this.swf.setHorizontalAxis(this.xAxis);
\r
351 setYAxis : function(value){
\r
352 this.yAxis = this.createAxis('yAxis', value);
\r
353 this.swf.setVerticalAxis(this.yAxis);
\r
356 createAxis : function(axis, value){
\r
357 var o = Ext.apply({}, value), oldFn = null;
\r
359 oldFn = this[axis].labelFunction;
\r
361 if(o.labelRenderer){
\r
362 var fn = o.labelRenderer;
\r
363 o.labelFunction = this.createFnProxy(function(v){
\r
366 delete o.labelRenderer;
\r
371 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
\r
373 <div id="cls-Ext.chart.LineChart"></div>/**
\r
374 * @class Ext.chart.LineChart
\r
375 * @extends Ext.chart.CartesianChart
\r
379 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
\r
382 Ext.reg('linechart', Ext.chart.LineChart);
\r
384 <div id="cls-Ext.chart.ColumnChart"></div>/**
\r
385 * @class Ext.chart.ColumnChart
\r
386 * @extends Ext.chart.CartesianChart
\r
388 * @xtype columnchart
\r
390 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
\r
393 Ext.reg('columnchart', Ext.chart.ColumnChart);
\r
395 <div id="cls-Ext.chart.StackedColumnChart"></div>/**
\r
396 * @class Ext.chart.StackedColumnChart
\r
397 * @extends Ext.chart.CartesianChart
\r
399 * @xtype stackedcolumnchart
\r
401 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
\r
402 type: 'stackcolumn'
\r
404 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
\r
406 <div id="cls-Ext.chart.BarChart"></div>/**
\r
407 * @class Ext.chart.BarChart
\r
408 * @extends Ext.chart.CartesianChart
\r
412 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
\r
415 Ext.reg('barchart', Ext.chart.BarChart);
\r
417 <div id="cls-Ext.chart.StackedBarChart"></div>/**
\r
418 * @class Ext.chart.StackedBarChart
\r
419 * @extends Ext.chart.CartesianChart
\r
421 * @xtype stackedbarchart
\r
423 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
\r
426 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
\r
430 <div id="cls-Ext.chart.Axis"></div>/**
\r
431 * @class Ext.chart.Axis
\r
432 * Defines a CartesianChart's vertical or horizontal axis.
\r
435 Ext.chart.Axis = function(config){
\r
436 Ext.apply(this, config);
\r
439 Ext.chart.Axis.prototype =
\r
441 <div id="prop-Ext.chart.Axis-type"></div>/**
\r
442 * The type of axis.
\r
449 <div id="prop-Ext.chart.Axis-orientation"></div>/**
\r
450 * The direction in which the axis is drawn. May be "horizontal" or "vertical".
\r
452 * @property orientation
\r
455 orientation: "horizontal",
\r
457 <div id="prop-Ext.chart.Axis-reverse"></div>/**
\r
458 * If true, the items on the axis will be drawn in opposite direction.
\r
460 * @property reverse
\r
465 <div id="prop-Ext.chart.Axis-labelFunction"></div>/**
\r
466 * A string reference to the globally-accessible function that may be called to
\r
467 * determine each of the label values for this axis.
\r
469 * @property labelFunction
\r
472 labelFunction: null,
\r
474 <div id="prop-Ext.chart.Axis-hideOverlappingLabels"></div>/**
\r
475 * If true, labels that overlap previously drawn labels on the axis will be hidden.
\r
477 * @property hideOverlappingLabels
\r
480 hideOverlappingLabels: true
\r
483 <div id="cls-Ext.chart.NumericAxis"></div>/**
\r
484 * @class Ext.chart.NumericAxis
\r
485 * @extends Ext.chart.Axis
\r
486 * A type of axis whose units are measured in numeric values.
\r
489 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
\r
492 <div id="prop-Ext.chart.NumericAxis-minimum"></div>/**
\r
493 * The minimum value drawn by the axis. If not set explicitly, the axis minimum
\r
494 * will be calculated automatically.
\r
496 * @property minimum
\r
501 <div id="prop-Ext.chart.NumericAxis-maximum"></div>/**
\r
502 * The maximum value drawn by the axis. If not set explicitly, the axis maximum
\r
503 * will be calculated automatically.
\r
505 * @property maximum
\r
510 <div id="prop-Ext.chart.NumericAxis-majorUnit"></div>/**
\r
511 * The spacing between major intervals on this axis.
\r
513 * @property majorUnit
\r
518 <div id="prop-Ext.chart.NumericAxis-minorUnit"></div>/**
\r
519 * The spacing between minor intervals on this axis.
\r
521 * @property minorUnit
\r
526 <div id="prop-Ext.chart.NumericAxis-snapToUnits"></div>/**
\r
527 * If true, the labels, ticks, gridlines, and other objects will snap to
\r
528 * the nearest major or minor unit. If false, their position will be based
\r
529 * on the minimum value.
\r
531 * @property snapToUnits
\r
536 <div id="prop-Ext.chart.NumericAxis-alwaysShowZero"></div>/**
\r
537 * If true, and the bounds are calculated automatically, either the minimum or
\r
538 * maximum will be set to zero.
\r
540 * @property alwaysShowZero
\r
543 alwaysShowZero: true,
\r
545 <div id="prop-Ext.chart.NumericAxis-scale"></div>/**
\r
546 * The scaling algorithm to use on this axis. May be "linear" or "logarithmic".
\r
554 <div id="cls-Ext.chart.TimeAxis"></div>/**
\r
555 * @class Ext.chart.TimeAxis
\r
556 * @extends Ext.chart.Axis
\r
557 * A type of axis whose units are measured in time-based values.
\r
560 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
\r
563 <div id="prop-Ext.chart.TimeAxis-minimum"></div>/**
\r
564 * The minimum value drawn by the axis. If not set explicitly, the axis minimum
\r
565 * will be calculated automatically.
\r
567 * @property minimum
\r
572 <div id="prop-Ext.chart.TimeAxis-maximum"></div>/**
\r
573 * The maximum value drawn by the axis. If not set explicitly, the axis maximum
\r
574 * will be calculated automatically.
\r
576 * @property maximum
\r
581 <div id="prop-Ext.chart.TimeAxis-majorUnit"></div>/**
\r
582 * The spacing between major intervals on this axis.
\r
584 * @property majorUnit
\r
589 <div id="prop-Ext.chart.TimeAxis-majorTimeUnit"></div>/**
\r
590 * The time unit used by the majorUnit.
\r
592 * @property majorTimeUnit
\r
595 majorTimeUnit: null,
\r
597 <div id="prop-Ext.chart.TimeAxis-majorUnit"></div>/**
\r
598 * The spacing between minor intervals on this axis.
\r
600 * @property majorUnit
\r
605 <div id="prop-Ext.chart.TimeAxis-majorTimeUnit"></div>/**
\r
606 * The time unit used by the minorUnit.
\r
608 * @property majorTimeUnit
\r
611 minorTimeUnit: null,
\r
613 <div id="prop-Ext.chart.TimeAxis-snapToUnits"></div>/**
\r
614 * If true, the labels, ticks, gridlines, and other objects will snap to
\r
615 * the nearest major or minor unit. If false, their position will be based
\r
616 * on the minimum value.
\r
618 * @property snapToUnits
\r
624 <div id="cls-Ext.chart.CategoryAxis"></div>/**
\r
625 * @class Ext.chart.CategoryAxis
\r
626 * @extends Ext.chart.Axis
\r
627 * A type of axis that displays items in categories.
\r
630 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
\r
633 <div id="prop-Ext.chart.CategoryAxis-categoryNames"></div>/**
\r
634 * A list of category names to display along this axis.
\r
636 * @property categoryNames
\r
639 categoryNames: null
\r
642 <div id="cls-Ext.chart.Series"></div>/**
\r
643 * @class Ext.chart.Series
\r
644 * Series class for the charts widget.
\r
647 Ext.chart.Series = function(config) { Ext.apply(this, config); };
\r
649 Ext.chart.Series.prototype =
\r
651 <div id="prop-Ext.chart.Series-type"></div>/**
\r
652 * The type of series.
\r
659 <div id="prop-Ext.chart.Series-displayName"></div>/**
\r
660 * The human-readable name of the series.
\r
662 * @property displayName
\r
668 <div id="cls-Ext.chart.CartesianSeries"></div>/**
\r
669 * @class Ext.chart.CartesianSeries
\r
670 * @extends Ext.chart.Series
\r
671 * CartesianSeries class for the charts widget.
\r
674 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
\r
675 <div id="prop-Ext.chart.CartesianSeries-xField"></div>/**
\r
676 * The field used to access the x-axis value from the items from the data source.
\r
683 <div id="prop-Ext.chart.CartesianSeries-yField"></div>/**
\r
684 * The field used to access the y-axis value from the items from the data source.
\r
692 <div id="cls-Ext.chart.ColumnSeries"></div>/**
\r
693 * @class Ext.chart.ColumnSeries
\r
694 * @extends Ext.chart.CartesianSeries
\r
695 * ColumnSeries class for the charts widget.
\r
698 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
702 <div id="cls-Ext.chart.LineSeries"></div>/**
\r
703 * @class Ext.chart.LineSeries
\r
704 * @extends Ext.chart.CartesianSeries
\r
705 * LineSeries class for the charts widget.
\r
708 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
712 <div id="cls-Ext.chart.BarSeries"></div>/**
\r
713 * @class Ext.chart.BarSeries
\r
714 * @extends Ext.chart.CartesianSeries
\r
715 * BarSeries class for the charts widget.
\r
718 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
\r
723 <div id="cls-Ext.chart.PieSeries"></div>/**
\r
724 * @class Ext.chart.PieSeries
\r
725 * @extends Ext.chart.Series
\r
726 * PieSeries class for the charts widget.
\r
729 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
\r
732 categoryField: null
\r