From c4d0299eca6941e4f38f86c7e8c4a3e9a5cf84a7 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 2 Apr 2014 09:43:41 +0200 Subject: [IMP] complete rewrite of the data loading code in the graph view, using the lazy/eager feature of readgroup. The code is simpler and more efficient: it only performs a fixed number of requests (well, the number is 'fixed' in the sense that it does not depend of the size of the data being displayed, but it still depends on the number of dimensions) (addon web_graph) bzr revid: ged@openerp.com-20140402074341-8cleqizqculxmkys --- addons/web_graph/static/src/js/pivot_table.js | 400 ++++++++++++-------------- 1 file changed, 179 insertions(+), 221 deletions(-) (limited to 'addons/web_graph/static/src') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index f77d49f9a1a..e8a438b3fe5 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -82,7 +82,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ get_values: function (id1, id2, default_values) { var cell = _.findWhere(this.cells, {x: Math.min(id1, id2), y: Math.max(id1, id2)}); - return (cell !== undefined) ? cell.values : (default_values || new Array(this.measures.length)); + return (cell !== undefined) ? + cell.values : + (default_values || new Array(this.measures.length)); }, // ---------------------------------------------------------------------- @@ -144,12 +146,16 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ get_ancestors: function (header) { var self = this; if (!header.children) return []; - return [].concat.apply([], _.map(header.children, function (c) {return self.get_ancestors_and_self(c); })); + return [].concat.apply([], _.map(header.children, function (c) { + return self.get_ancestors_and_self(c); + })); }, get_ancestors_and_self: function (header) { var self = this; - return [].concat.apply([header], _.map(header.children, function (c) { return self.get_ancestors_and_self(c); })); + return [].concat.apply([header], _.map(header.children, function (c) { + return self.get_ancestors_and_self(c); + })); }, get_total: function (header) { @@ -205,54 +211,28 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ expand: function (header_id, groupby) { var self = this, header = this.get_header(header_id), - otherRoot = this.get_other_root(header), - fields = otherRoot.groupby.concat(this.measures); + other_root = this.get_other_root(header), + this_gb = [groupby.field], + other_gbs = _.pluck(other_root.groupby, 'field'); if (header.path.length === header.root.groupby.length) { header.root.groupby.push(groupby); } - groupby = [groupby].concat(otherRoot.groupby); - - return this.get_groups(groupby, fields, header.domain).then(function (groups) { - _.each(groups.reverse(), function (group) { - // make header - var child = self.make_header(group, header); - child.expanded = false; - header.children.splice(0,0, child); - header.root.headers.splice(header.root.headers.indexOf(header) + 1, 0, child); - // make cells - _.each(self.get_ancestors_and_self(group), function (data) { - var values = _.map(self.measures, function (m) { - return data.attributes.aggregates[m.field]; - }); - var other = _.find(otherRoot.headers, function (h) { - if (header.root === self.cols) { - return _.isEqual(data.path.slice(1), h.path); - } else { - return _.isEqual(_.rest(data.path), h.path); - } - }); - if (other) { - self.add_cell(child.id, other.id, values); - } - }); + return this.perform_requests(this_gb, other_gbs, header.domain).then(function () { + var data = Array.prototype.slice.call(arguments); + data = data.slice(other_gbs.length + 1, data.length); + _.each(data, function (data_pt) { + self.make_headers_and_cell( + data_pt, header.root.headers, other_root.headers, 1, header.path); }); header.expanded = true; + header.children.forEach(function (child) { + child.expanded = false; + child.root = header.root; + }); }); }, - make_header: function (group, parent) { - var title = parent ? group.attributes.value : _t('Total'); - return { - id: _.uniqueId(), - path: parent ? parent.path.concat(title) : [], - title: title, - children: [], - domain: parent ? group.model._domain : this.domain, - root: parent ? parent.root : undefined, - }; - }, - swap_axis: function () { var temp = this.rows; this.rows = this.cols; @@ -262,206 +242,184 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ // ---------------------------------------------------------------------- // Data updating methods // ---------------------------------------------------------------------- - // Load the data from the db, using the method this.load_data // update_data will try to preserve the expand/not expanded status of each // column/row. If you want to expand all, then set this.cols.headers/this.rows.headers // to null before calling update_data. - update_data: function () { - var self = this; - - return this.load_data().then (function (result) { - if (result) { - self.no_data = false; - self[self.cols.headers ? 'update_headers' : 'expand_headers'](self.cols, result.col_headers); - self[self.rows.headers ? 'update_headers' : 'expand_headers'](self.rows, result.row_headers); - } else { - self.no_data = true; - } - }); - }, - - expand_headers: function (root, new_headers) { - root.headers = new_headers; - _.each(root.headers, function (header) { - header.root = root; - header.expanded = (header.children.length > 0); - }); - }, + update_data: function () { + var self = this; + return this.perform_requests().then (function () { + var data = Array.prototype.slice.call(arguments); + self.no_data = !data[0][0].attributes.length; + if (self.no_data) { + return; + } + var row_headers = [], + col_headers = []; + self.cells = []; + + var dim_col = self.cols.groupby.length, + i, j, index; + + for (i = 0; i < self.rows.groupby.length + 1; i++) { + for (j = 0; j < dim_col + 1; j++) { + index = i*(dim_col + 1) + j; + self.make_headers_and_cell(data[index], row_headers, col_headers, i); + } + } + self.set_headers(row_headers, self.rows); + self.set_headers(col_headers, self.cols); + }); + }, - update_headers: function (root, new_headers) { - _.each(root.headers, function (header) { - var corresponding_header = _.find(new_headers, function (h) { - return _.isEqual(h.path, header.path); - }); - if (corresponding_header && header.expanded) { - corresponding_header.expanded = true; - _.each(corresponding_header.children, function (c) { - c.expanded = false; - }); - } - if (corresponding_header && (!header.expanded)) { - corresponding_header.expanded = false; - } - }); - var updated_headers = _.filter(new_headers, function (header) { - return (header.expanded !== undefined); - }); - _.each(updated_headers, function (header) { - if (!header.expanded) { - header.children = []; - } - header.root = root; - }); - root.headers = updated_headers; - }, + make_headers_and_cell: function (data_pts, row_headers, col_headers, index, prefix) { + var self = this; + data_pts.forEach(function (data_pt) { + var row_value = (prefix || []).concat(data_pt.attributes.value.slice(0,index)); + var col_value = data_pt.attributes.value.slice(index); + + var row = self.find_or_create_header(row_headers, row_value, data_pt); + var col = self.find_or_create_header(col_headers, col_value, data_pt); + + var cell_value = _.map(self.measures, function (m) { + return data_pt.attributes.aggregates[m.field]; + }); + self.cells.push({ + x: Math.min(row.id, col.id), + y: Math.max(row.id, col.id), + values: cell_value + }); + }); + }, - // ---------------------------------------------------------------------- - // Data loading methods - // ---------------------------------------------------------------------- - - // To obtain all the values required to draw the full table, we have to do - // at least 2 + min(row.groupby.length, col.groupby.length) - // calls to readgroup. To simplify the code, we will always do - // 2 + row.groupby.length calls. For example, if row.groupby = [r1, r2, r3] - // and col.groupby = [c1, c2], then we will make the call with the following - // groupbys: [r1,r2,r3], [c1,r1,r2,r3], [c1,c2,r1,r2,r3], []. - load_data: function () { - var self = this, - cols = this.cols.groupby, - rows = this.rows.groupby, - visible_fields = rows.concat(cols, self.measures); + make_header: function (values) { + return _.extend({ + children: [], + domain: this.domain, + expanded: undefined, + id: _.uniqueId(), + path: [], + root: undefined, + title: undefined + }, values || {}); + }, - if (this.measures.length === 0) { - return $.Deferred.resolve().promise(); + find_or_create_header: function (headers, path, data_pt) { + var hdr = _.find(headers, function (header) { + return _.isEqual(path, header.path); + }); + if (hdr) { + return hdr; } - - var groupbys = _.map(_.range(cols.length + 1), function (i) { - return cols.slice(0, i).concat(rows); + if (!path.length) { + hdr = this.make_header({title: _t('Total')}); + headers.push(hdr); + return hdr; + } + hdr = this.make_header({ + path:path, + domain:data_pt.model._domain, + title: _t(_.last(path)) }); - groupbys.push([]); - - var get_data_requests = _.map(groupbys, function (groupby) { - return self.get_groups(groupby, visible_fields, self.domain); + parent = _.find(headers, function (header) { + return _.isEqual(header.path, _.initial(path, 1)); }); - return $.when.apply(null, get_data_requests).then(function () { - var data = Array.prototype.slice.call(arguments), - row_data = data[0], - col_data = (cols.length !== 0) ? data[data.length - 2] : [], - has_data = data[data.length - 1][0]; - - return has_data && self.format_data(col_data, row_data, data); - }); + var previous = parent.children.length ? _.last(parent.children) : parent; + headers.splice(headers.indexOf(previous) + 1, 0, hdr); + parent.children.push(hdr); + return hdr; }, - get_groups: function (groupbys, fields, domain, path) { - var self = this, - groupby = (groupbys.length) ? groupbys[0] : []; - path = path || []; - - return this._query_db(groupby, fields, domain, path).then(function (groups) { - if (groupbys.length > 1) { - var get_subgroups = $.when.apply(null, _.map(groups, function (group) { - return self.get_groups(_.rest(groupbys), fields, group.model._domain, path.concat(group.attributes.value)).then(function (subgroups) { - group.children = subgroups; - }); - })); - return get_subgroups.then(function () { - return groups; - }); - } else { - return groups; + perform_requests: function (group1, group2, domain) { + var self = this, + requests = [], + row_gbs = _.pluck(this.rows.groupby, 'field'), + col_gbs = _.pluck(this.cols.groupby, 'field'), + field_list = row_gbs.concat(col_gbs, _.pluck(this.measures, 'field')), + fields = field_list.map(function (f) { return self.raw_field(f); }); + + group1 = group1 || row_gbs; + group2 = group2 || col_gbs; + + var i,j, groupbys; + for (i = 0; i < group1.length + 1; i++) { + for (j = 0; j < group2.length + 1; j++) { + groupbys = group1.slice(0,i).concat(group2.slice(0,j)); + requests.push(self.get_groups(groupbys, fields, domain || self.domain)); } - }); + } + return $.when.apply(null, requests); + }, - }, + // set the 'expanded' status of new_headers more or less like root.headers, with root as root + set_headers: function(new_headers, root) { + if (root.headers) { + _.each(root.headers, function (header) { + var corresponding_header = _.find(new_headers, function (h) { + return _.isEqual(h.path, header.path); + }); + if (corresponding_header && header.expanded) { + corresponding_header.expanded = true; + _.each(corresponding_header.children, function (c) { + c.expanded = false; + }); + } + if (corresponding_header && (!header.expanded)) { + corresponding_header.expanded = false; + } + }); + var updated_headers = _.filter(new_headers, function (header) { + return (header.expanded !== undefined); + }); + _.each(updated_headers, function (header) { + header.root = root; + }); + root.headers = updated_headers; + } else { + root.headers = new_headers; + _.each(root.headers, function (header) { + header.root = root; + header.expanded = (header.children.length > 0); + }); + } + return new_headers; + }, - _query_db: function (groupby, fields, domain, path) { - var self = this, - field_ids = _.without(_.pluck(fields, 'field'), '__count'), - fields = _.map(field_ids, function(f) { return self.raw_field(f); }); - - return this.model.query(field_ids) - .filter(domain) - .group_by(groupby.field) - .then(function (results) { - var groups = _.filter(results, function (group) { - return group.attributes.length > 0; - }); - return _.map(groups, function (g) { return self.format_group(g, path); }); - }); - }, + get_groups: function (groupbys, fields, domain) { + var self = this; + return this.model.query(_.without(fields, '__count')) + .filter(domain) + .lazy(false) + .group_by(groupbys) + .then(function (groups) { + return groups.map(function (group) { + var attrs = group.attributes, + grouped_on = attrs.grouped_on instanceof Array + ? attrs.grouped_on : [attrs.grouped_on], + raw_grouped_on = grouped_on.map(function (f) { + return self.raw_field(f); + }); + if (grouped_on.length === 1) { attrs.value = [attrs.value]} + attrs.value = _.range(grouped_on.length).map(function (i) { + if (attrs.value[i] === false) { + return _t('Undefined'); + } else if (attrs.value[i] instanceof Array) { + return attrs.value[i][1]; + } + return attrs.value[i] + }); + attrs.aggregates.__count = group.attributes.length; + attrs.grouped_on = raw_grouped_on; + return group; + }); + }); + }, // if field is a fieldname, returns field, if field is field_id:interval, retuns field_id raw_field: function (field) { return field.split(':')[0]; }, - // add the path to the group and sanitize the value... - format_group: function (group, current_path) { - var attrs = group.attributes, - value = attrs.value, - grouped_on = attrs.grouped_on ? this.raw_field(attrs.grouped_on) : false; - - if (value === false) { - group.attributes.value = _t('Undefined'); - } else if (grouped_on && this.fields[grouped_on].type === 'selection') { - var selection = this.fields[grouped_on].selection, - value_lookup = _.where(selection, {0:value}); - group.attributes.value = value_lookup ? value_lookup[0][1] : _t('Undefined'); - } else if (value instanceof Array) { - group.attributes.value = value[1]; - } - - group.path = (value !== undefined) ? (current_path || []).concat(group.attributes.value) : []; - group.attributes.aggregates.__count = group.attributes.length; - - return group; - }, - - format_data: function (col_data, row_data, cell_data) { - var self = this, - dim_row = this.rows.groupby.length, - dim_col = this.cols.groupby.length, - col_headers = this.get_ancestors_and_self(this.make_headers(col_data, dim_col)), - row_headers = this.get_ancestors_and_self(this.make_headers(row_data, dim_row)); - - this.cells = []; - _.each(cell_data, function (data, index) { - self.make_cells(data, index, [], row_headers, col_headers); - }); // not pretty. make it more functional? - - return {col_headers: col_headers, row_headers: row_headers}; - }, - - make_headers: function (data, depth, parent) { - var self = this, - main = this.make_header(data, parent); - - if (main.path.length < depth) { - main.children = _.map(data.children || data, function (data_pt) { - return self.make_headers (data_pt, depth, main); - }); - } - return main; - }, - - make_cells: function (data, index, current_path, rows, cols) { - var self = this; - _.each(data, function (group) { - var attr = group.attributes, - path = attr.grouped_on ? current_path.concat(attr.value) : current_path, - values = _.map(self.measures, function (measure) { return attr.aggregates[measure.field]; }), - row = _.find(rows, function (header) { return _.isEqual(header.path, path.slice(index)); }), - col = _.find(cols, function (header) { return _.isEqual(header.path, path.slice(0, index)); }); - - self.add_cell(row.id, col.id, values); - if (group.children) { - self.make_cells (group.children, index, path, rows, cols); - } - }); - }, - }); })(); -- cgit v1.2.3 From c138b778df3055dad9e1add03deaf5b519e7581f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 2 Apr 2014 13:47:58 +0200 Subject: [FIX] correctly filters out empty groups in read_group results in the data loading code of graph view (addon web_graph) bzr revid: ged@openerp.com-20140402114758-8qfdz8j76t2p2juo --- addons/web_graph/static/src/js/pivot_table.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index e8a438b3fe5..824b41a6b25 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -392,7 +392,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ .lazy(false) .group_by(groupbys) .then(function (groups) { - return groups.map(function (group) { + return groups.filter(function (group) { + return group.attributes.length > 0; + }).map(function (group) { var attrs = group.attributes, grouped_on = attrs.grouped_on instanceof Array ? attrs.grouped_on : [attrs.grouped_on], -- cgit v1.2.3 From 729cd2ce023d8919aa1b250a4b51bf416cc12117 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 2 Apr 2014 17:08:17 +0200 Subject: [FIX] correct the expand functionality to avoid creating rows/cols in the other dimension of an unfolding action (addon web_graph) bzr revid: ged@openerp.com-20140402150817-5s8drvhbznxq0hh9 --- addons/web_graph/static/src/js/pivot_table.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 824b41a6b25..9231765c485 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -223,7 +223,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ data = data.slice(other_gbs.length + 1, data.length); _.each(data, function (data_pt) { self.make_headers_and_cell( - data_pt, header.root.headers, other_root.headers, 1, header.path); + data_pt, header.root.headers, other_root.headers, 1, header.path, true); }); header.expanded = true; header.children.forEach(function (child) { @@ -271,12 +271,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, - make_headers_and_cell: function (data_pts, row_headers, col_headers, index, prefix) { + make_headers_and_cell: function (data_pts, row_headers, col_headers, index, prefix, expand) { var self = this; data_pts.forEach(function (data_pt) { var row_value = (prefix || []).concat(data_pt.attributes.value.slice(0,index)); var col_value = data_pt.attributes.value.slice(index); + if (expand && !_.find(col_headers, function (hdr) {return _.isEqual(col_value, hdr.path);})) { + return; + } var row = self.find_or_create_header(row_headers, row_value, data_pt); var col = self.find_or_create_header(col_headers, col_value, data_pt); -- cgit v1.2.3 From 0d4732b5c4194c7c25a13266dfdd1aed05e534eb Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 3 Apr 2014 11:40:50 +0200 Subject: [FIX] makes sure the internal data structure of pivot table is correct after update_data (the children were not correct when the tree of headers was not full, after an expand for example (addon web_graph) bzr revid: ged@openerp.com-20140403094050-vjeq4dks86mejuub --- addons/web_graph/static/src/js/pivot_table.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 9231765c485..309bb103fa8 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -219,8 +219,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ header.root.groupby.push(groupby); } return this.perform_requests(this_gb, other_gbs, header.domain).then(function () { - var data = Array.prototype.slice.call(arguments); - data = data.slice(other_gbs.length + 1, data.length); + var data = Array.prototype.slice.call(arguments).slice(other_gbs.length + 1); _.each(data, function (data_pt) { self.make_headers_and_cell( data_pt, header.root.headers, other_root.headers, 1, header.path, true); @@ -369,6 +368,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } if (corresponding_header && (!header.expanded)) { corresponding_header.expanded = false; + corresponding_header.children = []; } }); var updated_headers = _.filter(new_headers, function (header) { -- cgit v1.2.3 From 4d797222279e361bfe6db0fe45f3ff503b87c717 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 4 Apr 2014 16:30:09 +0200 Subject: [FIX] add missing semicolons, add a missing 'var' statement and remove trailing whitespace (addon web_graph) bzr revid: ged@openerp.com-20140404143009-6uk7607bv4acbg4b --- addons/web_graph/static/src/js/pivot_table.js | 35 ++++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'addons/web_graph/static/src') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 309bb103fa8..d0867ca6d1a 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -278,26 +278,26 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ if (expand && !_.find(col_headers, function (hdr) {return _.isEqual(col_value, hdr.path);})) { return; - } + } var row = self.find_or_create_header(row_headers, row_value, data_pt); var col = self.find_or_create_header(col_headers, col_value, data_pt); - var cell_value = _.map(self.measures, function (m) { + var cell_value = _.map(self.measures, function (m) { return data_pt.attributes.aggregates[m.field]; }); self.cells.push({ - x: Math.min(row.id, col.id), - y: Math.max(row.id, col.id), + x: Math.min(row.id, col.id), + y: Math.max(row.id, col.id), values: cell_value - }); + }); }); }, make_header: function (values) { return _.extend({ - children: [], - domain: this.domain, - expanded: undefined, + children: [], + domain: this.domain, + expanded: undefined, id: _.uniqueId(), path: [], root: undefined, @@ -306,7 +306,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, find_or_create_header: function (headers, path, data_pt) { - var hdr = _.find(headers, function (header) { + var hdr = _.find(headers, function (header) { return _.isEqual(path, header.path); }); if (hdr) { @@ -318,11 +318,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return hdr; } hdr = this.make_header({ - path:path, + path:path, domain:data_pt.model._domain, title: _t(_.last(path)) }); - parent = _.find(headers, function (header) { + var parent = _.find(headers, function (header) { return _.isEqual(header.path, _.initial(path, 1)); }); @@ -399,26 +399,27 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return group.attributes.length > 0; }).map(function (group) { var attrs = group.attributes, - grouped_on = attrs.grouped_on instanceof Array - ? attrs.grouped_on : [attrs.grouped_on], + grouped_on = attrs.grouped_on instanceof Array ? attrs.grouped_on : [attrs.grouped_on], raw_grouped_on = grouped_on.map(function (f) { return self.raw_field(f); }); - if (grouped_on.length === 1) { attrs.value = [attrs.value]} + if (grouped_on.length === 1) { + attrs.value = [attrs.value]; + } attrs.value = _.range(grouped_on.length).map(function (i) { - if (attrs.value[i] === false) { + if (attrs.value[i] === false) { return _t('Undefined'); } else if (attrs.value[i] instanceof Array) { return attrs.value[i][1]; } - return attrs.value[i] + return attrs.value[i]; }); attrs.aggregates.__count = group.attributes.length; attrs.grouped_on = raw_grouped_on; return group; }); }); - }, + }, // if field is a fieldname, returns field, if field is field_id:interval, retuns field_id raw_field: function (field) { -- cgit v1.2.3 From 1330bb615e7f42a130b578f0ab79be7c0fa1765e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 9 Apr 2014 11:39:20 +0200 Subject: [IMP] massive optimization of the graph view code: more efficient access to values and smarter code to avoid reading uselessly many cells (graph view in web_graph) bzr revid: ged@openerp.com-20140409093920-xqls2o6j6tocgf6l --- addons/web_graph/static/src/js/graph_widget.js | 17 +++++++++++++++-- addons/web_graph/static/src/js/pivot_table.js | 13 +++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) (limited to 'addons/web_graph/static/src') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 3d8d8fa2d98..317ea6cbfb9 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -453,12 +453,25 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ build_rows: function (raw) { var self = this, pivot = this.pivot, - m, cell; + m, i, cell; return _.map(pivot.rows.headers, function (row) { var cells = []; + var pivot_cells = []; + for (i = 0; i < pivot.cells.length; i++) { + if (pivot.cells[i].x == row.id || pivot.cells[i].y == row.id) { + pivot_cells.push(pivot.cells[i]); + } + } _.each(pivot.get_cols_leaves(), function (col) { - var values = pivot.get_values(row.id,col.id); + var values; + for (i = 0; i < pivot_cells.length; i++) { + if (pivot_cells[i].x == col.id || pivot_cells[i].y == col.id) { + values = pivot_cells[i].values; + break; + } + } + if (!values) { values = new Array(pivot.measures.length);} for (m = 0; m < pivot.measures.length; m++) { cells.push(self.make_cell(row,col,values[m], m, raw)); } diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index d0867ca6d1a..d53c972a742 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -81,10 +81,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, get_values: function (id1, id2, default_values) { - var cell = _.findWhere(this.cells, {x: Math.min(id1, id2), y: Math.max(id1, id2)}); - return (cell !== undefined) ? - cell.values : - (default_values || new Array(this.measures.length)); + var cells = this.cells, + x = Math.min(id1, id2), + y = Math.max(id1, id2); + for (var i = 0; i < cells.length; i++) { + if (cells[i].x == x && cells[i].y == y) { + return cells[i].values; + } + } + return (default_values || new Array(this.measures.length)); }, // ---------------------------------------------------------------------- -- cgit v1.2.3 From 281c19a751be815f353cbda10c09ac055e5d9594 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 9 Apr 2014 14:36:28 +0200 Subject: [FIX] correctly determines when there is no data to read in graph view (instead of the good old crash) (addon web_graph) bzr revid: ged@openerp.com-20140409123628-erw8dpb2l36l7hu6 --- addons/web_graph/static/src/js/pivot_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index d53c972a742..6fc9cf2b12b 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -253,7 +253,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var self = this; return this.perform_requests().then (function () { var data = Array.prototype.slice.call(arguments); - self.no_data = !data[0][0].attributes.length; + self.no_data = !data[0].length; if (self.no_data) { return; } -- cgit v1.2.3 From f966931b879a1ed3cdc54b644c2e73456244c201 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 9 Apr 2014 16:57:35 +0200 Subject: [IMP] performance improvement: write a custom isEqual function to use instead of _.isEqual to make the code faster in graph view (isEqual was determined guilty of being slow by profiling on a large view) (addon web_graph) bzr revid: ged@openerp.com-20140409145735-m21t2fzmaepr1hsa --- addons/web_graph/static/src/js/pivot_table.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 6fc9cf2b12b..6b12829982e 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -281,7 +281,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var row_value = (prefix || []).concat(data_pt.attributes.value.slice(0,index)); var col_value = data_pt.attributes.value.slice(index); - if (expand && !_.find(col_headers, function (hdr) {return _.isEqual(col_value, hdr.path);})) { + if (expand && !_.find(col_headers, function (hdr) {return self.isEqual(col_value, hdr.path);})) { return; } var row = self.find_or_create_header(row_headers, row_value, data_pt); @@ -311,8 +311,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, find_or_create_header: function (headers, path, data_pt) { + var self = this; var hdr = _.find(headers, function (header) { - return _.isEqual(path, header.path); + return self.isEqual(path, header.path); }); if (hdr) { return hdr; @@ -328,7 +329,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ title: _t(_.last(path)) }); var parent = _.find(headers, function (header) { - return _.isEqual(header.path, _.initial(path, 1)); + return self.isEqual(header.path, _.initial(path, 1)); }); var previous = parent.children.length ? _.last(parent.children) : parent; @@ -360,10 +361,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ // set the 'expanded' status of new_headers more or less like root.headers, with root as root set_headers: function(new_headers, root) { + var self = this; if (root.headers) { _.each(root.headers, function (header) { var corresponding_header = _.find(new_headers, function (h) { - return _.isEqual(h.path, header.path); + return self.isEqual(h.path, header.path); }); if (corresponding_header && header.expanded) { corresponding_header.expanded = true; @@ -431,6 +433,16 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return field.split(':')[0]; }, + isEqual: function (path1, path2) { + if (path1.length !== path2.length) { return false; } + for (var i = 0; i < path1.length; i++) { + if (path1[i] !== path2[i]) { + return false; + } + } + return true; + }, + }); })(); -- cgit v1.2.3