source: trunk/web/addons/job_monarch/lib/extjs-30/src/widgets/chart/Chart.js @ 625

Last change on this file since 625 was 625, checked in by ramonb, 15 years ago

lib/extjs-30:

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