Merge lp:~openerp-dev/openerp-web/trunk-new-graphview-ged into lp:openerp-web
- trunk-new-graphview-ged
- Merge into trunk
Proposed by
Géry Debongnie
Status: | Merged |
---|---|
Merged at revision: | 3929 |
Proposed branch: | lp:~openerp-dev/openerp-web/trunk-new-graphview-ged |
Merge into: | lp:openerp-web |
Diff against target: |
545 lines (+292/-153) 6 files modified
addons/web_graph/__init__.py (+1/-0) addons/web_graph/controllers/__init__.py (+1/-0) addons/web_graph/controllers/main.py (+88/-0) addons/web_graph/static/src/js/graph_widget.js (+195/-153) addons/web_graph/static/src/js/pivot_table.js (+4/-0) addons/web_graph/static/src/xml/web_graph.xml (+3/-0) |
To merge this branch: | bzr merge lp:~openerp-dev/openerp-web/trunk-new-graphview-ged |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Xavier (Open ERP) (community) | Needs Fixing | ||
Review via email:
|
Commit message
Description of the change
Export functionality... Only code that changed is in addon web_graph (web)
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
review:
Needs Fixing
- 4119. By Géry Debongnie
-
[FIX] many small tweaks, add some comment, rename variables to have better more informative names in excel export functionality in graph view (addon web_graph)
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Géry Debongnie (gery-debongnie) wrote : | # |
The fixing has been done...
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'addons/web_graph/__init__.py' |
2 | --- addons/web_graph/__init__.py 2012-10-23 15:26:46 +0000 |
3 | +++ addons/web_graph/__init__.py 2014-02-05 13:14:23 +0000 |
4 | @@ -0,0 +1,1 @@ |
5 | +import controllers |
6 | |
7 | === added directory 'addons/web_graph/controllers' |
8 | === added file 'addons/web_graph/controllers/__init__.py' |
9 | --- addons/web_graph/controllers/__init__.py 1970-01-01 00:00:00 +0000 |
10 | +++ addons/web_graph/controllers/__init__.py 2014-02-05 13:14:23 +0000 |
11 | @@ -0,0 +1,1 @@ |
12 | +import main |
13 | \ No newline at end of file |
14 | |
15 | === added file 'addons/web_graph/controllers/main.py' |
16 | --- addons/web_graph/controllers/main.py 1970-01-01 00:00:00 +0000 |
17 | +++ addons/web_graph/controllers/main.py 2014-02-05 13:14:23 +0000 |
18 | @@ -0,0 +1,88 @@ |
19 | +from openerp import http |
20 | +import simplejson |
21 | +from openerp.http import request, serialize_exception as _serialize_exception |
22 | +from cStringIO import StringIO |
23 | +from collections import deque |
24 | + |
25 | +try: |
26 | + import xlwt |
27 | +except ImportError: |
28 | + xlwt = None |
29 | + |
30 | +class TableExporter(http.Controller): |
31 | + |
32 | + @http.route('/web_graph/check_xlwt', type='json', auth='none') |
33 | + def check_xlwt(self): |
34 | + return xlwt is not None |
35 | + |
36 | + |
37 | + @http.route('/web_graph/export_xls', type='http', auth="user") |
38 | + def export_xls(self, data, token): |
39 | + jdata = simplejson.loads(data) |
40 | + nbr_measures = jdata['nbr_measures'] |
41 | + workbook = xlwt.Workbook() |
42 | + worksheet = workbook.add_sheet(jdata['title']) |
43 | + header_bold = xlwt.easyxf("font: bold on; pattern: pattern solid, fore_colour gray25;") |
44 | + header_plain = xlwt.easyxf("pattern: pattern solid, fore_colour gray25;") |
45 | + bold = xlwt.easyxf("font: bold on;") |
46 | + |
47 | + # Step 1: writing headers |
48 | + headers = jdata['headers'] |
49 | + |
50 | + # x,y: current coordinates |
51 | + # carry: queue containing cell information when a cell has a >= 2 height |
52 | + # and the drawing code needs to add empty cells below |
53 | + x, y, carry = 1, 0, deque() |
54 | + for i, header_row in enumerate(headers): |
55 | + worksheet.write(i,0, '', header_plain) |
56 | + for header in header_row: |
57 | + while (carry and carry[0]['x'] == x): |
58 | + cell = carry.popleft() |
59 | + for i in range(nbr_measures): |
60 | + worksheet.write(y, x+i, '', header_plain) |
61 | + if cell['height'] > 1: |
62 | + carry.append({'x': x, 'height':cell['height'] - 1}) |
63 | + x = x + nbr_measures |
64 | + style = header_plain if 'expanded' in header else header_bold |
65 | + for i in range(header['width']): |
66 | + worksheet.write(y, x + i, header['title'] if i == 0 else '', style) |
67 | + if header['height'] > 1: |
68 | + carry.append({'x': x, 'height':header['height'] - 1}) |
69 | + x = x + header['width']; |
70 | + while (carry and carry[0]['x'] == x): |
71 | + cell = carry.popleft() |
72 | + for i in range(nbr_measures): |
73 | + worksheet.write(y, x+i, '', header_plain) |
74 | + if cell['height'] > 1: |
75 | + carry.append({'x': x, 'height':cell['height'] - 1}) |
76 | + x = x + nbr_measures |
77 | + x, y = 1, y + 1 |
78 | + |
79 | + # Step 2: measure row |
80 | + if nbr_measures > 1: |
81 | + worksheet.write(y,0, '', header_plain) |
82 | + for measure in jdata['measure_row']: |
83 | + style = header_bold if measure['is_bold'] else header_plain |
84 | + worksheet.write(y, x, measure['text'], style); |
85 | + x = x + 1 |
86 | + y = y + 1 |
87 | + |
88 | + # Step 3: writing data |
89 | + x = 0 |
90 | + for row in jdata['rows']: |
91 | + worksheet.write(y, x, row['indent'] * ' ' + row['title'], header_plain) |
92 | + for cell in row['cells']: |
93 | + x = x + 1 |
94 | + if cell.get('is_bold', False): |
95 | + worksheet.write(y, x, cell['value'], bold) |
96 | + else: |
97 | + worksheet.write(y, x, cell['value']) |
98 | + x, y = 0, y + 1 |
99 | + |
100 | + response = request.make_response(None, |
101 | + headers=[('Content-Type', 'application/vnd.ms-excel'), |
102 | + ('Content-Disposition', 'attachment; filename=table.xls;')], |
103 | + cookies={'fileToken': token}) |
104 | + workbook.save(response.stream) |
105 | + |
106 | + return response |
107 | |
108 | === modified file 'addons/web_graph/static/src/js/graph_widget.js' |
109 | --- addons/web_graph/static/src/js/graph_widget.js 2014-01-28 15:11:13 +0000 |
110 | +++ addons/web_graph/static/src/js/graph_widget.js 2014-02-05 13:14:23 +0000 |
111 | @@ -25,6 +25,7 @@ |
112 | this.bar_ui = options.bar_ui || 'group'; |
113 | this.graph_view = options.graph_view || null; |
114 | this.pivot_options = options; |
115 | + this.title = options.title || 'Data'; |
116 | }, |
117 | |
118 | start: function() { |
119 | @@ -39,6 +40,10 @@ |
120 | this.$('.graph_heatmap label').addClass('disabled'); |
121 | } |
122 | |
123 | + openerp.session.rpc('/web_graph/check_xlwt').then(function (result) { |
124 | + self.$('.graph_options_selection label').toggle(result); |
125 | + }); |
126 | + |
127 | return this.model.call('fields_get', []).then(function (f) { |
128 | self.fields = f; |
129 | self.fields.__count = {field:'__count', type: 'integer', string:_t('Quantity')}; |
130 | @@ -85,8 +90,8 @@ |
131 | groupbys = _.flatten(_.map(filters, function (filter) { |
132 | var groupby = py.eval(filter.attrs.context).group_by; |
133 | if (!(groupby instanceof Array)) { groupby = [groupby]; } |
134 | - return _.map(groupby, function(g) { |
135 | - return {field: g, filter: filter}; |
136 | + return _.map(groupby, function(g) { |
137 | + return {field: g, filter: filter}; |
138 | }); |
139 | })); |
140 | |
141 | @@ -264,6 +269,9 @@ |
142 | case 'update_values': |
143 | this.pivot.update_data().then(this.proxy('display_data')); |
144 | break; |
145 | + case 'export_data': |
146 | + this.export_xls(); |
147 | + break; |
148 | } |
149 | }, |
150 | |
151 | @@ -356,13 +364,117 @@ |
152 | }, |
153 | |
154 | // ---------------------------------------------------------------------- |
155 | + // Convert Pivot data structure into table structure : |
156 | + // compute rows, cols, colors, cell width, cell height, ... |
157 | + // ---------------------------------------------------------------------- |
158 | + build_table: function() { |
159 | + return { |
160 | + headers: this.build_headers(), |
161 | + measure_row: this.build_measure_row(), |
162 | + rows: this.build_rows(), |
163 | + nbr_measures: this.pivot.measures.length, |
164 | + title: this.title, |
165 | + }; |
166 | + }, |
167 | + |
168 | + build_headers: function () { |
169 | + var pivot = this.pivot, |
170 | + nbr_measures = pivot.measures.length, |
171 | + height = _.max(_.map(pivot.cols.headers, function(g) {return g.path.length;})), |
172 | + rows = []; |
173 | + |
174 | + _.each(pivot.cols.headers, function (col) { |
175 | + if (col.path.length === 0) { return;} |
176 | + var cell_width = nbr_measures * (col.expanded ? pivot.get_ancestor_leaves(col).length : 1), |
177 | + cell_height = col.expanded ? 1 : height - col.path.length + 1, |
178 | + cell = {width: cell_width, height: cell_height, title: col.title, id: col.id, expanded: col.expanded}; |
179 | + if (rows[col.path.length - 1]) { |
180 | + rows[col.path.length - 1].push(cell); |
181 | + } else { |
182 | + rows[col.path.length - 1] = [cell]; |
183 | + } |
184 | + }); |
185 | + |
186 | + if (pivot.get_cols_leaves().length > 1) { |
187 | + rows[0].push({width: nbr_measures, height: height, title: _t('Total'), id: pivot.main_col().id }); |
188 | + } |
189 | + if (pivot.cols.headers.length === 1) { |
190 | + rows = [[{width: nbr_measures, height: 1, title: _t('Total'), id: pivot.main_col().id, expanded: false}]]; |
191 | + } |
192 | + return rows; |
193 | + }, |
194 | + |
195 | + build_measure_row: function () { |
196 | + var nbr_leaves = this.pivot.get_cols_leaves().length, |
197 | + nbr_cols = nbr_leaves + ((nbr_leaves > 1) ? 1 : 0), |
198 | + result = [], |
199 | + add_total = this.pivot.get_cols_leaves().length > 1, |
200 | + i, m; |
201 | + for (i = 0; i < nbr_cols; i++) { |
202 | + for (m = 0; m < this.pivot.measures.length; m++) { |
203 | + result.push({ |
204 | + text:this.pivot.measures[m].string, |
205 | + is_bold: add_total && (i === nbr_cols - 1) |
206 | + }); |
207 | + } |
208 | + } |
209 | + return result; |
210 | + }, |
211 | + |
212 | + make_cell: function (row, col, value, index) { |
213 | + var formatted_value = openerp.web.format_value(value, {type:this.pivot.measures[index].type}), |
214 | + cell = {value:formatted_value}; |
215 | + |
216 | + if (this.heatmap_mode === 'none') { return cell; } |
217 | + var total = (this.heatmap_mode === 'both') ? this.pivot.get_total()[index] |
218 | + : (this.heatmap_mode === 'row') ? this.pivot.get_total(row)[index] |
219 | + : this.pivot.get_total(col)[index]; |
220 | + var color = Math.floor(90 + 165*(total - Math.abs(value))/total); |
221 | + if (color < 255) { |
222 | + cell.color = color; |
223 | + } |
224 | + return cell; |
225 | + }, |
226 | + |
227 | + build_rows: function () { |
228 | + var self = this, |
229 | + pivot = this.pivot, |
230 | + m, cell; |
231 | + |
232 | + return _.map(pivot.rows.headers, function (row) { |
233 | + var cells = []; |
234 | + _.each(pivot.get_cols_leaves(), function (col) { |
235 | + var values = pivot.get_values(row.id,col.id); |
236 | + for (m = 0; m < pivot.measures.length; m++) { |
237 | + cells.push(self.make_cell(row,col,values[m], m)); |
238 | + } |
239 | + }); |
240 | + if (pivot.get_cols_leaves().length > 1) { |
241 | + var totals = pivot.get_total(row); |
242 | + for (m = 0; m < pivot.measures.length; m++) { |
243 | + cell = self.make_cell(row, pivot.main_col(), totals[m], m); |
244 | + cell.is_bold = 'true'; |
245 | + cells.push(cell); |
246 | + } |
247 | + } |
248 | + return { |
249 | + id: row.id, |
250 | + indent: row.path.length, |
251 | + title: row.title, |
252 | + expanded: row.expanded, |
253 | + cells: cells, |
254 | + }; |
255 | + }); |
256 | + }, |
257 | + |
258 | + // ---------------------------------------------------------------------- |
259 | // Main display method |
260 | // ---------------------------------------------------------------------- |
261 | display_data: function () { |
262 | this.$('.graph_main_content svg').remove(); |
263 | this.$('.graph_main_content div').remove(); |
264 | this.table.empty(); |
265 | - this.table.toggleClass('heatmap', this.heatmap_mode !== 'none') |
266 | + this.table.toggleClass('heatmap', this.heatmap_mode !== 'none'); |
267 | this.width = this.$el.width(); |
268 | this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); |
269 | |
270 | @@ -384,159 +496,75 @@ |
271 | // Drawing the table |
272 | // ---------------------------------------------------------------------- |
273 | draw_table: function () { |
274 | - this.draw_top_headers(); |
275 | - _.each(this.pivot.rows.headers, this.proxy('draw_row')); |
276 | - }, |
277 | - |
278 | - make_border_cell: function (colspan, rowspan, headercell) { |
279 | - var tag = (headercell) ? $('<th>') : $('<td>'); |
280 | - return tag.addClass('graph_border') |
281 | - .attr('colspan', colspan || 1) |
282 | - .attr('rowspan', rowspan || 1); |
283 | - }, |
284 | - |
285 | - make_header_title: function (header) { |
286 | - return $('<span> ') |
287 | - .addClass('web_graph_click') |
288 | - .attr('href', '#') |
289 | - .addClass((header.expanded) ? 'fa fa-minus-square' : 'fa fa-plus-square') |
290 | - .text(' ' + (header.title || 'Undefined')); |
291 | - }, |
292 | - |
293 | - draw_top_headers: function () { |
294 | - var self = this, |
295 | - thead = $('<thead>'), |
296 | - pivot = this.pivot, |
297 | - height = _.max(_.map(pivot.cols.headers, function(g) {return g.path.length;})), |
298 | - header_cells = [[this.make_border_cell(1, height, true)]]; |
299 | - |
300 | - function set_dim (cols) { |
301 | - _.each(cols.children, set_dim); |
302 | - if (cols.children.length === 0) { |
303 | - cols.height = height - cols.path.length + 1; |
304 | - cols.width = 1; |
305 | - } else { |
306 | - cols.height = 1; |
307 | - cols.width = _.reduce(cols.children, function (sum,c) { return sum + c.width;}, 0); |
308 | - } |
309 | - } |
310 | - |
311 | - function make_col_header (col) { |
312 | - var cell = self.make_border_cell(col.width*pivot.measures.length, col.height, true); |
313 | - return cell.append(self.make_header_title(col).attr('data-id', col.id)); |
314 | - } |
315 | - |
316 | - function make_cells (queue, level) { |
317 | - var col = queue[0]; |
318 | - queue = _.rest(queue).concat(col.children); |
319 | - if (col.path.length == level) { |
320 | - _.last(header_cells).push(make_col_header(col)); |
321 | - } else { |
322 | - level +=1; |
323 | - header_cells.push([make_col_header(col)]); |
324 | - } |
325 | - if (queue.length !== 0) { |
326 | - make_cells(queue, level); |
327 | - } |
328 | - } |
329 | - |
330 | - set_dim(pivot.main_col()); // add width and height info to columns headers |
331 | - if (pivot.main_col().children.length === 0) { |
332 | - make_cells(pivot.cols.headers, 0); |
333 | + var table = this.build_table(); |
334 | + this.draw_headers(table.headers); |
335 | + this.draw_measure_row(table.measure_row); |
336 | + this.draw_rows(table.rows); |
337 | + }, |
338 | + |
339 | + make_header_cell: function (header) { |
340 | + var cell = (_.has(header, 'cells') ? $('<td>') : $('<th>')) |
341 | + .addClass('graph_border') |
342 | + .attr('rowspan', header.height) |
343 | + .attr('colspan', header.width); |
344 | + var content = $('<span>').addClass('web_graph_click') |
345 | + .attr('href','#') |
346 | + .text(' ' + (header.title || _t('Undefined'))) |
347 | + .attr('data-id', header.id); |
348 | + if (_.has(header, 'expanded')) { |
349 | + content.addClass(header.expanded ? 'fa fa-minus-square' : 'fa fa-plus-square'); |
350 | } else { |
351 | - make_cells(pivot.main_col().children, 1); |
352 | - if (pivot.get_cols_leaves().length > 1) { |
353 | - header_cells[0].push(self.make_border_cell(pivot.measures.length, height, true).text(_t('Total')).css('font-weight', 'bold')); |
354 | - } |
355 | - } |
356 | - |
357 | - _.each(header_cells, function (cells) { |
358 | - thead.append($('<tr>').append(cells)); |
359 | - }); |
360 | - |
361 | - if (pivot.measures.length >= 2) { |
362 | - thead.append(self.make_measure_row()); |
363 | - } |
364 | - |
365 | - self.table.append(thead); |
366 | - }, |
367 | - |
368 | - make_measure_cells: function () { |
369 | - return _.map(this.pivot.measures, function (measure) { |
370 | - return $('<th>').addClass('measure_row').text(measure.string); |
371 | - }); |
372 | - }, |
373 | - |
374 | - make_measure_row: function() { |
375 | - var self = this, |
376 | - cols = this.pivot.cols.headers, |
377 | - measure_row = $('<tr>'); |
378 | - |
379 | - measure_row.append($('<th>')); |
380 | - |
381 | - _.each(cols, function (col) { |
382 | - if (!col.children.length) { |
383 | - measure_row.append(self.make_measure_cells()); |
384 | - } |
385 | - }); |
386 | - |
387 | - if (this.pivot.get_cols_leaves().length > 1) { |
388 | - measure_row.append(self.make_measure_cells()); |
389 | - } |
390 | - return measure_row; |
391 | - }, |
392 | - |
393 | - draw_row: function (row) { |
394 | - var self = this, |
395 | - pivot = this.pivot, |
396 | - measure_types = _.pluck(this.pivot.measures, 'type'), |
397 | - html_row = $('<tr>'), |
398 | - row_header = this.make_border_cell(1,1) |
399 | - .append(this.make_header_title(row).attr('data-id', row.id)) |
400 | - .addClass('graph_border'); |
401 | - |
402 | - for (var i = 0; i < row.path.length; i++) { |
403 | - row_header.prepend($('<span>', {class:'web_graph_indent'})); |
404 | - } |
405 | - |
406 | - html_row.append(row_header); |
407 | - |
408 | - _.each(pivot.cols.headers, function (col) { |
409 | - if (!col.children.length) { |
410 | - var values = pivot.get_values(row.id, col.id); |
411 | - for (var i = 0; i < values.length; i++) { |
412 | - html_row.append(make_cell(values[i], measure_types[i], i, col)); |
413 | + content.css('font-weight', 'bold'); |
414 | + } |
415 | + if (_.has(header, 'indent')) { |
416 | + for (var i = 0; i < header.indent; i++) { cell.prepend($('<span>', {class:'web_graph_indent'})); } |
417 | + } |
418 | + return cell.append(content); |
419 | + }, |
420 | + |
421 | + draw_headers: function (headers) { |
422 | + var make_cell = this.make_header_cell, |
423 | + empty_cell = $('<th>').attr('rowspan', headers.length), |
424 | + thead = $('<thead>'); |
425 | + |
426 | + _.each(headers, function (row) { |
427 | + var html_row = $('<tr>'); |
428 | + _.each(row, function (header) { |
429 | + html_row.append(make_cell(header)); |
430 | + }); |
431 | + thead.append(html_row); |
432 | + }); |
433 | + thead.children(':first').prepend(empty_cell); |
434 | + this.table.append(thead); |
435 | + }, |
436 | + |
437 | + draw_measure_row: function (measure_row) { |
438 | + if (this.pivot.measures.length === 1) { return; } |
439 | + var html_row = $('<tr>').append('<th>'); |
440 | + _.each(measure_row, function (cell) { |
441 | + var measure_cell = $('<th>').addClass('measure_row').text(cell.text); |
442 | + if (cell.is_bold) {measure_cell.css('font-weight', 'bold');} |
443 | + html_row.append(measure_cell); |
444 | + }); |
445 | + this.$('thead').append(html_row); |
446 | + }, |
447 | + |
448 | + draw_rows: function (rows) { |
449 | + var table = this.table, |
450 | + make_cell = this.make_header_cell; |
451 | + |
452 | + _.each(rows, function (row) { |
453 | + var html_row = $('<tr>').append(make_cell(row)); |
454 | + _.each(row.cells, function (cell) { |
455 | + var html_cell = $('<td>').text(cell.value); |
456 | + if (_.has(cell, 'color')) { |
457 | + html_cell.css('background-color', $.Color(255, cell.color, cell.color)); |
458 | } |
459 | - } |
460 | + if (cell.is_bold) { html_cell.css('font-weight', 'bold'); } |
461 | + html_row.append(html_cell); |
462 | + }); |
463 | + table.append(html_row); |
464 | }); |
465 | - |
466 | - if (pivot.get_cols_leaves().length > 1) { |
467 | - var total_vals = pivot.get_total(row); |
468 | - for (var j = 0; j < total_vals.length; j++) { |
469 | - var cell = make_cell(total_vals[j], measure_types[j], j, pivot.cols[0]).css('font-weight', 'bold'); |
470 | - html_row.append(cell); |
471 | - } |
472 | - } |
473 | - |
474 | - this.table.append(html_row); |
475 | - |
476 | - function make_cell (value, measure_type, index, col) { |
477 | - var cell = $('<td>'); |
478 | - if (value === undefined) { |
479 | - return cell; |
480 | - } |
481 | - cell.text(openerp.web.format_value(value, {type: measure_type})); |
482 | - var total = (self.heatmap_mode === 'both') ? pivot.get_total()[index] |
483 | - : (self.heatmap_mode === 'row') ? pivot.get_total(row)[index] |
484 | - : (self.heatmap_mode === 'col') ? pivot.get_total(col)[index] |
485 | - : undefined; |
486 | - |
487 | - if (self.heatmap_mode !== 'none') { |
488 | - var color = Math.floor(90 + 165*(total - Math.abs(value))/total); |
489 | - cell.css('background-color', $.Color(255, color, color)); |
490 | - } |
491 | - return cell; |
492 | - } |
493 | }, |
494 | |
495 | // ---------------------------------------------------------------------- |
496 | @@ -693,6 +721,20 @@ |
497 | }); |
498 | }, |
499 | |
500 | + // ---------------------------------------------------------------------- |
501 | + // Controller stuff... |
502 | + // ---------------------------------------------------------------------- |
503 | + export_xls: function() { |
504 | + var c = openerp.webclient.crashmanager; |
505 | + openerp.web.blockUI(); |
506 | + this.session.get_file({ |
507 | + url: '/web_graph/export_xls', |
508 | + data: {data: JSON.stringify(this.build_table())}, |
509 | + complete: openerp.web.unblockUI, |
510 | + error: c.rpc_error.bind(c) |
511 | + }); |
512 | + }, |
513 | + |
514 | }); |
515 | |
516 | // Utility function: returns true if the beginning of array2 is array1 and |
517 | |
518 | === modified file 'addons/web_graph/static/src/js/pivot_table.js' |
519 | --- addons/web_graph/static/src/js/pivot_table.js 2014-01-28 15:11:57 +0000 |
520 | +++ addons/web_graph/static/src/js/pivot_table.js 2014-02-05 13:14:23 +0000 |
521 | @@ -127,6 +127,10 @@ |
522 | return this._get_headers_with_depth(this.rows.headers, depth); |
523 | }, |
524 | |
525 | + get_ancestor_leaves: function (header) { |
526 | + return _.where(this.get_ancestors_and_self(header), {expanded:false}); |
527 | + }, |
528 | + |
529 | // return all non expanded rows |
530 | get_rows_leaves: function () { |
531 | return _.where(this.rows.headers, {expanded:false}); |
532 | |
533 | === modified file 'addons/web_graph/static/src/xml/web_graph.xml' |
534 | --- addons/web_graph/static/src/xml/web_graph.xml 2014-01-17 14:43:03 +0000 |
535 | +++ addons/web_graph/static/src/xml/web_graph.xml 2014-02-05 13:14:23 +0000 |
536 | @@ -41,6 +41,9 @@ |
537 | <label class="btn btn-default" data-choice="update_values" title="Reload Data"> |
538 | <span class="fa fa-refresh"></span> |
539 | </label> |
540 | + <label class="btn btn-default" data-choice="export_data" title="Export Data" style="display:none"> |
541 | + <span class="fa fa-download"></span> |
542 | + </label> |
543 | </div> |
544 | <div class="btn-group"> |
545 | <label class="btn btn-default dropdown-toggle" data-toggle="dropdown"> |
* `if (result) { self.$( '.graph_ options_ selection label') .toggle( true); }` could be replaced by `self.$ ('.graph_ options_ selection label') .toggle( result) ;` I think
* The Response object returned by make_response has a write-only `stream` attribute, so maybe (depending how complex workbook.save is) the StringIO dance could be replaced by:
response = self.make_ response( params) save(response. stream)
workbook.
return response
* maybe give a better name to the sheet e.g. the model name?
* `L` could probably benefit from comments to explain what it and its purpose are, maybe even a renaming. It seems to be used as a queue, but I'm not sure a queue of what. Also since it's a FIFO, should probably use collection.deque (.pop(0) is O(n) on a list, it's ~O(1) on deque, also it's called .popleft() which is clearer)
* in many worksheet.write() calls, there's a space missing after the first argument's comma, spacing also somewhat inconsistent in JS e.g. {width: nbr_measures, height:height, title: _t('Total'), id: pivot.cols. headers[ 0].id } some colons are followed by a space, others not
* maybe bold_style and non_bold_style should be renamed to header (or header_plain) and header_bold? Something like that? They seem to be header styles of sort (I may be wrong)