FormDashboard.js 14 KB

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