a0e5fae8d5cc904a5fe1f3f05d4c0f82c617619e.svn-base 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. Ext.grid.GroupSummary = function(config){
  7. Ext.apply(this, config);
  8. };
  9. Ext.extend(Ext.grid.GroupSummary, Ext.util.Observable, {
  10. init : function(grid){
  11. this.grid = grid;
  12. this.cm = grid.getColumnModel();
  13. this.view = grid.getView();
  14. var v = this.view;
  15. v.doGroupEnd = this.doGroupEnd.createDelegate(this);
  16. v.afterMethod('onColumnWidthUpdated', this.doWidth, this);
  17. v.afterMethod('onAllColumnWidthsUpdated', this.doAllWidths, this);
  18. v.afterMethod('onColumnHiddenUpdated', this.doHidden, this);
  19. v.afterMethod('onUpdate', this.doUpdate, this);
  20. v.afterMethod('onRemove', this.doRemove, this);
  21. if(!this.rowTpl){
  22. this.rowTpl = new Ext.Template(
  23. '<div class="x-grid3-summary-row" style="{tstyle}">',
  24. '<table class="x-grid3-summary-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
  25. '<tbody><tr>{cells}</tr></tbody>',
  26. '</table></div>'
  27. );
  28. this.rowTpl.disableFormats = true;
  29. }
  30. this.rowTpl.compile();
  31. if(!this.cellTpl){
  32. this.cellTpl = new Ext.Template(
  33. '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
  34. '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on">{value}</div>',
  35. "</td>"
  36. );
  37. this.cellTpl.disableFormats = true;
  38. }
  39. this.cellTpl.compile();
  40. },
  41. toggleSummaries : function(visible){
  42. var el = this.grid.getGridEl();
  43. if(el){
  44. if(visible === undefined){
  45. visible = el.hasClass('x-grid-hide-summary');
  46. }
  47. el[visible ? 'removeClass' : 'addClass']('x-grid-hide-summary');
  48. }
  49. },
  50. renderSummary : function(o, cs){
  51. cs = cs || this.view.getColumnData();
  52. var cfg = this.cm.config;
  53. var buf = [], c, p = {}, cf, last = cs.length-1;
  54. for(var i = 0, len = cs.length; i < len; i++){
  55. c = cs[i];
  56. cf = cfg[i];
  57. p.id = c.id;
  58. p.style = c.style;
  59. p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
  60. if(cf.summaryType || cf.summaryRenderer){
  61. p.value = (cf.summaryRenderer || c.renderer)(o.data[c.name], p, o);
  62. }else{
  63. p.value = '';
  64. }
  65. if(p.value == undefined || p.value === "") p.value = "&#160;";
  66. buf[buf.length] = this.cellTpl.apply(p);
  67. }
  68. return this.rowTpl.apply({
  69. tstyle: 'width:'+this.view.getTotalWidth()+';',
  70. cells: buf.join('')
  71. });
  72. },
  73. calculate : function(rs, cs){
  74. var data = {}, r, c, cfg = this.cm.config, cf;
  75. for(var j = 0, jlen = rs.length; j < jlen; j++){
  76. r = rs[j];
  77. for(var i = 0, len = cs.length; i < len; i++){
  78. c = cs[i];
  79. cf = cfg[i];
  80. if(cf.summaryType){
  81. data[c.name] = Ext.grid.GroupSummary.Calculations[cf.summaryType](data[c.name] || 0, r, c.name, data);
  82. }
  83. }
  84. }
  85. return data;
  86. },
  87. doGroupEnd : function(buf, g, cs, ds, colCount){
  88. var data = this.calculate(g.rs, cs);
  89. buf.push('</div>', this.renderSummary({data: data}, cs), '</div>');
  90. },
  91. doWidth : function(col, w, tw){
  92. var gs = this.view.getGroups(), s;
  93. for(var i = 0, len = gs.length; i < len; i++){
  94. s = gs[i].childNodes[2];
  95. s.style.width = tw;
  96. s.firstChild.style.width = tw;
  97. s.firstChild.rows[0].childNodes[col].style.width = w;
  98. }
  99. },
  100. doAllWidths : function(ws, tw){
  101. var gs = this.view.getGroups(), s, cells, wlen = ws.length;
  102. for(var i = 0, len = gs.length; i < len; i++){
  103. s = gs[i].childNodes[2];
  104. s.style.width = tw;
  105. s.firstChild.style.width = tw;
  106. cells = s.firstChild.rows[0].childNodes;
  107. for(var j = 0; j < wlen; j++){
  108. cells[j].style.width = ws[j];
  109. }
  110. }
  111. },
  112. doHidden : function(col, hidden, tw){
  113. var gs = this.view.getGroups(), s, display = hidden ? 'none' : '';
  114. for(var i = 0, len = gs.length; i < len; i++){
  115. s = gs[i].childNodes[2];
  116. s.style.width = tw;
  117. s.firstChild.style.width = tw;
  118. s.firstChild.rows[0].childNodes[col].style.display = display;
  119. }
  120. },
  121. // Note: requires that all (or the first) record in the
  122. // group share the same group value. Returns false if the group
  123. // could not be found.
  124. refreshSummary : function(groupValue){
  125. return this.refreshSummaryById(this.view.getGroupId(groupValue));
  126. },
  127. getSummaryNode : function(gid){
  128. var g = Ext.fly(gid, '_gsummary');
  129. if(g){
  130. return g.down('.x-grid3-summary-row', true);
  131. }
  132. return null;
  133. },
  134. refreshSummaryById : function(gid){
  135. var g = document.getElementById(gid);
  136. if(!g){
  137. return false;
  138. }
  139. var rs = [];
  140. this.grid.store.each(function(r){
  141. if(r._groupId == gid){
  142. rs[rs.length] = r;
  143. }
  144. });
  145. var cs = this.view.getColumnData();
  146. var data = this.calculate(rs, cs);
  147. var markup = this.renderSummary({data: data}, cs);
  148. var existing = this.getSummaryNode(gid);
  149. if(existing){
  150. g.removeChild(existing);
  151. }
  152. Ext.DomHelper.append(g, markup);
  153. return true;
  154. },
  155. doUpdate : function(ds, record){
  156. this.refreshSummaryById(record._groupId);
  157. },
  158. doRemove : function(ds, record, index, isUpdate){
  159. if(!isUpdate){
  160. this.refreshSummaryById(record._groupId);
  161. }
  162. },
  163. showSummaryMsg : function(groupValue, msg){
  164. var gid = this.view.getGroupId(groupValue);
  165. var node = this.getSummaryNode(gid);
  166. if(node){
  167. node.innerHTML = '<div class="x-grid3-summary-msg">' + msg + '</div>';
  168. }
  169. }
  170. });
  171. Ext.grid.GroupSummary.Calculations = {
  172. 'sum' : function(v, record, field){
  173. return v + (record.data[field]||0);
  174. },
  175. 'count' : function(v, record, field, data){
  176. return data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
  177. },
  178. 'max' : function(v, record, field, data){
  179. var v = record.data[field];
  180. var max = data[field+'max'] === undefined ? (data[field+'max'] = v) : data[field+'max'];
  181. return v > max ? (data[field+'max'] = v) : max;
  182. },
  183. 'min' : function(v, record, field, data){
  184. var v = record.data[field];
  185. var min = data[field+'min'] === undefined ? (data[field+'min'] = v) : data[field+'min'];
  186. return v < min ? (data[field+'min'] = v) : min;
  187. },
  188. 'average' : function(v, record, field, data){
  189. var c = data[field+'count'] ? ++data[field+'count'] : (data[field+'count'] = 1);
  190. var t = (data[field+'total'] = ((data[field+'total']||0) + (record.data[field]||0)));
  191. return t === 0 ? 0 : t / c;
  192. }
  193. }
  194. Ext.grid.HybridSummary = Ext.extend(Ext.grid.GroupSummary, {
  195. calculate : function(rs, cs){
  196. var gcol = this.view.getGroupField();
  197. var gvalue = rs[0].data[gcol];
  198. var gdata = this.getSummaryData(gvalue);
  199. return gdata || Ext.grid.HybridSummary.superclass.calculate.call(this, rs, cs);
  200. },
  201. updateSummaryData : function(groupValue, data, skipRefresh){
  202. var json = this.grid.store.reader.jsonData;
  203. if(!json.summaryData){
  204. json.summaryData = {};
  205. }
  206. json.summaryData[groupValue] = data;
  207. if(!skipRefresh){
  208. this.refreshSummary(groupValue);
  209. }
  210. },
  211. getSummaryData : function(groupValue){
  212. var json = this.grid.store.reader.jsonData;
  213. if(json && json.summaryData){
  214. return json.summaryData[groupValue];
  215. }
  216. return null;
  217. }
  218. });