diff options
| author | Gery Debongnie <ged@openerp.com> | 2014-02-04 12:31:35 +0100 |
|---|---|---|
| committer | Gery Debongnie <ged@openerp.com> | 2014-02-04 12:31:35 +0100 |
| commit | cfef03432129484f2c026f866145420f73444c4a (patch) | |
| tree | cfa91e0fda481771c2f36c0df1006f1fc81c8ba1 /addons/web_graph/static/src | |
| parent | 6ddbb1f8c6903ccafce2afba22658626e6397383 (diff) | |
[IMP] separates the pivot table drawing from the pivot table 'computing' (width, cells, colors,...). This will be useful for the export functionality : the table can be easily serialized in json (addon web_graph)
bzr revid: ged@openerp.com-20140204113135-1igakgqdxewey3aj
Diffstat (limited to 'addons/web_graph/static/src')
| -rw-r--r-- | addons/web_graph/static/src/js/graph_widget.js | 397 |
1 files changed, 162 insertions, 235 deletions
diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index b7a7a63de79..19b7b04e269 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -89,8 +89,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ groupbys = _.flatten(_.map(filters, function (filter) { var groupby = py.eval(filter.attrs.context).group_by; if (!(groupby instanceof Array)) { groupby = [groupby]; } - return _.map(groupby, function(g) { - return {field: g, filter: filter}; + return _.map(groupby, function(g) { + return {field: g, filter: filter}; }); })); @@ -363,6 +363,104 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }, // ---------------------------------------------------------------------- + // Convert Pivot data structure into table structure : + // compute rows, cols, colors, cell width, cell height, ... + // ---------------------------------------------------------------------- + build_table: function() { + return { + headers: this.build_headers(), + measure_row: this.build_measure_row(), + rows: this.build_rows(), + }; + }, + + build_headers: function () { + var pivot = this.pivot, + nbr_measures = pivot.measures.length, + height = _.max(_.map(pivot.cols.headers, function(g) {return g.path.length;})), + rows = []; + + _.each(pivot.cols.headers, function (col) { + if (col.path.length === 0) { return;} + var cell_width = nbr_measures * (col.expanded ? pivot.get_ancestor_leaves(col).length : 1), + cell_height = col.expanded ? 1 : height - col.path.length + 1, + cell = {width: cell_width, height: cell_height, title: col.title, id: col.id, expanded: col.expanded}; + if (rows[col.path.length - 1]) { + rows[col.path.length - 1].push(cell); + } else { + rows[col.path.length - 1] = [cell]; + } + }); + + if (pivot.get_cols_leaves().length > 1) { + rows[0].push({width:nbr_measures, height:height, title: _t('Total'), id: pivot.cols.headers[0].id }); + } + if (pivot.cols.headers.length === 1) { + rows = [[{width:nbr_measures, height:1, title: _t('Total'), id: pivot.cols.headers[0].id, expanded: false}]]; + } + return rows; + }, + + build_measure_row: function () { + var nbr_leaves = this.pivot.get_cols_leaves().length, + nbr_cols = nbr_leaves + ((nbr_leaves > 1) ? 1 : 0), + result = [], + add_total = this.pivot.get_cols_leaves().length > 1, + i, m; + for (i = 0; i < nbr_cols; i++) { + for (m = 0; m < this.pivot.measures.length; m++) { + result.push({ + text:this.pivot.measures[m].string, + is_bold: add_total && (i === nbr_cols - 1) + }); + } + } + return result; + }, + + add_color: function (cell, row, col, index) { + if (this.heatmap_mode === 'none') { return cell; } + var total = (this.heatmap_mode === 'both') ? this.pivot.get_total()[index] + : (this.heatmap_mode === 'row') ? this.pivot.get_total(row)[index] + : this.pivot.get_total(col)[index]; + var color = Math.floor(90 + 165*(total - Math.abs(cell.value))/total); + if (color < 255) { + cell.color = color; + } + return cell; + }, + + build_rows: function () { + var self = this, + pivot = this.pivot, + m, + add_total = pivot.get_cols_leaves().length > 1; + + return _.map(pivot.rows.headers, function (row) { + var cells = []; + _.each(pivot.get_cols_leaves(), function (col) { + var values = pivot.get_values(row.id, col.id); + for (m = 0; m < pivot.measures.length; m++) { + cells.push(self.add_color({value:values[m], type:pivot.measures[m].type}, row,col,m)); + } + }); + if (add_total) { + var totals = pivot.get_total(row); + for (m = 0; m < pivot.measures.length; m++) { + cells.push(self.add_color({value:totals[m], type:pivot.measures[m].type, is_bold:true},row,pivot.main_col(),m)); + } + } + return { + id: row.id, + indent: row.path.length, + title: row.title, + expanded: row.expanded, + cells: cells, + }; + }); + }, + + // ---------------------------------------------------------------------- // Main display method // ---------------------------------------------------------------------- display_data: function () { @@ -391,159 +489,76 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // Drawing the table // ---------------------------------------------------------------------- draw_table: function () { - this.draw_top_headers(); - _.each(this.pivot.rows.headers, this.proxy('draw_row')); - }, - - make_border_cell: function (colspan, rowspan, headercell) { - var tag = (headercell) ? $('<th>') : $('<td>'); - return tag.addClass('graph_border') - .attr('colspan', colspan || 1) - .attr('rowspan', rowspan || 1); - }, - - make_header_title: function (header) { - return $('<span> ') - .addClass('web_graph_click') - .attr('href', '#') - .addClass((header.expanded) ? 'fa fa-minus-square' : 'fa fa-plus-square') - .text(' ' + (header.title || 'Undefined')); - }, - - draw_top_headers: function () { - var self = this, - thead = $('<thead>'), - pivot = this.pivot, - height = _.max(_.map(pivot.cols.headers, function(g) {return g.path.length;})), - header_cells = [[this.make_border_cell(1, height, true)]]; - - function set_dim (cols) { - _.each(cols.children, set_dim); - if (cols.children.length === 0) { - cols.height = height - cols.path.length + 1; - cols.width = 1; - } else { - cols.height = 1; - cols.width = _.reduce(cols.children, function (sum,c) { return sum + c.width;}, 0); - } - } - - function make_col_header (col) { - var cell = self.make_border_cell(col.width*pivot.measures.length, col.height, true); - return cell.append(self.make_header_title(col).attr('data-id', col.id)); - } - - function make_cells (queue, level) { - var col = queue[0]; - queue = _.rest(queue).concat(col.children); - if (col.path.length == level) { - _.last(header_cells).push(make_col_header(col)); - } else { - level +=1; - header_cells.push([make_col_header(col)]); - } - if (queue.length !== 0) { - make_cells(queue, level); - } - } - - set_dim(pivot.main_col()); // add width and height info to columns headers - if (pivot.main_col().children.length === 0) { - make_cells(pivot.cols.headers, 0); + var table = this.build_table(); + this.draw_headers(table.headers); + this.draw_measure_row(table.measure_row); + this.draw_rows(table.rows); + }, + + make_header_cell: function (header) { + var cell = (_.has(header, 'cells') ? $('<td>') : $('<th>')) + .addClass('graph_border') + .attr('rowspan', header.height) + .attr('colspan', header.width); + var content = $('<span>').addClass('web_graph_click') + .attr('href','#') + .text(' ' + (header.title || _t('Undefined'))) + .attr('data-id', header.id); + if (_.has(header, 'expanded')) { + content.addClass(header.expanded ? 'fa fa-minus-square' : 'fa fa-plus-square'); } else { - make_cells(pivot.main_col().children, 1); - if (pivot.get_cols_leaves().length > 1) { - header_cells[0].push(self.make_border_cell(pivot.measures.length, height, true).text(_t('Total')).css('font-weight', 'bold')); - } + content.css('font-weight', 'bold'); } - - _.each(header_cells, function (cells) { - thead.append($('<tr>').append(cells)); - }); - - if (pivot.measures.length >= 2) { - thead.append(self.make_measure_row()); + if (_.has(header, 'indent')) { + for (var i = 0; i < header.indent; i++) { cell.prepend($('<span>', {class:'web_graph_indent'})); } } - - self.table.append(thead); + return cell.append(content); }, - make_measure_cells: function () { - return _.map(this.pivot.measures, function (measure) { - return $('<th>').addClass('measure_row').text(measure.string); - }); - }, - - make_measure_row: function() { - var self = this, - cols = this.pivot.cols.headers, - measure_row = $('<tr>'); + draw_headers: function (headers) { + var make_cell = this.make_header_cell, + empty_cell = $('<th>').attr('rowspan', headers.length), + thead = $('<thead>'); - measure_row.append($('<th>')); - - _.each(cols, function (col) { - if (!col.children.length) { - measure_row.append(self.make_measure_cells()); - } + _.each(headers, function (row) { + var html_row = $('<tr>'); + _.each(row, function (header) { + html_row.append(make_cell(header)); + }); + thead.append(html_row); }); - - if (this.pivot.get_cols_leaves().length > 1) { - measure_row.append(self.make_measure_cells()); - } - return measure_row; - }, - - draw_row: function (row) { - var self = this, - pivot = this.pivot, - measure_types = _.pluck(this.pivot.measures, 'type'), - html_row = $('<tr>'), - row_header = this.make_border_cell(1,1) - .append(this.make_header_title(row).attr('data-id', row.id)) - .addClass('graph_border'); - - for (var i = 0; i < row.path.length; i++) { - row_header.prepend($('<span>', {class:'web_graph_indent'})); - } - - html_row.append(row_header); - - _.each(pivot.cols.headers, function (col) { - if (!col.children.length) { - var values = pivot.get_values(row.id, col.id); - for (var i = 0; i < values.length; i++) { - html_row.append(make_cell(values[i], measure_types[i], i, col)); + thead.children(':first').prepend(empty_cell); + this.table.append(thead); + }, + + draw_measure_row: function (measure_row) { + if (this.pivot.measures.length === 1) { return; } + var html_row = $('<tr>').append('<th>'); + _.each(measure_row, function (cell) { + var measure_cell = $('<th>').addClass('measure_row').text(cell.text); + if (cell.is_bold) {measure_cell.css('font-weight', 'bold');} + html_row.append(measure_cell); + }); + this.$('thead').append(html_row); + }, + + draw_rows: function (rows) { + var table = this.table, + make_cell = this.make_header_cell; + + _.each(rows, function (row) { + var html_row = $('<tr>').append(make_cell(row)); + _.each(row.cells, function (cell) { + var value = openerp.web.format_value(cell.value, {type: cell.type}), + html_cell = $('<td>').text(value); + if (_.has(cell, 'color')) { + html_cell.css('background-color', $.Color(255, cell.color, cell.color)); } - } + if (cell.is_bold) { html_cell.css('font-weight', 'bold'); } + html_row.append(html_cell); + }); + table.append(html_row); }); - - if (pivot.get_cols_leaves().length > 1) { - var total_vals = pivot.get_total(row); - for (var j = 0; j < total_vals.length; j++) { - var cell = make_cell(total_vals[j], measure_types[j], j, pivot.cols[0]).css('font-weight', 'bold'); - html_row.append(cell); - } - } - - this.table.append(html_row); - - function make_cell (value, measure_type, index, col) { - var cell = $('<td>'); - if (value === undefined) { - return cell; - } - cell.text(openerp.web.format_value(value, {type: measure_type})); - var total = (self.heatmap_mode === 'both') ? pivot.get_total()[index] - : (self.heatmap_mode === 'row') ? pivot.get_total(row)[index] - : (self.heatmap_mode === 'col') ? pivot.get_total(col)[index] - : undefined; - - if (self.heatmap_mode !== 'none') { - var color = Math.floor(90 + 165*(total - Math.abs(value))/total); - cell.css('background-color', $.Color(255, color, color)); - } - return cell; - } }, // ---------------------------------------------------------------------- @@ -701,95 +716,10 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }, // ---------------------------------------------------------------------- - // Convert Pivot data structure into table structure - // table = {headers: [header_rows], - // measure_row: [_], - // rows: [row]} - // header_rows = [header_cells], - // header_cells = {width:_, height:_, title:_, id:_} - // rows = {id:_, indent:_, title:_, cells: [cell]} - // cell = {row_id:_, col_id:_, value:_} - // ---------------------------------------------------------------------- - build_table: function() { - return { - headers: this.build_headers(), - measure_row: this.build_measure_row(), - rows: this.build_rows() - }; - }, - - build_headers: function () { - var pivot = this.pivot, - height = _.max(_.map(pivot.cols.headers, function(g) {return g.path.length;})), - rows = []; - - _.each(pivot.cols.headers, function (col) { - if (col.path.length === 0) { return;} - var cell_width = col.expanded ? pivot.get_ancestor_leaves(col).length : 1, - cell_height = col.expanded ? 1 : height - col.path.length + 1, - cell = {width: cell_width, height: cell_height, title: col.title, id: col.id}; - if (rows[col.path.length - 1]) { - rows[col.path.length - 1].push(cell); - } else { - rows[col.path.length - 1] = [cell]; - } - }); - - if (pivot.get_cols_leaves().length > 1) { - rows[0].push({width:1, height:1, title: _t('Total'), id: pivot.cols.headers[0].id }); - } - if (pivot.cols.headers.length === 1) { - rows = [{width:1, height:1, title: _t('Total'), id: pivot.cols.headers[0].id }]; - } - return rows; - }, - - build_measure_row: function () { - var nbr_leaves = this.pivot.get_cols_leaves().length, - nbr_cols = nbr_leaves + ((nbr_leaves > 1) ? 1 : 0), - result = [], - i, m; - for (i = 0; i < nbr_cols; i++) { - for (m = 0; m < this.pivot.measures.length; m++) { - result.push(this.pivot.measures[m].string); - } - } - return result; - }, - - build_rows: function () { - var pivot = this.pivot; - var m; - var add_total = pivot.get_cols_leaves().length > 1; - - return _.map(pivot.rows.headers, function (row) { - var cells = []; - _.each(pivot.get_cols_leaves(), function (col) { - var values = pivot.get_values(row.id, col.id); - for (m = 0; m < pivot.measures.length; m++) { - cells.push({value:values[m], type:pivot.measures[m].type}) - } - }); - if (add_total) { - var totals = pivot.get_total(row); - for (m = 0; m < pivot.measures.length; m++) { - cells.push({value:totals[m], type:pivot.measures[m].type}) - } - } - return { - id: row.id, - indent: row.path.length, - title: row.title, - cells: cells - }; - }); - }, - - // ---------------------------------------------------------------------- // Controller stuff... // ---------------------------------------------------------------------- export_xls: function() { - openerp.web.blockUI(); + openerp.web.blockUI(); this.session.get_file({ url: '/web_graph/export_xls', data: {data: JSON.stringify(this.build_table())}, @@ -798,9 +728,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }); }, - - - }); // Utility function: returns true if the beginning of array2 is array1 and |
