Upgrade to ExtJS 4.0.2 - Released 06/09/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                     form.updateRecord(rec);
80                     updateRecord(rec);
81                 }
82             };
83         };
84         
85     // sample static data for the store
86     var myData = [
87         ['3m Co'],
88         ['Alcoa Inc'],
89         ['Altria Group Inc'],
90         ['American Express Company'],
91         ['American International Group, Inc.'],
92         ['AT&T Inc'],
93         ['Boeing Co.'],
94         ['Caterpillar Inc.'],
95         ['Citigroup, Inc.'],
96         ['E.I. du Pont de Nemours and Company'],
97         ['Exxon Mobil Corp'],
98         ['General Electric Company'],
99         ['General Motors Corporation'],
100         ['Hewlett-Packard Co'],
101         ['Honeywell Intl Inc'],
102         ['Intel Corporation'],
103         ['International Business Machines'],
104         ['Johnson & Johnson'],
105         ['JP Morgan & Chase & Co'],
106         ['McDonald\'s Corporation'],
107         ['Merck & Co., Inc.'],
108         ['Microsoft Corporation'],
109         ['Pfizer Inc'],
110         ['The Coca-Cola Company'],
111         ['The Home Depot, Inc.'],
112         ['The Procter & Gamble Company'],
113         ['United Technologies Corporation'],
114         ['Verizon Communications'],
115         ['Wal-Mart Stores, Inc.']
116     ];
117     
118     for (var i = 0, l = myData.length, rand = Math.random; i < l; i++) {
119         var data = myData[i];
120         data[1] = ((rand() * 10000) >> 0) / 100;
121         data[2] = ((rand() * 10000) >> 0) / 100;
122         data[3] = ((rand() * 10000) >> 0) / 100;
123         data[4] = ((rand() * 10000) >> 0) / 100;
124         data[5] = ((rand() * 10000) >> 0) / 100;
125     }
126
127     //create data store to be shared among the grid and bar series.
128     var ds = Ext.create('Ext.data.ArrayStore', {
129         fields: [
130             {name: 'company'},
131             {name: 'price',   type: 'float'},
132             {name: 'revenue %', type: 'float'},
133             {name: 'growth %',  type: 'float'},
134             {name: 'product %', type: 'float'},
135             {name: 'market %',  type: 'float'}
136         ],
137         data: myData
138     });
139     
140     //create radar dataset model.
141     var chs = Ext.create('Ext.data.JsonStore', {
142         fields: ['Name', 'Data'],
143         data: [
144         {
145             'Name': 'Price',
146             'Data': 100
147         }, {
148             'Name': 'Revenue %',
149             'Data': 100
150         }, {
151             'Name': 'Growth %',
152             'Data': 100
153         }, {
154             'Name': 'Product %',
155             'Data': 100
156         }, {
157             'Name': 'Market %',
158             'Data': 100
159         }]
160     });
161     
162     //Radar chart will render information for a selected company in the
163     //list. Selection can also be done via clicking on the bars in the series.
164     var radarChart = Ext.create('Ext.chart.Chart', {
165         margin: '0 0 0 0',
166         insetPadding: 20,
167         flex: 1.2,
168         animate: true,
169         store: chs,
170         axes: [{
171             steps: 5,
172             type: 'Radial',
173             position: 'radial',
174             maximum: 100
175         }],
176         series: [{
177             type: 'radar',
178             xField: 'Name',
179             yField: 'Data',
180             showInLegend: false,
181             showMarkers: true,
182             markerConfig: {
183                 radius: 4,
184                 size: 4
185             },
186             style: {
187                 fill: 'rgb(194,214,240)',
188                 opacity: 0.5,
189                 'stroke-width': 0.5
190             }
191         }]
192     });
193     
194     //create a grid that will list the dataset items.
195     var gridPanel = Ext.create('Ext.grid.Panel', {
196         id: 'company-form',
197         flex: 0.60,
198         store: ds,
199         title:'Company Data',
200
201         columns: [
202             {
203                 id       :'company',
204                 text   : 'Company',
205                 flex: 1,
206                 sortable : true,
207                 dataIndex: 'company'
208             },
209             {
210                 text   : 'Price',
211                 width    : 75,
212                 sortable : true,
213                 dataIndex: 'price',
214                 align: 'right',
215                 renderer : 'usMoney'
216             },
217             {
218                 text   : 'Revenue',
219                 width    : 75,
220                 sortable : true,
221                 align: 'right',
222                 dataIndex: 'revenue %',
223                 renderer: perc
224             },
225             {
226                 text   : 'Growth',
227                 width    : 75,
228                 sortable : true,
229                 align: 'right',
230                 dataIndex: 'growth %',
231                 renderer: perc
232             },
233             {
234                 text   : 'Product',
235                 width    : 75,
236                 sortable : true,
237                 align: 'right',
238                 dataIndex: 'product %',
239                 renderer: perc
240             },
241             {
242                 text   : 'Market',
243                 width    : 75,
244                 sortable : true,
245                 align: 'right',
246                 dataIndex: 'market %',
247                 renderer: perc
248             }
249         ],
250
251         listeners: {
252             selectionchange: function(model, records) {
253                 var json, name, i, l, items, series, fields;
254                 if (records[0]) {
255                     rec = records[0];
256                     form = form || this.up('form').getForm();
257                     fields = form.getFields();
258                     // prevent change events from firing
259                     fields.each(function(field){
260                         field.suspendEvents();
261                     });
262                     form.loadRecord(rec);
263                     updateRecord(rec);
264                     fields.each(function(field){
265                         field.resumeEvents();
266                     });
267                 }
268             }
269         }
270     });
271
272     //create a bar series to be at the top of the panel.
273     var barChart = Ext.create('Ext.chart.Chart', {
274         flex: 1,
275         shadow: true,
276         animate: true,
277         store: ds,
278         axes: [{
279             type: 'Numeric',
280             position: 'left',
281             fields: ['price'],
282             minimum: 0,
283             hidden: true
284         }, {
285             type: 'Category',
286             position: 'bottom',
287             fields: ['company'],
288             label: {
289                 renderer: function(v) {
290                     return Ext.String.ellipsis(v, 15, false);
291                 },
292                 font: '9px Arial',
293                 rotate: {
294                     degrees: 270
295                 }
296             }
297         }],
298         series: [{
299             type: 'column',
300             axis: 'left',
301             highlight: true,
302             style: {
303                 fill: '#456d9f'
304             },
305             highlightCfg: {
306                 fill: '#a2b5ca'
307             },
308             label: {
309                 contrast: true,
310                 display: 'insideEnd',
311                 field: 'price',
312                 color: '#000',
313                 orientation: 'vertical',
314                 'text-anchor': 'middle'
315             },
316             listeners: {
317                 'itemmouseup': function(item) {
318                      var series = barChart.series.get(0),
319                          index = Ext.Array.indexOf(series.items, item),
320                          selectionModel = gridPanel.getSelectionModel();
321                      
322                      selectedStoreItem = item.storeItem;
323                      selectionModel.select(index);
324                 }
325             },
326             xField: 'name',
327             yField: ['price']
328         }]        
329     });
330     
331     //disable highlighting by default.
332     barChart.series.get(0).highlight = false;
333     
334     //add listener to (re)select bar item after sorting or refreshing the dataset.
335     barChart.addListener('beforerefresh', (function() {
336         var timer = false;
337         return function() {
338             clearTimeout(timer);
339             if (selectedStoreItem) {
340                 timer = setTimeout(function() {
341                     selectItem(selectedStoreItem);
342                 }, 900);
343             }
344         };
345     })());
346     
347     /*
348      * Here is where we create the Form
349      */
350     var gridForm = Ext.create('Ext.form.Panel', {
351         title: 'Company data',
352         frame: true,
353         bodyPadding: 5,
354         width: 870,
355         height: 720,
356
357         fieldDefaults: {
358             labelAlign: 'left',
359             msgTarget: 'side'
360         },
361     
362         layout: {
363             type: 'vbox',
364             align: 'stretch'
365         },
366         
367         items: [
368             {
369                 height: 200,
370                 layout: 'fit',
371                 margin: '0 0 3 0',
372                 items: [barChart]
373             },
374             {
375             
376             layout: {type: 'hbox', align: 'stretch'},
377             flex: 3,
378             border: false,
379             bodyStyle: 'background-color: transparent',
380             
381             items: [gridPanel, {
382                 flex: 0.4,
383                 layout: {
384                     type: 'vbox',
385                     align:'stretch'
386                 },
387                 margin: '0 0 0 5',
388                 title: 'Company Details',
389                 items: [{
390                     margin: '5',
391                     xtype: 'fieldset',
392                     flex: 1,
393                     title:'Company details',
394                     defaults: {
395                         width: 240,
396                         labelWidth: 90
397                     },
398                     defaultType: 'textfield',
399                     items: [{
400                         fieldLabel: 'Name',
401                         name: 'company',
402                         disabled: true
403                     },{
404                         fieldLabel: 'Price',
405                         name: 'price',
406                         listeners: createListeners('price')
407                     },{
408                         fieldLabel: 'Revenue %',
409                         name: 'revenue %',
410                         listeners: createListeners('revenue %')
411                     },{
412                         fieldLabel: 'Growth %',
413                         name: 'growth %',
414                         listeners: createListeners('growth %')
415                     },{
416                         fieldLabel: 'Product %',
417                         name: 'product %',
418                         listeners: createListeners('product %')
419                     },{
420                         fieldLabel: 'Market %',
421                         name: 'market %',
422                         listeners: createListeners('market %')
423                     }]
424                 }, radarChart]
425             }]
426         }],
427         renderTo: bd
428     });
429
430     var gp = Ext.getCmp('company-form');
431 });