Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / examples / charts / FormDashboard.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 Ext.require([
16     'Ext.form.*',
17     'Ext.data.*',
18     'Ext.chart.*',
19     'Ext.grid.Panel',
20     'Ext.layout.container.Column'
21 ]);
22
23
24 Ext.onReady(function(){
25     
26     //use a renderer for values in the data view.
27     function perc(v) {
28         return v + '%';
29     }
30
31     var bd = Ext.getBody(),
32         form = false,
33         rec = false,
34         selectedStoreItem = false,
35         //performs the highlight of an item in the bar series
36         selectItem = function(storeItem) {
37             var name = storeItem.get('company'),
38                 series = barChart.series.get(0),
39                 i, items, l;
40             
41             series.highlight = true;
42             series.unHighlightItem();
43             series.cleanHighlights();
44             for (i = 0, items = series.items, l = items.length; i < l; i++) {
45                 if (name == items[i].storeItem.get('company')) {
46                     selectedStoreItem = items[i].storeItem;
47                     series.highlightItem(items[i]);
48                     break;
49                 }
50             }
51             series.highlight = false;
52         },
53         //updates a record modified via the form
54         updateRecord = function(rec) {
55             var name, series, i, l, items, json = [{
56                 'Name': 'Price',
57                 'Data': rec.get('price')
58             }, {
59                 'Name': 'Revenue %',
60                 'Data': rec.get('revenue %')
61             }, {
62                 'Name': 'Growth %',
63                 'Data': rec.get('growth %')
64             }, {
65                 'Name': 'Product %',
66                 'Data': rec.get('product %')
67             }, {
68                 'Name': 'Market %',
69                 'Data': rec.get('market %')
70             }];
71             chs.loadData(json);
72             selectItem(rec);
73         },
74         createListeners = function() {
75             return {
76                 // buffer so we don't refire while the user is still typing
77                 buffer: 200,
78                 change: function(field, newValue, oldValue, listener) {
79                     if (rec && form) {
80                         if (newValue > field.maxValue) {
81                             field.setValue(field.maxValue);
82                         } else {
83                             form.updateRecord(rec);
84                             updateRecord(rec);
85                         }
86                     }
87                 }
88             };
89         };
90         
91     // sample static data for the store
92     var myData = [
93         ['3m Co'],
94         ['Alcoa Inc'],
95         ['Altria Group Inc'],
96         ['American Express Company'],
97         ['American International Group, Inc.'],
98         ['AT&T Inc'],
99         ['Boeing Co.'],
100         ['Caterpillar Inc.'],
101         ['Citigroup, Inc.'],
102         ['E.I. du Pont de Nemours and Company'],
103         ['Exxon Mobil Corp'],
104         ['General Electric Company'],
105         ['General Motors Corporation'],
106         ['Hewlett-Packard Co'],
107         ['Honeywell Intl Inc'],
108         ['Intel Corporation'],
109         ['International Business Machines'],
110         ['Johnson & Johnson'],
111         ['JP Morgan & Chase & Co'],
112         ['McDonald\'s Corporation'],
113         ['Merck & Co., Inc.'],
114         ['Microsoft Corporation'],
115         ['Pfizer Inc'],
116         ['The Coca-Cola Company'],
117         ['The Home Depot, Inc.'],
118         ['The Procter & Gamble Company'],
119         ['United Technologies Corporation'],
120         ['Verizon Communications'],
121         ['Wal-Mart Stores, Inc.']
122     ];
123     
124     for (var i = 0, l = myData.length, rand = Math.random; i < l; i++) {
125         var data = myData[i];
126         data[1] = ((rand() * 10000) >> 0) / 100;
127         data[2] = ((rand() * 10000) >> 0) / 100;
128         data[3] = ((rand() * 10000) >> 0) / 100;
129         data[4] = ((rand() * 10000) >> 0) / 100;
130         data[5] = ((rand() * 10000) >> 0) / 100;
131     }
132
133     //create data store to be shared among the grid and bar series.
134     var ds = Ext.create('Ext.data.ArrayStore', {
135         fields: [
136             {name: 'company'},
137             {name: 'price',   type: 'float'},
138             {name: 'revenue %', type: 'float'},
139             {name: 'growth %',  type: 'float'},
140             {name: 'product %', type: 'float'},
141             {name: 'market %',  type: 'float'}
142         ],
143         data: myData
144     });
145     
146     //create radar dataset model.
147     var chs = Ext.create('Ext.data.JsonStore', {
148         fields: ['Name', 'Data'],
149         data: [
150         {
151             'Name': 'Price',
152             'Data': 100
153         }, {
154             'Name': 'Revenue %',
155             'Data': 100
156         }, {
157             'Name': 'Growth %',
158             'Data': 100
159         }, {
160             'Name': 'Product %',
161             'Data': 100
162         }, {
163             'Name': 'Market %',
164             'Data': 100
165         }]
166     });
167     
168     //Radar chart will render information for a selected company in the
169     //list. Selection can also be done via clicking on the bars in the series.
170     var radarChart = Ext.create('Ext.chart.Chart', {
171         margin: '0 0 0 0',
172         insetPadding: 20,
173         flex: 1.2,
174         animate: true,
175         store: chs,
176         axes: [{
177             steps: 5,
178             type: 'Radial',
179             position: 'radial',
180             maximum: 100
181         }],
182         series: [{
183             type: 'radar',
184             xField: 'Name',
185             yField: 'Data',
186             showInLegend: false,
187             showMarkers: true,
188             markerConfig: {
189                 radius: 4,
190                 size: 4
191             },
192             style: {
193                 fill: 'rgb(194,214,240)',
194                 opacity: 0.5,
195                 'stroke-width': 0.5
196             }
197         }]
198     });
199     
200     //create a grid that will list the dataset items.
201     var gridPanel = Ext.create('Ext.grid.Panel', {
202         id: 'company-form',
203         flex: 0.60,
204         store: ds,
205         title:'Company Data',
206
207         columns: [
208             {
209                 id       :'company',
210                 text   : 'Company',
211                 flex: 1,
212                 sortable : true,
213                 dataIndex: 'company'
214             },
215             {
216                 text   : 'Price',
217                 width    : 75,
218                 sortable : true,
219                 dataIndex: 'price',
220                 align: 'right',
221                 renderer : 'usMoney'
222             },
223             {
224                 text   : 'Revenue',
225                 width    : 75,
226                 sortable : true,
227                 align: 'right',
228                 dataIndex: 'revenue %',
229                 renderer: perc
230             },
231             {
232                 text   : 'Growth',
233                 width    : 75,
234                 sortable : true,
235                 align: 'right',
236                 dataIndex: 'growth %',
237                 renderer: perc
238             },
239             {
240                 text   : 'Product',
241                 width    : 75,
242                 sortable : true,
243                 align: 'right',
244                 dataIndex: 'product %',
245                 renderer: perc
246             },
247             {
248                 text   : 'Market',
249                 width    : 75,
250                 sortable : true,
251                 align: 'right',
252                 dataIndex: 'market %',
253                 renderer: perc
254             }
255         ],
256
257         listeners: {
258             selectionchange: function(model, records) {
259                 var json, name, i, l, items, series, fields;
260                 if (records[0]) {
261                     rec = records[0];
262                     if (!form) {
263                         form = this.up('form').getForm();
264                         fields = form.getFields();
265                         fields.each(function(field){
266                             if (field.name != 'company') {
267                                 field.setDisabled(false);
268                             }
269                         });
270                     } else {
271                         fields = form.getFields();
272                     }
273                     
274                     // prevent change events from firing
275                     fields.each(function(field){
276                         field.suspendEvents();
277                     });
278                     form.loadRecord(rec);
279                     updateRecord(rec);
280                     fields.each(function(field){
281                         field.resumeEvents();
282                     });
283                 }
284             }
285         }
286     });
287
288     //create a bar series to be at the top of the panel.
289     var barChart = Ext.create('Ext.chart.Chart', {
290         flex: 1,
291         shadow: true,
292         animate: true,
293         store: ds,
294         axes: [{
295             type: 'Numeric',
296             position: 'left',
297             fields: ['price'],
298             minimum: 0,
299             hidden: true
300         }, {
301             type: 'Category',
302             position: 'bottom',
303             fields: ['company'],
304             label: {
305                 renderer: function(v) {
306                     return Ext.String.ellipsis(v, 15, false);
307                 },
308                 font: '9px Arial',
309                 rotate: {
310                     degrees: 270
311                 }
312             }
313         }],
314         series: [{
315             type: 'column',
316             axis: 'left',
317             highlight: true,
318             style: {
319                 fill: '#456d9f'
320             },
321             highlightCfg: {
322                 fill: '#a2b5ca'
323             },
324             label: {
325                 contrast: true,
326                 display: 'insideEnd',
327                 field: 'price',
328                 color: '#000',
329                 orientation: 'vertical',
330                 'text-anchor': 'middle'
331             },
332             listeners: {
333                 'itemmouseup': function(item) {
334                      var series = barChart.series.get(0),
335                          index = Ext.Array.indexOf(series.items, item),
336                          selectionModel = gridPanel.getSelectionModel();
337                      
338                      selectedStoreItem = item.storeItem;
339                      selectionModel.select(index);
340                 }
341             },
342             xField: 'name',
343             yField: ['price']
344         }]        
345     });
346     
347     //disable highlighting by default.
348     barChart.series.get(0).highlight = false;
349     
350     //add listener to (re)select bar item after sorting or refreshing the dataset.
351     barChart.addListener('beforerefresh', (function() {
352         var timer = false;
353         return function() {
354             clearTimeout(timer);
355             if (selectedStoreItem) {
356                 timer = setTimeout(function() {
357                     selectItem(selectedStoreItem);
358                 }, 900);
359             }
360         };
361     })());
362     
363     /*
364      * Here is where we create the Form
365      */
366     var gridForm = Ext.create('Ext.form.Panel', {
367         title: 'Company data',
368         frame: true,
369         bodyPadding: 5,
370         width: 870,
371         height: 720,
372
373         fieldDefaults: {
374             labelAlign: 'left',
375             msgTarget: 'side'
376         },
377     
378         layout: {
379             type: 'vbox',
380             align: 'stretch'
381         },
382         
383         items: [
384             {
385                 height: 200,
386                 layout: 'fit',
387                 margin: '0 0 3 0',
388                 items: [barChart]
389             },
390             {
391             
392             layout: {type: 'hbox', align: 'stretch'},
393             flex: 3,
394             border: false,
395             bodyStyle: 'background-color: transparent',
396             
397             items: [gridPanel, {
398                 flex: 0.4,
399                 layout: {
400                     type: 'vbox',
401                     align:'stretch'
402                 },
403                 margin: '0 0 0 5',
404                 title: 'Company Details',
405                 items: [{
406                     margin: '5',
407                     xtype: 'fieldset',
408                     flex: 1,
409                     title:'Company details',
410                     defaults: {
411                         width: 240,
412                         labelWidth: 90,
413                         disabled: true
414                     },
415                     defaultType: 'numberfield',
416                     items: [{
417                         fieldLabel: 'Name',
418                         name: 'company',
419                         xtype: 'textfield'
420                     },{
421                         fieldLabel: 'Price',
422                         name: 'price',
423                         maxValue: 100,
424                         minValue: 0,
425                         enforceMaxLength: true,
426                         maxLength: 5,
427                         listeners: createListeners('price')
428                     },{
429                         fieldLabel: 'Revenue %',
430                         name: 'revenue %',
431                         maxValue: 100,
432                         minValue: 0,
433                         enforceMaxLength: true,
434                         maxLength: 5,
435                         listeners: createListeners('revenue %')
436                     },{
437                         fieldLabel: 'Growth %',
438                         name: 'growth %',
439                         maxValue: 100,
440                         minValue: 0,
441                         enforceMaxLength: true,
442                         maxLength: 5,
443                         listeners: createListeners('growth %')
444                     },{
445                         fieldLabel: 'Product %',
446                         name: 'product %',
447                         maxValue: 100,
448                         minValue: 0,
449                         enforceMaxLength: true,
450                         maxLength: 5,
451                         listeners: createListeners('product %')
452                     },{
453                         fieldLabel: 'Market %',
454                         name: 'market %',
455                         maxValue: 100,
456                         minValue: 0,
457                         enforceMaxLength: true,
458                         maxLength: 5,
459                         listeners: createListeners('market %')
460                     }]
461                 }, radarChart]
462             }]
463         }],
464         renderTo: bd
465     });
466
467     var gp = Ext.getCmp('company-form');
468 });