From cd39bd968d28dcea1c14ebbf7815d752907f7d85 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 28 Sep 2011 15:52:19 +0200 Subject: [PATCH] [FIX] reimplement transformation for stacked bars In DHTMLX, stacked bars require a very different topology than clustered, essentially it requires taking clustered data and "rotating it". This implement the transformation of the series descriptors ('group_list' sequence which sets up the key, label and color for each series) and of the series itself (sets up a key for each possible value of the aggregation field, with each key prefixed by the name of the ordinate column). To handle grouped *and clustered* graphs, which dhtmlx does not natively support, might be able to reimplement this Excel/Numbers hack: http://peltiertech.com/WordPress/clustered-stacked-column-bar-charts/ by iterating over all this.columns (rather than just the ordinate) and... not sure actually, creating a record for each of these columns for each abscissa value, with all other fields set to 0? Maybe? bzr revid: xmo@openerp.com-20110928135219-edp80g7k6x60s3l8 --- addons/web_graph/static/src/js/graph.js | 61 ++++++++++++++++++++----- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7498859eac0..a440895cd2b 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -162,18 +162,57 @@ openerp.web_graph.GraphView = openerp.web.View.extend({ schedule_bar: function(results) { var self = this; - this.group_field = false; - var view_chart = (this.orientation === 'horizontal') - ? (this.group_field ? 'stackedBarH' : 'barH') - : (this.group_field ? 'stackedBar' : 'bar'); - - var group_list = _(this.columns).map(function (column, index) { - return { - group: column.name, - text: self.fields[column.name].string, - color: COLOR_PALETTE[index % (COLOR_PALETTE.length)] + var group_list, view_chart; + if (!this.group_field) { + view_chart = (this.orientation === 'horizontal') ? 'barH' : 'bar'; + group_list = _(this.columns).map(function (column, index) { + return { + group: column.name, + text: self.fields[column.name].string, + color: COLOR_PALETTE[index % (COLOR_PALETTE.length)] + } + }); + } else { + // dhtmlx handles clustered bar charts (> 1 column per abscissa + // value) and stacked bar charts (basically the same but with the + // columns on top of one another instead of side by side), but it + // does not handle clustered stacked bar charts + if (this.columns.length > 1) { + throw new Error( + 'dhtmlx can not handle columns counts of that magnitude'); } - }); + // transform series for clustered charts into series for stacked + // charts + view_chart = (this.orientation === 'horizontal') + ? 'stackedBarH' : 'stackedBar'; + group_list = _(results).chain() + .pluck(this.group_field) + .uniq() + .map(function (value, index) { + return { + group: self.ordinate + '_' + + value.toLowerCase().replace(/\s/g, '_'), + text: value, + color: COLOR_PALETTE[index % COLOR_PALETTE.length] + }; + }).value(); + + results = _(results).chain() + .groupBy(function (record) { return record[self.abscissa]; }) + .map(function (records) { + var r = {}; + // second argument is coerced to a str, no good for boolean + r[self.abscissa] = records[0][self.abscissa]; + _(records).each(function (record) { + var key = _.sprintf('%s_%s', + self.ordinate, + record[self.group_field].toLowerCase().replace(/\s/g, '_')); + r[key] = record[self.ordinate]; + }); + return r; + }) + .value(); + } var abscissa_description = { title: "" + this.fields[this.abscissa].string + "",