From 69257d5d6f9c757cfba4447f63336fd14fb4be49 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 8 Nov 2013 12:32:10 +0100 Subject: [REF] work in progress. reset graph view to minimal state in addon web_graph bzr revid: ged@openerp.com-20131108113210-aptz2pne05iwca82 --- addons/web_graph/static/src/js/graph.js | 412 +------------------------------- 1 file changed, 4 insertions(+), 408 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index a84bb53fc85..f0bef5d5749 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -7,15 +7,6 @@ openerp.web_graph = function (instance) { var _lt = instance.web._lt; var _t = instance.web._t; -// removed ``undefined`` values -var filter_values = function (o) { - var out = {}; - for (var k in o) { - if (!o.hasOwnProperty(k) || o[k] === undefined) { continue; } - out[k] = o[k]; - } - return out; -}; instance.web.views.add('graph', 'instance.web_graph.GraphView'); instance.web_graph.GraphView = instance.web.View.extend({ @@ -24,411 +15,16 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_type: "graph", init: function(parent, dataset, view_id, options) { - var self = this; - this._super(parent); + this._super(parent, dataset, view_id, options); this.set_default_options(options); - this.dataset = dataset; - this.view_id = view_id; - - this.mode = "bar"; // line, bar, area, pie, radar - this.orientation = false; // true: horizontal, false: vertical - this.stacked = true; - - this.spreadsheet = false; // Display data grid, allows copy to CSV - this.forcehtml = false; - this.legend = "top"; // top, inside, no - - this.domain = []; - this.context = {}; - this.group_by = []; - - this.graph = null; - }, - view_loading: function(r) { - return this.load_graph(r); - }, - destroy: function () { - if (this.graph) { - this.graph.destroy(); - } - this._super(); - }, - - load_graph: function(fields_view_get) { - // TODO: move to load_view and document - var self = this; - this.fields_view = fields_view_get; - this.$el.addClass(this.fields_view.arch.attrs['class']); - - this.mode = this.fields_view.arch.attrs.type || 'bar'; - this.orientation = this.fields_view.arch.attrs.orientation == 'horizontal'; - - var width = this.$el.parent().width(); - this.$el.css("width", width); - this.container = this.$el.find("#editor-render-body").css({ - width: width, - height: Math.min(500, width * 0.8) - })[0]; - - var graph_render = this.proxy('graph_render'); - this.$el.on('click', '.oe_graph_options a', function (evt) { - var $el = $(evt.target); - - self.graph_render({data: filter_values({ - mode: $el.data('mode'), - legend: $el.data('legend'), - orientation: $el.data('orientation'), - stacked: $el.data('stacked') - })}); - }); - - this.$el.find("#graph_show_data").click(function () { - self.spreadsheet = ! self.spreadsheet; - self.graph_render(); - }); - this.$el.find("#graph_switch").click(function () { - if (self.mode != 'radar') { - self.orientation = ! self.orientation; - } - self.graph_render(); - }); - - this.$el.find("#graph_download").click(function () { - if (self.legend == "top") { self.legend = "inside"; } - self.forcehtml = true; - - self.graph_get_data().done(function (result) { - self.graph_render_all(result).download.saveImage('png'); - }).always(function () { - self.forcehtml = false; - }); - }); - this.trigger('graph_view_loaded', fields_view_get); - }, - - get_format: function (options) { - options = options || {}; - var legend = { - show: this.legend != 'no', - }; - - switch (this.legend) { - case 'top': - legend.noColumns = 4; - legend.container = this.$el.find("div.graph_header_legend")[0]; - break; - case 'inside': - legend.position = 'nw'; - legend.backgroundColor = '#D2E8FF'; - break; - } - - return _.extend({ - legend: legend, - mouse: { - track: true, - relative: true - }, - spreadsheet : { - show: this.spreadsheet, - initialTab: "data" - }, - HtmlText : (options.xaxis && options.xaxis.labelsAngle) ? false : !this.forcehtml, - }, options); - }, - - make_graph: function (mode, container, data) { - if (mode === 'area') { mode = 'line'; } - var format = this.get_format(this['options_' + mode](data)); - return Flotr.draw(container, data.data, format); - }, - - options_bar: function (data) { - var min = _(data.data).chain() - .map(function (record) { - if (record.data.length > 0){ - return _.min(record.data, function (item) { - return item[1]; - })[1]; - } - }).min().value(); - return { - bars : { - show : true, - stacked : this.stacked, - horizontal : this.orientation, - barWidth : 0.7, - lineWidth : 1 - }, - grid : { - verticalLines : this.orientation, - horizontalLines : !this.orientation, - outline : "sw", - }, - yaxis : { - ticks: this.orientation ? data.ticks : false, - min: !this.orientation ? (min < 0 ? min : 0) : null - }, - xaxis : { - labelsAngle: 45, - ticks: this.orientation ? false : data.ticks, - min: this.orientation ? (min < 0 ? min : 0) : null - } - }; - }, - - options_pie: function (data) { - return { - pie : { - show: true - }, - grid : { - verticalLines : false, - horizontalLines : false, - outline : "", - }, - xaxis : {showLabels: false}, - yaxis : {showLabels: false}, - }; - }, - - options_radar: function (data) { - return { - radar : { - show : true, - stacked : this.stacked - }, - grid : { - circular : true, - minorHorizontalLines : true - }, - xaxis : { - ticks: data.ticks - }, - }; - }, - - options_line: function (data) { - return { - lines : { - show : true, - }, - points: { - show: true, - }, - grid : { - verticalLines : this.orientation, - horizontalLines : !this.orientation, - outline : "sw", - }, - yaxis : { - ticks: this.orientation ? data.ticks : false - }, - xaxis : { - labelsAngle: 45, - ticks: this.orientation ? false : data.ticks - } - }; - }, - - graph_get_data: function () { - var model = this.dataset.model, - domain = new instance.web.CompoundDomain(this.domain || []), - context = new instance.web.CompoundContext(this.context || {}), - group_by = this.group_by || [], - view_id = this.view_id || false, - mode = this.mode || 'bar', - orientation = this.orientation || false, - stacked = this.stacked || false; - - var obj = new instance.web.Model(model); - var view_get; - var fields; - var result = []; - var ticks = {}; - - return this.alive(obj.call("fields_view_get", [view_id, 'graph', context]).then(function(tmp) { - view_get = tmp; - fields = view_get['fields']; - var toload = _.select(group_by, function(x) { return fields[x] === undefined }); - if (toload.length >= 1) - return obj.call("fields_get", [toload, context]); - else - return $.when([]); - }).then(function (fields_to_add) { - _.extend(fields, fields_to_add); - - var tree = $($.parseXML(view_get['arch'])); - - var pos = 0; - var xaxis = _.clone(group_by || []); - var yaxis = []; - tree.find("field").each(function() { - var field = $(this); - if (! field.attr("name")) - return; - if ((group_by.length == 0) && ((! pos) || instance.web.py_eval(field.attr('group') || "false"))) { - xaxis.push(field.attr('name')); - } - if (pos && ! instance.web.py_eval(field.attr('group') || "false")) { - yaxis.push(field.attr('name')); - } - pos += 1; - }); - - if (xaxis.length === 0) - throw new Error("No field for the X axis!"); - if (yaxis.length === 0) - throw new Error("No field for the Y axis!"); - - // Convert a field's data into a displayable string - - function _convert_key(field, data) { - if (fields[field]['type'] === 'many2one') - data = data && data[0]; - return data; - } - - function _convert(field, data, tick) { - tick = tick === undefined ? true : false; - try { - data = instance.web.format_value(data, fields[field]); - } catch(e) { - data = "" + data; - } - if (tick) { - if (ticks[data] === undefined) - ticks[data] = _.size(ticks); - return ticks[data]; - } - return data || 0; - } - - function _orientation(x, y) { - if (! orientation) - return [x, y] - return [y, x] - } - - if (mode === "pie") { - return obj.call("read_group", [domain, yaxis.concat([xaxis[0]]), [xaxis[0]]], {context: context}).then(function(res) { - _.each(res, function(record) { - result.push({ - 'data': [[_convert(xaxis[0], record[xaxis[0]]), record[yaxis[0]]]], - 'label': _convert(xaxis[0], record[xaxis[0]], false) - }); - }); - }); - } else if ((! stacked) || (xaxis.length < 2)) { - var defs = []; - _.each(xaxis, function(x) { - defs.push(obj.call("read_group", [domain, yaxis.concat([x]), [x]], {context: context}).then(function(res) { - return [x, res]; - })); - }); - return $.when.apply($, defs).then(function() { - _.each(_.toArray(arguments), function(res) { - var x = res[0]; - res = res[1]; - result.push({ - 'data': _.map(res, function(record) { - return _orientation(_convert(x, record[x]), record[yaxis[0]] || 0); - }), - 'label': fields[x]['string'] - }); - }); - }); - } else { - xaxis.reverse(); - return obj.call("read_group", [domain, yaxis.concat(xaxis.slice(0, 1)), xaxis.slice(0, 1)], {context: context}).then(function(axis) { - var defs = []; - _.each(axis, function(x) { - var key = x[xaxis[0]] - defs.push(obj.call("read_group", [x['__domain'], yaxis.concat(xaxis.slice(1, 2)), xaxis.slice(1, 2)], {context: context}).then(function(res) { - return [x, key, res]; - })); - }); - return $.when.apply($, defs).then(function() { - _.each(_.toArray(arguments), function(res) { - var x = res[0]; - var key = res[1]; - res = res[2]; - result.push({ - 'data': _.map(res, function(record) { - return _orientation(_convert(xaxis[1], record[xaxis[1]]), record[yaxis[0]] || 0); - }), - 'label': _convert(xaxis[0], key, false) - }) - }); - }); - }); - } - }).then(function() { - var res = { - 'data': result, - 'ticks': _.map(ticks, function(el, key) { return [el, key || _t("Undefined")] }) - }; - return res; - })); - }, - // Render the graph and update menu styles - graph_render: function (options) { - options = options || {}; - _.extend(this, options.data); - - return this.graph_get_data() - .done(this.proxy('graph_render_all')); - }, - - graph_render_all: function (data) { - var i; - if (this.mode=='area') { - for (i=0; i 1) { - $active = $active.filter('[data-stacked=' + this.stacked + ']'); - } - $active = $active.add( - this.$el.find('a:not([data-mode])[data-legend=' + this.legend + ']')); - - $active.addClass('active'); - - if (this.spreadsheet) { - this.$el.find("#graph_show_data").addClass("active"); - } - return this.graph; }, - // render the graph using the domain, context and group_by - // calls the 'graph_data_get' python controller to process all data - // TODO: check is group_by should better be in the context - do_search: function(domain, context, group_by) { - this.domain = domain; - this.context = context; - this.group_by = group_by; - - this.graph_render(); - }, - - do_show: function() { + do_show: function () { this.do_push_state({}); return this._super(); }, + + }); }; -- cgit v1.2.3 From 23b9f226c782e1b8290171df530dfb0465933204 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 8 Nov 2013 12:50:30 +0100 Subject: [ADD] add (custom version of) bootstrap library to graph view (addon web_graph) bzr revid: ged@openerp.com-20131108115030-0r4e4vk379mqtkzf --- addons/web_graph/static/src/js/graph.js | 2 -- 1 file changed, 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index f0bef5d5749..af63c78cff1 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -16,8 +16,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ init: function(parent, dataset, view_id, options) { this._super(parent, dataset, view_id, options); - this.set_default_options(options); - }, do_show: function () { -- cgit v1.2.3 From 7ad9aecc13e23ce40a4b22e31ed5f7f9435adf4c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 8 Nov 2013 14:08:06 +0100 Subject: [IMP] add widgets (chart view and pivot view) in addon web_graph bzr revid: ged@openerp.com-20131108130806-ez2a6sxdsy0bzg62 --- addons/web_graph/static/src/js/graph.js | 57 +++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index af63c78cff1..173f2e8973a 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -1,28 +1,79 @@ /*--------------------------------------------------------- * OpenERP web_graph *---------------------------------------------------------*/ +/*global openerp:true*/ +/*global $:true*/ +'use strict'; openerp.web_graph = function (instance) { var _lt = instance.web._lt; var _t = instance.web._t; - instance.web.views.add('graph', 'instance.web_graph.GraphView'); + instance.web_graph.GraphView = instance.web.View.extend({ - template: "GraphView", + template: 'GraphView', display_name: _lt('Graph'), - view_type: "graph", + view_type: 'graph', + events: { + 'click .graph_mode_selection li' : function (event) { + event.preventDefault(); + var mode = event.target.attributes['data-mode'].nodeValue; + if (mode == 'data') { + this.chart_view.hide(); + this.pivot_table.show(); + } else { + this.pivot_table.hide(); + this.chart_view.show(mode); + } + }, + }, init: function(parent, dataset, view_id, options) { this._super(parent, dataset, view_id, options); + this.pivot_table = new PivotTable(this); + this.chart_view = new ChartView(this); + }, + + view_loading: function (fields_view_get) { + this.pivot_table.appendTo('.graph_pivot'); + this.chart_view.appendTo('.graph_chart'); + this.chart_view.hide(); }, do_show: function () { this.do_push_state({}); return this._super(); }, +}); + +var PivotTable = instance.web.Widget.extend({ + template: 'pivot_table', + + show: function () { + this.$el.css('display', 'block'); + }, + + hide: function () { + this.$el.css('display', 'none'); + }, + +}); + +var ChartView = instance.web.Widget.extend({ + template: 'chart_view', + + show: function () { + this.$el.css('display', 'block'); + }, + hide: function () { + this.$el.css('display', 'none'); + }, }); + + + }; -- cgit v1.2.3 From eab6a192e9413c09b67b28fbf856d3314051bc4a Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 8 Nov 2013 16:20:48 +0100 Subject: [IMP] add pie, line and bar chart to the chartview widget (addon web_graph) bzr revid: ged@openerp.com-20131108152048-0akyhf0c7lcdsqjh --- addons/web_graph/static/src/js/graph.js | 190 +++++++++++++++++++++++++++++++- 1 file changed, 188 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 173f2e8973a..aa4275493b6 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -12,6 +12,10 @@ var _t = instance.web._t; instance.web.views.add('graph', 'instance.web_graph.GraphView'); + /** + * GraphView view. It mostly contains two widgets (PivotTable and ChartView) + * and some data. + */ instance.web_graph.GraphView = instance.web.View.extend({ template: 'GraphView', display_name: _lt('Graph'), @@ -19,13 +23,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ events: { 'click .graph_mode_selection li' : function (event) { event.preventDefault(); - var mode = event.target.attributes['data-mode'].nodeValue; + var self = this, + mode = event.target.attributes['data-mode'].nodeValue; if (mode == 'data') { this.chart_view.hide(); this.pivot_table.show(); } else { this.pivot_table.hide(); - this.chart_view.show(mode); + this.get_data().done(function (data) { + self.chart_view.draw(data, mode); + self.chart_view.show(mode); + }); } }, }, @@ -34,20 +42,56 @@ instance.web_graph.GraphView = instance.web.View.extend({ this._super(parent, dataset, view_id, options); this.pivot_table = new PivotTable(this); this.chart_view = new ChartView(this); + this.x_groups = []; + this.measure = null; + this.domain = []; + this.model = null; + }, view_loading: function (fields_view_get) { + var self = this; + this.model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); + + // get the default groupbys and measure defined in the field view + _.each(fields_view_get.arch.children, function (field) { + if ('name' in field.attrs) { + if ('operator' in field.attrs) { + self.measure = field.attrs.name; + } else { + self.x_groups.push(field.attrs.name); + } + } + }); + + this.chart_view.set_measure(this.measure); this.pivot_table.appendTo('.graph_pivot'); this.chart_view.appendTo('.graph_chart'); this.chart_view.hide(); + this.get_data().done(this.pivot_table.draw); + }, + + get_data: function () { + var view_fields = this.x_groups.concat(this.measure); + + return query_groups(this.model, view_fields, this.domain, this.x_groups); + }, + + do_search: function (domain, context, group_by) { + this.domain = new instance.web.CompoundDomain(domain); }, do_show: function () { this.do_push_state({}); return this._super(); }, + }); + /** + * PivotTable widget. It displays the data in tabular data and allows the + * user to drill down and up in the table + */ var PivotTable = instance.web.Widget.extend({ template: 'pivot_table', @@ -59,10 +103,18 @@ var PivotTable = instance.web.Widget.extend({ this.$el.css('display', 'none'); }, + draw: function (data) { + console.log("data",data); + }, }); + /** + * ChartView widget. It displays the data in chart form, using the nvd3 + * library. Various modes include bar charts, pie charts or line charts. + */ var ChartView = instance.web.Widget.extend({ template: 'chart_view', + measure: null, show: function () { this.$el.css('display', 'block'); @@ -72,8 +124,142 @@ var ChartView = instance.web.Widget.extend({ this.$el.css('display', 'none'); }, + set_measure: function (measure) { + this.measure = measure; + }, + + draw: function (data, mode) { + // d3.select('.graph_chart_svg').remove(); + + $('.graph_chart_svg').empty(); + $('.graph_chart_svg').append(''); + + switch (mode) { + case 'bar_chart': + this.render_bar_chart(data); + break; + case 'pie_chart': + this.render_pie_chart(data); + break; + case 'line_chart': + this.render_line_chart(data); + break; + } + }, + + format_data: function (datapt) { + var val = datapt.attributes; + return { + x: datapt.attributes.value[1], + y: this.measure ? val.aggregates[this.measure] : val.length, + }; + }, + + render_bar_chart: function (data) { + var formatted_data = [{ + key: 'Bar chart', + values: _.map(data, this.format_data.bind(this)), + }]; + + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .tooltips(false) + .showValues(true) + .staggerLabels(true) + .width(650) + .height(400); + + d3.select('.graph_chart_svg svg') + .datum(formatted_data) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + }, + + render_pie_chart: function (data) { + var formatted_data = _.map(data, this.format_data.bind(this)); + + nv.addGraph(function () { + var chart = nv.models.pieChart() + .color(d3.scale.category10().range()) + .width(650) + .height(400); + + d3.select('.graph_chart_svg svg') + .datum(formatted_data) + .transition().duration(1200) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + }, + + render_line_chart: function (data) { + var measure_label = (this.measure) ? this.measure : 'Quantity'; + + var formatted_data = [{ + key: measure_label, + values: _.map(data, this.format_data.bind(this)) + }]; + + nv.addGraph(function () { + var width = 600, + height = 300; + + var chart = nv.models.lineChart() + .x(function (d,u) { return u; }) + .width(width) + .height(height) + .margin({top: 30, right: 20, bottom: 20, left: 60}); + + d3.select('.graph_chart_svg svg') + .attr('width', width) + .attr('height', height) + .datum(formatted_data) + .call(chart); + + return chart; + }); + }, + }); +/** + * Query the server and return a deferred which will return the data + * with all the groupbys applied (this is done for now, but the goal + * is to modify read_group in order to allow eager and lazy groupbys + */ +function query_groups (model, fields, domain, groupbys) { + return model.query(fields) + .filter(domain) + .group_by(groupbys) + .then(function (results) { + var non_empty_results = _.filter(results, function (group) { + return group.attributes.length > 0; + }); + if (groupbys.length <= 1) { + return non_empty_results; + } else { + var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { + var new_domain = result.model._domain; + var new_groupings = groupbys.slice(1); + return query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { + result.subgroups_data = subgroups; + }); + })); + return get_subgroups.then(function () { + return non_empty_results; + }); + } + }); +} }; -- cgit v1.2.3 From 906d5168cc29f3258dfa2899de1e8c45f88098b7 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 8 Nov 2013 16:27:17 +0100 Subject: [IMP] small cleanups to chartview widget (addon web_graph) bzr revid: ged@openerp.com-20131108152717-stbx0us8ipom67iq --- addons/web_graph/static/src/js/graph.js | 69 +++++++++++++++------------------ 1 file changed, 32 insertions(+), 37 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index aa4275493b6..ca704e31527 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -129,21 +129,19 @@ var ChartView = instance.web.Widget.extend({ }, draw: function (data, mode) { - // d3.select('.graph_chart_svg').remove(); - - $('.graph_chart_svg').empty(); - $('.graph_chart_svg').append(''); + $('.graph_chart').empty(); + $('.graph_chart').append(''); switch (mode) { case 'bar_chart': this.render_bar_chart(data); break; - case 'pie_chart': - this.render_pie_chart(data); - break; case 'line_chart': this.render_line_chart(data); break; + case 'pie_chart': + this.render_pie_chart(data); + break; } }, @@ -169,29 +167,8 @@ var ChartView = instance.web.Widget.extend({ .width(650) .height(400); - d3.select('.graph_chart_svg svg') - .datum(formatted_data) - .attr('width', 650) - .attr('height', 400) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - }, - - render_pie_chart: function (data) { - var formatted_data = _.map(data, this.format_data.bind(this)); - - nv.addGraph(function () { - var chart = nv.models.pieChart() - .color(d3.scale.category10().range()) - .width(650) - .height(400); - - d3.select('.graph_chart_svg svg') + d3.select('.graph_chart svg') .datum(formatted_data) - .transition().duration(1200) .attr('width', 650) .attr('height', 400) .call(chart); @@ -210,18 +187,15 @@ var ChartView = instance.web.Widget.extend({ }]; nv.addGraph(function () { - var width = 600, - height = 300; - var chart = nv.models.lineChart() .x(function (d,u) { return u; }) - .width(width) - .height(height) + .width(600) + .height(300) .margin({top: 30, right: 20, bottom: 20, left: 60}); - d3.select('.graph_chart_svg svg') - .attr('width', width) - .attr('height', height) + d3.select('.graph_chart svg') + .attr('width', 600) + .attr('height', 300) .datum(formatted_data) .call(chart); @@ -229,6 +203,27 @@ var ChartView = instance.web.Widget.extend({ }); }, + render_pie_chart: function (data) { + var formatted_data = _.map(data, this.format_data.bind(this)); + + nv.addGraph(function () { + var chart = nv.models.pieChart() + .color(d3.scale.category10().range()) + .width(650) + .height(400); + + d3.select('.graph_chart svg') + .datum(formatted_data) + .transition().duration(1200) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + }, + }); /** -- cgit v1.2.3 From 4dd5ac99249c3addd3806b31476a536c721b4fb6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 8 Nov 2013 16:41:14 +0100 Subject: [FIX] fix a bug preventing hide and show method of chartview widget to function properly (addon web_graph) bzr revid: ged@openerp.com-20131108154114-25zqn3jq5u6iuibt --- addons/web_graph/static/src/js/graph.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index ca704e31527..30318a923a7 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -1,8 +1,10 @@ /*--------------------------------------------------------- * OpenERP web_graph *---------------------------------------------------------*/ -/*global openerp:true*/ +/*global openerp:true $:true*/ /*global $:true*/ +/*global _:true*/ + 'use strict'; openerp.web_graph = function (instance) { @@ -117,11 +119,11 @@ var ChartView = instance.web.Widget.extend({ measure: null, show: function () { - this.$el.css('display', 'block'); + $('.graph_chart').css('display', 'block'); }, hide: function () { - this.$el.css('display', 'none'); + $('.graph_chart').css('display', 'none'); }, set_measure: function (measure) { -- cgit v1.2.3 From 6ecbf2ef80552656b1ea065ba0fb5ae92967ab1d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 12 Nov 2013 09:38:27 +0100 Subject: [IMP] add access to model fields description in addon web_graph bzr revid: ged@openerp.com-20131112083827-fy9i054l9mq3vynz --- addons/web_graph/static/src/js/graph.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 30318a923a7..e5e297dc2a8 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -1,11 +1,10 @@ /*--------------------------------------------------------- * OpenERP web_graph *---------------------------------------------------------*/ -/*global openerp:true $:true*/ -/*global $:true*/ -/*global _:true*/ 'use strict'; +/* jshint undef: false */ + openerp.web_graph = function (instance) { @@ -48,6 +47,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.measure = null; this.domain = []; this.model = null; + this.model_fields = []; }, @@ -71,6 +71,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.chart_view.appendTo('.graph_chart'); this.chart_view.hide(); this.get_data().done(this.pivot_table.draw); + + return this.model.call('fields_get', []).then(function (fields) { + self.model_fields = fields; + }); }, get_data: function () { @@ -79,6 +83,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ return query_groups(this.model, view_fields, this.domain, this.x_groups); }, + get_desc: function(field_id) { + return this.model_fields[field_id].string; + }, + do_search: function (domain, context, group_by) { this.domain = new instance.web.CompoundDomain(domain); }, @@ -106,7 +114,7 @@ var PivotTable = instance.web.Widget.extend({ }, draw: function (data) { - console.log("data",data); + console.log('data',data); }, }); @@ -260,3 +268,4 @@ function query_groups (model, fields, domain, groupbys) { }; + -- cgit v1.2.3 From d947299a740b9b7f6d40097b69235d6aa004aa38 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 12 Nov 2013 09:49:55 +0100 Subject: [FIX] fix pivottable and chartview widget to use their template instead of hardcoded divs (addon web_graph) bzr revid: ged@openerp.com-20131112084955-2x8o57ndln0xx0nx --- addons/web_graph/static/src/js/graph.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index e5e297dc2a8..5cfd437d666 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -67,8 +67,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); this.chart_view.set_measure(this.measure); - this.pivot_table.appendTo('.graph_pivot'); - this.chart_view.appendTo('.graph_chart'); + this.pivot_table.appendTo('.graph_main_content'); + this.chart_view.appendTo('.graph_main_content'); this.chart_view.hide(); this.get_data().done(this.pivot_table.draw); @@ -127,11 +127,11 @@ var ChartView = instance.web.Widget.extend({ measure: null, show: function () { - $('.graph_chart').css('display', 'block'); + this.$el.css('display', 'block'); }, hide: function () { - $('.graph_chart').css('display', 'none'); + this.$el.css('display', 'none'); }, set_measure: function (measure) { @@ -139,8 +139,8 @@ var ChartView = instance.web.Widget.extend({ }, draw: function (data, mode) { - $('.graph_chart').empty(); - $('.graph_chart').append(''); + this.$el.empty(); + this.$el.append(''); switch (mode) { case 'bar_chart': -- cgit v1.2.3 From 4d7150fc5895e518e313398715170020c3287eca Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 12 Nov 2013 12:31:34 +0100 Subject: [REF] large refactoring of addon web_graph (mainly add widget BasicDataView and many cleanups) bzr revid: ged@openerp.com-20131112113134-w2298fsh1va4jpm7 --- addons/web_graph/static/src/js/graph.js | 124 +++++++++++++++----------------- 1 file changed, 58 insertions(+), 66 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 5cfd437d666..a36f8f68db0 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -21,6 +21,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ template: 'GraphView', display_name: _lt('Graph'), view_type: 'graph', + events: { 'click .graph_mode_selection li' : function (event) { event.preventDefault(); @@ -31,62 +32,46 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table.show(); } else { this.pivot_table.hide(); - this.get_data().done(function (data) { - self.chart_view.draw(data, mode); - self.chart_view.show(mode); - }); + this.chart_view.set_mode(mode); + this.chart_view.show(); } }, }, - init: function(parent, dataset, view_id, options) { - this._super(parent, dataset, view_id, options); - this.pivot_table = new PivotTable(this); - this.chart_view = new ChartView(this); - this.x_groups = []; - this.measure = null; - this.domain = []; - this.model = null; - this.model_fields = []; - - }, - view_loading: function (fields_view_get) { var self = this; - this.model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); + var model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); + var measure = null; + var groupbys = [] // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { if ('operator' in field.attrs) { - self.measure = field.attrs.name; + measure = field.attrs.name; } else { - self.x_groups.push(field.attrs.name); + groupbys.push(field.attrs.name); } } }); - this.chart_view.set_measure(this.measure); - this.pivot_table.appendTo('.graph_main_content'); - this.chart_view.appendTo('.graph_main_content'); - this.chart_view.hide(); - this.get_data().done(this.pivot_table.draw); - - return this.model.call('fields_get', []).then(function (fields) { - self.model_fields = fields; + return model.call('fields_get', []).then(function (fields) { + var view_fields = groupbys.concat(measure); + query_groups(model, view_fields, self.domain, groupbys).done(function (data) { + self.pivot_table = new PivotTable(data, fields, groupbys, measure); + self.chart_view = new ChartView(data, fields, groupbys, measure); + self.pivot_table.appendTo('.graph_main_content') + .done(function () { + self.pivot_table.draw(); + }); + self.chart_view.appendTo('.graph_main_content') + .done(function () { + self.chart_view.hide(); + }); + }); }); }, - get_data: function () { - var view_fields = this.x_groups.concat(this.measure); - - return query_groups(this.model, view_fields, this.domain, this.x_groups); - }, - - get_desc: function(field_id) { - return this.model_fields[field_id].string; - }, - do_search: function (domain, context, group_by) { this.domain = new instance.web.CompoundDomain(domain); }, @@ -99,11 +84,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); /** - * PivotTable widget. It displays the data in tabular data and allows the - * user to drill down and up in the table + * BasicDataView widget. Basic widget to manage show/hide functionality + * and to initialize some attributes. It is inherited by PivotTable + * and ChartView widget. */ -var PivotTable = instance.web.Widget.extend({ - template: 'pivot_table', +var BasicDataView = instance.web.Widget.extend({ + init: function (data, fields, groupby, measure) { + this.data = data; + this.fields = fields; + this.groupby = groupby; + this.measure = measure; + }, show: function () { this.$el.css('display', 'block'); @@ -112,9 +103,17 @@ var PivotTable = instance.web.Widget.extend({ hide: function () { this.$el.css('display', 'none'); }, +}); - draw: function (data) { - console.log('data',data); + /** + * PivotTable widget. It displays the data in tabular data and allows the + * user to drill down and up in the table + */ +var PivotTable = BasicDataView.extend({ + template: 'pivot_table', + + draw: function () { + console.log('data',this.data); }, }); @@ -122,35 +121,28 @@ var PivotTable = instance.web.Widget.extend({ * ChartView widget. It displays the data in chart form, using the nvd3 * library. Various modes include bar charts, pie charts or line charts. */ -var ChartView = instance.web.Widget.extend({ +var ChartView = BasicDataView.extend({ template: 'chart_view', - measure: null, + mode: 'bar_chart', - show: function () { - this.$el.css('display', 'block'); - }, - - hide: function () { - this.$el.css('display', 'none'); - }, - - set_measure: function (measure) { - this.measure = measure; + set_mode: function (mode) { + this.mode = mode; + this.draw(); }, - draw: function (data, mode) { + draw: function () { this.$el.empty(); this.$el.append(''); - switch (mode) { + switch (this.mode) { case 'bar_chart': - this.render_bar_chart(data); + this.render_bar_chart(); break; case 'line_chart': - this.render_line_chart(data); + this.render_line_chart(); break; case 'pie_chart': - this.render_pie_chart(data); + this.render_pie_chart(); break; } }, @@ -163,10 +155,10 @@ var ChartView = instance.web.Widget.extend({ }; }, - render_bar_chart: function (data) { + render_bar_chart: function () { var formatted_data = [{ key: 'Bar chart', - values: _.map(data, this.format_data.bind(this)), + values: _.map(this.data, this.format_data.bind(this)), }]; nv.addGraph(function () { @@ -188,12 +180,12 @@ var ChartView = instance.web.Widget.extend({ }); }, - render_line_chart: function (data) { + render_line_chart: function () { var measure_label = (this.measure) ? this.measure : 'Quantity'; var formatted_data = [{ key: measure_label, - values: _.map(data, this.format_data.bind(this)) + values: _.map(this.data, this.format_data.bind(this)) }]; nv.addGraph(function () { @@ -213,8 +205,8 @@ var ChartView = instance.web.Widget.extend({ }); }, - render_pie_chart: function (data) { - var formatted_data = _.map(data, this.format_data.bind(this)); + render_pie_chart: function () { + var formatted_data = _.map(this.data, this.format_data.bind(this)); nv.addGraph(function () { var chart = nv.models.pieChart() -- cgit v1.2.3 From 298a7012bfb1ba3b66bee56d196aa52be7bb2789 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 12 Nov 2013 14:53:44 +0100 Subject: [IMP] add rendering of basic table in pivottable widget (addon web_graph) bzr revid: ged@openerp.com-20131112135344-fi7mwyd49bqnbg69 --- addons/web_graph/static/src/js/graph.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index a36f8f68db0..e8836604324 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -10,6 +10,7 @@ openerp.web_graph = function (instance) { var _lt = instance.web._lt; var _t = instance.web._t; +var QWeb = instance.web.qweb; instance.web.views.add('graph', 'instance.web_graph.GraphView'); @@ -94,6 +95,7 @@ var BasicDataView = instance.web.Widget.extend({ this.fields = fields; this.groupby = groupby; this.measure = measure; + this.measure_label = measure ? fields[measure].string : 'Quantity'; }, show: function () { @@ -113,7 +115,23 @@ var PivotTable = BasicDataView.extend({ template: 'pivot_table', draw: function () { - console.log('data',this.data); + var self = this; + console.log("data",this.data); + + var rows = '' + + this.fields[this.groupby[0]].string + + '' + + this.measure_label + + ''; + _.each(this.data, function (datapt) { + rows += '' + + datapt.attributes.value[1] + + '' + + datapt.attributes.aggregates[self.measure]+ + ''; + }); + + this.$el.append(rows); }, }); @@ -181,10 +199,9 @@ var ChartView = BasicDataView.extend({ }, render_line_chart: function () { - var measure_label = (this.measure) ? this.measure : 'Quantity'; var formatted_data = [{ - key: measure_label, + key: this.measure_label, values: _.map(this.data, this.format_data.bind(this)) }]; -- cgit v1.2.3 From 8eeaca216d796eca53b361dfad364028ef09882e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 12 Nov 2013 17:10:34 +0100 Subject: [REF] refactoring of addon web_graph. goal is to handle properly the switch of chart view to table view bzr revid: ged@openerp.com-20131112161034-yy80ypm39j32sazv --- addons/web_graph/static/src/js/graph.js | 114 ++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 51 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index e8836604324..44152e45372 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -22,59 +22,72 @@ instance.web_graph.GraphView = instance.web.View.extend({ template: 'GraphView', display_name: _lt('Graph'), view_type: 'graph', + mode: 'pivot', // pivot => display pivot table, chart => display chart events: { 'click .graph_mode_selection li' : function (event) { event.preventDefault(); - var self = this, - mode = event.target.attributes['data-mode'].nodeValue; - if (mode == 'data') { - this.chart_view.hide(); - this.pivot_table.show(); + var view_mode = event.target.attributes['data-mode'].nodeValue; + if (view_mode === 'data') { + this.mode = 'pivot'; } else { - this.pivot_table.hide(); - this.chart_view.set_mode(mode); - this.chart_view.show(); + this.mode = 'chart'; + this.chart_view.set_mode(view_mode); } + this.display_data(); }, }, + display_data : function () { + if (this.mode === 'pivot') { + this.chart_view.hide(); + this.pivot_table.show(); + } else { + this.pivot_table.hide(); + this.chart_view.draw(); + this.chart_view.show(); + } + }, + view_loading: function (fields_view_get) { var self = this; - var model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); - var measure = null; - var groupbys = [] + this.model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); + this.measure = null; + this.groupbys = []; // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { if ('operator' in field.attrs) { - measure = field.attrs.name; + self.measure = field.attrs.name; } else { - groupbys.push(field.attrs.name); + self.groupbys.push(field.attrs.name); } } }); - return model.call('fields_get', []).then(function (fields) { - var view_fields = groupbys.concat(measure); - query_groups(model, view_fields, self.domain, groupbys).done(function (data) { - self.pivot_table = new PivotTable(data, fields, groupbys, measure); - self.chart_view = new ChartView(data, fields, groupbys, measure); - self.pivot_table.appendTo('.graph_main_content') - .done(function () { - self.pivot_table.draw(); - }); - self.chart_view.appendTo('.graph_main_content') - .done(function () { - self.chart_view.hide(); - }); - }); + return this.model.call('fields_get', []).then(function (fields) { + self.pivot_table = new PivotTable(fields, self.groupbys, self.measure); + self.chart_view = new ChartView(fields, self.groupbys, self.measure); + self.pivot_table.appendTo('.graph_main_content'); + self.chart_view.appendTo('.graph_main_content'); }); }, + get_data: function () { + var view_fields = this.groupbys.concat(this.measure); + return query_groups(this.model, view_fields, this.domain, this.groupbys); + }, + do_search: function (domain, context, group_by) { + var self = this; this.domain = new instance.web.CompoundDomain(domain); + return this.get_data().done(function (data) { + self.pivot_table.set_data(data); + self.chart_view.set_data(data); + self.pivot_table.draw(); + self.display_data(); + }); }, do_show: function () { @@ -90,12 +103,16 @@ instance.web_graph.GraphView = instance.web.View.extend({ * and ChartView widget. */ var BasicDataView = instance.web.Widget.extend({ - init: function (data, fields, groupby, measure) { - this.data = data; + init: function (fields, groupby, measure) { this.fields = fields; this.groupby = groupby; this.measure = measure; this.measure_label = measure ? fields[measure].string : 'Quantity'; + this.data = []; + }, + + set_data : function (data) { + this.data = data; }, show: function () { @@ -105,6 +122,9 @@ var BasicDataView = instance.web.Widget.extend({ hide: function () { this.$el.css('display', 'none'); }, + + draw: function() { + }, }); /** @@ -115,19 +135,19 @@ var PivotTable = BasicDataView.extend({ template: 'pivot_table', draw: function () { + this.$el.empty(); var self = this; - console.log("data",this.data); - var rows = '' + + var rows = '' + this.fields[this.groupby[0]].string + - '' + + '' + this.measure_label + ''; _.each(this.data, function (datapt) { - rows += '' + + rows += '' + datapt.attributes.value[1] + - '' + - datapt.attributes.aggregates[self.measure]+ + '' + + datapt.attributes.aggregates[self.measure] + ''; }); @@ -141,28 +161,21 @@ var PivotTable = BasicDataView.extend({ */ var ChartView = BasicDataView.extend({ template: 'chart_view', - mode: 'bar_chart', set_mode: function (mode) { - this.mode = mode; - this.draw(); + var render_functions = { + 'bar_chart' : this.render_bar_chart, + 'line_chart' : this.render_line_chart, + 'pie_chart' : this.render_pie_chart, + }; + + this.render = render_functions[mode]; }, draw: function () { this.$el.empty(); this.$el.append(''); - - switch (this.mode) { - case 'bar_chart': - this.render_bar_chart(); - break; - case 'line_chart': - this.render_line_chart(); - break; - case 'pie_chart': - this.render_pie_chart(); - break; - } + this.render(); }, format_data: function (datapt) { @@ -199,7 +212,6 @@ var ChartView = BasicDataView.extend({ }, render_line_chart: function () { - var formatted_data = [{ key: this.measure_label, values: _.map(this.data, this.format_data.bind(this)) -- cgit v1.2.3 From 3c0445479bf5ceaab5bb2b6f201daa787c53bb82 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 13 Nov 2013 10:18:07 +0100 Subject: [REF] move the method displaydata to a better place in addon web_graph bzr revid: ged@openerp.com-20131113091807-cxmc4aaaswdmkfia --- addons/web_graph/static/src/js/graph.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 44152e45372..7ade3843bde 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -38,17 +38,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, }, - display_data : function () { - if (this.mode === 'pivot') { - this.chart_view.hide(); - this.pivot_table.show(); - } else { - this.pivot_table.hide(); - this.chart_view.draw(); - this.chart_view.show(); - } - }, - view_loading: function (fields_view_get) { var self = this; this.model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); @@ -79,6 +68,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ return query_groups(this.model, view_fields, this.domain, this.groupbys); }, + display_data : function () { + if (this.mode === 'pivot') { + this.chart_view.hide(); + this.pivot_table.show(); + } else { + this.pivot_table.hide(); + this.chart_view.draw(); + this.chart_view.show(); + } + }, + do_search: function (domain, context, group_by) { var self = this; this.domain = new instance.web.CompoundDomain(domain); @@ -138,7 +138,7 @@ var PivotTable = BasicDataView.extend({ this.$el.empty(); var self = this; - var rows = '' + + var rows = ' fa-sort-asc' + this.fields[this.groupby[0]].string + '' + this.measure_label + -- cgit v1.2.3 From 3be25d2c45b6869e30b7ad77413b50bd99f62822 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 13 Nov 2013 10:26:46 +0100 Subject: [IMP] add redraw flag to basicview widget in addon web_graph bzr revid: ged@openerp.com-20131113092646-182veoj027lkbdb6 --- addons/web_graph/static/src/js/graph.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7ade3843bde..7f83d656059 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -74,7 +74,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table.show(); } else { this.pivot_table.hide(); - this.chart_view.draw(); this.chart_view.show(); } }, @@ -85,7 +84,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ return this.get_data().done(function (data) { self.pivot_table.set_data(data); self.chart_view.set_data(data); - self.pivot_table.draw(); self.display_data(); }); }, @@ -103,6 +101,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ * and ChartView widget. */ var BasicDataView = instance.web.Widget.extend({ + + need_redraw: false, + init: function (fields, groupby, measure) { this.fields = fields; this.groupby = groupby; @@ -113,9 +114,14 @@ var BasicDataView = instance.web.Widget.extend({ set_data : function (data) { this.data = data; + this.need_redraw = true; }, show: function () { + if (this.need_redraw) { + this.draw(); + this.need_redraw = false; + } this.$el.css('display', 'block'); }, @@ -170,6 +176,7 @@ var ChartView = BasicDataView.extend({ }; this.render = render_functions[mode]; + this.need_redraw = true; }, draw: function () { -- cgit v1.2.3 From b5af9d421e6aa98ea21b47416cd9dc7391a5e54b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 13 Nov 2013 11:50:59 +0100 Subject: [IMP] add functionality to basicview widget and rearrange code in addon web_graph bzr revid: ged@openerp.com-20131113105059-1l6th5zcn5wrm3x7 --- addons/web_graph/static/src/js/graph.js | 106 +++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 35 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7f83d656059..0361cd12e0d 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -2,11 +2,11 @@ * OpenERP web_graph *---------------------------------------------------------*/ -'use strict'; /* jshint undef: false */ openerp.web_graph = function (instance) { +'use strict'; var _lt = instance.web._lt; var _t = instance.web._t; @@ -40,32 +40,30 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_loading: function (fields_view_get) { var self = this; - this.model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); - this.measure = null; + var model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); + var measure = null; this.groupbys = []; // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { if ('operator' in field.attrs) { - self.measure = field.attrs.name; + measure = field.attrs.name; } else { self.groupbys.push(field.attrs.name); } } }); - return this.model.call('fields_get', []).then(function (fields) { - self.pivot_table = new PivotTable(fields, self.groupbys, self.measure); - self.chart_view = new ChartView(fields, self.groupbys, self.measure); - self.pivot_table.appendTo('.graph_main_content'); - self.chart_view.appendTo('.graph_main_content'); + return model.call('fields_get', []).then(function (fields) { + self.pivot_table = new PivotTable(model, fields, [], self.groupbys, [], measure); + self.chart_view = new ChartView(model, fields, [], self.groupbys, [], measure); + return self.pivot_table.appendTo('.graph_main_content'); + }).then(function() { + return self.chart_view.appendTo('.graph_main_content'); }); - }, - get_data: function () { - var view_fields = this.groupbys.concat(this.measure); - return query_groups(this.model, view_fields, this.domain, this.groupbys); + }, display_data : function () { @@ -79,13 +77,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { - var self = this; this.domain = new instance.web.CompoundDomain(domain); - return this.get_data().done(function (data) { - self.pivot_table.set_data(data); - self.chart_view.set_data(data); - self.display_data(); - }); + this.pivot_table.set_domain(domain); + this.chart_view.set_domain(domain); + this.display_data(); }, do_show: function () { @@ -104,16 +99,43 @@ var BasicDataView = instance.web.Widget.extend({ need_redraw: false, - init: function (fields, groupby, measure) { + // Input parameters: + // model: model to display + // fields: dictionary returned by field_get on model (desc of model) + // domain: constraints on model records + // row_groupby: groubys on rows (so, row headers in the pivot table) + // col_groupby: idem, but on col + // measure: quantity to display. either a field from the model, or + // null, in which case we use the "count" measure + init: function (model, fields, domain, row_groupby, col_groupby, measure) { + this.model = model; this.fields = fields; - this.groupby = groupby; + this.domain = domain; + this.row_groupby = row_groupby; + this.col_groupby = col_groupby; this.measure = measure; this.measure_label = measure ? fields[measure].string : 'Quantity'; this.data = []; + this.need_redraw = true; }, - set_data : function (data) { - this.data = data; + set_domain: function (domain) { + this.domain = domain; + this.need_redraw = true; + }, + + set_row_groupby: function (row_groupby) { + this.row_groupby = row_groupby; + this.need_redraw = true; + }, + + set_col_groupby: function (col_groupby) { + this.col_groupby = col_groupby; + this.need_redraw = true; + }, + + set_measure: function (measure) { + this.measure = measure; this.need_redraw = true; }, @@ -131,6 +153,12 @@ var BasicDataView = instance.web.Widget.extend({ draw: function() { }, + + get_data: function (groupby) { + var view_fields = this.row_groupby.concat(this.measure, this.col_groupby); + return query_groups(this.model, view_fields, this.domain, groupby); + }, + }); /** @@ -141,24 +169,29 @@ var PivotTable = BasicDataView.extend({ template: 'pivot_table', draw: function () { + this.get_data(this.row_groupby).done(this._draw.bind(this)); + }, + + _draw: function (data) { + console.log("data",data); this.$el.empty(); var self = this; - var rows = ' fa-sort-asc' + - this.fields[this.groupby[0]].string + + var rows = '' + + this.fields[this.row_groupby[0]].string + '' + this.measure_label + ''; - _.each(this.data, function (datapt) { + + _.each(data, function (datapt) { rows += '' + datapt.attributes.value[1] + '' + datapt.attributes.aggregates[self.measure] + ''; }); - this.$el.append(rows); - }, + } }); /** @@ -180,9 +213,12 @@ var ChartView = BasicDataView.extend({ }, draw: function () { + var self = this; this.$el.empty(); this.$el.append(''); - this.render(); + this.get_data(this.row_groupby).done(function (data) { + self.render(data); + }); }, format_data: function (datapt) { @@ -193,10 +229,10 @@ var ChartView = BasicDataView.extend({ }; }, - render_bar_chart: function () { + render_bar_chart: function (data) { var formatted_data = [{ key: 'Bar chart', - values: _.map(this.data, this.format_data.bind(this)), + values: _.map(data, this.format_data.bind(this)), }]; nv.addGraph(function () { @@ -218,10 +254,10 @@ var ChartView = BasicDataView.extend({ }); }, - render_line_chart: function () { + render_line_chart: function (data) { var formatted_data = [{ key: this.measure_label, - values: _.map(this.data, this.format_data.bind(this)) + values: _.map(data, this.format_data.bind(this)) }]; nv.addGraph(function () { @@ -241,8 +277,8 @@ var ChartView = BasicDataView.extend({ }); }, - render_pie_chart: function () { - var formatted_data = _.map(this.data, this.format_data.bind(this)); + render_pie_chart: function (data) { + var formatted_data = _.map(data, this.format_data.bind(this)); nv.addGraph(function () { var chart = nv.models.pieChart() -- cgit v1.2.3 From cecac9a32a786a4bdb5d0e0c8a4847738c7ffc00 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 13 Nov 2013 15:44:24 +0100 Subject: [IMP] improve the rendering of the table in pivottable widget (addon web_graph) bzr revid: ged@openerp.com-20131113144424-8i4ld0fjggw6nled --- addons/web_graph/static/src/js/graph.js | 73 +++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 21 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 0361cd12e0d..f400f76d459 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -167,30 +167,67 @@ var BasicDataView = instance.web.Widget.extend({ */ var PivotTable = BasicDataView.extend({ template: 'pivot_table', + rows: null, + cols: null, draw: function () { - this.get_data(this.row_groupby).done(this._draw.bind(this)); + this.get_data(this.row_groupby) + .then(this.proxy('build_table')) + .done(this.proxy('_draw')); }, - _draw: function (data) { - console.log("data",data); + build_table: function (data) { + var self = this; + function make_cell (content, is_border) { + return '' + content + ''; + } + + this.cols = [{ + path: [], + value: this.measure_label, + expanded: false, + parent: null, + children: [], + html_tds: [], + domain: this.domain, + header: $(make_cell(this.measure_label, true)), + }]; + + this.rows = _.map(data, function (datapt) { + var row = $(''); + row.html(make_cell(datapt.attributes.value[1], true)); + row.append(make_cell(datapt.attributes.aggregates[self.measure])); + + return { + path: [datapt.attributes.grouped_on], + value: datapt.attributes.value[1], + expanded: false, + parent: null, + children: [], + html_tr: row, + domain: datapt.model._domain + }; + }); + }, + + _draw: function () { + this.$el.empty(); var self = this; - var rows = '' + + var header = '' + this.fields[this.row_groupby[0]].string + '' + this.measure_label + ''; + this.$el.append(header); - _.each(data, function (datapt) { - rows += '' + - datapt.attributes.value[1] + - '' + - datapt.attributes.aggregates[self.measure] + - ''; + _.each(this.rows, function (row) { + self.$el.append(row.html_tr); }); - this.$el.append(rows); + } }); @@ -202,13 +239,7 @@ var ChartView = BasicDataView.extend({ template: 'chart_view', set_mode: function (mode) { - var render_functions = { - 'bar_chart' : this.render_bar_chart, - 'line_chart' : this.render_line_chart, - 'pie_chart' : this.render_pie_chart, - }; - - this.render = render_functions[mode]; + this.render = this['render_' + mode]; this.need_redraw = true; }, @@ -232,7 +263,7 @@ var ChartView = BasicDataView.extend({ render_bar_chart: function (data) { var formatted_data = [{ key: 'Bar chart', - values: _.map(data, this.format_data.bind(this)), + values: _.map(data, this.proxy('format_data')), }]; nv.addGraph(function () { @@ -257,7 +288,7 @@ var ChartView = BasicDataView.extend({ render_line_chart: function (data) { var formatted_data = [{ key: this.measure_label, - values: _.map(data, this.format_data.bind(this)) + values: _.map(data, this.proxy('format_data')) }]; nv.addGraph(function () { @@ -278,7 +309,7 @@ var ChartView = BasicDataView.extend({ }, render_pie_chart: function (data) { - var formatted_data = _.map(data, this.format_data.bind(this)); + var formatted_data = _.map(data, this.proxy('format_data')); nv.addGraph(function () { var chart = nv.models.pieChart() -- cgit v1.2.3 From 26e6a496bebb3200c58e37b5e5bb7f167e0f3618 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 13 Nov 2013 16:47:31 +0100 Subject: [IMP] work in progress. goal is to allow expansion of rows/cols in pivottable (addon web_graph) bzr revid: ged@openerp.com-20131113154731-lmhcyajqcf2k4bxt --- addons/web_graph/static/src/js/graph.js | 97 +++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 22 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index f400f76d459..bc1040e9df9 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -41,29 +41,62 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_loading: function (fields_view_get) { var self = this; var model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); - var measure = null; - this.groupbys = []; + var options = {}; + options.domain = []; + options.col_groupby = []; // get the default groupbys and measure defined in the field view + options.measure = null; + options.row_groupby = []; _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { if ('operator' in field.attrs) { - measure = field.attrs.name; + options.measure = field.attrs.name; } else { - self.groupbys.push(field.attrs.name); + options.row_groupby.push(field.attrs.name); } } }); - return model.call('fields_get', []).then(function (fields) { - self.pivot_table = new PivotTable(model, fields, [], self.groupbys, [], measure); - self.chart_view = new ChartView(model, fields, [], self.groupbys, [], measure); - return self.pivot_table.appendTo('.graph_main_content'); - }).then(function() { - return self.chart_view.appendTo('.graph_main_content'); + // get the most important fields (of the model) by looking at the + // groupby filters defined in the search view + options.important_fields = [] + var load_view = instance.web.fields_view_get({ + model: model, + view_type: 'search', }); + var important_fields_def = $.when(load_view).then(function (search_view) { + var groups = _.select(search_view.arch.children, function (c) { + return (c.tag == 'group') && (c.attrs.string != 'Display'); + }); + _.each(groups, function(g) { + _.each(g.children, function (g) { + if (g.attrs.context) { + var field_id = py.eval(g.attrs.context).group_by; + options.important_fields.push(field_id); + } + }); + }); + }).then + + // get the fields descriptions from the model + var field_descr_def = model.call('fields_get', []) + .then(function (fields) { options.fields = fields; }); + + + return $.when(important_fields_def, field_descr_def) + .then(function () { + self.pivot_table = new PivotTable(model, options); + self.chart_view = new ChartView(model, options); + }) + .then(function () { + return self.pivot_table.appendTo('.graph_main_content') + }) + .then(function() { + return self.chart_view.appendTo('.graph_main_content'); + }); }, display_data : function () { @@ -107,16 +140,17 @@ var BasicDataView = instance.web.Widget.extend({ // col_groupby: idem, but on col // measure: quantity to display. either a field from the model, or // null, in which case we use the "count" measure - init: function (model, fields, domain, row_groupby, col_groupby, measure) { + init: function (model, options) { this.model = model; - this.fields = fields; - this.domain = domain; - this.row_groupby = row_groupby; - this.col_groupby = col_groupby; - this.measure = measure; - this.measure_label = measure ? fields[measure].string : 'Quantity'; + this.fields = options.fields; + this.domain = options.domain; + this.row_groupby = options.row_groupby; + this.col_groupby = options.col_groupby; + this.measure = options.measure; + this.measure_label = options.measure ? options.fields[options.measure].string : 'Quantity'; this.data = []; this.need_redraw = true; + this.important_fields = options.important_fields; }, set_domain: function (domain) { @@ -169,6 +203,20 @@ var PivotTable = BasicDataView.extend({ template: 'pivot_table', rows: null, cols: null, + current_row_id : 0, + + events: { + 'click .graph_border a' : function (event) { + event.preventDefault(); + var row_id = event.target.attributes['data-row-id'].nodeValue; + console.log("clickclick on row ", row_id); + }, + }, + + generate_id: function () { + this.current_row_id += 1; + return this.current_row_id - 1; + }, draw: function () { this.get_data(this.row_groupby) @@ -196,19 +244,24 @@ var PivotTable = BasicDataView.extend({ }]; this.rows = _.map(data, function (datapt) { - var row = $(''); - row.html(make_cell(datapt.attributes.value[1], true)); - row.append(make_cell(datapt.attributes.aggregates[self.measure])); + var jquery_row = $(''); + var header = $(make_cell(datapt.attributes.value[1], true)); + var row_id = self.generate_id(); + + header.prepend('+ '); + jquery_row.html(header); + jquery_row.append(make_cell(datapt.attributes.aggregates[self.measure])); - return { + var row = { path: [datapt.attributes.grouped_on], value: datapt.attributes.value[1], expanded: false, parent: null, children: [], - html_tr: row, + html_tr: jquery_row, domain: datapt.model._domain }; + return row; }); }, -- cgit v1.2.3 From 4f448f36317eab36e332544a1463c85c3abaa740 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 14 Nov 2013 11:34:46 +0100 Subject: [IMP] work in progress. goal is to allow expansion of rows/cols in pivottable (addon web_graph) bzr revid: ged@openerp.com-20131114103446-qpqs3j0i8yhbvbg3 --- addons/web_graph/static/src/js/graph.js | 81 +++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 14 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index bc1040e9df9..e1c20281bd0 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -60,7 +60,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ // get the most important fields (of the model) by looking at the // groupby filters defined in the search view - options.important_fields = [] + options.important_fields = []; var load_view = instance.web.fields_view_get({ model: model, view_type: 'search', @@ -79,7 +79,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }); }); - }).then + }); // get the fields descriptions from the model var field_descr_def = model.call('fields_get', []) @@ -92,7 +92,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ self.chart_view = new ChartView(model, options); }) .then(function () { - return self.pivot_table.appendTo('.graph_main_content') + return self.pivot_table.appendTo('.graph_main_content'); }) .then(function() { return self.chart_view.appendTo('.graph_main_content'); @@ -153,6 +153,10 @@ var BasicDataView = instance.web.Widget.extend({ this.important_fields = options.important_fields; }, + get_descr: function (field_id) { + return this.fields[field_id].string; + }, + set_domain: function (domain) { this.domain = domain; this.need_redraw = true; @@ -206,18 +210,70 @@ var PivotTable = BasicDataView.extend({ current_row_id : 0, events: { - 'click .graph_border a' : function (event) { + 'click .graph_border > a' : function (event) { + var self = this; event.preventDefault(); + + var dropdown_options = { + fields: _.map(this.important_fields, function (field) { + return {id: field, value: self.fields[field].string}; + }), + row_id: event.target.attributes['data-row-id'].nodeValue, + }; + + this.dropdown = $(QWeb.render('field_selection', dropdown_options)); + + $(event.target).after(this.dropdown); + $('.field-selection').next('.dropdown-menu').toggle(); + }, + 'click a.field-selection' : function (event) { + event.preventDefault(); + this.dropdown.remove(); var row_id = event.target.attributes['data-row-id'].nodeValue; - console.log("clickclick on row ", row_id); + var field_id = event.target.attributes['data-field-id'].nodeValue; + this.expand_row(row_id, field_id); }, }, + init: function (model, options) { + this._super(model, options); + }, + generate_id: function () { this.current_row_id += 1; return this.current_row_id - 1; }, + get_row: function (id) { + return _.find(this.rows, function(row) { + return (row.id == id); + }); + }, + + make_cell: function (content, is_border) { + return '' + content + ''; + }, + + expand_row: function (row_id, field_id) { + var row = this.get_row(row_id); + this.row_groupby.push(field_id); + var visible_fields = this.row_groupby.concat(this.col_groupby, this.measure); + + console.log("model",this.model); + console.log("vf",visible_fields); + console.log("domain",row.domain); + console.log("gb",this.row_groupby); + + query_groups(this.model, visible_fields, row.domain, [field_id]) + .then(function (data) { + console.log("datapt",data); + }); + + }, +// function query_groups (model, fields, domain, groupbys) { + draw: function () { this.get_data(this.row_groupby) .then(this.proxy('build_table')) @@ -226,11 +282,7 @@ var PivotTable = BasicDataView.extend({ build_table: function (data) { var self = this; - function make_cell (content, is_border) { - return '' + content + ''; - } + this.cols = [{ path: [], @@ -240,26 +292,27 @@ var PivotTable = BasicDataView.extend({ children: [], html_tds: [], domain: this.domain, - header: $(make_cell(this.measure_label, true)), + header: $(this.make_cell(this.measure_label, true)), }]; this.rows = _.map(data, function (datapt) { var jquery_row = $(''); - var header = $(make_cell(datapt.attributes.value[1], true)); + var header = $(self.make_cell(datapt.attributes.value[1], true)); var row_id = self.generate_id(); header.prepend('+ '); jquery_row.html(header); - jquery_row.append(make_cell(datapt.attributes.aggregates[self.measure])); + jquery_row.append(self.make_cell(datapt.attributes.aggregates[self.measure])); var row = { + id: row_id, path: [datapt.attributes.grouped_on], value: datapt.attributes.value[1], expanded: false, parent: null, children: [], html_tr: jquery_row, - domain: datapt.model._domain + domain: datapt.model._domain, }; return row; }); -- cgit v1.2.3 From a38ab9c56c7316dc8984fb80474339e3d7c81e89 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 14 Nov 2013 14:17:47 +0100 Subject: [IMP] work in progress. goal is to allow expansion of rows/cols in pivottable (addon web_graph) bzr revid: ged@openerp.com-20131114131747-mq8uh02iplc0xmer --- addons/web_graph/static/src/js/graph.js | 97 +++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 35 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index e1c20281bd0..f7670ab7b60 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -205,8 +205,8 @@ var BasicDataView = instance.web.Widget.extend({ */ var PivotTable = BasicDataView.extend({ template: 'pivot_table', - rows: null, - cols: null, + rows: [], + cols: [], current_row_id : 0, events: { @@ -250,29 +250,74 @@ var PivotTable = BasicDataView.extend({ }); }, - make_cell: function (content, is_border) { - return '' + content + ''; + make_cell: function (content, options) { + var attrs = [''); + if (options && options.indent) { + _.each(_.range(options.indent), function () { + attrs.push(''); + }); + } + return attrs.join(' ') + content + ''; + }, + + make_row: function (data, parent_id) { + var has_parent = (parent_id !== undefined); + var parent = has_parent ? this.get_row(parent_id) : null; + var path = has_parent ? parent.path.concat(data.attributes.grouped_on) + : [data.attributes.grouped_on]; + + + var indent_level = has_parent ? parent.path.length : 0; + + + var jquery_row = $(''); + var header = $(this.make_cell(data.attributes.value[1], {is_border:true, indent: indent_level})); + var row_id = this.generate_id(); + + header.prepend('+ '); + jquery_row.html(header); + jquery_row.append(this.make_cell(data.attributes.aggregates[this.measure])); + + var row = { + id: row_id, + path: path, + value: data.attributes.value[1], + expanded: false, + parent: parent_id, + children: [], + html_tr: jquery_row, + domain: data.model._domain, + }; + this.rows.push(row); // to do, insert it properly + + if (has_parent) { + parent.children.push(row); + } + return row; }, expand_row: function (row_id, field_id) { + var self = this; var row = this.get_row(row_id); this.row_groupby.push(field_id); var visible_fields = this.row_groupby.concat(this.col_groupby, this.measure); - console.log("model",this.model); - console.log("vf",visible_fields); - console.log("domain",row.domain); - console.log("gb",this.row_groupby); - query_groups(this.model, visible_fields, row.domain, [field_id]) .then(function (data) { - console.log("datapt",data); + _.each(data, function (datapt) { + + var new_row = self.make_row(datapt, row_id); + row.html_tr.after(new_row.html_tr); + }); + row.expanded = true; }); }, -// function query_groups (model, fields, domain, groupbys) { draw: function () { this.get_data(this.row_groupby) @@ -292,31 +337,13 @@ var PivotTable = BasicDataView.extend({ children: [], html_tds: [], domain: this.domain, - header: $(this.make_cell(this.measure_label, true)), + header: $(this.make_cell(this.measure_label, {is_border:true})), }]; - this.rows = _.map(data, function (datapt) { - var jquery_row = $(''); - var header = $(self.make_cell(datapt.attributes.value[1], true)); - var row_id = self.generate_id(); - - header.prepend('+ '); - jquery_row.html(header); - jquery_row.append(self.make_cell(datapt.attributes.aggregates[self.measure])); - - var row = { - id: row_id, - path: [datapt.attributes.grouped_on], - value: datapt.attributes.value[1], - expanded: false, - parent: null, - children: [], - html_tr: jquery_row, - domain: datapt.model._domain, - }; - return row; + _.each(data, function (datapt) { + self.make_row(datapt); }); - }, + }, _draw: function () { -- cgit v1.2.3 From 3c16fd11320fbc381855474116f90cddb7fb44be Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 14 Nov 2013 15:00:15 +0100 Subject: [IMP] allows expansion of rows in pivottable (addon web_graph) bzr revid: ged@openerp.com-20131114140015-h1hqzl5a70921vkq --- addons/web_graph/static/src/js/graph.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index f7670ab7b60..1c3ebd74075 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -262,6 +262,9 @@ var PivotTable = BasicDataView.extend({ attrs.push(''); }); } + if (options && options.foldable) { + attrs.push(' '); + } return attrs.join(' ') + content + ''; }, @@ -276,10 +279,9 @@ var PivotTable = BasicDataView.extend({ var jquery_row = $(''); - var header = $(this.make_cell(data.attributes.value[1], {is_border:true, indent: indent_level})); var row_id = this.generate_id(); - header.prepend('+ '); + var header = $(this.make_cell(data.attributes.value[1], {is_border:true, indent: indent_level, foldable:true, row_id: row_id})); jquery_row.html(header); jquery_row.append(this.make_cell(data.attributes.aggregates[this.measure])); @@ -315,6 +317,12 @@ var PivotTable = BasicDataView.extend({ row.html_tr.after(new_row.html_tr); }); row.expanded = true; + console.log("tr",row.html_tr); + var icon = row.html_tr.find('.icon-caret-right'); + icon.removeClass('icon-caret-right') + .addClass('icon-caret-down'); + console.log("icon",icon); + // console.log("nrst",); }); }, -- cgit v1.2.3 From 3e607e8e3c9809a4279d96727a46887eebeeb69c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 14 Nov 2013 15:07:33 +0100 Subject: [IMP] changes triangle icon into + and - signs icon in pivot table (addon web_graph) bzr revid: ged@openerp.com-20131114140733-9jyvttydbb2gm5jv --- addons/web_graph/static/src/js/graph.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 1c3ebd74075..46c739121f9 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -263,7 +263,7 @@ var PivotTable = BasicDataView.extend({ }); } if (options && options.foldable) { - attrs.push(' '); + attrs.push(' '); } return attrs.join(' ') + content + ''; }, @@ -312,17 +312,13 @@ var PivotTable = BasicDataView.extend({ query_groups(this.model, visible_fields, row.domain, [field_id]) .then(function (data) { _.each(data, function (datapt) { - var new_row = self.make_row(datapt, row_id); row.html_tr.after(new_row.html_tr); }); row.expanded = true; - console.log("tr",row.html_tr); - var icon = row.html_tr.find('.icon-caret-right'); - icon.removeClass('icon-caret-right') - .addClass('icon-caret-down'); - console.log("icon",icon); - // console.log("nrst",); + var icon = row.html_tr.find('.icon-plus-sign'); + icon.removeClass('icon-plus-sign') + .addClass('icon-minus-sign'); }); }, -- cgit v1.2.3 From ba5de8088bf0448a6c015ccf0292decbc03c760c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 14 Nov 2013 16:33:48 +0100 Subject: [IMP] allows the user to clear the groupbys in pivottable (addon web_graph) bzr revid: ged@openerp.com-20131114153348-bux7ldhkhe1jl29e --- addons/web_graph/static/src/js/graph.js | 69 ++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 46c739121f9..ffc773f1c3e 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -36,6 +36,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ } this.display_data(); }, + 'click .graph_clear_groups' : function (event) { + this.pivot_table.clear_groups(); + }, }, view_loading: function (fields_view_get) { @@ -216,7 +219,7 @@ var PivotTable = BasicDataView.extend({ var dropdown_options = { fields: _.map(this.important_fields, function (field) { - return {id: field, value: self.fields[field].string}; + return {id: field, value: self.get_descr(field)}; }), row_id: event.target.attributes['data-row-id'].nodeValue, }; @@ -235,6 +238,14 @@ var PivotTable = BasicDataView.extend({ }, }, + clear_groups: function () { + this.row_groupby = []; + this.col_groupby = []; + this.rows = []; + this.cols = []; + this.draw(); + }, + init: function (model, options) { this._super(model, options); }, @@ -271,24 +282,31 @@ var PivotTable = BasicDataView.extend({ make_row: function (data, parent_id) { var has_parent = (parent_id !== undefined); var parent = has_parent ? this.get_row(parent_id) : null; - var path = has_parent ? parent.path.concat(data.attributes.grouped_on) - : [data.attributes.grouped_on]; - + var path; + if (has_parent) { + console.log("parent",parent); + path = parent.path.concat(data.attributes.grouped_on); + } else if (data.attributes.grouped_on !== undefined) { + path = [data.attributes.grouped_on]; + } else { + path = []; + } var indent_level = has_parent ? parent.path.length : 0; + var value = (this.row_groupby.length > 0) ? data.attributes.value[1] : "Total"; var jquery_row = $(''); var row_id = this.generate_id(); - var header = $(this.make_cell(data.attributes.value[1], {is_border:true, indent: indent_level, foldable:true, row_id: row_id})); + var header = $(this.make_cell(value, {is_border:true, indent: indent_level, foldable:true, row_id: row_id})); jquery_row.html(header); jquery_row.append(this.make_cell(data.attributes.aggregates[this.measure])); var row = { id: row_id, path: path, - value: data.attributes.value[1], + value: value, expanded: false, parent: parent_id, children: [], @@ -297,6 +315,9 @@ var PivotTable = BasicDataView.extend({ }; this.rows.push(row); // to do, insert it properly + if (this.row_groupby.length === 0) { + row.remove_when_expanded = true; + } if (has_parent) { parent.children.push(row); } @@ -307,18 +328,31 @@ var PivotTable = BasicDataView.extend({ var self = this; var row = this.get_row(row_id); this.row_groupby.push(field_id); + var visible_fields = this.row_groupby.concat(this.col_groupby, this.measure); + if (row.remove_when_expanded) { + this.rows = []; + row.html_tr.remove(); + } else { + row.expanded = true; + row.html_tr.find('.icon-plus-sign') + .removeClass('icon-plus-sign') + .addClass('icon-minus-sign'); + } + query_groups(this.model, visible_fields, row.domain, [field_id]) .then(function (data) { _.each(data, function (datapt) { - var new_row = self.make_row(datapt, row_id); - row.html_tr.after(new_row.html_tr); + var new_row; + if (row.remove_when_expanded) { + new_row = self.make_row(datapt); + self.$('tr.graph_table_header').after(new_row.html_tr); + } else { + new_row = self.make_row(datapt, row_id); + row.html_tr.after(new_row.html_tr); + } }); - row.expanded = true; - var icon = row.html_tr.find('.icon-plus-sign'); - icon.removeClass('icon-plus-sign') - .addClass('icon-minus-sign'); }); }, @@ -332,6 +366,7 @@ var PivotTable = BasicDataView.extend({ build_table: function (data) { var self = this; + console.log("data",data); this.cols = [{ path: [], @@ -353,12 +388,20 @@ var PivotTable = BasicDataView.extend({ this.$el.empty(); var self = this; + var header; - var header = '' + + if (this.row_groupby.length > 0) { + header = '' + this.fields[this.row_groupby[0]].string + '' + this.measure_label + ''; + } else { + header = '' + + '' + + this.measure_label + + ''; + } this.$el.append(header); _.each(this.rows, function (row) { -- cgit v1.2.3 From 2216a699087c790182bd34227d3d1d4554131b9d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 14 Nov 2013 17:31:07 +0100 Subject: [IMP] many usability fixes in pivottable drill down and up (addon web_graph) bzr revid: ged@openerp.com-20131114163107-pm3s3siwtzqn98jy --- addons/web_graph/static/src/js/graph.js | 43 +++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index ffc773f1c3e..3ab9b034ea1 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -216,18 +216,24 @@ var PivotTable = BasicDataView.extend({ 'click .graph_border > a' : function (event) { var self = this; event.preventDefault(); + var row_id = event.target.attributes['data-row-id'].nodeValue; - var dropdown_options = { - fields: _.map(this.important_fields, function (field) { - return {id: field, value: self.get_descr(field)}; - }), - row_id: event.target.attributes['data-row-id'].nodeValue, - }; - - this.dropdown = $(QWeb.render('field_selection', dropdown_options)); + var row = this.get_row(row_id); + if (row.expanded) { + this.fold_row(row_id) + } else { + var dropdown_options = { + fields: _.map(this.important_fields, function (field) { + return {id: field, value: self.get_descr(field)}; + }), + row_id: row_id, + }; + this.dropdown = $(QWeb.render('field_selection', dropdown_options)); + $(event.target).after(this.dropdown); + $('.field-selection').next('.dropdown-menu').toggle(); + } - $(event.target).after(this.dropdown); - $('.field-selection').next('.dropdown-menu').toggle(); + }, 'click a.field-selection' : function (event) { event.preventDefault(); @@ -284,7 +290,6 @@ var PivotTable = BasicDataView.extend({ var parent = has_parent ? this.get_row(parent_id) : null; var path; if (has_parent) { - console.log("parent",parent); path = parent.path.concat(data.attributes.grouped_on); } else if (data.attributes.grouped_on !== undefined) { path = [data.attributes.grouped_on]; @@ -293,7 +298,7 @@ var PivotTable = BasicDataView.extend({ } var indent_level = has_parent ? parent.path.length : 0; - var value = (this.row_groupby.length > 0) ? data.attributes.value[1] : "Total"; + var value = (this.row_groupby.length > 0) ? data.attributes.value[1] : 'Total'; var jquery_row = $(''); @@ -313,10 +318,12 @@ var PivotTable = BasicDataView.extend({ html_tr: jquery_row, domain: data.model._domain, }; + // rows.splice(index of parent if any,0,row); this.rows.push(row); // to do, insert it properly if (this.row_groupby.length === 0) { row.remove_when_expanded = true; + row.domain = this.domain; } if (has_parent) { parent.children.push(row); @@ -333,7 +340,6 @@ var PivotTable = BasicDataView.extend({ if (row.remove_when_expanded) { this.rows = []; - row.html_tr.remove(); } else { row.expanded = true; row.html_tr.find('.icon-plus-sign') @@ -343,7 +349,7 @@ var PivotTable = BasicDataView.extend({ query_groups(this.model, visible_fields, row.domain, [field_id]) .then(function (data) { - _.each(data, function (datapt) { + _.each(data.reverse(), function (datapt) { var new_row; if (row.remove_when_expanded) { new_row = self.make_row(datapt); @@ -353,10 +359,17 @@ var PivotTable = BasicDataView.extend({ row.html_tr.after(new_row.html_tr); } }); + if (row.remove_when_expanded) { + row.html_tr.remove(); + } }); }, + fold_row: function (row_id) { + + }, + draw: function () { this.get_data(this.row_groupby) .then(this.proxy('build_table')) @@ -366,8 +379,6 @@ var PivotTable = BasicDataView.extend({ build_table: function (data) { var self = this; - console.log("data",data); - this.cols = [{ path: [], value: this.measure_label, -- cgit v1.2.3 From 2609105d41cfd7ef798a87c161e84eaf0092e2f1 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 09:50:37 +0100 Subject: [IMP] allow pivottable to fold rows (addon web_graph) bzr revid: ged@openerp.com-20131115085037-nhbi5x9ooa75drnk --- addons/web_graph/static/src/js/graph.js | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 3ab9b034ea1..efde4315b29 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -220,7 +220,7 @@ var PivotTable = BasicDataView.extend({ var row = this.get_row(row_id); if (row.expanded) { - this.fold_row(row_id) + this.fold_row(row_id); } else { var dropdown_options = { fields: _.map(this.important_fields, function (field) { @@ -326,7 +326,7 @@ var PivotTable = BasicDataView.extend({ row.domain = this.domain; } if (has_parent) { - parent.children.push(row); + parent.children.push(row.id); } return row; }, @@ -360,14 +360,37 @@ var PivotTable = BasicDataView.extend({ } }); if (row.remove_when_expanded) { - row.html_tr.remove(); + row.html_tr.remove(); } }); }, fold_row: function (row_id) { + var self = this; + var row = this.get_row(row_id); + + _.each(row.children, function (child_row) { + self.remove_row(child_row); + }); + row.children = []; + + row.expanded = false; + row.html_tr.find('.icon-minus-sign') + .removeClass('icon-minus-sign') + .addClass('icon-plus-sign');; + + }, + + remove_row: function (row_id) { + var self = this; + var row = this.get_row(row_id); + + _.each(row.children, function (child_row) { + self.remove_row(child_row); + }); + row.html_tr.remove(); }, draw: function () { -- cgit v1.2.3 From fecfa8e52cdaca9925c32945da0d5638a6802c1b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 10:24:11 +0100 Subject: [IMP] makes display smarter list of options in dropdown menu on pivottable widget (addon web_graph) bzr revid: ged@openerp.com-20131115092411-abnckphk4mn9ji3z --- addons/web_graph/static/src/js/graph.js | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index efde4315b29..875a34aa92f 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -222,15 +222,22 @@ var PivotTable = BasicDataView.extend({ if (row.expanded) { this.fold_row(row_id); } else { - var dropdown_options = { - fields: _.map(this.important_fields, function (field) { - return {id: field, value: self.get_descr(field)}; - }), - row_id: row_id, - }; - this.dropdown = $(QWeb.render('field_selection', dropdown_options)); - $(event.target).after(this.dropdown); - $('.field-selection').next('.dropdown-menu').toggle(); + if (row.path.length < this.row_groupby.length) { + var field_to_expand = this.row_groupby[row.path.length]; + this.expand_row(row_id, field_to_expand); + } else { + var already_grouped = self.row_groupby.concat(self.col_groupby); + var possible_groups = _.difference(self.important_fields, already_grouped); + var dropdown_options = { + fields: _.map(possible_groups, function (field) { + return {id: field, value: self.get_descr(field)}; + }), + row_id: row_id, + }; + this.dropdown = $(QWeb.render('field_selection', dropdown_options)); + $(event.target).after(this.dropdown); + $('.field-selection').next('.dropdown-menu').toggle(); + } } @@ -334,7 +341,10 @@ var PivotTable = BasicDataView.extend({ expand_row: function (row_id, field_id) { var self = this; var row = this.get_row(row_id); - this.row_groupby.push(field_id); + + if (row.path.length == this.row_groupby.length) { + this.row_groupby.push(field_id); + } var visible_fields = this.row_groupby.concat(this.col_groupby, this.measure); -- cgit v1.2.3 From 75caaeb1a39cea51b05e41c3f5db1fe904f64f43 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 12:19:32 +0100 Subject: [IMP] smarter behavior when unfolding/refolding: check 'unfolding' level and do not ask what field to expand if it already knows (addon web_graph) bzr revid: ged@openerp.com-20131115111932-rdphi3w01nmein7t --- addons/web_graph/static/src/js/graph.js | 61 +++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 21 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 875a34aa92f..93e8d72cfe8 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -144,11 +144,15 @@ var BasicDataView = instance.web.Widget.extend({ // measure: quantity to display. either a field from the model, or // null, in which case we use the "count" measure init: function (model, options) { + var self = this; this.model = model; this.fields = options.fields; this.domain = options.domain; - this.row_groupby = options.row_groupby; - this.col_groupby = options.col_groupby; + this.groupby = { + row: options.row_groupby, + col: options.col_groupby, + }; + this.measure = options.measure; this.measure_label = options.measure ? options.fields[options.measure].string : 'Quantity'; this.data = []; @@ -166,12 +170,12 @@ var BasicDataView = instance.web.Widget.extend({ }, set_row_groupby: function (row_groupby) { - this.row_groupby = row_groupby; + this.groupby.row = row_groupby; this.need_redraw = true; }, set_col_groupby: function (col_groupby) { - this.col_groupby = col_groupby; + this.groupby.col = col_groupby; this.need_redraw = true; }, @@ -196,7 +200,7 @@ var BasicDataView = instance.web.Widget.extend({ }, get_data: function (groupby) { - var view_fields = this.row_groupby.concat(this.measure, this.col_groupby); + var view_fields = this.groupby.row.concat(this.measure, this.groupby.col); return query_groups(this.model, view_fields, this.domain, groupby); }, @@ -222,11 +226,11 @@ var PivotTable = BasicDataView.extend({ if (row.expanded) { this.fold_row(row_id); } else { - if (row.path.length < this.row_groupby.length) { - var field_to_expand = this.row_groupby[row.path.length]; + if (row.path.length < this.groupby.row.length) { + var field_to_expand = this.groupby.row[row.path.length]; this.expand_row(row_id, field_to_expand); } else { - var already_grouped = self.row_groupby.concat(self.col_groupby); + var already_grouped = self.groupby.row.concat(self.groupby.col); var possible_groups = _.difference(self.important_fields, already_grouped); var dropdown_options = { fields: _.map(possible_groups, function (field) { @@ -252,8 +256,8 @@ var PivotTable = BasicDataView.extend({ }, clear_groups: function () { - this.row_groupby = []; - this.col_groupby = []; + this.groupby.row = []; + this.groupby.col = []; this.rows = []; this.cols = []; this.draw(); @@ -305,7 +309,7 @@ var PivotTable = BasicDataView.extend({ } var indent_level = has_parent ? parent.path.length : 0; - var value = (this.row_groupby.length > 0) ? data.attributes.value[1] : 'Total'; + var value = (this.groupby.row.length > 0) ? data.attributes.value[1] : 'Total'; var jquery_row = $(''); @@ -328,7 +332,7 @@ var PivotTable = BasicDataView.extend({ // rows.splice(index of parent if any,0,row); this.rows.push(row); // to do, insert it properly - if (this.row_groupby.length === 0) { + if (this.groupby.row.length === 0) { row.remove_when_expanded = true; row.domain = this.domain; } @@ -342,11 +346,11 @@ var PivotTable = BasicDataView.extend({ var self = this; var row = this.get_row(row_id); - if (row.path.length == this.row_groupby.length) { - this.row_groupby.push(field_id); + if (row.path.length == this.groupby.row.length) { + this.groupby.row.push(field_id); } - var visible_fields = this.row_groupby.concat(this.col_groupby, this.measure); + var visible_fields = this.groupby.row.concat(this.groupby.col, this.measure); if (row.remove_when_expanded) { this.rows = []; @@ -381,15 +385,21 @@ var PivotTable = BasicDataView.extend({ var row = this.get_row(row_id); _.each(row.children, function (child_row) { - self.remove_row(child_row); + self.remove_row(child_row); }); row.children = []; row.expanded = false; row.html_tr.find('.icon-minus-sign') .removeClass('icon-minus-sign') - .addClass('icon-plus-sign');; + .addClass('icon-plus-sign'); + var fold_levels = _.map(self.rows, function(g) {return g.path.length;}); + var new_groupby_length = _.reduce(fold_levels, function (x, y) { + return Math.max(x,y); + }, 0); + + this.groupby.row.splice(new_groupby_length); }, remove_row: function (row_id) { @@ -401,10 +411,11 @@ var PivotTable = BasicDataView.extend({ }); row.html_tr.remove(); + removeFromArray(this.rows, row); }, draw: function () { - this.get_data(this.row_groupby) + this.get_data(this.groupby.row) .then(this.proxy('build_table')) .done(this.proxy('_draw')); }, @@ -434,9 +445,9 @@ var PivotTable = BasicDataView.extend({ var self = this; var header; - if (this.row_groupby.length > 0) { + if (this.groupby.row.length > 0) { header = '' + - this.fields[this.row_groupby[0]].string + + this.fields[this.groupby.row[0]].string + '' + this.measure_label + ''; @@ -471,7 +482,7 @@ var ChartView = BasicDataView.extend({ var self = this; this.$el.empty(); this.$el.append(''); - this.get_data(this.row_groupby).done(function (data) { + this.get_data(this.groupby.row).done(function (data) { self.render(data); }); }, @@ -555,6 +566,14 @@ var ChartView = BasicDataView.extend({ }); +// utility +function removeFromArray(array, element) { + var index = array.indexOf(element); + if (index > -1) { + array.splice(index, 1); + } +} + /** * Query the server and return a deferred which will return the data * with all the groupbys applied (this is done for now, but the goal -- cgit v1.2.3 From 776a57ef0cda65ce03f60d9f5bf3d466225dd4b2 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 12:26:59 +0100 Subject: [FIX] fixes a bug where the view build a table without clearing the existing rows (addon web_graph) bzr revid: ged@openerp.com-20131115112659-mzb4smcr85dq60ww --- addons/web_graph/static/src/js/graph.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 93e8d72cfe8..5a4ff51f2d4 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -144,6 +144,7 @@ var BasicDataView = instance.web.Widget.extend({ // measure: quantity to display. either a field from the model, or // null, in which case we use the "count" measure init: function (model, options) { + console.log("initializing", model, options); var self = this; this.model = model; this.fields = options.fields; @@ -422,6 +423,7 @@ var PivotTable = BasicDataView.extend({ build_table: function (data) { var self = this; + this.rows = []; this.cols = [{ path: [], -- cgit v1.2.3 From ab1411aa9eaedc8ef569aaa660cf7a3584f3ef30 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 13:13:15 +0100 Subject: [IMP] makes the text clickable in clickable cells in pivottable (addon web_graph) bzr revid: ged@openerp.com-20131115121315-2lb0mptvv44g8xjk --- addons/web_graph/static/src/js/graph.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 5a4ff51f2d4..9f94f5eb0ee 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -144,7 +144,6 @@ var BasicDataView = instance.web.Widget.extend({ // measure: quantity to display. either a field from the model, or // null, in which case we use the "count" measure init: function (model, options) { - console.log("initializing", model, options); var self = this; this.model = model; this.fields = options.fields; @@ -218,7 +217,7 @@ var PivotTable = BasicDataView.extend({ current_row_id : 0, events: { - 'click .graph_border > a' : function (event) { + 'click .web_graph_click' : function (event) { var self = this; event.preventDefault(); var row_id = event.target.attributes['data-row-id'].nodeValue; @@ -241,6 +240,9 @@ var PivotTable = BasicDataView.extend({ }; this.dropdown = $(QWeb.render('field_selection', dropdown_options)); $(event.target).after(this.dropdown); + this.dropdown.css({position:"absolute", + left:event.pageX, + top:event.pageY}); $('.field-selection').next('.dropdown-menu').toggle(); } } @@ -292,9 +294,18 @@ var PivotTable = BasicDataView.extend({ }); } if (options && options.foldable) { - attrs.push(' '); + attrs.push(''); } - return attrs.join(' ') + content + ''; + if (content) { + attrs.push(content); + } else { + attrs.push('Undefined'); + } + if (options && options.foldable) { + attrs.push(''); + } + attrs.push(''); + return attrs.join(' '); }, make_row: function (data, parent_id) { -- cgit v1.2.3 From b08a38c5286ddca7945ed73938e53b0d7e98dbd2 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 16:16:59 +0100 Subject: [REF] refactoring in progress. moves charts to its own file in addon web_graph bzr revid: ged@openerp.com-20131115151659-g1lc0ypd9v3cxg1p --- addons/web_graph/static/src/js/charts.js | 84 ++++++++++++++++++++ addons/web_graph/static/src/js/graph.js | 131 ++++++++----------------------- 2 files changed, 116 insertions(+), 99 deletions(-) create mode 100644 addons/web_graph/static/src/js/charts.js (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js new file mode 100644 index 00000000000..728b435dbd1 --- /dev/null +++ b/addons/web_graph/static/src/js/charts.js @@ -0,0 +1,84 @@ + +var formatter = function (measure) { + return function (datapt) { + var val = datapt.attributes; + return { + x: datapt.attributes.value[1], + y: measure ? val.aggregates[measure] : val.length, + }; + }; +}; + + +var Charts = { + bar_chart : function (groups, measure) { + var formatted_data = [{ + key: 'Bar chart', + values: _.map(groups, formatter(measure)), + }]; + + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .tooltips(false) + .showValues(true) + .staggerLabels(true) + .width(650) + .height(400); + + d3.select('.graph_chart svg') + .datum(formatted_data) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + }, + + line_chart: function (groups, measure, measure_label) { + var formatted_data = [{ + key: measure_label, + values: _.map(groups, formatter(measure)) + }]; + + nv.addGraph(function () { + var chart = nv.models.lineChart() + .x(function (d,u) { return u; }) + .width(600) + .height(300) + .margin({top: 30, right: 20, bottom: 20, left: 60}); + + d3.select('.graph_chart svg') + .attr('width', 600) + .attr('height', 300) + .datum(formatted_data) + .call(chart); + + return chart; + }); + }, + + pie_chart: function (groups, measure) { + var formatted_data = _.map(groups, formatter(measure)); + + nv.addGraph(function () { + var chart = nv.models.pieChart() + .color(d3.scale.category10().range()) + .width(650) + .height(400); + + d3.select('.graph_chart svg') + .datum(formatted_data) + .transition().duration(1200) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + }, + + +}; \ No newline at end of file diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 9f94f5eb0ee..ccec8f03ec3 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -126,6 +126,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); + + /** * BasicDataView widget. Basic widget to manage show/hide functionality * and to initialize some attributes. It is inherited by PivotTable @@ -206,6 +208,35 @@ var BasicDataView = instance.web.Widget.extend({ }); + + + /** + * ChartView widget. It displays the data in chart form, using the nvd3 + * library. Various modes include bar charts, pie charts or line charts. + */ +var ChartView = BasicDataView.extend({ + template: 'chart_view', + + set_mode: function (mode) { + this.mode = mode; + console.log("mode",mode); + this.render = this['render_' + mode]; + this.need_redraw = true; + }, + + draw: function () { + var self = this; + this.$el.empty(); + console.log("measrue",self.measure); + this.$el.append(''); + this.get_data(this.groupby.row).done(function (data) { + Charts[self.mode](data, self.measure, self.measure_label); + }); + }, + + + +}); /** * PivotTable widget. It displays the data in tabular data and allows the * user to drill down and up in the table @@ -479,106 +510,8 @@ var PivotTable = BasicDataView.extend({ } }); - /** - * ChartView widget. It displays the data in chart form, using the nvd3 - * library. Various modes include bar charts, pie charts or line charts. - */ -var ChartView = BasicDataView.extend({ - template: 'chart_view', - - set_mode: function (mode) { - this.render = this['render_' + mode]; - this.need_redraw = true; - }, - - draw: function () { - var self = this; - this.$el.empty(); - this.$el.append(''); - this.get_data(this.groupby.row).done(function (data) { - self.render(data); - }); - }, - - format_data: function (datapt) { - var val = datapt.attributes; - return { - x: datapt.attributes.value[1], - y: this.measure ? val.aggregates[this.measure] : val.length, - }; - }, - - render_bar_chart: function (data) { - var formatted_data = [{ - key: 'Bar chart', - values: _.map(data, this.proxy('format_data')), - }]; - - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .tooltips(false) - .showValues(true) - .staggerLabels(true) - .width(650) - .height(400); - - d3.select('.graph_chart svg') - .datum(formatted_data) - .attr('width', 650) - .attr('height', 400) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - }, - - render_line_chart: function (data) { - var formatted_data = [{ - key: this.measure_label, - values: _.map(data, this.proxy('format_data')) - }]; - - nv.addGraph(function () { - var chart = nv.models.lineChart() - .x(function (d,u) { return u; }) - .width(600) - .height(300) - .margin({top: 30, right: 20, bottom: 20, left: 60}); - - d3.select('.graph_chart svg') - .attr('width', 600) - .attr('height', 300) - .datum(formatted_data) - .call(chart); - - return chart; - }); - }, - - render_pie_chart: function (data) { - var formatted_data = _.map(data, this.proxy('format_data')); - - nv.addGraph(function () { - var chart = nv.models.pieChart() - .color(d3.scale.category10().range()) - .width(650) - .height(400); - - d3.select('.graph_chart svg') - .datum(formatted_data) - .transition().duration(1200) - .attr('width', 650) - .attr('height', 400) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - }, - -}); +//////////////////////////////////////////////////////////////////////////////// // utility function removeFromArray(array, element) { var index = array.indexOf(element); -- cgit v1.2.3 From 08a26f9e95ab5a432385d803679eba030fcb6673 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 16:37:01 +0100 Subject: [REF] refactoring in progress. moves some util functions to its own file in addon web_graph bzr revid: ged@openerp.com-20131115153701-rxh1voksnu0ule4t --- addons/web_graph/static/src/js/graph.js | 40 --------------------------------- 1 file changed, 40 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index ccec8f03ec3..48fa416ba75 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -511,45 +511,5 @@ var PivotTable = BasicDataView.extend({ }); -//////////////////////////////////////////////////////////////////////////////// -// utility -function removeFromArray(array, element) { - var index = array.indexOf(element); - if (index > -1) { - array.splice(index, 1); - } -} - -/** - * Query the server and return a deferred which will return the data - * with all the groupbys applied (this is done for now, but the goal - * is to modify read_group in order to allow eager and lazy groupbys - */ -function query_groups (model, fields, domain, groupbys) { - return model.query(fields) - .filter(domain) - .group_by(groupbys) - .then(function (results) { - var non_empty_results = _.filter(results, function (group) { - return group.attributes.length > 0; - }); - if (groupbys.length <= 1) { - return non_empty_results; - } else { - var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { - var new_domain = result.model._domain; - var new_groupings = groupbys.slice(1); - return query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { - result.subgroups_data = subgroups; - }); - })); - return get_subgroups.then(function () { - return non_empty_results; - }); - } - }); -} - - }; -- cgit v1.2.3 From 990deeebe465ae9ee992b1251b89c46683d84589 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 17:32:09 +0100 Subject: [REF] refactoring in progress. removes widget chartview and merges basicdataview with pivottable widgets in addon web_graph bzr revid: ged@openerp.com-20131115163209-iebydq0jth2f8lee --- addons/web_graph/static/src/js/charts.js | 6 +- addons/web_graph/static/src/js/graph.js | 102 +++++++++++-------------------- 2 files changed, 37 insertions(+), 71 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 728b435dbd1..f35d012b592 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -25,7 +25,7 @@ var Charts = { .width(650) .height(400); - d3.select('.graph_chart svg') + d3.select('.graph_main_content svg') .datum(formatted_data) .attr('width', 650) .attr('height', 400) @@ -49,7 +49,7 @@ var Charts = { .height(300) .margin({top: 30, right: 20, bottom: 20, left: 60}); - d3.select('.graph_chart svg') + d3.select('.graph_main_content svg') .attr('width', 600) .attr('height', 300) .datum(formatted_data) @@ -68,7 +68,7 @@ var Charts = { .width(650) .height(400); - d3.select('.graph_chart svg') + d3.select('.graph_main_content svg') .datum(formatted_data) .transition().duration(1200) .attr('width', 650) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 48fa416ba75..3b53744d9f3 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -22,18 +22,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ template: 'GraphView', display_name: _lt('Graph'), view_type: 'graph', - mode: 'pivot', // pivot => display pivot table, chart => display chart + mode: 'pivot', // pivot, bar_chart, line_chart or pie_chart events: { 'click .graph_mode_selection li' : function (event) { event.preventDefault(); - var view_mode = event.target.attributes['data-mode'].nodeValue; - if (view_mode === 'data') { - this.mode = 'pivot'; - } else { - this.mode = 'chart'; - this.chart_view.set_mode(view_mode); - } + this.mode = event.target.attributes['data-mode'].nodeValue; this.display_data(); }, 'click .graph_clear_groups' : function (event) { @@ -91,31 +85,48 @@ instance.web_graph.GraphView = instance.web.View.extend({ return $.when(important_fields_def, field_descr_def) .then(function () { + + self.data = { + model: model, + domain: options.domain, + fields: options.fields, + important_fields: options.important_fields, + measure: options.measure, + measure_label: options.fields[options.measure].string, + col_groupby: [], + row_groupby: options.row_groupby, + groups: [], + total: null, + }; self.pivot_table = new PivotTable(model, options); - self.chart_view = new ChartView(model, options); }) .then(function () { return self.pivot_table.appendTo('.graph_main_content'); - }) - .then(function() { - return self.chart_view.appendTo('.graph_main_content'); }); + }, display_data : function () { + var content = this.$el.filter('.graph_main_content'); + content.find('svg').remove(); + var self = this; if (this.mode === 'pivot') { - this.chart_view.hide(); this.pivot_table.show(); + } else { this.pivot_table.hide(); - this.chart_view.show(); + content.append(''); + var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); + query_groups(this.data.model, view_fields, this.data.domain, this.data.row_groupby).then(function (groups) { + Charts[self.mode](groups, self.data.measure, self.data.measure_label); + }); + } }, do_search: function (domain, context, group_by) { - this.domain = new instance.web.CompoundDomain(domain); + this.data.domain = new instance.web.CompoundDomain(domain); this.pivot_table.set_domain(domain); - this.chart_view.set_domain(domain); this.display_data(); }, @@ -127,14 +138,15 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); - /** - * BasicDataView widget. Basic widget to manage show/hide functionality - * and to initialize some attributes. It is inherited by PivotTable - * and ChartView widget. + * PivotTable widget. It displays the data in tabular data and allows the + * user to drill down and up in the table */ -var BasicDataView = instance.web.Widget.extend({ - +var PivotTable = instance.web.Widget.extend({ + template: 'pivot_table', + rows: [], + cols: [], + current_row_id : 0, need_redraw: false, // Input parameters: @@ -198,54 +210,12 @@ var BasicDataView = instance.web.Widget.extend({ this.$el.css('display', 'none'); }, - draw: function() { - }, get_data: function (groupby) { var view_fields = this.groupby.row.concat(this.measure, this.groupby.col); return query_groups(this.model, view_fields, this.domain, groupby); }, -}); - - - - /** - * ChartView widget. It displays the data in chart form, using the nvd3 - * library. Various modes include bar charts, pie charts or line charts. - */ -var ChartView = BasicDataView.extend({ - template: 'chart_view', - - set_mode: function (mode) { - this.mode = mode; - console.log("mode",mode); - this.render = this['render_' + mode]; - this.need_redraw = true; - }, - - draw: function () { - var self = this; - this.$el.empty(); - console.log("measrue",self.measure); - this.$el.append(''); - this.get_data(this.groupby.row).done(function (data) { - Charts[self.mode](data, self.measure, self.measure_label); - }); - }, - - - -}); - /** - * PivotTable widget. It displays the data in tabular data and allows the - * user to drill down and up in the table - */ -var PivotTable = BasicDataView.extend({ - template: 'pivot_table', - rows: [], - cols: [], - current_row_id : 0, events: { 'click .web_graph_click' : function (event) { @@ -297,10 +267,6 @@ var PivotTable = BasicDataView.extend({ this.draw(); }, - init: function (model, options) { - this._super(model, options); - }, - generate_id: function () { this.current_row_id += 1; return this.current_row_id - 1; -- cgit v1.2.3 From afb1382575c2904fb40217c8cba7fee2d3de0d17 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 15 Nov 2013 17:32:47 +0100 Subject: [ADD] forgot to add utility.js file to addon web_graph bzr revid: ged@openerp.com-20131115163247-9tv5t7w9ygcmcnnm --- addons/web_graph/static/src/js/utility.js | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 addons/web_graph/static/src/js/utility.js (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/utility.js b/addons/web_graph/static/src/js/utility.js new file mode 100644 index 00000000000..9f4ab2bb6a3 --- /dev/null +++ b/addons/web_graph/static/src/js/utility.js @@ -0,0 +1,38 @@ + +function removeFromArray(array, element) { + var index = array.indexOf(element); + if (index > -1) { + array.splice(index, 1); + } +} + +/** + * Query the server and return a deferred which will return the data + * with all the groupbys applied (this is done for now, but the goal + * is to modify read_group in order to allow eager and lazy groupbys + */ +function query_groups (model, fields, domain, groupbys) { + return model.query(fields) + .filter(domain) + .group_by(groupbys) + .then(function (results) { + var non_empty_results = _.filter(results, function (group) { + return group.attributes.length > 0; + }); + if (groupbys.length <= 1) { + return non_empty_results; + } else { + var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { + var new_domain = result.model._domain; + var new_groupings = groupbys.slice(1); + return query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { + result.subgroups_data = subgroups; + }); + })); + return get_subgroups.then(function () { + return non_empty_results; + }); + } + }); +} + -- cgit v1.2.3 From 0b9150160c89f96388b50ad6eb39bfe9595a1c50 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 18 Nov 2013 10:07:15 +0100 Subject: [REF] refactoring in progress. removes widget chartview and merges basicdataview with pivottable widgets in addon web_graph bzr revid: ged@openerp.com-20131118090715-2e9vgt7y2ynm6nql --- addons/web_graph/static/src/js/graph.js | 34 +++++++-------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 3b53744d9f3..a0762dd5ae0 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -15,8 +15,8 @@ var QWeb = instance.web.qweb; instance.web.views.add('graph', 'instance.web_graph.GraphView'); /** - * GraphView view. It mostly contains two widgets (PivotTable and ChartView) - * and some data. + * GraphView view. It mostly contains a widget (PivotTable), some data, and + * calls to charts function. */ instance.web_graph.GraphView = instance.web.View.extend({ template: 'GraphView', @@ -111,6 +111,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ content.find('svg').remove(); var self = this; if (this.mode === 'pivot') { + this.pivot_table.draw(); this.pivot_table.show(); } else { @@ -126,7 +127,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { this.data.domain = new instance.web.CompoundDomain(domain); - this.pivot_table.set_domain(domain); + this.pivot_table.set_domain(this.data.domain); this.display_data(); }, @@ -147,7 +148,6 @@ var PivotTable = instance.web.Widget.extend({ rows: [], cols: [], current_row_id : 0, - need_redraw: false, // Input parameters: // model: model to display @@ -170,39 +170,16 @@ var PivotTable = instance.web.Widget.extend({ this.measure = options.measure; this.measure_label = options.measure ? options.fields[options.measure].string : 'Quantity'; this.data = []; - this.need_redraw = true; this.important_fields = options.important_fields; }, - get_descr: function (field_id) { - return this.fields[field_id].string; - }, set_domain: function (domain) { this.domain = domain; - this.need_redraw = true; - }, - - set_row_groupby: function (row_groupby) { - this.groupby.row = row_groupby; - this.need_redraw = true; - }, - - set_col_groupby: function (col_groupby) { - this.groupby.col = col_groupby; - this.need_redraw = true; }, - set_measure: function (measure) { - this.measure = measure; - this.need_redraw = true; - }, show: function () { - if (this.need_redraw) { - this.draw(); - this.need_redraw = false; - } this.$el.css('display', 'block'); }, @@ -210,6 +187,9 @@ var PivotTable = instance.web.Widget.extend({ this.$el.css('display', 'none'); }, + get_descr: function (field_id) { + return this.fields[field_id].string; + }, get_data: function (groupby) { var view_fields = this.groupby.row.concat(this.measure, this.groupby.col); -- cgit v1.2.3 From 06b125de40269076969232fa877ea8b8ec3c61ec Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 18 Nov 2013 13:53:20 +0100 Subject: [REF] large refactoring. removes widget chartview and merges basicdataview with pivottable widgets in addon web_graph bzr revid: ged@openerp.com-20131118125320-uhy58xmxlx4nkvbt --- addons/web_graph/static/src/js/graph.js | 385 +++++++++++++------------------- 1 file changed, 157 insertions(+), 228 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index a0762dd5ae0..558e101c921 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -23,6 +23,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ display_name: _lt('Graph'), view_type: 'graph', mode: 'pivot', // pivot, bar_chart, line_chart or pie_chart + pivot_table: null, events: { 'click .graph_mode_selection li' : function (event) { @@ -30,34 +31,31 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.mode = event.target.attributes['data-mode'].nodeValue; this.display_data(); }, - 'click .graph_clear_groups' : function (event) { - this.pivot_table.clear_groups(); - }, }, view_loading: function (fields_view_get) { var self = this; var model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); - var options = {}; - options.domain = []; - options.col_groupby = []; + var domain = []; + var col_groupby = []; + var row_groupby = []; + var measure = null; + var fields; + var important_fields = []; // get the default groupbys and measure defined in the field view - options.measure = null; - options.row_groupby = []; _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { if ('operator' in field.attrs) { - options.measure = field.attrs.name; + measure = field.attrs.name; } else { - options.row_groupby.push(field.attrs.name); + row_groupby.push(field.attrs.name); } } }); // get the most important fields (of the model) by looking at the // groupby filters defined in the search view - options.important_fields = []; var load_view = instance.web.fields_view_get({ model: model, view_type: 'search', @@ -67,12 +65,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ var groups = _.select(search_view.arch.children, function (c) { return (c.tag == 'group') && (c.attrs.string != 'Display'); }); - _.each(groups, function(g) { _.each(g.children, function (g) { if (g.attrs.context) { var field_id = py.eval(g.attrs.context).group_by; - options.important_fields.push(field_id); + important_fields.push(field_id); } }); }); @@ -80,30 +77,23 @@ instance.web_graph.GraphView = instance.web.View.extend({ // get the fields descriptions from the model var field_descr_def = model.call('fields_get', []) - .then(function (fields) { options.fields = fields; }); - + .then(function (fs) { fields = fs; }); return $.when(important_fields_def, field_descr_def) .then(function () { - self.data = { model: model, - domain: options.domain, - fields: options.fields, - important_fields: options.important_fields, - measure: options.measure, - measure_label: options.fields[options.measure].string, + domain: domain, + fields: fields, + important_fields: important_fields, + measure: measure, + measure_label: fields[measure].string, col_groupby: [], - row_groupby: options.row_groupby, + row_groupby: row_groupby, groups: [], total: null, }; - self.pivot_table = new PivotTable(model, options); - }) - .then(function () { - return self.pivot_table.appendTo('.graph_main_content'); }); - }, display_data : function () { @@ -111,9 +101,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ content.find('svg').remove(); var self = this; if (this.mode === 'pivot') { - this.pivot_table.draw(); this.pivot_table.show(); - } else { this.pivot_table.hide(); content.append(''); @@ -127,7 +115,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { this.data.domain = new instance.web.CompoundDomain(domain); - this.pivot_table.set_domain(this.data.domain); + + if (this.pivot_table) { + this.pivot_table.draw(); + } else { + this.pivot_table = new PivotTable(this.data); + this.pivot_table.appendTo('.graph_main_content'); + } this.display_data(); }, @@ -139,64 +133,19 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); + /** * PivotTable widget. It displays the data in tabular data and allows the * user to drill down and up in the table */ var PivotTable = instance.web.Widget.extend({ template: 'pivot_table', + data: null, + headers: [], rows: [], cols: [], current_row_id : 0, - // Input parameters: - // model: model to display - // fields: dictionary returned by field_get on model (desc of model) - // domain: constraints on model records - // row_groupby: groubys on rows (so, row headers in the pivot table) - // col_groupby: idem, but on col - // measure: quantity to display. either a field from the model, or - // null, in which case we use the "count" measure - init: function (model, options) { - var self = this; - this.model = model; - this.fields = options.fields; - this.domain = options.domain; - this.groupby = { - row: options.row_groupby, - col: options.col_groupby, - }; - - this.measure = options.measure; - this.measure_label = options.measure ? options.fields[options.measure].string : 'Quantity'; - this.data = []; - this.important_fields = options.important_fields; - }, - - - set_domain: function (domain) { - this.domain = domain; - }, - - - show: function () { - this.$el.css('display', 'block'); - }, - - hide: function () { - this.$el.css('display', 'none'); - }, - - get_descr: function (field_id) { - return this.fields[field_id].string; - }, - - get_data: function (groupby) { - var view_fields = this.groupby.row.concat(this.measure, this.groupby.col); - return query_groups(this.model, view_fields, this.domain, groupby); - }, - - events: { 'click .web_graph_click' : function (event) { var self = this; @@ -207,12 +156,12 @@ var PivotTable = instance.web.Widget.extend({ if (row.expanded) { this.fold_row(row_id); } else { - if (row.path.length < this.groupby.row.length) { - var field_to_expand = this.groupby.row[row.path.length]; + if (row.path.length < this.data.row_groupby.length) { + var field_to_expand = this.data.row_groupby[row.path.length]; this.expand_row(row_id, field_to_expand); } else { - var already_grouped = self.groupby.row.concat(self.groupby.col); - var possible_groups = _.difference(self.important_fields, already_grouped); + var already_grouped = self.data.row_groupby.concat(self.data.col_groupby); + var possible_groups = _.difference(self.data.important_fields, already_grouped); var dropdown_options = { fields: _.map(possible_groups, function (field) { return {id: field, value: self.get_descr(field)}; @@ -221,14 +170,13 @@ var PivotTable = instance.web.Widget.extend({ }; this.dropdown = $(QWeb.render('field_selection', dropdown_options)); $(event.target).after(this.dropdown); - this.dropdown.css({position:"absolute", - left:event.pageX, + this.dropdown.css({position:'absolute', + left:event.pageX, top:event.pageY}); $('.field-selection').next('.dropdown-menu').toggle(); } } - }, 'click a.field-selection' : function (event) { event.preventDefault(); @@ -238,133 +186,167 @@ var PivotTable = instance.web.Widget.extend({ this.expand_row(row_id, field_id); }, }, + + init: function (data) { + this.data = data; + }, - clear_groups: function () { - this.groupby.row = []; - this.groupby.col = []; - this.rows = []; - this.cols = []; - this.draw(); + start: function () { + var self = this; + this.get_groups(this.data.row_groupby) + .then(function (groups) { + self.data.groups = groups; + return self.get_groups([]); + }).then(function (total) { + self.data.total = total; + self.build_table(); + self.draw(); + }); }, - generate_id: function () { - this.current_row_id += 1; - return this.current_row_id - 1; + draw: function () { + var self = this; + this.$el.empty(); + + _.each(this.headers, function (header) { + self.$el.append(header); + }); + + _.each(this.rows, function (row) { + self.$el.append(row.html); + }); }, - get_row: function (id) { - return _.find(this.rows, function(row) { - return (row.id == id); + show: function () { + this.$el.css('display', 'block'); + }, + + hide: function () { + this.$el.css('display', 'none'); + }, + + build_table: function () { + var self = this; + + this.headers.push('' + + '' + + this.data.measure_label + + ''); + + var main_row = this.make_row(this.data.total[0]); + + _.each(this.data.groups, function (group) { + self.make_row(group, main_row.id); }); }, - make_cell: function (content, options) { - var attrs = [''); - if (options && options.indent) { - _.each(_.range(options.indent), function () { - attrs.push(''); - }); - } - if (options && options.foldable) { - attrs.push(''); - } - if (content) { - attrs.push(content); - } else { - attrs.push('Undefined'); - } - if (options && options.foldable) { - attrs.push(''); - } - attrs.push(''); - return attrs.join(' '); + get_groups: function (groupby) { + var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); + return query_groups(this.data.model, view_fields, this.data.domain, groupby); }, - make_row: function (data, parent_id) { - var has_parent = (parent_id !== undefined); - var parent = has_parent ? this.get_row(parent_id) : null; - var path; + make_row: function (group, parent_id) { + var path, + value, + expanded, + domain, + parent, + has_parent = (parent_id !== undefined), + row_id = this.generate_id(); + if (has_parent) { - path = parent.path.concat(data.attributes.grouped_on); - } else if (data.attributes.grouped_on !== undefined) { - path = [data.attributes.grouped_on]; + parent = this.get_row(parent_id); + path = parent.path.concat(group.attributes.grouped_on); + value = group.attributes.value[1]; + expanded = false; + parent.children.push(row_id); + domain = group.model._domain; } else { + parent = null; path = []; + value = 'Total'; + expanded = true; + domain = this.data.domain; } - var indent_level = has_parent ? parent.path.length : 0; - var value = (this.groupby.row.length > 0) ? data.attributes.value[1] : 'Total'; - - var jquery_row = $(''); - var row_id = this.generate_id(); - var header = $(this.make_cell(value, {is_border:true, indent: indent_level, foldable:true, row_id: row_id})); + var header = this.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); jquery_row.html(header); - jquery_row.append(this.make_cell(data.attributes.aggregates[this.measure])); + jquery_row.append(this.make_cell(group.attributes.aggregates[this.data.measure])); var row = { id: row_id, path: path, value: value, - expanded: false, + expanded: expanded, parent: parent_id, children: [], - html_tr: jquery_row, - domain: data.model._domain, + html: jquery_row, + domain: domain, }; - // rows.splice(index of parent if any,0,row); - this.rows.push(row); // to do, insert it properly + this.rows.push(row); // to do, insert it properly, after all childs of parent + return row; + }, - if (this.groupby.row.length === 0) { - row.remove_when_expanded = true; - row.domain = this.domain; - } - if (has_parent) { - parent.children.push(row.id); + generate_id: function () { + this.current_row_id += 1; + return this.current_row_id - 1; + }, + + get_row: function (id) { + return _.find(this.rows, function(row) { + return (row.id == id); + }); + }, + + make_cell: function (content, options) { + options = _.extend({is_border: false, indent:0, foldable:false}, options); + content = (content) ? content : 'Undefined'; + + var cell = $(''); + if (options.is_border) cell.addClass('graph_border'); + _.each(_.range(options.indent), function () { + cell.prepend($('', {class:'web_graph_indent'})); + }); + + if (options.foldable) { + var plus = $('', {'data-row-id':options.row_id, + class:'icon-plus-sign web_graph_click', + href:'#'}); + plus.append(' '); + plus.append(content); + cell.append(plus); + } else { + cell.append(content); } - return row; + return cell; }, expand_row: function (row_id, field_id) { var self = this; var row = this.get_row(row_id); - if (row.path.length == this.groupby.row.length) { - this.groupby.row.push(field_id); + if (row.path.length == this.data.row_groupby.length) { + this.data.row_groupby.push(field_id); } + row.expanded = true; + row.html.find('.icon-plus-sign') + .removeClass('icon-plus-sign') + .addClass('icon-minus-sign'); - var visible_fields = this.groupby.row.concat(this.groupby.col, this.measure); - - if (row.remove_when_expanded) { - this.rows = []; - } else { - row.expanded = true; - row.html_tr.find('.icon-plus-sign') - .removeClass('icon-plus-sign') - .addClass('icon-minus-sign'); - } - - query_groups(this.model, visible_fields, row.domain, [field_id]) + var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); + query_groups(this.data.model, visible_fields, row.domain, [field_id]) .then(function (data) { _.each(data.reverse(), function (datapt) { - var new_row; - if (row.remove_when_expanded) { - new_row = self.make_row(datapt); - self.$('tr.graph_table_header').after(new_row.html_tr); - } else { - new_row = self.make_row(datapt, row_id); - row.html_tr.after(new_row.html_tr); - } + var new_row = self.make_row(datapt, row_id); + row.html.after(new_row.html); + }); - if (row.remove_when_expanded) { - row.html_tr.remove(); - } }); }, @@ -379,7 +361,7 @@ var PivotTable = instance.web.Widget.extend({ row.children = []; row.expanded = false; - row.html_tr.find('.icon-minus-sign') + row.html.find('.icon-minus-sign') .removeClass('icon-minus-sign') .addClass('icon-plus-sign'); @@ -388,7 +370,7 @@ var PivotTable = instance.web.Widget.extend({ return Math.max(x,y); }, 0); - this.groupby.row.splice(new_groupby_length); + this.data.row_groupby.splice(new_groupby_length); }, remove_row: function (row_id) { @@ -399,63 +381,10 @@ var PivotTable = instance.web.Widget.extend({ self.remove_row(child_row); }); - row.html_tr.remove(); + row.html.remove(); removeFromArray(this.rows, row); }, - draw: function () { - this.get_data(this.groupby.row) - .then(this.proxy('build_table')) - .done(this.proxy('_draw')); - }, - - build_table: function (data) { - var self = this; - this.rows = []; - - this.cols = [{ - path: [], - value: this.measure_label, - expanded: false, - parent: null, - children: [], - html_tds: [], - domain: this.domain, - header: $(this.make_cell(this.measure_label, {is_border:true})), - }]; - - _.each(data, function (datapt) { - self.make_row(datapt); - }); - }, - - _draw: function () { - - this.$el.empty(); - var self = this; - var header; - - if (this.groupby.row.length > 0) { - header = '' + - this.fields[this.groupby.row[0]].string + - '' + - this.measure_label + - ''; - } else { - header = '' + - '' + - this.measure_label + - ''; - } - this.$el.append(header); - - _.each(this.rows, function (row) { - self.$el.append(row.html_tr); - }); - - } }); - }; - -- cgit v1.2.3 From b34a2307cd60d857d4bcbf8cec053cf6748a8dc0 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 18 Nov 2013 14:07:56 +0100 Subject: [REF] moves the loading data code from start to draw function, in widget pivottable (addon web_graph) bzr revid: ged@openerp.com-20131118130756-rx6wqcejn92j5sl4 --- addons/web_graph/static/src/js/graph.js | 45 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 558e101c921..a1a9ef68429 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -117,7 +117,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.data.domain = new instance.web.CompoundDomain(domain); if (this.pivot_table) { - this.pivot_table.draw(); + this.pivot_table.draw(true); } else { this.pivot_table = new PivotTable(this.data); this.pivot_table.appendTo('.graph_main_content'); @@ -133,7 +133,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); - /** * PivotTable widget. It displays the data in tabular data and allows the * user to drill down and up in the table @@ -186,35 +185,39 @@ var PivotTable = instance.web.Widget.extend({ this.expand_row(row_id, field_id); }, }, - + init: function (data) { this.data = data; }, start: function () { - var self = this; - this.get_groups(this.data.row_groupby) - .then(function (groups) { - self.data.groups = groups; - return self.get_groups([]); - }).then(function (total) { - self.data.total = total; - self.build_table(); - self.draw(); - }); + this.draw(true); }, - draw: function () { + draw: function (load_data) { var self = this; - this.$el.empty(); - _.each(this.headers, function (header) { - self.$el.append(header); - }); + if (load_data === true) { + this.get_groups(this.data.row_groupby) + .then(function (groups) { + self.data.groups = groups; + return self.get_groups([]); + }).then(function (total) { + self.data.total = total; + self.build_table(); + self.draw(false); + }); + } else { + this.$el.empty(); - _.each(this.rows, function (row) { - self.$el.append(row.html); - }); + _.each(this.headers, function (header) { + self.$el.append(header); + }); + + _.each(this.rows, function (row) { + self.$el.append(row.html); + }); + } }, show: function () { -- cgit v1.2.3 From a6848a195a60b9b0d2a6a65daa2716dbeece4708 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 18 Nov 2013 15:19:55 +0100 Subject: [IMP] small code cleanup in addon web_graph bzr revid: ged@openerp.com-20131118141955-00qcb19wm0gswvck --- addons/web_graph/static/src/js/graph.js | 49 +++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index a1a9ef68429..4f8c579cfc3 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -147,11 +147,11 @@ var PivotTable = instance.web.Widget.extend({ events: { 'click .web_graph_click' : function (event) { - var self = this; + var row_id = event.target.attributes['data-row-id'].nodeValue, + row = this.get_row(row_id); + event.preventDefault(); - var row_id = event.target.attributes['data-row-id'].nodeValue; - var row = this.get_row(row_id); if (row.expanded) { this.fold_row(row_id); } else { @@ -159,24 +159,12 @@ var PivotTable = instance.web.Widget.extend({ var field_to_expand = this.data.row_groupby[row.path.length]; this.expand_row(row_id, field_to_expand); } else { - var already_grouped = self.data.row_groupby.concat(self.data.col_groupby); - var possible_groups = _.difference(self.data.important_fields, already_grouped); - var dropdown_options = { - fields: _.map(possible_groups, function (field) { - return {id: field, value: self.get_descr(field)}; - }), - row_id: row_id, - }; - this.dropdown = $(QWeb.render('field_selection', dropdown_options)); - $(event.target).after(this.dropdown); - this.dropdown.css({position:'absolute', - left:event.pageX, - top:event.pageY}); - $('.field-selection').next('.dropdown-menu').toggle(); + this.display_dropdown(row_id, $(event.target), event.pageY, event.pageY); } } }, + 'click a.field-selection' : function (event) { event.preventDefault(); this.dropdown.remove(); @@ -228,13 +216,32 @@ var PivotTable = instance.web.Widget.extend({ this.$el.css('display', 'none'); }, + display_dropdown: function (row_id, target, x, y) { + var self = this, + already_grouped = self.data.row_groupby.concat(self.data.col_groupby), + possible_groups = _.difference(self.data.important_fields, already_grouped), + dropdown_options = { + fields: _.map(possible_groups, function (field) { + return {id: field, value: self.get_descr(field)}; + }), + row_id: row_id, + }; + this.dropdown = $(QWeb.render('field_selection', dropdown_options)); + target.after(this.dropdown); + this.dropdown.css({position:'absolute', + left:x, + top:y}); + $('.field-selection').next('.dropdown-menu').toggle(); + }, + build_table: function () { var self = this; - this.headers.push('' + - '' + - this.data.measure_label + - ''); + var header = $(''); + header.append(this.make_cell(' ', {is_border:true})); + header.append(this.make_cell(this.data.measure_label, + {is_border:true, foldable: true})); + this.headers = [header]; var main_row = this.make_row(this.data.total[0]); -- cgit v1.2.3 From 1901b38c16648267077a3a2f5671ba1f2ad04ba3 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 18 Nov 2013 16:26:20 +0100 Subject: [IMP] preliminary work on supporting col expansion in pivottable widget (addon web_graph) bzr revid: ged@openerp.com-20131118152620-srzpkuom8rmxlik1 --- addons/web_graph/static/src/js/graph.js | 101 ++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 23 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 4f8c579cfc3..949739c7ae1 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -143,26 +143,18 @@ var PivotTable = instance.web.Widget.extend({ headers: [], rows: [], cols: [], - current_row_id : 0, + id_seed : 0, events: { 'click .web_graph_click' : function (event) { - var row_id = event.target.attributes['data-row-id'].nodeValue, - row = this.get_row(row_id); - event.preventDefault(); - if (row.expanded) { - this.fold_row(row_id); - } else { - if (row.path.length < this.data.row_groupby.length) { - var field_to_expand = this.data.row_groupby[row.path.length]; - this.expand_row(row_id, field_to_expand); - } else { - this.display_dropdown(row_id, $(event.target), event.pageY, event.pageY); - } + if (event.target.attributes['data-row-id'] !== undefined) { + this.handle_row_event(event); + } + if (event.target.attributes['data-col-id'] !== undefined) { + this.handle_col_event(event); } - }, 'click a.field-selection' : function (event) { @@ -174,6 +166,39 @@ var PivotTable = instance.web.Widget.extend({ }, }, + handle_row_event: function (event) { + var row_id = event.target.attributes['data-row-id'].nodeValue, + row = this.get_row(row_id); + + if (row.expanded) { + this.fold_row(row_id); + } else { + if (row.path.length < this.data.row_groupby.length) { + var field_to_expand = this.data.row_groupby[row.path.length]; + this.expand_row(row_id, field_to_expand); + } else { + this.display_dropdown(row_id, $(event.target), event.pageY, event.pageY); + } + } + }, + + handle_col_event: function (event) { + console.log("col expand", this.cols); + // var col_id = event.target.attributes['data-col-id'].nodeValue, + // col = this.get_row(col_id); + + // if (col.expanded) { + // this.fold_row(row_id); + // } else { + // if (col.path.length < this.data.col_groupby.length) { + // var field_to_expand = this.data.col_groupby[col.path.length]; + // this.expand_col(col_id, field_to_expand); + // } else { + // this.display_dropdown(col_id, $(event.target), event.pageY, event.pageY); + // } + // } + }, + init: function (data) { this.data = data; }, @@ -237,12 +262,24 @@ var PivotTable = instance.web.Widget.extend({ build_table: function () { var self = this; + var col_id = this.generate_id(); + var header = $(''); header.append(this.make_cell(' ', {is_border:true})); header.append(this.make_cell(this.data.measure_label, - {is_border:true, foldable: true})); + {is_border:true, foldable: true, col_id:col_id})); this.headers = [header]; + this.cols= [{ + path: [], + value: this.data.measure_label, + expanded: false, + parent: null, + children: [], + cells: [], // a cell is {td:, row_id:} + domain: this.data.domain, + }]; + var main_row = this.make_row(this.data.total[0]); _.each(this.data.groups, function (group) { @@ -286,8 +323,14 @@ var PivotTable = instance.web.Widget.extend({ var jquery_row = $(''); var header = this.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); + var cell = this.make_cell(group.attributes.aggregates[this.data.measure]); jquery_row.html(header); - jquery_row.append(this.make_cell(group.attributes.aggregates[this.data.measure])); + jquery_row.append(cell); + + _.each(this.cols, function (col) { + col.cells.push({row_id: row_id, td: cell }); + // insert cells into corresponding col + }); var row = { id: row_id, @@ -304,8 +347,8 @@ var PivotTable = instance.web.Widget.extend({ }, generate_id: function () { - this.current_row_id += 1; - return this.current_row_id - 1; + this.id_seed += 1; + return this.id_seed - 1; }, get_row: function (id) { @@ -314,9 +357,15 @@ var PivotTable = instance.web.Widget.extend({ }); }, + get_col: function (id) { + return _.find(this.cols, function(col) { + return (col.id == id); + }); + }, + make_cell: function (content, options) { options = _.extend({is_border: false, indent:0, foldable:false}, options); - content = (content) ? content : 'Undefined'; + content = (content !== undefined) ? content : 'Undefined'; var cell = $(''); if (options.is_border) cell.addClass('graph_border'); @@ -325,9 +374,10 @@ var PivotTable = instance.web.Widget.extend({ }); if (options.foldable) { - var plus = $('', {'data-row-id':options.row_id, - class:'icon-plus-sign web_graph_click', - href:'#'}); + var attrs = {class:'icon-plus-sign web_graph_click', href:'#'}; + if (options.row_id !== undefined) attrs['data-row-id'] = options.row_id; + if (options.col_id !== undefined) attrs['data-col-id'] = options.col_id; + var plus = $('', attrs); plus.append(' '); plus.append(content); cell.append(plus); @@ -355,7 +405,6 @@ var PivotTable = instance.web.Widget.extend({ _.each(data.reverse(), function (datapt) { var new_row = self.make_row(datapt, row_id); row.html.after(new_row.html); - }); }); @@ -393,6 +442,12 @@ var PivotTable = instance.web.Widget.extend({ row.html.remove(); removeFromArray(this.rows, row); + + _.each(this.cols, function (col) { + col.cells = _.filter(col.cells, function (cell) { + return cell.row_id !== row_id; + }); + }); }, }); -- cgit v1.2.3 From 40ededd5401624b65392c3936e739217e5f5e0a8 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 19 Nov 2013 10:20:53 +0100 Subject: [IMP] preliminary work on supporting col expansion in pivottable widget (addon web_graph) bzr revid: ged@openerp.com-20131119092053-hp1pdgckiplw8mgp --- addons/web_graph/static/src/js/graph.js | 71 +++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 25 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 949739c7ae1..83b99d63b36 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -158,11 +158,18 @@ var PivotTable = instance.web.Widget.extend({ }, 'click a.field-selection' : function (event) { + var id, + field_id = event.target.attributes['data-field-id'].nodeValue; event.preventDefault(); this.dropdown.remove(); - var row_id = event.target.attributes['data-row-id'].nodeValue; - var field_id = event.target.attributes['data-field-id'].nodeValue; - this.expand_row(row_id, field_id); + if (event.target.attributes['data-row-id'] !== undefined) { + var id = event.target.attributes['data-row-id'].nodeValue; + this.expand_row(id, field_id); + } + if (event.target.attributes['data-col-id'] !== undefined) { + var id = event.target.attributes['data-col-id'].nodeValue; + this.expand_col(id, field_id); + } }, }, @@ -177,26 +184,31 @@ var PivotTable = instance.web.Widget.extend({ var field_to_expand = this.data.row_groupby[row.path.length]; this.expand_row(row_id, field_to_expand); } else { - this.display_dropdown(row_id, $(event.target), event.pageY, event.pageY); + this.display_dropdown({row_id:row_id, + target: $(event.target), + x: event.pageY, + y: event.pageY}); } } }, handle_col_event: function (event) { - console.log("col expand", this.cols); - // var col_id = event.target.attributes['data-col-id'].nodeValue, - // col = this.get_row(col_id); - - // if (col.expanded) { - // this.fold_row(row_id); - // } else { - // if (col.path.length < this.data.col_groupby.length) { - // var field_to_expand = this.data.col_groupby[col.path.length]; - // this.expand_col(col_id, field_to_expand); - // } else { - // this.display_dropdown(col_id, $(event.target), event.pageY, event.pageY); - // } - // } + var col_id = event.target.attributes['data-col-id'].nodeValue, + col = this.get_col(col_id); + + if (col.expanded) { + this.fold_col(col_id); + } else { + if (col.path.length < this.data.col_groupby.length) { + var field_to_expand = this.data.col_groupby[col.path.length]; + this.expand_col(col_id, field_to_expand); + } else { + this.display_dropdown({col_id: col_id, + target: $(event.target), + x: event.pageX, + y: event.pageY}); + } + } }, init: function (data) { @@ -241,21 +253,25 @@ var PivotTable = instance.web.Widget.extend({ this.$el.css('display', 'none'); }, - display_dropdown: function (row_id, target, x, y) { + display_dropdown: function (options) { var self = this, already_grouped = self.data.row_groupby.concat(self.data.col_groupby), possible_groups = _.difference(self.data.important_fields, already_grouped), dropdown_options = { fields: _.map(possible_groups, function (field) { return {id: field, value: self.get_descr(field)}; - }), - row_id: row_id, - }; + })}; + if (options.row_id) { + dropdown_options.row_id= options.row_id; + } else { + dropdown_options.col_id = options.col_id; + } + this.dropdown = $(QWeb.render('field_selection', dropdown_options)); - target.after(this.dropdown); + options.target.after(this.dropdown); this.dropdown.css({position:'absolute', - left:x, - top:y}); + left:options.x, + top:options.y}); $('.field-selection').next('.dropdown-menu').toggle(); }, @@ -271,6 +287,7 @@ var PivotTable = instance.web.Widget.extend({ this.headers = [header]; this.cols= [{ + id: col_id, path: [], value: this.data.measure_label, expanded: false, @@ -410,6 +427,10 @@ var PivotTable = instance.web.Widget.extend({ }, + expand_col: function (col_id, field_id) { + console.log("expandidng col",col_id, field_id); + }, + fold_row: function (row_id) { var self = this; var row = this.get_row(row_id); -- cgit v1.2.3 From 3ce4ec44d92136a0b8e7ed01f31636aa5328373f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 19 Nov 2013 14:20:24 +0100 Subject: [IMP] preliminary work on supporting col expansion in pivottable widget (addon web_graph) bzr revid: ged@openerp.com-20131119132024-k67wlje2h14p5ptu --- addons/web_graph/static/src/js/graph.js | 79 +++++++++++++++++++++++++++---- addons/web_graph/static/src/js/utility.js | 16 +++++++ 2 files changed, 87 insertions(+), 8 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 83b99d63b36..dfcc2759ffa 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -279,11 +279,11 @@ var PivotTable = instance.web.Widget.extend({ var self = this; var col_id = this.generate_id(); - + var col_header = this.make_cell(this.data.measure_label, + {is_border:true, foldable: true, col_id:col_id}); var header = $(''); header.append(this.make_cell(' ', {is_border:true})); - header.append(this.make_cell(this.data.measure_label, - {is_border:true, foldable: true, col_id:col_id})); + header.append(col_header); this.headers = [header]; this.cols= [{ @@ -295,6 +295,7 @@ var PivotTable = instance.web.Widget.extend({ children: [], cells: [], // a cell is {td:, row_id:} domain: this.data.domain, + header: col_header }]; var main_row = this.make_row(this.data.total[0]); @@ -324,7 +325,7 @@ var PivotTable = instance.web.Widget.extend({ if (has_parent) { parent = this.get_row(parent_id); - path = parent.path.concat(group.attributes.grouped_on); + path = parent.path.concat(group.attributes.value[1]); value = group.attributes.value[1]; expanded = false; parent.children.push(row_id); @@ -418,9 +419,9 @@ var PivotTable = instance.web.Widget.extend({ var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); query_groups(this.data.model, visible_fields, row.domain, [field_id]) - .then(function (data) { - _.each(data.reverse(), function (datapt) { - var new_row = self.make_row(datapt, row_id); + .then(function (groups) { + _.each(groups.reverse(), function (group) { + var new_row = self.make_row(group, row_id); row.html.after(new_row.html); }); }); @@ -428,7 +429,69 @@ var PivotTable = instance.web.Widget.extend({ }, expand_col: function (col_id, field_id) { - console.log("expandidng col",col_id, field_id); + var self = this; + var col = this.get_col(col_id); + + console.log("expanding col",col); + if (col.path.length == this.data.col_groupby.length) { + this.data.col_groupby.push(field_id); + } + col.expanded = true; + col.header.find('.icon-plus-sign') + .removeClass('icon-plus-sign') + .addClass('icon-minus-sign'); + + + var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); + query_groups_data(this.data.model, visible_fields, col.domain, this.data.row_groupby, field_id) + .then(function (groups) { + console.log("inserting groups",groups); + console.log("this.rows",self.rows); + console.log("this.cols",self.cols); + _.each(groups, function (group) { + var new_col = { + id: self.generate_id(), + path: col.path.concat(field_id), + value: group[0].attributes.value[1], + expanded: false, + parent: col_id, + children: [], + cells: [], // a cell is {td:, row_id:} + domain: group[0].model._domain, + // header: col_header + }; + col.header.css('display','none'); + col.children.push(new_col.id); + self.cols.push(new_col); + _.each(col.cells, function (cell) { + var col_path = self.get_row(cell.row_id).path; + + var datapt = _.find(group, function (g) { + return _.isEqual(g.path.slice(1), col_path); + }); + + var value; + if (datapt === undefined) { + value = ''; + } else { + value = datapt.attributes.aggregates[self.data.measure]; + } + console.log("value", value); + // make new cell + var new_cell = { + row_id: cell.row_id, + td: self.make_cell(value) + }; + // add cell to new_col cells ({row_id, td}) + new_col.cells.push(new_cell); + // insert new cell (td) after cell.td + cell.td.after(new_cell.td); + cell.td.css('display','none'); + }); + + }); + }); + }, fold_row: function (row_id) { diff --git a/addons/web_graph/static/src/js/utility.js b/addons/web_graph/static/src/js/utility.js index 9f4ab2bb6a3..7f67ace0f4c 100644 --- a/addons/web_graph/static/src/js/utility.js +++ b/addons/web_graph/static/src/js/utility.js @@ -36,3 +36,19 @@ function query_groups (model, fields, domain, groupbys) { }); } +function query_groups_data(model, fields, domain, row_groupbys, col_groupby) { + return query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { + return _.map(groups, function (group) { + return format_group(group, []); + }); + }); +} + +function format_group (group, path) { + group.path = path.concat(group.attributes.value[1]); + result = [group]; + _.each(group.subgroups_data, function (subgroup) { + result = result.concat(format_group (subgroup, group.path)); + }); + return result; +} \ No newline at end of file -- cgit v1.2.3 From ad8bddd00eac5c97ab077d225a0714d08407f24b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 19 Nov 2013 15:52:33 +0100 Subject: [IMP] col expansion support in pivottable widget, still many bugs left (addon web_graph) bzr revid: ged@openerp.com-20131119145233-n8gjast7q48foku9 --- addons/web_graph/static/src/js/graph.js | 64 ++++++++++++++++++------------- addons/web_graph/static/src/js/utility.js | 11 ++++++ 2 files changed, 49 insertions(+), 26 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index dfcc2759ffa..ca852a36c5c 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -235,9 +235,7 @@ var PivotTable = instance.web.Widget.extend({ } else { this.$el.empty(); - _.each(this.headers, function (header) { - self.$el.append(header); - }); + this.draw_top_headers(); _.each(this.rows, function (row) { self.$el.append(row.html); @@ -279,12 +277,6 @@ var PivotTable = instance.web.Widget.extend({ var self = this; var col_id = this.generate_id(); - var col_header = this.make_cell(this.data.measure_label, - {is_border:true, foldable: true, col_id:col_id}); - var header = $(''); - header.append(this.make_cell(' ', {is_border:true})); - header.append(col_header); - this.headers = [header]; this.cols= [{ id: col_id, @@ -295,9 +287,11 @@ var PivotTable = instance.web.Widget.extend({ children: [], cells: [], // a cell is {td:, row_id:} domain: this.data.domain, - header: col_header + // header: col_header }]; + self.make_top_headers(); + var main_row = this.make_row(this.data.total[0]); _.each(this.data.groups, function (group) { @@ -314,6 +308,33 @@ var PivotTable = instance.web.Widget.extend({ return query_groups(this.data.model, view_fields, this.data.domain, groupby); }, + make_top_headers : function () { + var self = this; + + var height = maxInArray(_.map(self.rows, function(g) {return g.path.length;}),1); + + var header = $(''); + header.append(this.make_cell('', {is_border:true, }).attr('colspan', height)); + + _.each(this.cols, function (col) { + if (col.children.length === 0) { + var options = {is_border: true, foldable:true, col_id: col.id}; + header.append(self.make_cell(col.value, options)); + } + }); + header.addClass('graph_top'); + this.headers = [header]; + }, + + draw_top_headers: function () { + var self = this; + $("tr.graph_top").remove(); + _.each(this.headers, function (header) { + self.$el.prepend(header); + }); + + }, + make_row: function (group, parent_id) { var path, value, @@ -432,22 +453,18 @@ var PivotTable = instance.web.Widget.extend({ var self = this; var col = this.get_col(col_id); - console.log("expanding col",col); if (col.path.length == this.data.col_groupby.length) { this.data.col_groupby.push(field_id); } col.expanded = true; - col.header.find('.icon-plus-sign') - .removeClass('icon-plus-sign') - .addClass('icon-minus-sign'); + // col.header.find('.icon-plus-sign') + // .removeClass('icon-plus-sign') + // .addClass('icon-minus-sign'); var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); query_groups_data(this.data.model, visible_fields, col.domain, this.data.row_groupby, field_id) .then(function (groups) { - console.log("inserting groups",groups); - console.log("this.rows",self.rows); - console.log("this.cols",self.cols); _.each(groups, function (group) { var new_col = { id: self.generate_id(), @@ -460,7 +477,7 @@ var PivotTable = instance.web.Widget.extend({ domain: group[0].model._domain, // header: col_header }; - col.header.css('display','none'); + // col.header.css('display','none'); col.children.push(new_col.id); self.cols.push(new_col); _.each(col.cells, function (cell) { @@ -476,22 +493,19 @@ var PivotTable = instance.web.Widget.extend({ } else { value = datapt.attributes.aggregates[self.data.measure]; } - console.log("value", value); - // make new cell var new_cell = { row_id: cell.row_id, td: self.make_cell(value) }; - // add cell to new_col cells ({row_id, td}) new_col.cells.push(new_cell); - // insert new cell (td) after cell.td cell.td.after(new_cell.td); cell.td.css('display','none'); }); }); + self.make_top_headers(); + self.draw_top_headers(); }); - }, fold_row: function (row_id) { @@ -509,9 +523,7 @@ var PivotTable = instance.web.Widget.extend({ .addClass('icon-plus-sign'); var fold_levels = _.map(self.rows, function(g) {return g.path.length;}); - var new_groupby_length = _.reduce(fold_levels, function (x, y) { - return Math.max(x,y); - }, 0); + var new_groupby_length = maxInArray(fold_levels); this.data.row_groupby.splice(new_groupby_length); }, diff --git a/addons/web_graph/static/src/js/utility.js b/addons/web_graph/static/src/js/utility.js index 7f67ace0f4c..b7c9c1e37c8 100644 --- a/addons/web_graph/static/src/js/utility.js +++ b/addons/web_graph/static/src/js/utility.js @@ -6,6 +6,17 @@ function removeFromArray(array, element) { } } +function maxInArray(array, def_val) { + if (def_val === undefined ) {def_val = 0;} + + if (array.length === 0) { + return def_val; + } else { + return _.reduce(array, function (x, y) { + return Math.max(x,y); + }, def_val); + } +} /** * Query the server and return a deferred which will return the data * with all the groupbys applied (this is done for now, but the goal -- cgit v1.2.3 From 01a4fc36240711c535db253189a21edd9fd38fd7 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 20 Nov 2013 12:08:21 +0100 Subject: [IMP] col expansion support in pivottable widget, improve the column headers rendering (addon web_graph) bzr revid: ged@openerp.com-20131120110821-8r4q3dybhndm3gjz --- addons/web_graph/static/src/js/graph.js | 116 +++++++++++++++++++++++++----- addons/web_graph/static/src/js/utility.js | 13 +--- 2 files changed, 102 insertions(+), 27 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index ca852a36c5c..606de2ba2a9 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -163,11 +163,11 @@ var PivotTable = instance.web.Widget.extend({ event.preventDefault(); this.dropdown.remove(); if (event.target.attributes['data-row-id'] !== undefined) { - var id = event.target.attributes['data-row-id'].nodeValue; + id = event.target.attributes['data-row-id'].nodeValue; this.expand_row(id, field_id); } if (event.target.attributes['data-col-id'] !== undefined) { - var id = event.target.attributes['data-col-id'].nodeValue; + id = event.target.attributes['data-col-id'].nodeValue; this.expand_col(id, field_id); } }, @@ -309,27 +309,106 @@ var PivotTable = instance.web.Widget.extend({ }, make_top_headers : function () { - var self = this; + var self = this, + header; - var height = maxInArray(_.map(self.rows, function(g) {return g.path.length;}),1); + function partition (columns) { + return _.reduce(columns, function (partial, col) { + if (partial.length === 0) return [[col]]; + if (col.path.length > _.first(_.last(partial)).path.length) { + _.last(partial).push(col); + } else { + partial.push([col]); + } + return partial; + }, []); + } - var header = $(''); - header.append(this.make_cell('', {is_border:true, }).attr('colspan', height)); + function side_by_side(blocks) { + var result = _.zip.apply(_,blocks); + result = _.map(result, function(line) {return _.compact(_.flatten(line))}); + return result; + } - _.each(this.cols, function (col) { - if (col.children.length === 0) { - var options = {is_border: true, foldable:true, col_id: col.id}; - header.append(self.make_cell(col.value, options)); + function make_header_cell(col, span) { + var options = { + is_border:true, + foldable:true, + row_span: (span === undefined) ? 1 : span, + col_id: col.id, + }; + var result = self.make_cell(col.value, options); + return result; + } + + function calculate_width(cols) { + if (cols.length === 1) { + return 1; } - }); - header.addClass('graph_top'); - this.headers = [header]; + var p = partition(_.rest(cols)); + return _.reduce(p, function(x, y){ return x + calculate_width(y); }, 0); + } + + function make_header_cells(cols, height) { + var p = partition(cols); + if ((p.length === 1) && (p[0].length === 1)) { + var result = [[make_header_cell(cols[0], height)]]; + return result; + } + if ((p.length === 1) && (p[0].length > 1)) { + var cell = make_header_cell(p[0][0]); + cell.attr('colspan', calculate_width(cols)); + return [[cell]].concat(make_header_cells(_.rest(cols), height - 1)); + } + if (p.length > 1) { + return side_by_side(_.map(p, function (group) { + return make_header_cells(group, height); + })); + } + } + + if (this.cols.length === 1) { + header = $(''); + header.append(this.make_cell('', {is_border:true})); + header.append(this.make_cell(this.cols[0].value, + {is_border:true, foldable:true, col_id:this.cols[0].id})); + header.addClass('graph_top'); + this.headers = [header]; + } else { + console.log("cols",this.cols); + var height = _.max(_.map(self.cols, function(g) {return g.path.length;})); + console.log("height",height); + var header_rows = make_header_cells(_.rest(this.cols), height); + + header_rows[0].splice(0,0,self.make_cell('', {is_border:true, }).attr('rowspan', height)) + console.log("header rows",header_rows); + self.headers = []; + _.each(header_rows, function (cells) { + header = $(''); + console.log("cells",cells); + header.append(cells); + header.addClass('graph_top'); + self.headers.push(header); + }); + + // header = + // header.append(this.make_cell('', {is_border:true, }).attr('rowspan', height)); + + // _.each(this.cols, function (col) { + // if (col.children.length === 0) { + // var options = {is_border: true, foldable:true, col_id: col.id}; + // header.append(self.make_cell(col.value, options)); + // } + // }); + // header.addClass('graph_top'); + // this.headers = [header]; + } }, draw_top_headers: function () { var self = this; $("tr.graph_top").remove(); - _.each(this.headers, function (header) { + _.each(this.headers.reverse(), function (header) { self.$el.prepend(header); }); @@ -408,6 +487,8 @@ var PivotTable = instance.web.Widget.extend({ var cell = $(''); if (options.is_border) cell.addClass('graph_border'); + if (options.row_span) cell.attr('rowspan', options.row_span); + if (options.col_span) cell.attr('rowspan', options.col_span); _.each(_.range(options.indent), function () { cell.prepend($('', {class:'web_graph_indent'})); }); @@ -468,7 +549,7 @@ var PivotTable = instance.web.Widget.extend({ _.each(groups, function (group) { var new_col = { id: self.generate_id(), - path: col.path.concat(field_id), + path: col.path.concat(group[0].attributes.value[1]), value: group[0].attributes.value[1], expanded: false, parent: col_id, @@ -479,7 +560,8 @@ var PivotTable = instance.web.Widget.extend({ }; // col.header.css('display','none'); col.children.push(new_col.id); - self.cols.push(new_col); + insertAfter(self.cols, col, new_col) + // self.cols.push(new_col); _.each(col.cells, function (cell) { var col_path = self.get_row(cell.row_id).path; @@ -523,7 +605,7 @@ var PivotTable = instance.web.Widget.extend({ .addClass('icon-plus-sign'); var fold_levels = _.map(self.rows, function(g) {return g.path.length;}); - var new_groupby_length = maxInArray(fold_levels); + var new_groupby_length = _.max(fold_levels); this.data.row_groupby.splice(new_groupby_length); }, diff --git a/addons/web_graph/static/src/js/utility.js b/addons/web_graph/static/src/js/utility.js index b7c9c1e37c8..bb0f6a9835d 100644 --- a/addons/web_graph/static/src/js/utility.js +++ b/addons/web_graph/static/src/js/utility.js @@ -6,17 +6,10 @@ function removeFromArray(array, element) { } } -function maxInArray(array, def_val) { - if (def_val === undefined ) {def_val = 0;} - - if (array.length === 0) { - return def_val; - } else { - return _.reduce(array, function (x, y) { - return Math.max(x,y); - }, def_val); - } +function insertAfter(array, after, elem) { + array.splice(array.indexOf(after) + 1, 0, elem); } + /** * Query the server and return a deferred which will return the data * with all the groupbys applied (this is done for now, but the goal -- cgit v1.2.3 From fde3f47a2e21afbee6d7ec575590e97a05a3eb98 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 20 Nov 2013 12:17:28 +0100 Subject: [FIX] properly clears the current rows when building pivot table (addon web_graph) bzr revid: ged@openerp.com-20131120111728-3aqr9xxz8kdhkfg6 --- addons/web_graph/static/src/js/graph.js | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 606de2ba2a9..6e9e20d943a 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -275,6 +275,8 @@ var PivotTable = instance.web.Widget.extend({ build_table: function () { var self = this; + this.rows = []; + var col_id = this.generate_id(); @@ -287,7 +289,6 @@ var PivotTable = instance.web.Widget.extend({ children: [], cells: [], // a cell is {td:, row_id:} domain: this.data.domain, - // header: col_header }]; self.make_top_headers(); @@ -375,33 +376,17 @@ var PivotTable = instance.web.Widget.extend({ header.addClass('graph_top'); this.headers = [header]; } else { - console.log("cols",this.cols); var height = _.max(_.map(self.cols, function(g) {return g.path.length;})); - console.log("height",height); var header_rows = make_header_cells(_.rest(this.cols), height); header_rows[0].splice(0,0,self.make_cell('', {is_border:true, }).attr('rowspan', height)) - console.log("header rows",header_rows); self.headers = []; _.each(header_rows, function (cells) { header = $(''); - console.log("cells",cells); header.append(cells); header.addClass('graph_top'); self.headers.push(header); }); - - // header = - // header.append(this.make_cell('', {is_border:true, }).attr('rowspan', height)); - - // _.each(this.cols, function (col) { - // if (col.children.length === 0) { - // var options = {is_border: true, foldable:true, col_id: col.id}; - // header.append(self.make_cell(col.value, options)); - // } - // }); - // header.addClass('graph_top'); - // this.headers = [header]; } }, -- cgit v1.2.3 From 215f66550805e81c8fa53125734fb3ee0e8a1f63 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 20 Nov 2013 13:46:32 +0100 Subject: [IMP] supports columns folding in pivottable (addon web_graph) bzr revid: ged@openerp.com-20131120124632-ydjuvtcvou14qivo --- addons/web_graph/static/src/js/graph.js | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 6e9e20d943a..d99bffbb2d6 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -613,6 +613,55 @@ var PivotTable = instance.web.Widget.extend({ }); }, + fold_col: function (col_id) { + var self = this; + var col = this.get_col(col_id); + + _.each(col.children, function (child_col) { + self.remove_col(child_col); + }); + col.children = []; + + _.each(col.cells, function (cell) { + cell.td.css('display','table-cell'); + }); + col.expanded = false; + // row.html.find('.icon-minus-sign') + // .removeClass('icon-minus-sign') + // .addClass('icon-plus-sign'); + + var fold_levels = _.map(self.cols, function(g) {return g.path.length;}); + var new_groupby_length = _.max(fold_levels); + + this.data.col_groupby.splice(new_groupby_length); + this.make_top_headers(); + this.draw_top_headers(); + + + }, + + remove_col: function (col_id) { + var self = this; + var col = this.get_col(col_id); + + _.each(col.children, function (child_col) { + self.remove_col(child_col); + }); + + _.each(col.cells, function (cell) { + cell.td.remove(); + }); + // row.html.remove(); + removeFromArray(this.cols, col); + + // _.each(this.cols, function (col) { + // col.cells = _.filter(col.cells, function (cell) { + // return cell.row_id !== row_id; + // }); + // }); + }, + + }); }; -- cgit v1.2.3 From 53a8f56f03b2097d58ccf8ba687df641680ae821 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 20 Nov 2013 14:07:48 +0100 Subject: [FIX] correctly handles + and - signs on rows/columns expansion/folding (addon web_graph) bzr revid: ged@openerp.com-20131120130748-mge1w8apby67miqm --- addons/web_graph/static/src/js/graph.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index d99bffbb2d6..5f7d70776a3 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -339,6 +339,11 @@ var PivotTable = instance.web.Widget.extend({ col_id: col.id, }; var result = self.make_cell(col.value, options); + if (col.expanded) { + result.find('.icon-plus-sign') + .removeClass('icon-plus-sign') + .addClass('icon-minus-sign'); + } return result; } @@ -432,9 +437,14 @@ var PivotTable = instance.web.Widget.extend({ _.each(this.cols, function (col) { col.cells.push({row_id: row_id, td: cell }); - // insert cells into corresponding col }); + if (!has_parent) { + header.find('.icon-plus-sign') + .removeClass('icon-plus-sign') + .addClass('icon-minus-sign'); + } + var row = { id: row_id, path: path, @@ -523,10 +533,6 @@ var PivotTable = instance.web.Widget.extend({ this.data.col_groupby.push(field_id); } col.expanded = true; - // col.header.find('.icon-plus-sign') - // .removeClass('icon-plus-sign') - // .addClass('icon-minus-sign'); - var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); query_groups_data(this.data.model, visible_fields, col.domain, this.data.row_groupby, field_id) -- cgit v1.2.3 From 9c76cb8a4c8366979e40bc86fc0b66e088c026c3 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 20 Nov 2013 14:15:43 +0100 Subject: [FIX] fixes a bug where dropdown menu used wrong coordinates when expanding rows (addon web_graph) bzr revid: ged@openerp.com-20131120131543-d119benx379oglry --- addons/web_graph/static/src/js/graph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 5f7d70776a3..7e6f5b78ef7 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -186,7 +186,7 @@ var PivotTable = instance.web.Widget.extend({ } else { this.display_dropdown({row_id:row_id, target: $(event.target), - x: event.pageY, + x: event.pageX, y: event.pageY}); } } -- cgit v1.2.3 From a7953bbd850468cbf0abfb41da49f501e6e65a42 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 20 Nov 2013 15:19:14 +0100 Subject: [REF] preparation work to allows row expansion to query and display correct data when columns are already expanded (addon web_graph) bzr revid: ged@openerp.com-20131120141914-yf4o5sh4gzagh2ym --- addons/web_graph/static/src/js/graph.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7e6f5b78ef7..357fc2b2a8a 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -223,12 +223,13 @@ var PivotTable = instance.web.Widget.extend({ var self = this; if (load_data === true) { - this.get_groups(this.data.row_groupby) + var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); + query_groups_data(this.data.model, view_fields, this.data.domain, this.data.col_groupby, this.data.row_groupby[0]) .then(function (groups) { self.data.groups = groups; return self.get_groups([]); }).then(function (total) { - self.data.total = total; + self.data.total = [total]; self.build_table(); self.draw(false); }); @@ -405,6 +406,7 @@ var PivotTable = instance.web.Widget.extend({ }, make_row: function (group, parent_id) { + group = group[0]; var path, value, expanded, @@ -515,7 +517,7 @@ var PivotTable = instance.web.Widget.extend({ .addClass('icon-minus-sign'); var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); - query_groups(this.data.model, visible_fields, row.domain, [field_id]) + query_groups_data(this.data.model, visible_fields, row.domain, this.data.col_groupby, field_id) .then(function (groups) { _.each(groups.reverse(), function (group) { var new_row = self.make_row(group, row_id); @@ -547,12 +549,9 @@ var PivotTable = instance.web.Widget.extend({ children: [], cells: [], // a cell is {td:, row_id:} domain: group[0].model._domain, - // header: col_header }; - // col.header.css('display','none'); col.children.push(new_col.id); insertAfter(self.cols, col, new_col) - // self.cols.push(new_col); _.each(col.cells, function (cell) { var col_path = self.get_row(cell.row_id).path; -- cgit v1.2.3 From a309c97505dd01072225a1f45b39c19f1e6b32e6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 21 Nov 2013 10:07:19 +0100 Subject: [IMP] allows row expansion to query and display correct data when columns are already expanded (addon web_graph) bzr revid: ged@openerp.com-20131121090719-lauwesqz7c189nba --- addons/web_graph/static/src/js/graph.js | 37 ++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 357fc2b2a8a..7d73f0df695 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -222,13 +222,14 @@ var PivotTable = instance.web.Widget.extend({ draw: function (load_data) { var self = this; - if (load_data === true) { + if (load_data) { var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); query_groups_data(this.data.model, view_fields, this.data.domain, this.data.col_groupby, this.data.row_groupby[0]) .then(function (groups) { self.data.groups = groups; return self.get_groups([]); }).then(function (total) { + total[0].path = []; self.data.total = [total]; self.build_table(); self.draw(false); @@ -405,9 +406,9 @@ var PivotTable = instance.web.Widget.extend({ }, - make_row: function (group, parent_id) { - group = group[0]; - var path, + make_row: function (groups, parent_id) { + var self = this, + path, value, expanded, domain, @@ -417,11 +418,11 @@ var PivotTable = instance.web.Widget.extend({ if (has_parent) { parent = this.get_row(parent_id); - path = parent.path.concat(group.attributes.value[1]); - value = group.attributes.value[1]; + path = parent.path.concat(groups[0].attributes.value[1]); + value = groups[0].attributes.value[1]; expanded = false; parent.children.push(row_id); - domain = group.model._domain; + domain = groups[0].model._domain; } else { parent = null; path = []; @@ -432,13 +433,25 @@ var PivotTable = instance.web.Widget.extend({ var jquery_row = $(''); - var header = this.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); - var cell = this.make_cell(group.attributes.aggregates[this.data.measure]); - jquery_row.html(header); - jquery_row.append(cell); + var header = self.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); + jquery_row.append(header); + + var cell; _.each(this.cols, function (col) { - col.cells.push({row_id: row_id, td: cell }); + var element = _.find(groups, function (group) { + return _.isEqual(_.rest(group.path), col.path); + }); + if (element === undefined) { + cell = self.make_cell(''); + } else { + cell = self.make_cell(element.attributes.aggregates[self.data.measure]); + } + if (col.expanded) { + cell.css('display', 'none'); + } + col.cells.push({td:cell, row_id:row_id}); + jquery_row.append(cell); }); if (!has_parent) { -- cgit v1.2.3 From d0cb5149b4dc03f233fcce60d498b24ab8ac0259 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 22 Nov 2013 08:43:27 +0100 Subject: [REF] large refactoring in progress. goal is to separate the data handling code (pivot) from the ui code (drawing, buttons, events (addon web_graph) bzr revid: ged@openerp.com-20131122074327-bfnlw3ew1120um0k --- addons/web_graph/static/src/js/graph.js | 1326 ++++++++++++++++++------------- addons/web_graph/static/src/js/pivot.js | 132 +++ 2 files changed, 911 insertions(+), 547 deletions(-) create mode 100644 addons/web_graph/static/src/js/pivot.js (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7d73f0df695..3363f7cb3a8 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -22,26 +22,26 @@ instance.web_graph.GraphView = instance.web.View.extend({ template: 'GraphView', display_name: _lt('Graph'), view_type: 'graph', - mode: 'pivot', // pivot, bar_chart, line_chart or pie_chart - pivot_table: null, events: { 'click .graph_mode_selection li' : function (event) { event.preventDefault(); this.mode = event.target.attributes['data-mode'].nodeValue; - this.display_data(); + console.log("change mode",this.mode); }, }, view_loading: function (fields_view_get) { - var self = this; - var model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}); - var domain = []; - var col_groupby = []; - var row_groupby = []; - var measure = null; - var fields; - var important_fields = []; + var self = this, + model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}), + domain = [], + measure = null, + fields, + important_fields = [], + col_groupby = [], + row_groupby = []; + + this.pivot_table = null; // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { @@ -96,33 +96,26 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); }, - display_data : function () { - var content = this.$el.filter('.graph_main_content'); - content.find('svg').remove(); - var self = this; - if (this.mode === 'pivot') { - this.pivot_table.show(); - } else { - this.pivot_table.hide(); - content.append(''); - var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); - query_groups(this.data.model, view_fields, this.data.domain, this.data.row_groupby).then(function (groups) { - Charts[self.mode](groups, self.data.measure, self.data.measure_label); - }); - - } + start: function () { + this.table = $('
'); + this.svg = $(''); + this.$el.filter('.graph_main_content').append(this.table); + this.$el.filter('.graph_main_content').append(this.svg); + return this.load_view(); }, do_search: function (domain, context, group_by) { + var self = this; this.data.domain = new instance.web.CompoundDomain(domain); - if (this.pivot_table) { - this.pivot_table.draw(true); + if (!this.pivot_table) { + self.pivot_table = new PivotTable(self.data); + self.pivot_table.start().then(self.proxy('draw_table')); } else { - this.pivot_table = new PivotTable(this.data); - this.pivot_table.appendTo('.graph_main_content'); + this.pivot_table.update_values.done(function () { + self.draw_table(); + }); } - this.display_data(); }, do_show: function () { @@ -130,556 +123,795 @@ instance.web_graph.GraphView = instance.web.View.extend({ return this._super(); }, -}); - - - /** - * PivotTable widget. It displays the data in tabular data and allows the - * user to drill down and up in the table - */ -var PivotTable = instance.web.Widget.extend({ - template: 'pivot_table', - data: null, - headers: [], - rows: [], - cols: [], - id_seed : 0, - - events: { - 'click .web_graph_click' : function (event) { - event.preventDefault(); - - if (event.target.attributes['data-row-id'] !== undefined) { - this.handle_row_event(event); - } - if (event.target.attributes['data-col-id'] !== undefined) { - this.handle_col_event(event); - } - }, - - 'click a.field-selection' : function (event) { - var id, - field_id = event.target.attributes['data-field-id'].nodeValue; - event.preventDefault(); - this.dropdown.remove(); - if (event.target.attributes['data-row-id'] !== undefined) { - id = event.target.attributes['data-row-id'].nodeValue; - this.expand_row(id, field_id); - } - if (event.target.attributes['data-col-id'] !== undefined) { - id = event.target.attributes['data-col-id'].nodeValue; - this.expand_col(id, field_id); - } - }, - }, - - handle_row_event: function (event) { - var row_id = event.target.attributes['data-row-id'].nodeValue, - row = this.get_row(row_id); - - if (row.expanded) { - this.fold_row(row_id); - } else { - if (row.path.length < this.data.row_groupby.length) { - var field_to_expand = this.data.row_groupby[row.path.length]; - this.expand_row(row_id, field_to_expand); - } else { - this.display_dropdown({row_id:row_id, - target: $(event.target), - x: event.pageX, - y: event.pageY}); - } - } - }, - - handle_col_event: function (event) { - var col_id = event.target.attributes['data-col-id'].nodeValue, - col = this.get_col(col_id); - - if (col.expanded) { - this.fold_col(col_id); - } else { - if (col.path.length < this.data.col_groupby.length) { - var field_to_expand = this.data.col_groupby[col.path.length]; - this.expand_col(col_id, field_to_expand); - } else { - this.display_dropdown({col_id: col_id, - target: $(event.target), - x: event.pageX, - y: event.pageY}); - } - } - }, - - init: function (data) { - this.data = data; - }, - - start: function () { - this.draw(true); - }, - - draw: function (load_data) { - var self = this; - - if (load_data) { - var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); - query_groups_data(this.data.model, view_fields, this.data.domain, this.data.col_groupby, this.data.row_groupby[0]) - .then(function (groups) { - self.data.groups = groups; - return self.get_groups([]); - }).then(function (total) { - total[0].path = []; - self.data.total = [total]; - self.build_table(); - self.draw(false); - }); - } else { - this.$el.empty(); - - this.draw_top_headers(); - - _.each(this.rows, function (row) { - self.$el.append(row.html); - }); - } - }, - - show: function () { - this.$el.css('display', 'block'); - }, - - hide: function () { - this.$el.css('display', 'none'); - }, - - display_dropdown: function (options) { - var self = this, - already_grouped = self.data.row_groupby.concat(self.data.col_groupby), - possible_groups = _.difference(self.data.important_fields, already_grouped), - dropdown_options = { - fields: _.map(possible_groups, function (field) { - return {id: field, value: self.get_descr(field)}; - })}; - if (options.row_id) { - dropdown_options.row_id= options.row_id; - } else { - dropdown_options.col_id = options.col_id; - } - - this.dropdown = $(QWeb.render('field_selection', dropdown_options)); - options.target.after(this.dropdown); - this.dropdown.css({position:'absolute', - left:options.x, - top:options.y}); - $('.field-selection').next('.dropdown-menu').toggle(); - }, - - build_table: function () { - var self = this; - this.rows = []; - - - var col_id = this.generate_id(); - - this.cols= [{ - id: col_id, - path: [], - value: this.data.measure_label, - expanded: false, - parent: null, - children: [], - cells: [], // a cell is {td:, row_id:} - domain: this.data.domain, - }]; - - self.make_top_headers(); - - var main_row = this.make_row(this.data.total[0]); - - _.each(this.data.groups, function (group) { - self.make_row(group, main_row.id); - }); - }, - - get_descr: function (field_id) { - return this.data.fields[field_id].string; - }, - - get_groups: function (groupby) { - var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); - return query_groups(this.data.model, view_fields, this.data.domain, groupby); + draw_table: function () { + this.draw_top_headers(); + _.each(this.pivot_table.rows, this.proxy('draw_row')); }, - make_top_headers : function () { + draw_top_headers: function () { var self = this, - header; - - function partition (columns) { - return _.reduce(columns, function (partial, col) { - if (partial.length === 0) return [[col]]; - if (col.path.length > _.first(_.last(partial)).path.length) { - _.last(partial).push(col); - } else { - partial.push([col]); - } - return partial; - }, []); - } + pivot = this.pivot_table; - function side_by_side(blocks) { - var result = _.zip.apply(_,blocks); - result = _.map(result, function(line) {return _.compact(_.flatten(line))}); - return result; - } - - function make_header_cell(col, span) { - var options = { - is_border:true, - foldable:true, - row_span: (span === undefined) ? 1 : span, - col_id: col.id, - }; - var result = self.make_cell(col.value, options); - if (col.expanded) { - result.find('.icon-plus-sign') - .removeClass('icon-plus-sign') - .addClass('icon-minus-sign'); - } - return result; - } - - function calculate_width(cols) { - if (cols.length === 1) { - return 1; - } - var p = partition(_.rest(cols)); - return _.reduce(p, function(x, y){ return x + calculate_width(y); }, 0); - } - - function make_header_cells(cols, height) { - var p = partition(cols); - if ((p.length === 1) && (p[0].length === 1)) { - var result = [[make_header_cell(cols[0], height)]]; - return result; - } - if ((p.length === 1) && (p[0].length > 1)) { - var cell = make_header_cell(p[0][0]); - cell.attr('colspan', calculate_width(cols)); - return [[cell]].concat(make_header_cells(_.rest(cols), height - 1)); - } - if (p.length > 1) { - return side_by_side(_.map(p, function (group) { - return make_header_cells(group, height); - })); + function get_column_tree(cols, level) { + var height, + width, + children = _.map(cols[0].children, function (child) { + get_column_tree(child, level - 1); + }); + if (children.length > 0) { + height = 1; + width = _.reduce(children, function (x,y) { return x + y;}, 0); + } else { + height = level; + width = 1; } + return {level: level, + width: width, + height: height, + col:cols[0], + children: children}; } - if (this.cols.length === 1) { - header = $(''); - header.append(this.make_cell('', {is_border:true})); - header.append(this.make_cell(this.cols[0].value, - {is_border:true, foldable:true, col_id:this.cols[0].id})); - header.addClass('graph_top'); - this.headers = [header]; - } else { - var height = _.max(_.map(self.cols, function(g) {return g.path.length;})); - var header_rows = make_header_cells(_.rest(this.cols), height); - - header_rows[0].splice(0,0,self.make_cell('', {is_border:true, }).attr('rowspan', height)) - self.headers = []; - _.each(header_rows, function (cells) { - header = $(''); - header.append(cells); - header.addClass('graph_top'); - self.headers.push(header); - }); - } - }, - - draw_top_headers: function () { - var self = this; - $("tr.graph_top").remove(); - _.each(this.headers.reverse(), function (header) { - self.$el.prepend(header); - }); - - }, - - make_row: function (groups, parent_id) { - var self = this, - path, - value, - expanded, - domain, - parent, - has_parent = (parent_id !== undefined), - row_id = this.generate_id(); - - if (has_parent) { - parent = this.get_row(parent_id); - path = parent.path.concat(groups[0].attributes.value[1]); - value = groups[0].attributes.value[1]; - expanded = false; - parent.children.push(row_id); - domain = groups[0].model._domain; - } else { - parent = null; - path = []; - value = 'Total'; - expanded = true; - domain = this.data.domain; + function make_cell(elem) { + var title = $(' ') + .addClass('web_graph_click') + .attr('href', '#') + .attr('data-col-id', elem.col.id) + .addClass((elem.col.is_expanded) ? 'icon-minus-sign' : 'icon-plus-sign') + .append(elem.col.name); + return $('').addClass('graph_border') + .append(title) + .attr('rowspan', elem.height) + .attr('colspan', elem.width); } - var jquery_row = $(''); + var height = _.max(_.map(pivot.cols, function(g) {return g.path.length;})); + height = (height === 0) ? 1 : height; - var header = self.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); - jquery_row.append(header); + var col_tree = get_column_tree(pivot.cols, height); - var cell; + var header_cells = [[$('') + .attr('rowspan', height) + .addClass('graph_border')]]; - _.each(this.cols, function (col) { - var element = _.find(groups, function (group) { - return _.isEqual(_.rest(group.path), col.path); - }); - if (element === undefined) { - cell = self.make_cell(''); + function make_cells (queue, level) { + var tree = queue.shift(); + queue = queue.concat(tree.children); + if (tree.level == level) { + _.last(header_cells).push(make_cell(tree)); } else { - cell = self.make_cell(element.attributes.aggregates[self.data.measure]); + level -=1; + header_cells.push([make_cell(tree)]); } - if (col.expanded) { - cell.css('display', 'none'); + if (queue.length !== 0) { + make_cells(queue, level); } - col.cells.push({td:cell, row_id:row_id}); - jquery_row.append(cell); - }); - - if (!has_parent) { - header.find('.icon-plus-sign') - .removeClass('icon-plus-sign') - .addClass('icon-minus-sign'); } - var row = { - id: row_id, - path: path, - value: value, - expanded: expanded, - parent: parent_id, - children: [], - html: jquery_row, - domain: domain, - }; - this.rows.push(row); // to do, insert it properly, after all childs of parent - return row; - }, - - generate_id: function () { - this.id_seed += 1; - return this.id_seed - 1; - }, - - get_row: function (id) { - return _.find(this.rows, function(row) { - return (row.id == id); - }); - }, - - get_col: function (id) { - return _.find(this.cols, function(col) { - return (col.id == id); + make_cells([col_tree], height); + _.each(header_cells, function (cells) { + var row = $("").append(cells); + self.table.append(row); }); }, - make_cell: function (content, options) { - options = _.extend({is_border: false, indent:0, foldable:false}, options); - content = (content !== undefined) ? content : 'Undefined'; - - var cell = $(''); - if (options.is_border) cell.addClass('graph_border'); - if (options.row_span) cell.attr('rowspan', options.row_span); - if (options.col_span) cell.attr('rowspan', options.col_span); - _.each(_.range(options.indent), function () { - cell.prepend($('', {class:'web_graph_indent'})); - }); - - if (options.foldable) { - var attrs = {class:'icon-plus-sign web_graph_click', href:'#'}; - if (options.row_id !== undefined) attrs['data-row-id'] = options.row_id; - if (options.col_id !== undefined) attrs['data-col-id'] = options.col_id; - var plus = $('', attrs); - plus.append(' '); - plus.append(content); - cell.append(plus); - } else { - cell.append(content); + draw_row: function (row) { + var pivot = this.pivot_table, + html_row = $(''), + name = $(' ') + .addClass('web_graph_click') + .attr('href', '#') + .attr('data-row-id', row.id) + .addClass((row.is_expanded) ? 'icon-minus-sign' : 'icon-plus-sign') + .append(row.name), + row_header = $('') + .append(name) + .addClass('graph_border'); + + for (var i in _.range(row.path.length)) { + row_header.prepend($('', {class:'web_graph_indent'})); } - return cell; - }, - expand_row: function (row_id, field_id) { - var self = this; - var row = this.get_row(row_id); + html_row.append(row_header); - if (row.path.length == this.data.row_groupby.length) { - this.data.row_groupby.push(field_id); - } - row.expanded = true; - row.html.find('.icon-plus-sign') - .removeClass('icon-plus-sign') - .addClass('icon-minus-sign'); - - var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); - query_groups_data(this.data.model, visible_fields, row.domain, this.data.col_groupby, field_id) - .then(function (groups) { - _.each(groups.reverse(), function (group) { - var new_row = self.make_row(group, row_id); - row.html.after(new_row.html); - }); + _.each(pivot.cols, function (col) { + var cell = $('').append(pivot.get_value(row.id, col.id)); + html_row.append(cell) }); + this.table.append(html_row); + } +}); - }, - - expand_col: function (col_id, field_id) { - var self = this; - var col = this.get_col(col_id); - - if (col.path.length == this.data.col_groupby.length) { - this.data.col_groupby.push(field_id); - } - col.expanded = true; - - var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); - query_groups_data(this.data.model, visible_fields, col.domain, this.data.row_groupby, field_id) - .then(function (groups) { - _.each(groups, function (group) { - var new_col = { - id: self.generate_id(), - path: col.path.concat(group[0].attributes.value[1]), - value: group[0].attributes.value[1], - expanded: false, - parent: col_id, - children: [], - cells: [], // a cell is {td:, row_id:} - domain: group[0].model._domain, - }; - col.children.push(new_col.id); - insertAfter(self.cols, col, new_col) - _.each(col.cells, function (cell) { - var col_path = self.get_row(cell.row_id).path; - - var datapt = _.find(group, function (g) { - return _.isEqual(g.path.slice(1), col_path); - }); - - var value; - if (datapt === undefined) { - value = ''; - } else { - value = datapt.attributes.aggregates[self.data.measure]; - } - var new_cell = { - row_id: cell.row_id, - td: self.make_cell(value) - }; - new_col.cells.push(new_cell); - cell.td.after(new_cell.td); - cell.td.css('display','none'); - }); - - }); - self.make_top_headers(); - self.draw_top_headers(); - }); - }, - - fold_row: function (row_id) { - var self = this; - var row = this.get_row(row_id); - - _.each(row.children, function (child_row) { - self.remove_row(child_row); - }); - row.children = []; - - row.expanded = false; - row.html.find('.icon-minus-sign') - .removeClass('icon-minus-sign') - .addClass('icon-plus-sign'); - - var fold_levels = _.map(self.rows, function(g) {return g.path.length;}); - var new_groupby_length = _.max(fold_levels); - - this.data.row_groupby.splice(new_groupby_length); - }, - - remove_row: function (row_id) { - var self = this; - var row = this.get_row(row_id); - - _.each(row.children, function (child_row) { - self.remove_row(child_row); - }); - - row.html.remove(); - removeFromArray(this.rows, row); - - _.each(this.cols, function (col) { - col.cells = _.filter(col.cells, function (cell) { - return cell.row_id !== row_id; - }); - }); - }, - - fold_col: function (col_id) { - var self = this; - var col = this.get_col(col_id); - - _.each(col.children, function (child_col) { - self.remove_col(child_col); - }); - col.children = []; - _.each(col.cells, function (cell) { - cell.td.css('display','table-cell'); - }); - col.expanded = false; - // row.html.find('.icon-minus-sign') - // .removeClass('icon-minus-sign') - // .addClass('icon-plus-sign'); - var fold_levels = _.map(self.cols, function(g) {return g.path.length;}); - var new_groupby_length = _.max(fold_levels); +// make_top_headers : function () { +// var self = this, +// header; + +// function partition (columns) { +// return _.reduce(columns, function (partial, col) { +// if (partial.length === 0) return [[col]]; +// if (col.path.length > _.first(_.last(partial)).path.length) { +// _.last(partial).push(col); +// } else { +// partial.push([col]); +// } +// return partial; +// }, []); +// } + +// function side_by_side(blocks) { +// var result = _.zip.apply(_,blocks); +// result = _.map(result, function(line) {return _.compact(_.flatten(line))}); +// return result; +// } + +// function make_header_cell(col, span) { +// var options = { +// is_border:true, +// foldable:true, +// row_span: (span === undefined) ? 1 : span, +// col_id: col.id, +// }; +// var result = self.make_cell(col.value, options); +// if (col.expanded) { +// result.find('.icon-plus-sign') +// .removeClass('icon-plus-sign') +// .addClass('icon-minus-sign'); +// } +// return result; +// } + +// function calculate_width(cols) { +// if (cols.length === 1) { +// return 1; +// } +// var p = partition(_.rest(cols)); +// return _.reduce(p, function(x, y){ return x + calculate_width(y); }, 0); +// } + +// function make_header_cells(cols, height) { +// var p = partition(cols); +// if ((p.length === 1) && (p[0].length === 1)) { +// var result = [[make_header_cell(cols[0], height)]]; +// return result; +// } +// if ((p.length === 1) && (p[0].length > 1)) { +// var cell = make_header_cell(p[0][0]); +// cell.attr('colspan', calculate_width(cols)); +// return [[cell]].concat(make_header_cells(_.rest(cols), height - 1)); +// } +// if (p.length > 1) { +// return side_by_side(_.map(p, function (group) { +// return make_header_cells(group, height); +// })); +// } +// } + +// if (this.cols.length === 1) { +// header = $(''); +// header.append(this.make_cell('', {is_border:true})); +// header.append(this.make_cell(this.cols[0].value, +// {is_border:true, foldable:true, col_id:this.cols[0].id})); +// header.addClass('graph_top'); +// this.headers = [header]; +// } else { +// var height = _.max(_.map(self.cols, function(g) {return g.path.length;})); +// var header_rows = make_header_cells(_.rest(this.cols), height); + +// header_rows[0].splice(0,0,self.make_cell('', {is_border:true, }).attr('rowspan', height)) +// self.headers = []; +// _.each(header_rows, function (cells) { +// header = $(''); +// header.append(cells); +// header.addClass('graph_top'); +// self.headers.push(header); +// }); +// } +// }, + + + // mode: 'pivot', // pivot, bar_chart, line_chart or pie_chart + // pivot_table: null, + + // events: { + // 'click .graph_mode_selection li' : function (event) { + // event.preventDefault(); + // this.mode = event.target.attributes['data-mode'].nodeValue; + // this.display_data(); + // }, + // }, + + // display_data : function () { + // var content = this.$el.filter('.graph_main_content'); + // content.find('svg').remove(); + // var self = this; + // if (this.mode === 'pivot') { + // this.pivot_table.show(); + // } else { + // this.pivot_table.hide(); + // content.append(''); + // var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); + // query_groups(this.data.model, view_fields, this.data.domain, this.data.row_groupby).then(function (groups) { + // Charts[self.mode](groups, self.data.measure, self.data.measure_label); + // }); + + // } + // }, + + + // if (this.pivot_table) { + // this.pivot_table.draw(true); + // } else { + + // this.pivot_table = new PivotTable(this.data); + // this.pivot_table.appendTo('.graph_main_content'); + // } + // this.display_data(); - this.data.col_groupby.splice(new_groupby_length); - this.make_top_headers(); - this.draw_top_headers(); + /** + * PivotTable widget. It displays the data in tabular data and allows the + * user to drill down and up in the table + */ +// var PivotTable = instance.web.Widget.extend({ +// template: 'pivot_table', + +// init: function (data) { +// var self = this; +// makePivotTable(this.data).done(function (table) { +// self.pivottable = table; +// }); +// }, + +// }); + +// var PivotTable = instance.web.Widget.extend({ +// template: 'pivot_table', +// data: null, +// headers: [], +// rows: [], +// cols: [], +// id_seed : 0, + +// events: { +// 'click .web_graph_click' : function (event) { +// event.preventDefault(); + +// if (event.target.attributes['data-row-id'] !== undefined) { +// this.handle_row_event(event); +// } +// if (event.target.attributes['data-col-id'] !== undefined) { +// this.handle_col_event(event); +// } +// }, + +// 'click a.field-selection' : function (event) { +// var id, +// field_id = event.target.attributes['data-field-id'].nodeValue; +// event.preventDefault(); +// this.dropdown.remove(); +// if (event.target.attributes['data-row-id'] !== undefined) { +// id = event.target.attributes['data-row-id'].nodeValue; +// this.expand_row(id, field_id); +// } +// if (event.target.attributes['data-col-id'] !== undefined) { +// id = event.target.attributes['data-col-id'].nodeValue; +// this.expand_col(id, field_id); +// } +// }, +// }, + +// handle_row_event: function (event) { +// var row_id = event.target.attributes['data-row-id'].nodeValue, +// row = this.get_row(row_id); + +// if (row.expanded) { +// this.fold_row(row_id); +// } else { +// if (row.path.length < this.data.row_groupby.length) { +// var field_to_expand = this.data.row_groupby[row.path.length]; +// this.expand_row(row_id, field_to_expand); +// } else { +// this.display_dropdown({row_id:row_id, +// target: $(event.target), +// x: event.pageX, +// y: event.pageY}); +// } +// } +// }, + +// handle_col_event: function (event) { +// var col_id = event.target.attributes['data-col-id'].nodeValue, +// col = this.get_col(col_id); + +// if (col.expanded) { +// this.fold_col(col_id); +// } else { +// if (col.path.length < this.data.col_groupby.length) { +// var field_to_expand = this.data.col_groupby[col.path.length]; +// this.expand_col(col_id, field_to_expand); +// } else { +// this.display_dropdown({col_id: col_id, +// target: $(event.target), +// x: event.pageX, +// y: event.pageY}); +// } +// } +// }, + +// init: function (data) { +// this.data = data; +// makePivotTable(this.data).done(function (table) { +// self.pivottable = table; +// }); + +// }, + +// start: function () { +// this.draw(true); +// }, + +// draw: function (load_data) { +// var self = this; + +// if (load_data) { +// var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); +// query_groups_data(this.data.model, view_fields, this.data.domain, this.data.col_groupby, this.data.row_groupby[0]) +// .then(function (groups) { +// self.data.groups = groups; +// return self.get_groups([]); +// }).then(function (total) { +// total[0].path = []; +// self.data.total = [total]; +// self.build_table(); +// self.draw(false); +// }); +// } else { +// this.$el.empty(); + +// this.draw_top_headers(); + +// _.each(this.rows, function (row) { +// self.$el.append(row.html); +// }); +// } +// }, + +// show: function () { +// this.$el.css('display', 'block'); +// }, + +// hide: function () { +// this.$el.css('display', 'none'); +// }, + +// display_dropdown: function (options) { +// var self = this, +// already_grouped = self.data.row_groupby.concat(self.data.col_groupby), +// possible_groups = _.difference(self.data.important_fields, already_grouped), +// dropdown_options = { +// fields: _.map(possible_groups, function (field) { +// return {id: field, value: self.get_descr(field)}; +// })}; +// if (options.row_id) { +// dropdown_options.row_id= options.row_id; +// } else { +// dropdown_options.col_id = options.col_id; +// } + +// this.dropdown = $(QWeb.render('field_selection', dropdown_options)); +// options.target.after(this.dropdown); +// this.dropdown.css({position:'absolute', +// left:options.x, +// top:options.y}); +// $('.field-selection').next('.dropdown-menu').toggle(); +// }, + +// build_table: function () { +// var self = this; +// this.rows = []; + + +// var col_id = this.generate_id(); + +// this.cols= [{ +// id: col_id, +// path: [], +// value: this.data.measure_label, +// expanded: false, +// parent: null, +// children: [], +// cells: [], // a cell is {td:, row_id:} +// domain: this.data.domain, +// }]; + +// self.make_top_headers(); + +// var main_row = this.make_row(this.data.total[0]); + +// _.each(this.data.groups, function (group) { +// self.make_row(group, main_row.id); +// }); +// }, + +// get_descr: function (field_id) { +// return this.data.fields[field_id].string; +// }, + +// get_groups: function (groupby) { +// var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); +// return query_groups(this.data.model, view_fields, this.data.domain, groupby); +// }, + +// make_top_headers : function () { +// var self = this, +// header; + +// function partition (columns) { +// return _.reduce(columns, function (partial, col) { +// if (partial.length === 0) return [[col]]; +// if (col.path.length > _.first(_.last(partial)).path.length) { +// _.last(partial).push(col); +// } else { +// partial.push([col]); +// } +// return partial; +// }, []); +// } + +// function side_by_side(blocks) { +// var result = _.zip.apply(_,blocks); +// result = _.map(result, function(line) {return _.compact(_.flatten(line))}); +// return result; +// } + +// function make_header_cell(col, span) { +// var options = { +// is_border:true, +// foldable:true, +// row_span: (span === undefined) ? 1 : span, +// col_id: col.id, +// }; +// var result = self.make_cell(col.value, options); +// if (col.expanded) { +// result.find('.icon-plus-sign') +// .removeClass('icon-plus-sign') +// .addClass('icon-minus-sign'); +// } +// return result; +// } + +// function calculate_width(cols) { +// if (cols.length === 1) { +// return 1; +// } +// var p = partition(_.rest(cols)); +// return _.reduce(p, function(x, y){ return x + calculate_width(y); }, 0); +// } + +// function make_header_cells(cols, height) { +// var p = partition(cols); +// if ((p.length === 1) && (p[0].length === 1)) { +// var result = [[make_header_cell(cols[0], height)]]; +// return result; +// } +// if ((p.length === 1) && (p[0].length > 1)) { +// var cell = make_header_cell(p[0][0]); +// cell.attr('colspan', calculate_width(cols)); +// return [[cell]].concat(make_header_cells(_.rest(cols), height - 1)); +// } +// if (p.length > 1) { +// return side_by_side(_.map(p, function (group) { +// return make_header_cells(group, height); +// })); +// } +// } + +// if (this.cols.length === 1) { +// header = $(''); +// header.append(this.make_cell('', {is_border:true})); +// header.append(this.make_cell(this.cols[0].value, +// {is_border:true, foldable:true, col_id:this.cols[0].id})); +// header.addClass('graph_top'); +// this.headers = [header]; +// } else { +// var height = _.max(_.map(self.cols, function(g) {return g.path.length;})); +// var header_rows = make_header_cells(_.rest(this.cols), height); + +// header_rows[0].splice(0,0,self.make_cell('', {is_border:true, }).attr('rowspan', height)) +// self.headers = []; +// _.each(header_rows, function (cells) { +// header = $(''); +// header.append(cells); +// header.addClass('graph_top'); +// self.headers.push(header); +// }); +// } +// }, + +// draw_top_headers: function () { +// var self = this; +// $("tr.graph_top").remove(); +// _.each(this.headers.reverse(), function (header) { +// self.$el.prepend(header); +// }); + +// }, + +// make_row: function (groups, parent_id) { +// var self = this, +// path, +// value, +// expanded, +// domain, +// parent, +// has_parent = (parent_id !== undefined), +// row_id = this.generate_id(); + +// if (has_parent) { +// parent = this.get_row(parent_id); +// path = parent.path.concat(groups[0].attributes.value[1]); +// value = groups[0].attributes.value[1]; +// expanded = false; +// parent.children.push(row_id); +// domain = groups[0].model._domain; +// } else { +// parent = null; +// path = []; +// value = 'Total'; +// expanded = true; +// domain = this.data.domain; +// } + +// var jquery_row = $(''); + +// var header = self.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); +// jquery_row.append(header); + +// var cell; + +// _.each(this.cols, function (col) { +// var element = _.find(groups, function (group) { +// return _.isEqual(_.rest(group.path), col.path); +// }); +// if (element === undefined) { +// cell = self.make_cell(''); +// } else { +// cell = self.make_cell(element.attributes.aggregates[self.data.measure]); +// } +// if (col.expanded) { +// cell.css('display', 'none'); +// } +// col.cells.push({td:cell, row_id:row_id}); +// jquery_row.append(cell); +// }); + +// if (!has_parent) { +// header.find('.icon-plus-sign') +// .removeClass('icon-plus-sign') +// .addClass('icon-minus-sign'); +// } + +// var row = { +// id: row_id, +// path: path, +// value: value, +// expanded: expanded, +// parent: parent_id, +// children: [], +// html: jquery_row, +// domain: domain, +// }; +// this.rows.push(row); // to do, insert it properly, after all childs of parent +// return row; +// }, + +// generate_id: function () { +// this.id_seed += 1; +// return this.id_seed - 1; +// }, + +// get_row: function (id) { +// return _.find(this.rows, function(row) { +// return (row.id == id); +// }); +// }, + +// get_col: function (id) { +// return _.find(this.cols, function(col) { +// return (col.id == id); +// }); +// }, + +// make_cell: function (content, options) { +// options = _.extend({is_border: false, indent:0, foldable:false}, options); +// content = (content !== undefined) ? content : 'Undefined'; + +// var cell = $(''); +// if (options.is_border) cell.addClass('graph_border'); +// if (options.row_span) cell.attr('rowspan', options.row_span); +// if (options.col_span) cell.attr('rowspan', options.col_span); +// _.each(_.range(options.indent), function () { +// cell.prepend($('', {class:'web_graph_indent'})); +// }); + +// if (options.foldable) { +// var attrs = {class:'icon-plus-sign web_graph_click', href:'#'}; +// if (options.row_id !== undefined) attrs['data-row-id'] = options.row_id; +// if (options.col_id !== undefined) attrs['data-col-id'] = options.col_id; +// var plus = $('', attrs); +// plus.append(' '); +// plus.append(content); +// cell.append(plus); +// } else { +// cell.append(content); +// } +// return cell; +// }, + +// expand_row: function (row_id, field_id) { +// var self = this; +// var row = this.get_row(row_id); + +// if (row.path.length == this.data.row_groupby.length) { +// this.data.row_groupby.push(field_id); +// } +// row.expanded = true; +// row.html.find('.icon-plus-sign') +// .removeClass('icon-plus-sign') +// .addClass('icon-minus-sign'); + +// var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); +// query_groups_data(this.data.model, visible_fields, row.domain, this.data.col_groupby, field_id) +// .then(function (groups) { +// _.each(groups.reverse(), function (group) { +// var new_row = self.make_row(group, row_id); +// row.html.after(new_row.html); +// }); +// }); + +// }, + +// expand_col: function (col_id, field_id) { +// var self = this; +// var col = this.get_col(col_id); + +// if (col.path.length == this.data.col_groupby.length) { +// this.data.col_groupby.push(field_id); +// } +// col.expanded = true; + +// var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); +// query_groups_data(this.data.model, visible_fields, col.domain, this.data.row_groupby, field_id) +// .then(function (groups) { +// _.each(groups, function (group) { +// var new_col = { +// id: self.generate_id(), +// path: col.path.concat(group[0].attributes.value[1]), +// value: group[0].attributes.value[1], +// expanded: false, +// parent: col_id, +// children: [], +// cells: [], // a cell is {td:, row_id:} +// domain: group[0].model._domain, +// }; +// col.children.push(new_col.id); +// insertAfter(self.cols, col, new_col) +// _.each(col.cells, function (cell) { +// var col_path = self.get_row(cell.row_id).path; + +// var datapt = _.find(group, function (g) { +// return _.isEqual(g.path.slice(1), col_path); +// }); + +// var value; +// if (datapt === undefined) { +// value = ''; +// } else { +// value = datapt.attributes.aggregates[self.data.measure]; +// } +// var new_cell = { +// row_id: cell.row_id, +// td: self.make_cell(value) +// }; +// new_col.cells.push(new_cell); +// cell.td.after(new_cell.td); +// cell.td.css('display','none'); +// }); + +// }); +// self.make_top_headers(); +// self.draw_top_headers(); +// }); +// }, + +// fold_row: function (row_id) { +// var self = this; +// var row = this.get_row(row_id); + +// _.each(row.children, function (child_row) { +// self.remove_row(child_row); +// }); +// row.children = []; + +// row.expanded = false; +// row.html.find('.icon-minus-sign') +// .removeClass('icon-minus-sign') +// .addClass('icon-plus-sign'); + +// var fold_levels = _.map(self.rows, function(g) {return g.path.length;}); +// var new_groupby_length = _.max(fold_levels); + +// this.data.row_groupby.splice(new_groupby_length); +// }, + +// remove_row: function (row_id) { +// var self = this; +// var row = this.get_row(row_id); + +// _.each(row.children, function (child_row) { +// self.remove_row(child_row); +// }); + +// row.html.remove(); +// removeFromArray(this.rows, row); + +// _.each(this.cols, function (col) { +// col.cells = _.filter(col.cells, function (cell) { +// return cell.row_id !== row_id; +// }); +// }); +// }, + +// fold_col: function (col_id) { +// var self = this; +// var col = this.get_col(col_id); + +// _.each(col.children, function (child_col) { +// self.remove_col(child_col); +// }); +// col.children = []; + +// _.each(col.cells, function (cell) { +// cell.td.css('display','table-cell'); +// }); +// col.expanded = false; +// // row.html.find('.icon-minus-sign') +// // .removeClass('icon-minus-sign') +// // .addClass('icon-plus-sign'); + +// var fold_levels = _.map(self.cols, function(g) {return g.path.length;}); +// var new_groupby_length = _.max(fold_levels); + +// this.data.col_groupby.splice(new_groupby_length); +// this.make_top_headers(); +// this.draw_top_headers(); - }, +// }, - remove_col: function (col_id) { - var self = this; - var col = this.get_col(col_id); +// remove_col: function (col_id) { +// var self = this; +// var col = this.get_col(col_id); - _.each(col.children, function (child_col) { - self.remove_col(child_col); - }); +// _.each(col.children, function (child_col) { +// self.remove_col(child_col); +// }); - _.each(col.cells, function (cell) { - cell.td.remove(); - }); - // row.html.remove(); - removeFromArray(this.cols, col); - - // _.each(this.cols, function (col) { - // col.cells = _.filter(col.cells, function (cell) { - // return cell.row_id !== row_id; - // }); - // }); - }, +// _.each(col.cells, function (cell) { +// cell.td.remove(); +// }); +// // row.html.remove(); +// removeFromArray(this.cols, col); +// // _.each(this.cols, function (col) { +// // col.cells = _.filter(col.cells, function (cell) { +// // return cell.row_id !== row_id; +// // }); +// // }); +// }, -}); + +// }); }; diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js new file mode 100644 index 00000000000..3df67e188d8 --- /dev/null +++ b/addons/web_graph/static/src/js/pivot.js @@ -0,0 +1,132 @@ + + +var PivotTable = openerp.web.Class.extend({ + init: function (options) { + this.rows = []; + this.cols = []; + this.cells = []; + this.row_groupby = options.row_groupby; + this.col_groupby = []; + this.model = options.model; + this.measure = options.measure; + this.measure_label = options.measure_label; + this.domain = options.domain; + + this.id_seed = -1; + }, + + // Load initial data into the rows, cols and cells array. + // This function needs to be called after init and before + // drawing the table (otherwise the data returned will be empty...) + start: function () { + var self = this; + var main_row = { + id: this.generate_id(), + path: [], + name: "Total", + is_expanded: false, + parent: null, + children: [], + domain: this.domain, + }; + this.rows.push(main_row); + + var main_col = { + id: this.generate_id(), + path: [], + name: this.measure_label, + is_expanded: false, + parent: null, + children: [], + domain: this.domain, + }; + this.cols.push(main_col); + + // get total and create first cell + var tot = query_groups (this.model, this.measure, this.domain, []) + .then(function (total) { + var val = total[0].attributes.aggregates[self.measure]; + self.set_value(main_row.id, main_col.id, val); + }); + + var grp = query_groups (this.model, this.visible_fields(), this.domain, this.row_groupby) + .then(function (groups) { + _.each(groups, function (group) { + var new_row = { + id: self.generate_id(), + path: [group.attributes.value[1]], + name: group.attributes.value[1], + is_expanded: false, + parent: main_row, + children: [], + domain: group.model._domain, + } + self.rows.push(new_row); + main_row.children.push(new_row.id); + self.set_value(new_row.id, main_col.id, + group.attributes.aggregates[self.measure]); + }); + main_row.is_expanded = true; + }); + + return $.when(tot, grp); + }, + + generate_id: function () { + this.id_seed += 1; + return this.id_seed; + }, + + visible_fields: function () { + return this.row_groupby.concat(this.col_groupby, this.measure); + }, + + set_value: function (row, col, value) { + var cell = _.find(this.cells, function (c) { + return ((c.row_id == row) && (c.col_id == col)); + }); + if (cell) { + cell.value = value; + } else { + this.cells.push({row_id: row, col_id: col, value: value}); + } + }, + + get_value: function (row, col) { + var cell = _.find(this.cells, function (c) { + return ((c.row_id == row) && (c.col_id == col)); + }); + return (cell) ? cell.value : ''; + } + + +}); + + + + // function expand_row (row, field) { + + // } + + // function expand_col (col, field) { + + // } + + // function fold_row (row) { + + // } + + // function fold_col (col) { + + // } + + +// function update_values () { +// // update all cells (reload data from db) +// // return a deferred +// } + +// var id_seed = -1; + +// return init(); +// } \ No newline at end of file -- cgit v1.2.3 From a32018f96237b72ee2ad021987d97539ff433129 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 22 Nov 2013 10:43:22 +0100 Subject: [REF] large refactoring in progress. goal is to separate the data handling code (pivot) from the ui code (drawing, buttons, events (addon web_graph) bzr revid: ged@openerp.com-20131122094322-wn36gtmtv9pgn5su --- addons/web_graph/static/src/js/graph.js | 99 +++++++++++++-------------------- addons/web_graph/static/src/js/pivot.js | 67 ++++++++++++++++------ 2 files changed, 90 insertions(+), 76 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 3363f7cb3a8..7ad283c6810 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -125,87 +125,66 @@ instance.web_graph.GraphView = instance.web.View.extend({ draw_table: function () { this.draw_top_headers(); - _.each(this.pivot_table.rows, this.proxy('draw_row')); + this.pivot_table.iterate(this.pivot_table.rows, this.proxy('draw_row')); }, - draw_top_headers: function () { - var self = this, - pivot = this.pivot_table; + make_border_cell: function (colspan, rowspan) { + return $('').addClass('graph_border') + .attr('colspan', colspan) + .attr('rowspan', rowspan); + }, - function get_column_tree(cols, level) { - var height, - width, - children = _.map(cols[0].children, function (child) { - get_column_tree(child, level - 1); - }); - if (children.length > 0) { - height = 1; - width = _.reduce(children, function (x,y) { return x + y;}, 0); - } else { - height = level; - width = 1; - } - return {level: level, - width: width, - height: height, - col:cols[0], - children: children}; - } + make_header_title: function (header) { + return $(' ') + .addClass('web_graph_click') + .attr('href', '#') + .addClass((header.is_expanded) ? 'icon-minus-sign' : 'icon-plus-sign') + .append(header.name); + }, - function make_cell(elem) { - var title = $(' ') - .addClass('web_graph_click') - .attr('href', '#') - .attr('data-col-id', elem.col.id) - .addClass((elem.col.is_expanded) ? 'icon-minus-sign' : 'icon-plus-sign') - .append(elem.col.name); - return $('').addClass('graph_border') - .append(title) - .attr('rowspan', elem.height) - .attr('colspan', elem.width); + draw_top_headers: function () { + var self = this, + pivot = this.pivot_table, + height = pivot.get_max_path_length(pivot.cols), + header_cells = [[this.make_border_cell(1, height)]]; + + function make_col_header (col) { + var cell = self.make_border_cell(col.width, col.height); + return cell.append(self.make_header_title(col)) + .attr('data-col-id', col.id); } - var height = _.max(_.map(pivot.cols, function(g) {return g.path.length;})); - height = (height === 0) ? 1 : height; - - var col_tree = get_column_tree(pivot.cols, height); - - var header_cells = [[$('') - .attr('rowspan', height) - .addClass('graph_border')]]; - function make_cells (queue, level) { - var tree = queue.shift(); - queue = queue.concat(tree.children); - if (tree.level == level) { - _.last(header_cells).push(make_cell(tree)); + var col = queue.shift(); + queue = queue.concat(col.children); + console.log("col",col, level); + if (col.path.length == level) { + _.last(header_cells).push(make_col_header(col)); } else { - level -=1; - header_cells.push([make_cell(tree)]); + level +=1; + header_cells.push([make_col_header(col)]); } if (queue.length !== 0) { make_cells(queue, level); } } - make_cells([col_tree], height); + if (pivot.cols.children.length === 0) { + make_cells([pivot.cols], 0); + } else { + make_cells(pivot.cols.children, 1); + } + _.each(header_cells, function (cells) { - var row = $("").append(cells); - self.table.append(row); + self.table.append($("").append(cells)); }); }, draw_row: function (row) { var pivot = this.pivot_table, html_row = $(''), - name = $(' ') - .addClass('web_graph_click') - .attr('href', '#') - .attr('data-row-id', row.id) - .addClass((row.is_expanded) ? 'icon-minus-sign' : 'icon-plus-sign') - .append(row.name), row_header = $('') - .append(name) + .append(this.make_header_title(row)) .addClass('graph_border'); for (var i in _.range(row.path.length)) { @@ -214,7 +193,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ html_row.append(row_header); - _.each(pivot.cols, function (col) { + pivot.iterate(pivot.cols, function (col) { var cell = $('').append(pivot.get_value(row.id, col.id)); html_row.append(cell) }); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 3df67e188d8..dca21087ce5 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -2,8 +2,8 @@ var PivotTable = openerp.web.Class.extend({ init: function (options) { - this.rows = []; - this.cols = []; + this.rows = {}; + this.cols = {}; this.cells = []; this.row_groupby = options.row_groupby; this.col_groupby = []; @@ -20,7 +20,7 @@ var PivotTable = openerp.web.Class.extend({ // drawing the table (otherwise the data returned will be empty...) start: function () { var self = this; - var main_row = { + this.rows = { id: this.generate_id(), path: [], name: "Total", @@ -28,10 +28,11 @@ var PivotTable = openerp.web.Class.extend({ parent: null, children: [], domain: this.domain, + height: 1, + width: 1, }; - this.rows.push(main_row); - var main_col = { + this.cols = { id: this.generate_id(), path: [], name: this.measure_label, @@ -39,34 +40,37 @@ var PivotTable = openerp.web.Class.extend({ parent: null, children: [], domain: this.domain, + height: 1, + width: 1, }; - this.cols.push(main_col); // get total and create first cell var tot = query_groups (this.model, this.measure, this.domain, []) .then(function (total) { var val = total[0].attributes.aggregates[self.measure]; - self.set_value(main_row.id, main_col.id, val); + self.set_value(self.rows.id, self.cols.id, val); }); var grp = query_groups (this.model, this.visible_fields(), this.domain, this.row_groupby) .then(function (groups) { _.each(groups, function (group) { - var new_row = { - id: self.generate_id(), + var new_id = self.generate_id(); + self.rows.children.push({ + id: new_id, path: [group.attributes.value[1]], name: group.attributes.value[1], is_expanded: false, - parent: main_row, + parent: self.rows, children: [], domain: group.model._domain, - } - self.rows.push(new_row); - main_row.children.push(new_row.id); - self.set_value(new_row.id, main_col.id, + height: 1, + width: 1, + }); + self.set_value(new_id, self.cols.id, group.attributes.aggregates[self.measure]); }); - main_row.is_expanded = true; + self.rows.is_expanded = true; + self.rows.width = groups.length; }); return $.when(tot, grp); @@ -97,8 +101,39 @@ var PivotTable = openerp.web.Class.extend({ return ((c.row_id == row) && (c.col_id == col)); }); return (cell) ? cell.value : ''; - } + }, + + iterate: function (header, iterator) { + var self = this; + iterator(header); + _.each(header.children, function (child) { + self.iterate(child, iterator); + }); + }, + get_max_path_length: function (header) { + var height = 0; + this.iterate(this.cols, function (col) { + height = Math.max(height, col.path.length); + }); + return height; + }, + + // 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); + // } + // } + + + // toArray: function (header) { + // return [header].concat(_.map(header.children), this.toArray(hea)) + // } }); -- cgit v1.2.3 From 2c5fb3b2a29aae9a27b957f4db456643c35db746 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 22 Nov 2013 14:59:27 +0100 Subject: [REF] large refactoring in progress. goal is to separate the data handling code (pivot) from the ui code (drawing, buttons, events (addon web_graph) bzr revid: ged@openerp.com-20131122135927-mfaa44juzjhp4kas --- addons/web_graph/static/src/js/graph.js | 101 ++++++++++++-- addons/web_graph/static/src/js/pivot.js | 231 +++++++++++++++++++++++++++++--- 2 files changed, 303 insertions(+), 29 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7ad283c6810..91c794ea2ae 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -27,7 +27,34 @@ instance.web_graph.GraphView = instance.web.View.extend({ 'click .graph_mode_selection li' : function (event) { event.preventDefault(); this.mode = event.target.attributes['data-mode'].nodeValue; - console.log("change mode",this.mode); + }, + + 'click .web_graph_click' : function (event) { + event.preventDefault(); + if (event.target.attributes['data-row-id'] !== undefined) { + this.handle_header_event({type:'row', event:event}); + + } + if (event.target.attributes['data-col-id'] !== undefined) { + this.handle_header_event({type:'col', event:event}); + } + }, + + 'click a.field-selection' : function (event) { + var id, + field_id = event.target.attributes['data-field-id'].nodeValue; + event.preventDefault(); + this.dropdown.remove(); + if (event.target.attributes['data-row-id'] !== undefined) { + id = event.target.attributes['data-row-id'].nodeValue; + this.pivot_table.expand_row(id, field_id) + .then(this.proxy('draw_table')); + } + if (event.target.attributes['data-col-id'] !== undefined) { + id = event.target.attributes['data-col-id'].nodeValue; + this.pivot_table.expand_col(id, field_id) + .then(this.proxy('draw_table')); + } }, }, @@ -123,9 +150,56 @@ instance.web_graph.GraphView = instance.web.View.extend({ return this._super(); }, + + handle_header_event: function (options) { + var pivot = this.pivot_table, + id = options.event.target.attributes['data-' + options.type + '-id'].nodeValue, + header = pivot['get_' + options.type](id); + + if (header.is_expanded) { + pivot['fold_' + options.type](header); + this.draw_table(); + } else { + if (header.path.length < pivot[options.type + '_groupby'].length) { + // expand the corresponding header + var field = pivot[options.type + '_groupby'][header.path.length]; + pivot['expand_' + options.type](id, field) + .then(this.proxy('draw_table')); + } else { + // display dropdown to query field to expand + this.display_dropdown({id:header.id, + type: options.type, + target: $(event.target), + x: event.pageX, + y: event.pageY}); + } + } + + }, + + display_dropdown: function (options) { + var self = this, + pivot = this.pivot_table, + already_grouped = pivot.row_groupby.concat(pivot.col_groupby), + possible_groups = _.difference(self.data.important_fields, already_grouped), + dropdown_options = { + fields: _.map(possible_groups, function (field) { + return {id: field, value: self.data.fields[field].string}; + })}; + dropdown_options[options.type + '_id'] = options.id; + + this.dropdown = $(QWeb.render('field_selection', dropdown_options)); + options.target.after(this.dropdown); + this.dropdown.css({position:'absolute', + left:options.x, + top:options.y}); + $('.field-selection').next('.dropdown-menu').toggle(); + }, + draw_table: function () { + this.table.empty(); this.draw_top_headers(); - this.pivot_table.iterate(this.pivot_table.rows, this.proxy('draw_row')); + _.each(this.pivot_table.rows_array(), this.proxy('draw_row')); }, make_border_cell: function (colspan, rowspan) { @@ -148,16 +222,25 @@ instance.web_graph.GraphView = instance.web.View.extend({ height = pivot.get_max_path_length(pivot.cols), header_cells = [[this.make_border_cell(1, height)]]; + 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, col.height); - return cell.append(self.make_header_title(col)) - .attr('data-col-id', col.id); + return cell.append(self.make_header_title(col).attr('data-col-id', col.id)); } function make_cells (queue, level) { var col = queue.shift(); queue = queue.concat(col.children); - console.log("col",col, level); if (col.path.length == level) { _.last(header_cells).push(make_col_header(col)); } else { @@ -169,6 +252,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ } } + set_dim(pivot.cols); // add width and height info to columns headers + if (pivot.cols.children.length === 0) { make_cells([pivot.cols], 0); } else { @@ -183,8 +268,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ draw_row: function (row) { var pivot = this.pivot_table, html_row = $(''), - row_header = $('') - .append(this.make_header_title(row)) + row_header = this.make_border_cell(1,1) + .append(this.make_header_title(row).attr('data-row-id', row.id)) .addClass('graph_border'); for (var i in _.range(row.path.length)) { @@ -193,7 +278,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ html_row.append(row_header); - pivot.iterate(pivot.cols, function (col) { + _.each(pivot.cols_array(), function (col) { var cell = $('').append(pivot.get_value(row.id, col.id)); html_row.append(cell) }); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index dca21087ce5..9783155848b 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -28,8 +28,6 @@ var PivotTable = openerp.web.Class.extend({ parent: null, children: [], domain: this.domain, - height: 1, - width: 1, }; this.cols = { @@ -40,8 +38,6 @@ var PivotTable = openerp.web.Class.extend({ parent: null, children: [], domain: this.domain, - height: 1, - width: 1, }; // get total and create first cell @@ -63,14 +59,11 @@ var PivotTable = openerp.web.Class.extend({ parent: self.rows, children: [], domain: group.model._domain, - height: 1, - width: 1, }); self.set_value(new_id, self.cols.id, group.attributes.aggregates[self.measure]); }); self.rows.is_expanded = true; - self.rows.width = groups.length; }); return $.when(tot, grp); @@ -111,25 +104,224 @@ var PivotTable = openerp.web.Class.extend({ }); }, + iterate_rows: function (iterator) { + this.iterate(this.rows, iterator); + }, + + iterate_cols: function (iterator) { + this.iterate(this.cols, iterator); + }, + get_max_path_length: function (header) { var height = 0; - this.iterate(this.cols, function (col) { + this.iterate_cols(function (col) { height = Math.max(height, col.path.length); }); return height; }, - // 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); - // } - // } + rows_array: function () { + var result = []; + this.iterate_rows(function (row) { result.push(row); }); + return result; + }, + + cols_array: function () { + var result = []; + this.iterate_cols(function (col) { result.push(col); }); + return result; + }, + + get_col: function (id) { + return _.find(this.cols_array(), function (col) { return col.id == id;}); + }, + + get_row: function (id) { + return _.find(this.rows_array(), function (row) { return row.id == id;}); + }, + + fold: function (header) { + header.children = []; + header.is_expanded = false; + var fold_lvls = _.map(this.rows_array(), function(g) {return g.path.length;}); + var new_groupby_length = _.max(fold_lvls); + this.row_groupby.splice(new_groupby_length); + + // to do : remove every corresponding cells + }, + + fold_row: function (row) { + this.fold(row); + }, + + fold_col: function (col) { + this.fold(col); + }, + + expand_row: function (row_id, field_id) { + var self = this, + row = this.get_row(row_id); + + if (row.path.length == this.row_groupby.length) { + this.row_groupby.push(field_id); + } + return query_groups_data(this.model, this.visible_fields(), row.domain, this.col_groupby, field_id) + .then(function (groups) { + _.each(groups, function (group) { + var new_row_id = self.make_header(group, row); + var cols_array = self.cols_array(); + _.each(group, function (data) { + var col = _.find(cols_array, function (c) { + return _.isEqual(_.rest(data.path), c.path); + }); + if (col) { + self.set_value(new_row_id, col.id, data.attributes.aggregates[self.measure]); + } + }); + }); + row.is_expanded = true; + }); + }, + + expand_col: function (col_id, field_id) { + var self = this, + col = this.get_col(col_id); + + if (col.path.length == this.col_groupby.length) { + this.col_groupby.push(field_id); + } + + console.log("cols",this.cols_array()); + console.log("dbg",this.col_groupby); + return query_groups_data(this.model, this.visible_fields(), col.domain, this.row_groupby, field_id) + .then(function (groups) { + console.log("groups",groups); + _.each(groups, function (group) { + // console.log("adding group",group); + var new_col_id = self.make_header(group, col); + // // var rows_array = self.rows_array(); + // // _.each(group, function (data) { + // // var row = _.find(rows_array, function (c) { + // // return _.isEqual(data.path.slice(1), c.path); + // // }); + // // if (row) { + // // self.set_value(row.id, new_col_id, data.attributes.aggregates[self.measure]); + // // } + // // }); + }); + // col.is_expanded = true; + // // console.log("col is now",col); + // // console.log("dbg",col.children.length); + }); + + }, + + make_header: function (groups, parent) { + + var new_header = { + id: this.generate_id(), + path: parent.path.concat(groups[0].attributes.value[1]), + name: groups[0].attributes.value[1], + is_expanded: false, + parent: parent.id, + children: [], + domain: groups[0].model._domain, + }; + parent.children.push(new_header); + return new_header.id; + }, + +// make_row: function (groups, parent_id) { +// var self = this, +// path, +// value, +// expanded, +// domain, +// parent, +// has_parent = (parent_id !== undefined), +// row_id = this.generate_id(); + +// if (has_parent) { +// parent = this.get_row(parent_id); +// path = parent.path.concat(groups[0].attributes.value[1]); +// value = groups[0].attributes.value[1]; +// expanded = false; +// parent.children.push(row_id); +// domain = groups[0].model._domain; +// } else { +// parent = null; +// path = []; +// value = 'Total'; +// expanded = true; +// domain = this.data.domain; +// } + +// var jquery_row = $(''); + +// var header = self.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); +// jquery_row.append(header); + +// var cell; + +// _.each(this.cols, function (col) { +// var element = _.find(groups, function (group) { +// return _.isEqual(_.rest(group.path), col.path); +// }); +// if (element === undefined) { +// cell = self.make_cell(''); +// } else { +// cell = self.make_cell(element.attributes.aggregates[self.data.measure]); +// } +// if (col.expanded) { +// cell.css('display', 'none'); +// } +// col.cells.push({td:cell, row_id:row_id}); +// jquery_row.append(cell); +// }); + +// if (!has_parent) { +// header.find('.icon-plus-sign') +// .removeClass('icon-plus-sign') +// .addClass('icon-minus-sign'); +// } + +// var row = { +// id: row_id, +// path: path, +// value: value, +// expanded: expanded, +// parent: parent_id, +// children: [], +// html: jquery_row, +// domain: domain, +// }; +// this.rows.push(row); // to do, insert it properly, after all childs of parent +// return row; +// }, + +// expand_row: function (row_id, field_id) { +// var self = this; +// var row = this.get_row(row_id); + +// if (row.path.length == this.data.row_groupby.length) { +// this.data.row_groupby.push(field_id); +// } +// row.expanded = true; +// row.html.find('.icon-plus-sign') +// .removeClass('icon-plus-sign') +// .addClass('icon-minus-sign'); + +// var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); +// query_groups_data(this.data.model, visible_fields, row.domain, this.data.col_groupby, field_id) +// .then(function (groups) { +// _.each(groups.reverse(), function (group) { +// var new_row = self.make_row(group, row_id); +// row.html.after(new_row.html); +// }); +// }); + +// }, // toArray: function (header) { // return [header].concat(_.map(header.children), this.toArray(hea)) @@ -147,9 +339,6 @@ var PivotTable = openerp.web.Class.extend({ // } - // function fold_row (row) { - - // } // function fold_col (col) { -- cgit v1.2.3 From 200762944abc00e5cb748af96583302237c9a669 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 22 Nov 2013 16:10:25 +0100 Subject: [REF] large refactoring in progress. goal is to separate the data handling code (pivot) from the ui code (drawing, buttons, events (addon web_graph) bzr revid: ged@openerp.com-20131122151025-8npxh5g5y2ema4tq --- addons/web_graph/static/src/js/graph.js | 26 +-- addons/web_graph/static/src/js/pivot.js | 283 +++++++++----------------------- 2 files changed, 88 insertions(+), 221 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 91c794ea2ae..7d7d575756c 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -197,9 +197,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, draw_table: function () { + console.log("cols",this.pivot_table.cols); this.table.empty(); this.draw_top_headers(); - _.each(this.pivot_table.rows_array(), this.proxy('draw_row')); + _.each(this.pivot_table.rows, this.proxy('draw_row')); }, make_border_cell: function (colspan, rowspan) { @@ -219,7 +220,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ draw_top_headers: function () { var self = this, pivot = this.pivot_table, - height = pivot.get_max_path_length(pivot.cols), + height = _.max(_.map(pivot.cols, function(g) {return g.path.length;})), header_cells = [[this.make_border_cell(1, height)]]; function set_dim (cols) { @@ -239,8 +240,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ } function make_cells (queue, level) { - var col = queue.shift(); - queue = queue.concat(col.children); + var col = queue[0]; + queue = _.rest(queue).concat(col.children); if (col.path.length == level) { _.last(header_cells).push(make_col_header(col)); } else { @@ -252,12 +253,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ } } - set_dim(pivot.cols); // add width and height info to columns headers - - if (pivot.cols.children.length === 0) { - make_cells([pivot.cols], 0); + set_dim(pivot.cols[0]); // add width and height info to columns headers + if (pivot.cols[0].children.length === 0) { + make_cells(pivot.cols, 0); } else { - make_cells(pivot.cols.children, 1); + make_cells(pivot.cols[0].children, 1); } _.each(header_cells, function (cells) { @@ -278,9 +278,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ html_row.append(row_header); - _.each(pivot.cols_array(), function (col) { - var cell = $('').append(pivot.get_value(row.id, col.id)); - html_row.append(cell) + _.each(pivot.cols, function (col) { + if (col.children.length === 0) { + var cell = $('').append(pivot.get_value(row.id, col.id)); + html_row.append(cell); + } }); this.table.append(html_row); } diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 9783155848b..081470fcb37 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -2,8 +2,8 @@ var PivotTable = openerp.web.Class.extend({ init: function (options) { - this.rows = {}; - this.cols = {}; + this.rows = []; + this.cols = []; this.cells = []; this.row_groupby = options.row_groupby; this.col_groupby = []; @@ -11,8 +11,7 @@ var PivotTable = openerp.web.Class.extend({ this.measure = options.measure; this.measure_label = options.measure_label; this.domain = options.domain; - - this.id_seed = -1; + this.id_seed = 0; }, // Load initial data into the rows, cols and cells array. @@ -20,7 +19,7 @@ var PivotTable = openerp.web.Class.extend({ // drawing the table (otherwise the data returned will be empty...) start: function () { var self = this; - this.rows = { + this.rows.push({ id: this.generate_id(), path: [], name: "Total", @@ -28,9 +27,9 @@ var PivotTable = openerp.web.Class.extend({ parent: null, children: [], domain: this.domain, - }; + }); - this.cols = { + this.cols.push({ id: this.generate_id(), path: [], name: this.measure_label, @@ -38,32 +37,35 @@ var PivotTable = openerp.web.Class.extend({ parent: null, children: [], domain: this.domain, - }; + }); // get total and create first cell var tot = query_groups (this.model, this.measure, this.domain, []) .then(function (total) { var val = total[0].attributes.aggregates[self.measure]; - self.set_value(self.rows.id, self.cols.id, val); + self.set_value(self.rows[0].id, self.cols[0].id, val); }); var grp = query_groups (this.model, this.visible_fields(), this.domain, this.row_groupby) .then(function (groups) { _.each(groups, function (group) { - var new_id = self.generate_id(); - self.rows.children.push({ + var new_id = self.generate_id(), + new_row = { id: new_id, path: [group.attributes.value[1]], name: group.attributes.value[1], is_expanded: false, - parent: self.rows, + parent: self.rows[0], children: [], domain: group.model._domain, - }); - self.set_value(new_id, self.cols.id, + }; + + self.rows[0].children.push(new_row); + self.rows.push(new_row); + self.set_value(new_id, self.cols[0].id, group.attributes.aggregates[self.measure]); }); - self.rows.is_expanded = true; + self.rows[0].is_expanded = true; }); return $.when(tot, grp); @@ -96,67 +98,42 @@ var PivotTable = openerp.web.Class.extend({ return (cell) ? cell.value : ''; }, - iterate: function (header, iterator) { - var self = this; - iterator(header); - _.each(header.children, function (child) { - self.iterate(child, iterator); - }); - }, - - iterate_rows: function (iterator) { - this.iterate(this.rows, iterator); - }, - - iterate_cols: function (iterator) { - this.iterate(this.cols, iterator); - }, - - get_max_path_length: function (header) { - var height = 0; - this.iterate_cols(function (col) { - height = Math.max(height, col.path.length); - }); - return height; - }, - - rows_array: function () { - var result = []; - this.iterate_rows(function (row) { result.push(row); }); - return result; - }, - - cols_array: function () { - var result = []; - this.iterate_cols(function (col) { result.push(col); }); - return result; - }, - get_col: function (id) { - return _.find(this.cols_array(), function (col) { return col.id == id;}); + return _.find(this.cols, function (col) { return col.id == id;}); }, get_row: function (id) { - return _.find(this.rows_array(), function (row) { return row.id == id;}); + return _.find(this.rows, function (row) { return row.id == id;}); }, - fold: function (header) { - header.children = []; - header.is_expanded = false; - var fold_lvls = _.map(this.rows_array(), function(g) {return g.path.length;}); + fold_row: function (row) { + var list = []; + function tree_traversal(tree) { + list.push(tree); + _.each(tree.children, tree_traversal); + } + tree_traversal(row); + this.rows = _.difference(this.rows, _.rest(list)); + row.is_expanded = false; + var fold_lvls = _.map(this.rows, function(g) {return g.path.length;}); var new_groupby_length = _.max(fold_lvls); - this.row_groupby.splice(new_groupby_length); - - // to do : remove every corresponding cells - }, - - fold_row: function (row) { - this.fold(row); + row.children = []; }, fold_col: function (col) { - this.fold(col); + var list = []; + function tree_traversal(tree) { + list.push(tree); + _.each(tree.children, tree_traversal); + } + tree_traversal(col); + this.cols = _.difference(this.cols, _.rest(list)); + col.is_expanded = false; + var fold_lvls = _.map(this.cols, function(g) {return g.path.length;}); + var new_groupby_length = _.max(fold_lvls); + this.col_groupby.splice(new_groupby_length); + col.children = []; }, expand_row: function (row_id, field_id) { @@ -169,10 +146,9 @@ var PivotTable = openerp.web.Class.extend({ return query_groups_data(this.model, this.visible_fields(), row.domain, this.col_groupby, field_id) .then(function (groups) { _.each(groups, function (group) { - var new_row_id = self.make_header(group, row); - var cols_array = self.cols_array(); + var new_row_id = self.make_row(group, row); _.each(group, function (data) { - var col = _.find(cols_array, function (c) { + var col = _.find(self.cols, function (c) { return _.isEqual(_.rest(data.path), c.path); }); if (col) { @@ -184,6 +160,21 @@ var PivotTable = openerp.web.Class.extend({ }); }, + make_row: function (groups, parent) { + var new_row = { + id: this.generate_id(), + path: parent.path.concat(groups[0].attributes.value[1]), + name: groups[0].attributes.value[1], + is_expanded: false, + parent: parent.id, + children: [], + domain: groups[0].model._domain, + }; + parent.children.push(new_row); + insertAfter(this.rows, parent, new_row); + return new_row.id; + }, + expand_col: function (col_id, field_id) { var self = this, col = this.get_col(col_id); @@ -192,34 +183,26 @@ var PivotTable = openerp.web.Class.extend({ this.col_groupby.push(field_id); } - console.log("cols",this.cols_array()); - console.log("dbg",this.col_groupby); return query_groups_data(this.model, this.visible_fields(), col.domain, this.row_groupby, field_id) .then(function (groups) { - console.log("groups",groups); _.each(groups, function (group) { - // console.log("adding group",group); - var new_col_id = self.make_header(group, col); - // // var rows_array = self.rows_array(); - // // _.each(group, function (data) { - // // var row = _.find(rows_array, function (c) { - // // return _.isEqual(data.path.slice(1), c.path); - // // }); - // // if (row) { - // // self.set_value(row.id, new_col_id, data.attributes.aggregates[self.measure]); - // // } - // // }); + var new_col_id = self.make_col(group, col); + _.each(group, function (data) { + var row = _.find(self.rows, function (c) { + return _.isEqual(data.path.slice(1), c.path); + }); + if (row) { + self.set_value(row.id, new_col_id, data.attributes.aggregates[self.measure]); + } + }); }); - // col.is_expanded = true; - // // console.log("col is now",col); - // // console.log("dbg",col.children.length); + col.is_expanded = true; }); }, - make_header: function (groups, parent) { - - var new_header = { + make_col: function (groups, parent) { + var new_col = { id: this.generate_id(), path: parent.path.concat(groups[0].attributes.value[1]), name: groups[0].attributes.value[1], @@ -228,129 +211,11 @@ var PivotTable = openerp.web.Class.extend({ children: [], domain: groups[0].model._domain, }; - parent.children.push(new_header); - return new_header.id; + parent.children.push(new_col); + insertAfter(this.cols, parent, new_col); + return new_col.id; }, -// make_row: function (groups, parent_id) { -// var self = this, -// path, -// value, -// expanded, -// domain, -// parent, -// has_parent = (parent_id !== undefined), -// row_id = this.generate_id(); - -// if (has_parent) { -// parent = this.get_row(parent_id); -// path = parent.path.concat(groups[0].attributes.value[1]); -// value = groups[0].attributes.value[1]; -// expanded = false; -// parent.children.push(row_id); -// domain = groups[0].model._domain; -// } else { -// parent = null; -// path = []; -// value = 'Total'; -// expanded = true; -// domain = this.data.domain; -// } - -// var jquery_row = $(''); - -// var header = self.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); -// jquery_row.append(header); - -// var cell; - -// _.each(this.cols, function (col) { -// var element = _.find(groups, function (group) { -// return _.isEqual(_.rest(group.path), col.path); -// }); -// if (element === undefined) { -// cell = self.make_cell(''); -// } else { -// cell = self.make_cell(element.attributes.aggregates[self.data.measure]); -// } -// if (col.expanded) { -// cell.css('display', 'none'); -// } -// col.cells.push({td:cell, row_id:row_id}); -// jquery_row.append(cell); -// }); - -// if (!has_parent) { -// header.find('.icon-plus-sign') -// .removeClass('icon-plus-sign') -// .addClass('icon-minus-sign'); -// } - -// var row = { -// id: row_id, -// path: path, -// value: value, -// expanded: expanded, -// parent: parent_id, -// children: [], -// html: jquery_row, -// domain: domain, -// }; -// this.rows.push(row); // to do, insert it properly, after all childs of parent -// return row; -// }, - -// expand_row: function (row_id, field_id) { -// var self = this; -// var row = this.get_row(row_id); - -// if (row.path.length == this.data.row_groupby.length) { -// this.data.row_groupby.push(field_id); -// } -// row.expanded = true; -// row.html.find('.icon-plus-sign') -// .removeClass('icon-plus-sign') -// .addClass('icon-minus-sign'); - -// var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); -// query_groups_data(this.data.model, visible_fields, row.domain, this.data.col_groupby, field_id) -// .then(function (groups) { -// _.each(groups.reverse(), function (group) { -// var new_row = self.make_row(group, row_id); -// row.html.after(new_row.html); -// }); -// }); - -// }, - - // toArray: function (header) { - // return [header].concat(_.map(header.children), this.toArray(hea)) - // } }); - - - // function expand_row (row, field) { - - // } - - // function expand_col (col, field) { - - // } - - - // function fold_col (col) { - - // } - - -// function update_values () { -// // update all cells (reload data from db) -// // return a deferred -// } - -// var id_seed = -1; - -// return init(); -// } \ No newline at end of file -- cgit v1.2.3 From 7299cde4cf2063dbccc797b6612c2b41c3564a8e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 22 Nov 2013 17:04:49 +0100 Subject: [REF] large refactoring. it separates the data handling code (pivot) from the ui code (drawing, buttons, events (addon web_graph) bzr revid: ged@openerp.com-20131122160449-lv2t09bs67ux42m5 --- addons/web_graph/static/src/js/charts.js | 26 +- addons/web_graph/static/src/js/graph.js | 713 +------------------------------ addons/web_graph/static/src/js/pivot.js | 11 +- 3 files changed, 34 insertions(+), 716 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index f35d012b592..0ecd15d1daf 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -11,14 +11,9 @@ var formatter = function (measure) { var Charts = { - bar_chart : function (groups, measure) { - var formatted_data = [{ - key: 'Bar chart', - values: _.map(groups, formatter(measure)), - }]; - + bar_chart : function (data) { nv.addGraph(function () { - var chart = nv.models.discreteBarChart() + var chart = nv.models.discreteBarChart() .tooltips(false) .showValues(true) .staggerLabels(true) @@ -26,7 +21,7 @@ var Charts = { .height(400); d3.select('.graph_main_content svg') - .datum(formatted_data) + .datum(data) .attr('width', 650) .attr('height', 400) .call(chart); @@ -36,12 +31,7 @@ var Charts = { }); }, - line_chart: function (groups, measure, measure_label) { - var formatted_data = [{ - key: measure_label, - values: _.map(groups, formatter(measure)) - }]; - + line_chart: function (data) { nv.addGraph(function () { var chart = nv.models.lineChart() .x(function (d,u) { return u; }) @@ -52,16 +42,14 @@ var Charts = { d3.select('.graph_main_content svg') .attr('width', 600) .attr('height', 300) - .datum(formatted_data) + .datum(data) .call(chart); return chart; }); }, - pie_chart: function (groups, measure) { - var formatted_data = _.map(groups, formatter(measure)); - + pie_chart: function (data) { nv.addGraph(function () { var chart = nv.models.pieChart() .color(d3.scale.category10().range()) @@ -69,7 +57,7 @@ var Charts = { .height(400); d3.select('.graph_main_content svg') - .datum(formatted_data) + .datum(data[0].values) .transition().duration(1200) .attr('width', 650) .attr('height', 400) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7d7d575756c..cfabdead833 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -26,7 +26,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ events: { 'click .graph_mode_selection li' : function (event) { event.preventDefault(); - this.mode = event.target.attributes['data-mode'].nodeValue; + var mode = event.target.attributes['data-mode'].nodeValue; + this.switch_mode(mode); }, 'click .web_graph_click' : function (event) { @@ -125,7 +126,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ start: function () { this.table = $('
'); - this.svg = $(''); + this.svg = $('
'); this.$el.filter('.graph_main_content').append(this.table); this.$el.filter('.graph_main_content').append(this.svg); return this.load_view(); @@ -150,6 +151,21 @@ instance.web_graph.GraphView = instance.web.View.extend({ return this._super(); }, + switch_mode: function (mode) { + var self = this; + this.mode = mode; + if (mode === 'pivot') { + this.table.css('display', 'block'); + this.svg.css('display','none'); + } else { + this.table.css('display', 'none'); + this.svg.remove(); + this.svg = $('
'); + this.$el.filter('.graph_main_content').append(this.svg); + Charts[mode](this.pivot_table.get_chart_data()); + + } + }, handle_header_event: function (options) { var pivot = this.pivot_table, @@ -174,7 +190,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ y: event.pageY}); } } - }, display_dropdown: function (options) { @@ -288,696 +303,4 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }); - - -// make_top_headers : function () { -// var self = this, -// header; - -// function partition (columns) { -// return _.reduce(columns, function (partial, col) { -// if (partial.length === 0) return [[col]]; -// if (col.path.length > _.first(_.last(partial)).path.length) { -// _.last(partial).push(col); -// } else { -// partial.push([col]); -// } -// return partial; -// }, []); -// } - -// function side_by_side(blocks) { -// var result = _.zip.apply(_,blocks); -// result = _.map(result, function(line) {return _.compact(_.flatten(line))}); -// return result; -// } - -// function make_header_cell(col, span) { -// var options = { -// is_border:true, -// foldable:true, -// row_span: (span === undefined) ? 1 : span, -// col_id: col.id, -// }; -// var result = self.make_cell(col.value, options); -// if (col.expanded) { -// result.find('.icon-plus-sign') -// .removeClass('icon-plus-sign') -// .addClass('icon-minus-sign'); -// } -// return result; -// } - -// function calculate_width(cols) { -// if (cols.length === 1) { -// return 1; -// } -// var p = partition(_.rest(cols)); -// return _.reduce(p, function(x, y){ return x + calculate_width(y); }, 0); -// } - -// function make_header_cells(cols, height) { -// var p = partition(cols); -// if ((p.length === 1) && (p[0].length === 1)) { -// var result = [[make_header_cell(cols[0], height)]]; -// return result; -// } -// if ((p.length === 1) && (p[0].length > 1)) { -// var cell = make_header_cell(p[0][0]); -// cell.attr('colspan', calculate_width(cols)); -// return [[cell]].concat(make_header_cells(_.rest(cols), height - 1)); -// } -// if (p.length > 1) { -// return side_by_side(_.map(p, function (group) { -// return make_header_cells(group, height); -// })); -// } -// } - -// if (this.cols.length === 1) { -// header = $(''); -// header.append(this.make_cell('', {is_border:true})); -// header.append(this.make_cell(this.cols[0].value, -// {is_border:true, foldable:true, col_id:this.cols[0].id})); -// header.addClass('graph_top'); -// this.headers = [header]; -// } else { -// var height = _.max(_.map(self.cols, function(g) {return g.path.length;})); -// var header_rows = make_header_cells(_.rest(this.cols), height); - -// header_rows[0].splice(0,0,self.make_cell('', {is_border:true, }).attr('rowspan', height)) -// self.headers = []; -// _.each(header_rows, function (cells) { -// header = $(''); -// header.append(cells); -// header.addClass('graph_top'); -// self.headers.push(header); -// }); -// } -// }, - - - // mode: 'pivot', // pivot, bar_chart, line_chart or pie_chart - // pivot_table: null, - - // events: { - // 'click .graph_mode_selection li' : function (event) { - // event.preventDefault(); - // this.mode = event.target.attributes['data-mode'].nodeValue; - // this.display_data(); - // }, - // }, - - // display_data : function () { - // var content = this.$el.filter('.graph_main_content'); - // content.find('svg').remove(); - // var self = this; - // if (this.mode === 'pivot') { - // this.pivot_table.show(); - // } else { - // this.pivot_table.hide(); - // content.append(''); - // var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); - // query_groups(this.data.model, view_fields, this.data.domain, this.data.row_groupby).then(function (groups) { - // Charts[self.mode](groups, self.data.measure, self.data.measure_label); - // }); - - // } - // }, - - - // if (this.pivot_table) { - // this.pivot_table.draw(true); - // } else { - - // this.pivot_table = new PivotTable(this.data); - // this.pivot_table.appendTo('.graph_main_content'); - // } - // this.display_data(); - - /** - * PivotTable widget. It displays the data in tabular data and allows the - * user to drill down and up in the table - */ -// var PivotTable = instance.web.Widget.extend({ -// template: 'pivot_table', - -// init: function (data) { -// var self = this; -// makePivotTable(this.data).done(function (table) { -// self.pivottable = table; -// }); -// }, - -// }); - -// var PivotTable = instance.web.Widget.extend({ -// template: 'pivot_table', -// data: null, -// headers: [], -// rows: [], -// cols: [], -// id_seed : 0, - -// events: { -// 'click .web_graph_click' : function (event) { -// event.preventDefault(); - -// if (event.target.attributes['data-row-id'] !== undefined) { -// this.handle_row_event(event); -// } -// if (event.target.attributes['data-col-id'] !== undefined) { -// this.handle_col_event(event); -// } -// }, - -// 'click a.field-selection' : function (event) { -// var id, -// field_id = event.target.attributes['data-field-id'].nodeValue; -// event.preventDefault(); -// this.dropdown.remove(); -// if (event.target.attributes['data-row-id'] !== undefined) { -// id = event.target.attributes['data-row-id'].nodeValue; -// this.expand_row(id, field_id); -// } -// if (event.target.attributes['data-col-id'] !== undefined) { -// id = event.target.attributes['data-col-id'].nodeValue; -// this.expand_col(id, field_id); -// } -// }, -// }, - -// handle_row_event: function (event) { -// var row_id = event.target.attributes['data-row-id'].nodeValue, -// row = this.get_row(row_id); - -// if (row.expanded) { -// this.fold_row(row_id); -// } else { -// if (row.path.length < this.data.row_groupby.length) { -// var field_to_expand = this.data.row_groupby[row.path.length]; -// this.expand_row(row_id, field_to_expand); -// } else { -// this.display_dropdown({row_id:row_id, -// target: $(event.target), -// x: event.pageX, -// y: event.pageY}); -// } -// } -// }, - -// handle_col_event: function (event) { -// var col_id = event.target.attributes['data-col-id'].nodeValue, -// col = this.get_col(col_id); - -// if (col.expanded) { -// this.fold_col(col_id); -// } else { -// if (col.path.length < this.data.col_groupby.length) { -// var field_to_expand = this.data.col_groupby[col.path.length]; -// this.expand_col(col_id, field_to_expand); -// } else { -// this.display_dropdown({col_id: col_id, -// target: $(event.target), -// x: event.pageX, -// y: event.pageY}); -// } -// } -// }, - -// init: function (data) { -// this.data = data; -// makePivotTable(this.data).done(function (table) { -// self.pivottable = table; -// }); - -// }, - -// start: function () { -// this.draw(true); -// }, - -// draw: function (load_data) { -// var self = this; - -// if (load_data) { -// var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); -// query_groups_data(this.data.model, view_fields, this.data.domain, this.data.col_groupby, this.data.row_groupby[0]) -// .then(function (groups) { -// self.data.groups = groups; -// return self.get_groups([]); -// }).then(function (total) { -// total[0].path = []; -// self.data.total = [total]; -// self.build_table(); -// self.draw(false); -// }); -// } else { -// this.$el.empty(); - -// this.draw_top_headers(); - -// _.each(this.rows, function (row) { -// self.$el.append(row.html); -// }); -// } -// }, - -// show: function () { -// this.$el.css('display', 'block'); -// }, - -// hide: function () { -// this.$el.css('display', 'none'); -// }, - -// display_dropdown: function (options) { -// var self = this, -// already_grouped = self.data.row_groupby.concat(self.data.col_groupby), -// possible_groups = _.difference(self.data.important_fields, already_grouped), -// dropdown_options = { -// fields: _.map(possible_groups, function (field) { -// return {id: field, value: self.get_descr(field)}; -// })}; -// if (options.row_id) { -// dropdown_options.row_id= options.row_id; -// } else { -// dropdown_options.col_id = options.col_id; -// } - -// this.dropdown = $(QWeb.render('field_selection', dropdown_options)); -// options.target.after(this.dropdown); -// this.dropdown.css({position:'absolute', -// left:options.x, -// top:options.y}); -// $('.field-selection').next('.dropdown-menu').toggle(); -// }, - -// build_table: function () { -// var self = this; -// this.rows = []; - - -// var col_id = this.generate_id(); - -// this.cols= [{ -// id: col_id, -// path: [], -// value: this.data.measure_label, -// expanded: false, -// parent: null, -// children: [], -// cells: [], // a cell is {td:, row_id:} -// domain: this.data.domain, -// }]; - -// self.make_top_headers(); - -// var main_row = this.make_row(this.data.total[0]); - -// _.each(this.data.groups, function (group) { -// self.make_row(group, main_row.id); -// }); -// }, - -// get_descr: function (field_id) { -// return this.data.fields[field_id].string; -// }, - -// get_groups: function (groupby) { -// var view_fields = this.data.row_groupby.concat(this.data.measure, this.data.col_groupby); -// return query_groups(this.data.model, view_fields, this.data.domain, groupby); -// }, - -// make_top_headers : function () { -// var self = this, -// header; - -// function partition (columns) { -// return _.reduce(columns, function (partial, col) { -// if (partial.length === 0) return [[col]]; -// if (col.path.length > _.first(_.last(partial)).path.length) { -// _.last(partial).push(col); -// } else { -// partial.push([col]); -// } -// return partial; -// }, []); -// } - -// function side_by_side(blocks) { -// var result = _.zip.apply(_,blocks); -// result = _.map(result, function(line) {return _.compact(_.flatten(line))}); -// return result; -// } - -// function make_header_cell(col, span) { -// var options = { -// is_border:true, -// foldable:true, -// row_span: (span === undefined) ? 1 : span, -// col_id: col.id, -// }; -// var result = self.make_cell(col.value, options); -// if (col.expanded) { -// result.find('.icon-plus-sign') -// .removeClass('icon-plus-sign') -// .addClass('icon-minus-sign'); -// } -// return result; -// } - -// function calculate_width(cols) { -// if (cols.length === 1) { -// return 1; -// } -// var p = partition(_.rest(cols)); -// return _.reduce(p, function(x, y){ return x + calculate_width(y); }, 0); -// } - -// function make_header_cells(cols, height) { -// var p = partition(cols); -// if ((p.length === 1) && (p[0].length === 1)) { -// var result = [[make_header_cell(cols[0], height)]]; -// return result; -// } -// if ((p.length === 1) && (p[0].length > 1)) { -// var cell = make_header_cell(p[0][0]); -// cell.attr('colspan', calculate_width(cols)); -// return [[cell]].concat(make_header_cells(_.rest(cols), height - 1)); -// } -// if (p.length > 1) { -// return side_by_side(_.map(p, function (group) { -// return make_header_cells(group, height); -// })); -// } -// } - -// if (this.cols.length === 1) { -// header = $(''); -// header.append(this.make_cell('', {is_border:true})); -// header.append(this.make_cell(this.cols[0].value, -// {is_border:true, foldable:true, col_id:this.cols[0].id})); -// header.addClass('graph_top'); -// this.headers = [header]; -// } else { -// var height = _.max(_.map(self.cols, function(g) {return g.path.length;})); -// var header_rows = make_header_cells(_.rest(this.cols), height); - -// header_rows[0].splice(0,0,self.make_cell('', {is_border:true, }).attr('rowspan', height)) -// self.headers = []; -// _.each(header_rows, function (cells) { -// header = $(''); -// header.append(cells); -// header.addClass('graph_top'); -// self.headers.push(header); -// }); -// } -// }, - -// draw_top_headers: function () { -// var self = this; -// $("tr.graph_top").remove(); -// _.each(this.headers.reverse(), function (header) { -// self.$el.prepend(header); -// }); - -// }, - -// make_row: function (groups, parent_id) { -// var self = this, -// path, -// value, -// expanded, -// domain, -// parent, -// has_parent = (parent_id !== undefined), -// row_id = this.generate_id(); - -// if (has_parent) { -// parent = this.get_row(parent_id); -// path = parent.path.concat(groups[0].attributes.value[1]); -// value = groups[0].attributes.value[1]; -// expanded = false; -// parent.children.push(row_id); -// domain = groups[0].model._domain; -// } else { -// parent = null; -// path = []; -// value = 'Total'; -// expanded = true; -// domain = this.data.domain; -// } - -// var jquery_row = $(''); - -// var header = self.make_cell(value, {is_border:true, indent: path.length, foldable:true, row_id: row_id}); -// jquery_row.append(header); - -// var cell; - -// _.each(this.cols, function (col) { -// var element = _.find(groups, function (group) { -// return _.isEqual(_.rest(group.path), col.path); -// }); -// if (element === undefined) { -// cell = self.make_cell(''); -// } else { -// cell = self.make_cell(element.attributes.aggregates[self.data.measure]); -// } -// if (col.expanded) { -// cell.css('display', 'none'); -// } -// col.cells.push({td:cell, row_id:row_id}); -// jquery_row.append(cell); -// }); - -// if (!has_parent) { -// header.find('.icon-plus-sign') -// .removeClass('icon-plus-sign') -// .addClass('icon-minus-sign'); -// } - -// var row = { -// id: row_id, -// path: path, -// value: value, -// expanded: expanded, -// parent: parent_id, -// children: [], -// html: jquery_row, -// domain: domain, -// }; -// this.rows.push(row); // to do, insert it properly, after all childs of parent -// return row; -// }, - -// generate_id: function () { -// this.id_seed += 1; -// return this.id_seed - 1; -// }, - -// get_row: function (id) { -// return _.find(this.rows, function(row) { -// return (row.id == id); -// }); -// }, - -// get_col: function (id) { -// return _.find(this.cols, function(col) { -// return (col.id == id); -// }); -// }, - -// make_cell: function (content, options) { -// options = _.extend({is_border: false, indent:0, foldable:false}, options); -// content = (content !== undefined) ? content : 'Undefined'; - -// var cell = $(''); -// if (options.is_border) cell.addClass('graph_border'); -// if (options.row_span) cell.attr('rowspan', options.row_span); -// if (options.col_span) cell.attr('rowspan', options.col_span); -// _.each(_.range(options.indent), function () { -// cell.prepend($('', {class:'web_graph_indent'})); -// }); - -// if (options.foldable) { -// var attrs = {class:'icon-plus-sign web_graph_click', href:'#'}; -// if (options.row_id !== undefined) attrs['data-row-id'] = options.row_id; -// if (options.col_id !== undefined) attrs['data-col-id'] = options.col_id; -// var plus = $('', attrs); -// plus.append(' '); -// plus.append(content); -// cell.append(plus); -// } else { -// cell.append(content); -// } -// return cell; -// }, - -// expand_row: function (row_id, field_id) { -// var self = this; -// var row = this.get_row(row_id); - -// if (row.path.length == this.data.row_groupby.length) { -// this.data.row_groupby.push(field_id); -// } -// row.expanded = true; -// row.html.find('.icon-plus-sign') -// .removeClass('icon-plus-sign') -// .addClass('icon-minus-sign'); - -// var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); -// query_groups_data(this.data.model, visible_fields, row.domain, this.data.col_groupby, field_id) -// .then(function (groups) { -// _.each(groups.reverse(), function (group) { -// var new_row = self.make_row(group, row_id); -// row.html.after(new_row.html); -// }); -// }); - -// }, - -// expand_col: function (col_id, field_id) { -// var self = this; -// var col = this.get_col(col_id); - -// if (col.path.length == this.data.col_groupby.length) { -// this.data.col_groupby.push(field_id); -// } -// col.expanded = true; - -// var visible_fields = this.data.row_groupby.concat(this.data.col_groupby, this.data.measure); -// query_groups_data(this.data.model, visible_fields, col.domain, this.data.row_groupby, field_id) -// .then(function (groups) { -// _.each(groups, function (group) { -// var new_col = { -// id: self.generate_id(), -// path: col.path.concat(group[0].attributes.value[1]), -// value: group[0].attributes.value[1], -// expanded: false, -// parent: col_id, -// children: [], -// cells: [], // a cell is {td:, row_id:} -// domain: group[0].model._domain, -// }; -// col.children.push(new_col.id); -// insertAfter(self.cols, col, new_col) -// _.each(col.cells, function (cell) { -// var col_path = self.get_row(cell.row_id).path; - -// var datapt = _.find(group, function (g) { -// return _.isEqual(g.path.slice(1), col_path); -// }); - -// var value; -// if (datapt === undefined) { -// value = ''; -// } else { -// value = datapt.attributes.aggregates[self.data.measure]; -// } -// var new_cell = { -// row_id: cell.row_id, -// td: self.make_cell(value) -// }; -// new_col.cells.push(new_cell); -// cell.td.after(new_cell.td); -// cell.td.css('display','none'); -// }); - -// }); -// self.make_top_headers(); -// self.draw_top_headers(); -// }); -// }, - -// fold_row: function (row_id) { -// var self = this; -// var row = this.get_row(row_id); - -// _.each(row.children, function (child_row) { -// self.remove_row(child_row); -// }); -// row.children = []; - -// row.expanded = false; -// row.html.find('.icon-minus-sign') -// .removeClass('icon-minus-sign') -// .addClass('icon-plus-sign'); - -// var fold_levels = _.map(self.rows, function(g) {return g.path.length;}); -// var new_groupby_length = _.max(fold_levels); - -// this.data.row_groupby.splice(new_groupby_length); -// }, - -// remove_row: function (row_id) { -// var self = this; -// var row = this.get_row(row_id); - -// _.each(row.children, function (child_row) { -// self.remove_row(child_row); -// }); - -// row.html.remove(); -// removeFromArray(this.rows, row); - -// _.each(this.cols, function (col) { -// col.cells = _.filter(col.cells, function (cell) { -// return cell.row_id !== row_id; -// }); -// }); -// }, - -// fold_col: function (col_id) { -// var self = this; -// var col = this.get_col(col_id); - -// _.each(col.children, function (child_col) { -// self.remove_col(child_col); -// }); -// col.children = []; - -// _.each(col.cells, function (cell) { -// cell.td.css('display','table-cell'); -// }); -// col.expanded = false; -// // row.html.find('.icon-minus-sign') -// // .removeClass('icon-minus-sign') -// // .addClass('icon-plus-sign'); - -// var fold_levels = _.map(self.cols, function(g) {return g.path.length;}); -// var new_groupby_length = _.max(fold_levels); - -// this.data.col_groupby.splice(new_groupby_length); -// this.make_top_headers(); -// this.draw_top_headers(); - - -// }, - -// remove_col: function (col_id) { -// var self = this; -// var col = this.get_col(col_id); - -// _.each(col.children, function (child_col) { -// self.remove_col(child_col); -// }); - -// _.each(col.cells, function (cell) { -// cell.td.remove(); -// }); -// // row.html.remove(); -// removeFromArray(this.cols, col); - -// // _.each(this.cols, function (col) { -// // col.cells = _.filter(col.cells, function (cell) { -// // return cell.row_id !== row_id; -// // }); -// // }); -// }, - - -// }); - }; diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 081470fcb37..4ab6b637422 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -1,5 +1,4 @@ - var PivotTable = openerp.web.Class.extend({ init: function (options) { this.rows = []; @@ -198,7 +197,6 @@ var PivotTable = openerp.web.Class.extend({ }); col.is_expanded = true; }); - }, make_col: function (groups, parent) { @@ -216,6 +214,15 @@ var PivotTable = openerp.web.Class.extend({ return new_col.id; }, + get_chart_data: function () { + var self = this; + var values = _.map(this.rows[0].children, function (pt) { + var val = self.get_value(pt.id, 2); + return {x: pt.name, y: val}; + }); + return [{key: 'Bar chart', values: values}]; + + }, }); -- cgit v1.2.3 From 1e32b763f0e1da669d835b02fbf680f2deea0f65 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sat, 23 Nov 2013 11:11:35 +0100 Subject: [IMP] add 'clear all groups' and 'swap axis' functionality to pivot table in addon web_graph bzr revid: ged@openerp.com-20131123101135-m0cx5eg0o41k7x2m --- addons/web_graph/static/src/js/graph.js | 11 ++++- addons/web_graph/static/src/js/pivot.js | 75 +++++++++++++-------------------- 2 files changed, 40 insertions(+), 46 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index cfabdead833..da3f4257b33 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -57,6 +57,16 @@ instance.web_graph.GraphView = instance.web.View.extend({ .then(this.proxy('draw_table')); } }, + + 'click label.graph_swap_axis' : function (event) { + this.pivot_table.swap_axis(); + this.draw_table(); + }, + + 'click label.graph_clear_all' : function (event) { + this.pivot_table.clear_all(); + this.draw_table(); + }, }, view_loading: function (fields_view_get) { @@ -212,7 +222,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, draw_table: function () { - console.log("cols",this.pivot_table.cols); this.table.empty(); this.draw_top_headers(); _.each(this.pivot_table.rows, this.proxy('draw_row')); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 4ab6b637422..288bd14436e 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -45,29 +45,9 @@ var PivotTable = openerp.web.Class.extend({ self.set_value(self.rows[0].id, self.cols[0].id, val); }); - var grp = query_groups (this.model, this.visible_fields(), this.domain, this.row_groupby) - .then(function (groups) { - _.each(groups, function (group) { - var new_id = self.generate_id(), - new_row = { - id: new_id, - path: [group.attributes.value[1]], - name: group.attributes.value[1], - is_expanded: false, - parent: self.rows[0], - children: [], - domain: group.model._domain, - }; - - self.rows[0].children.push(new_row); - self.rows.push(new_row); - self.set_value(new_id, self.cols[0].id, - group.attributes.aggregates[self.measure]); - }); - self.rows[0].is_expanded = true; - }); + var initial_group = this.expand_row(this.rows[0].id, this.row_groupby[0]); - return $.when(tot, grp); + return $.when(tot, initial_group); }, generate_id: function () { @@ -144,8 +124,8 @@ var PivotTable = openerp.web.Class.extend({ } return query_groups_data(this.model, this.visible_fields(), row.domain, this.col_groupby, field_id) .then(function (groups) { - _.each(groups, function (group) { - var new_row_id = self.make_row(group, row); + _.each(groups.reverse(), function (group) { + var new_row_id = self.make_header(group, row, self.rows); _.each(group, function (data) { var col = _.find(self.cols, function (c) { return _.isEqual(_.rest(data.path), c.path); @@ -159,8 +139,8 @@ var PivotTable = openerp.web.Class.extend({ }); }, - make_row: function (groups, parent) { - var new_row = { + make_header: function (groups, parent, header_list) { + var new_header = { id: this.generate_id(), path: parent.path.concat(groups[0].attributes.value[1]), name: groups[0].attributes.value[1], @@ -169,9 +149,9 @@ var PivotTable = openerp.web.Class.extend({ children: [], domain: groups[0].model._domain, }; - parent.children.push(new_row); - insertAfter(this.rows, parent, new_row); - return new_row.id; + parent.children.push(new_header); + insertAfter(header_list, parent, new_header); + return new_header.id; }, expand_col: function (col_id, field_id) { @@ -185,7 +165,7 @@ var PivotTable = openerp.web.Class.extend({ return query_groups_data(this.model, this.visible_fields(), col.domain, this.row_groupby, field_id) .then(function (groups) { _.each(groups, function (group) { - var new_col_id = self.make_col(group, col); + var new_col_id = self.make_header(group, col, self.cols); _.each(group, function (data) { var row = _.find(self.rows, function (c) { return _.isEqual(data.path.slice(1), c.path); @@ -199,21 +179,6 @@ var PivotTable = openerp.web.Class.extend({ }); }, - make_col: function (groups, parent) { - var new_col = { - id: this.generate_id(), - path: parent.path.concat(groups[0].attributes.value[1]), - name: groups[0].attributes.value[1], - is_expanded: false, - parent: parent.id, - children: [], - domain: groups[0].model._domain, - }; - parent.children.push(new_col); - insertAfter(this.cols, parent, new_col); - return new_col.id; - }, - get_chart_data: function () { var self = this; var values = _.map(this.rows[0].children, function (pt) { @@ -224,5 +189,25 @@ var PivotTable = openerp.web.Class.extend({ }, + swap_axis: function () { + var temp = this.rows; + this.rows = this.cols; + this.cols = temp; + + temp = this.row_groupby; + this.row_groupby = this.col_groupby; + this.col_groupby = temp; + + _.each(this.cells, function (cell) { + temp = cell.row_id; + cell.row_id = cell.col_id; + cell.col_id = temp; + }); + }, + + clear_all: function () { + this.fold_row(this.rows[0]); + this.fold_col(this.cols[0]); + } }); -- cgit v1.2.3 From ebf46e668d6f0ae9695eb693b8ffb6b1498ba6c4 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sat, 23 Nov 2013 11:19:22 +0100 Subject: [REF] moves the data formatting for charts to the charts file (instead of pivot) in addon web_graph bzr revid: ged@openerp.com-20131123101922-xi429dmnwpqlfsiq --- addons/web_graph/static/src/js/charts.js | 27 +++++++++++++-------------- addons/web_graph/static/src/js/graph.js | 2 +- addons/web_graph/static/src/js/pivot.js | 10 ---------- 3 files changed, 14 insertions(+), 25 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 0ecd15d1daf..2fb0cd7b380 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,17 +1,16 @@ -var formatter = function (measure) { - return function (datapt) { - var val = datapt.attributes; - return { - x: datapt.attributes.value[1], - y: measure ? val.aggregates[measure] : val.length, - }; - }; -}; +function format_chart_data (pivot) { + var values = _.map(pivot.rows[0].children.reverse(), function (pt) { + var val = pivot.get_value(pt.id, 2); + return {x: pt.name, y: val}; + }); + return [{key: 'Bar chart', values: values}]; +}; var Charts = { - bar_chart : function (data) { + bar_chart : function (pivot) { + var data = format_chart_data(pivot); nv.addGraph(function () { var chart = nv.models.discreteBarChart() .tooltips(false) @@ -31,7 +30,8 @@ var Charts = { }); }, - line_chart: function (data) { + line_chart: function (pivot) { + data = format_chart_data(pivot); nv.addGraph(function () { var chart = nv.models.lineChart() .x(function (d,u) { return u; }) @@ -49,7 +49,8 @@ var Charts = { }); }, - pie_chart: function (data) { + pie_chart: function (pivot) { + data = format_chart_data(pivot); nv.addGraph(function () { var chart = nv.models.pieChart() .color(d3.scale.category10().range()) @@ -67,6 +68,4 @@ var Charts = { return chart; }); }, - - }; \ No newline at end of file diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index da3f4257b33..4d74ad71121 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -172,7 +172,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.svg.remove(); this.svg = $('
'); this.$el.filter('.graph_main_content').append(this.svg); - Charts[mode](this.pivot_table.get_chart_data()); + Charts[mode](this.pivot_table); } }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 288bd14436e..a5a3af78ae9 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -179,16 +179,6 @@ var PivotTable = openerp.web.Class.extend({ }); }, - get_chart_data: function () { - var self = this; - var values = _.map(this.rows[0].children, function (pt) { - var val = self.get_value(pt.id, 2); - return {x: pt.name, y: val}; - }); - return [{key: 'Bar chart', values: values}]; - - }, - swap_axis: function () { var temp = this.rows; this.rows = this.cols; -- cgit v1.2.3 From 0f995a25d5bb467dfb309a9f197a1f7e962b2445 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sat, 23 Nov 2013 11:59:25 +0100 Subject: [REF] moves utility functions to pivot.js file and remove utility.js in addon web_graph bzr revid: ged@openerp.com-20131123105925-edix9lyw9k6tjlmw --- addons/web_graph/static/src/js/pivot.js | 59 +++++++++++++++++++++++++++++++ addons/web_graph/static/src/js/utility.js | 58 ------------------------------ 2 files changed, 59 insertions(+), 58 deletions(-) delete mode 100644 addons/web_graph/static/src/js/utility.js (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index a5a3af78ae9..e42f8f272ff 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -201,3 +201,62 @@ var PivotTable = openerp.web.Class.extend({ } }); + +function removeFromArray(array, element) { + var index = array.indexOf(element); + if (index > -1) { + array.splice(index, 1); + } +} + +function insertAfter(array, after, elem) { + array.splice(array.indexOf(after) + 1, 0, elem); +} + +/** + * Query the server and return a deferred which will return the data + * with all the groupbys applied (this is done for now, but the goal + * is to modify read_group in order to allow eager and lazy groupbys + */ +function query_groups (model, fields, domain, groupbys) { + return model.query(fields) + .filter(domain) + .group_by(groupbys) + .then(function (results) { + var non_empty_results = _.filter(results, function (group) { + return group.attributes.length > 0; + }); + if (groupbys.length <= 1) { + return non_empty_results; + } else { + var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { + var new_domain = result.model._domain; + var new_groupings = groupbys.slice(1); + return query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { + result.subgroups_data = subgroups; + }); + })); + return get_subgroups.then(function () { + return non_empty_results; + }); + } + }); +} + +function query_groups_data(model, fields, domain, row_groupbys, col_groupby) { + return query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { + return _.map(groups, function (group) { + return format_group(group, []); + }); + }); +} + +function format_group (group, path) { + group.path = path.concat(group.attributes.value[1]); + result = [group]; + _.each(group.subgroups_data, function (subgroup) { + result = result.concat(format_group (subgroup, group.path)); + }); + return result; +} + diff --git a/addons/web_graph/static/src/js/utility.js b/addons/web_graph/static/src/js/utility.js deleted file mode 100644 index bb0f6a9835d..00000000000 --- a/addons/web_graph/static/src/js/utility.js +++ /dev/null @@ -1,58 +0,0 @@ - -function removeFromArray(array, element) { - var index = array.indexOf(element); - if (index > -1) { - array.splice(index, 1); - } -} - -function insertAfter(array, after, elem) { - array.splice(array.indexOf(after) + 1, 0, elem); -} - -/** - * Query the server and return a deferred which will return the data - * with all the groupbys applied (this is done for now, but the goal - * is to modify read_group in order to allow eager and lazy groupbys - */ -function query_groups (model, fields, domain, groupbys) { - return model.query(fields) - .filter(domain) - .group_by(groupbys) - .then(function (results) { - var non_empty_results = _.filter(results, function (group) { - return group.attributes.length > 0; - }); - if (groupbys.length <= 1) { - return non_empty_results; - } else { - var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { - var new_domain = result.model._domain; - var new_groupings = groupbys.slice(1); - return query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { - result.subgroups_data = subgroups; - }); - })); - return get_subgroups.then(function () { - return non_empty_results; - }); - } - }); -} - -function query_groups_data(model, fields, domain, row_groupbys, col_groupby) { - return query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { - return _.map(groups, function (group) { - return format_group(group, []); - }); - }); -} - -function format_group (group, path) { - group.path = path.concat(group.attributes.value[1]); - result = [group]; - _.each(group.subgroups_data, function (subgroup) { - result = result.concat(format_group (subgroup, group.path)); - }); - return result; -} \ No newline at end of file -- cgit v1.2.3 From 42e38292b8ba13f54349203a16e9b61e33ebfe7b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sat, 23 Nov 2013 12:42:01 +0100 Subject: [REF] slight modifications to the underlying data structure of pivot table in addon web_graph bzr revid: ged@openerp.com-20131123114201-g6v6q9r15n9gdzg2 --- addons/web_graph/static/src/js/charts.js | 2 +- addons/web_graph/static/src/js/graph.js | 20 +++--- addons/web_graph/static/src/js/pivot.js | 117 ++++++++++++++++--------------- 3 files changed, 70 insertions(+), 69 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 2fb0cd7b380..036299ebdfd 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,6 +1,6 @@ function format_chart_data (pivot) { - var values = _.map(pivot.rows[0].children.reverse(), function (pt) { + var values = _.map(pivot.rows.headers[0].children.reverse(), function (pt) { var val = pivot.get_value(pt.id, 2); return {x: pt.name, y: val}; }); diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 4d74ad71121..cd6cb44f93c 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -186,9 +186,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ pivot['fold_' + options.type](header); this.draw_table(); } else { - if (header.path.length < pivot[options.type + '_groupby'].length) { + if (header.path.length < pivot[options.type + 's'].groupby.length) { // expand the corresponding header - var field = pivot[options.type + '_groupby'][header.path.length]; + var field = pivot[options.type + 's'].groupby[header.path.length]; pivot['expand_' + options.type](id, field) .then(this.proxy('draw_table')); } else { @@ -205,7 +205,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ display_dropdown: function (options) { var self = this, pivot = this.pivot_table, - already_grouped = pivot.row_groupby.concat(pivot.col_groupby), + already_grouped = pivot.rows.groupby.concat(pivot.cols.groupby), possible_groups = _.difference(self.data.important_fields, already_grouped), dropdown_options = { fields: _.map(possible_groups, function (field) { @@ -224,7 +224,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ draw_table: function () { this.table.empty(); this.draw_top_headers(); - _.each(this.pivot_table.rows, this.proxy('draw_row')); + _.each(this.pivot_table.rows.headers, this.proxy('draw_row')); }, make_border_cell: function (colspan, rowspan) { @@ -244,7 +244,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ draw_top_headers: function () { var self = this, pivot = this.pivot_table, - height = _.max(_.map(pivot.cols, function(g) {return g.path.length;})), + height = _.max(_.map(pivot.cols.headers, function(g) {return g.path.length;})), header_cells = [[this.make_border_cell(1, height)]]; function set_dim (cols) { @@ -277,11 +277,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ } } - set_dim(pivot.cols[0]); // add width and height info to columns headers - if (pivot.cols[0].children.length === 0) { - make_cells(pivot.cols, 0); + set_dim(pivot.cols.main); // add width and height info to columns headers + if (pivot.cols.main.children.length === 0) { + make_cells(pivot.cols.headers, 0); } else { - make_cells(pivot.cols[0].children, 1); + make_cells(pivot.cols.main.children, 1); } _.each(header_cells, function (cells) { @@ -302,7 +302,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ html_row.append(row_header); - _.each(pivot.cols, function (col) { + _.each(pivot.cols.headers, function (col) { if (col.children.length === 0) { var cell = $('').append(pivot.get_value(row.id, col.id)); html_row.append(cell); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index e42f8f272ff..a4f8ad5246a 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -1,53 +1,58 @@ var PivotTable = openerp.web.Class.extend({ - init: function (options) { - this.rows = []; - this.cols = []; - this.cells = []; - this.row_groupby = options.row_groupby; - this.col_groupby = []; - this.model = options.model; - this.measure = options.measure; - this.measure_label = options.measure_label; - this.domain = options.domain; - this.id_seed = 0; - }, + id_seed: 0, - // Load initial data into the rows, cols and cells array. - // This function needs to be called after init and before - // drawing the table (otherwise the data returned will be empty...) - start: function () { - var self = this; - this.rows.push({ + init: function (options) { + main_row = { id: this.generate_id(), path: [], name: "Total", is_expanded: false, parent: null, children: [], - domain: this.domain, - }); - - this.cols.push({ + domain: options.domain, + }; + main_col = { id: this.generate_id(), path: [], - name: this.measure_label, + name: options.measure_label, is_expanded: false, parent: null, children: [], - domain: this.domain, - }); + domain: options.domain, + }; - // get total and create first cell - var tot = query_groups (this.model, this.measure, this.domain, []) - .then(function (total) { - var val = total[0].attributes.aggregates[self.measure]; - self.set_value(self.rows[0].id, self.cols[0].id, val); - }); + this.rows = { + groupby: options.row_groupby, + main: main_row, + headers: [main_row], + }; + this.cols = { + groupby: [], + main: main_col, + headers: [main_col], + }; - var initial_group = this.expand_row(this.rows[0].id, this.row_groupby[0]); + this.cells = []; + this.model = options.model; + this.domain = options.domain; + this.measure = options.measure; + this.measure_label = options.measure_label; + }, - return $.when(tot, initial_group); + // Load initial data into the rows, cols and cells array. + // This function needs to be called after init and before + // drawing the table (otherwise the data returned will be empty...) + start: function () { + var self = this, + initial_group = this.expand_row(this.rows.main.id, this.rows.groupby[0]), + total = query_groups(this.model, this.measure, this.domain, []) + .then(function (total) { + var val = total[0].attributes.aggregates[self.measure]; + self.set_value(self.rows.main.id, self.cols.main.id, val); + }); + + return $.when(total, initial_group); }, generate_id: function () { @@ -56,7 +61,7 @@ var PivotTable = openerp.web.Class.extend({ }, visible_fields: function () { - return this.row_groupby.concat(this.col_groupby, this.measure); + return this.rows.groupby.concat(this.cols.groupby, this.measure); }, set_value: function (row, col, value) { @@ -78,11 +83,11 @@ var PivotTable = openerp.web.Class.extend({ }, get_col: function (id) { - return _.find(this.cols, function (col) { return col.id == id;}); + return _.find(this.cols.headers, function (col) { return col.id == id;}); }, get_row: function (id) { - return _.find(this.rows, function (row) { return row.id == id;}); + return _.find(this.rows.headers, function (row) { return row.id == id;}); }, fold_row: function (row) { @@ -92,11 +97,11 @@ var PivotTable = openerp.web.Class.extend({ _.each(tree.children, tree_traversal); } tree_traversal(row); - this.rows = _.difference(this.rows, _.rest(list)); + this.rows.headers = _.difference(this.rows.headers, _.rest(list)); row.is_expanded = false; - var fold_lvls = _.map(this.rows, function(g) {return g.path.length;}); + var fold_lvls = _.map(this.rows.headers, function(g) {return g.path.length;}); var new_groupby_length = _.max(fold_lvls); - this.row_groupby.splice(new_groupby_length); + this.rows.groupby.splice(new_groupby_length); row.children = []; }, @@ -107,11 +112,11 @@ var PivotTable = openerp.web.Class.extend({ _.each(tree.children, tree_traversal); } tree_traversal(col); - this.cols = _.difference(this.cols, _.rest(list)); + this.cols.headers = _.difference(this.cols.headers, _.rest(list)); col.is_expanded = false; - var fold_lvls = _.map(this.cols, function(g) {return g.path.length;}); + var fold_lvls = _.map(this.cols.headers, function(g) {return g.path.length;}); var new_groupby_length = _.max(fold_lvls); - this.col_groupby.splice(new_groupby_length); + this.cols.groupby.splice(new_groupby_length); col.children = []; }, @@ -119,15 +124,15 @@ var PivotTable = openerp.web.Class.extend({ var self = this, row = this.get_row(row_id); - if (row.path.length == this.row_groupby.length) { - this.row_groupby.push(field_id); + if (row.path.length == this.rows.groupby.length) { + this.rows.groupby.push(field_id); } - return query_groups_data(this.model, this.visible_fields(), row.domain, this.col_groupby, field_id) + return query_groups_data(this.model, this.visible_fields(), row.domain, this.cols.groupby, field_id) .then(function (groups) { _.each(groups.reverse(), function (group) { - var new_row_id = self.make_header(group, row, self.rows); + var new_row_id = self.make_header(group, row, self.rows.headers); _.each(group, function (data) { - var col = _.find(self.cols, function (c) { + var col = _.find(self.cols.headers, function (c) { return _.isEqual(_.rest(data.path), c.path); }); if (col) { @@ -158,16 +163,16 @@ var PivotTable = openerp.web.Class.extend({ var self = this, col = this.get_col(col_id); - if (col.path.length == this.col_groupby.length) { - this.col_groupby.push(field_id); + if (col.path.length == this.cols.groupby.length) { + this.cols.groupby.push(field_id); } - return query_groups_data(this.model, this.visible_fields(), col.domain, this.row_groupby, field_id) + return query_groups_data(this.model, this.visible_fields(), col.domain, this.rows.groupby, field_id) .then(function (groups) { _.each(groups, function (group) { - var new_col_id = self.make_header(group, col, self.cols); + var new_col_id = self.make_header(group, col, self.cols.headers); _.each(group, function (data) { - var row = _.find(self.rows, function (c) { + var row = _.find(self.rows.headers, function (c) { return _.isEqual(data.path.slice(1), c.path); }); if (row) { @@ -184,10 +189,6 @@ var PivotTable = openerp.web.Class.extend({ this.rows = this.cols; this.cols = temp; - temp = this.row_groupby; - this.row_groupby = this.col_groupby; - this.col_groupby = temp; - _.each(this.cells, function (cell) { temp = cell.row_id; cell.row_id = cell.col_id; @@ -196,8 +197,8 @@ var PivotTable = openerp.web.Class.extend({ }, clear_all: function () { - this.fold_row(this.rows[0]); - this.fold_col(this.cols[0]); + this.fold_row(this.rows.main); + this.fold_col(this.cols.main); } }); -- cgit v1.2.3 From aa5958eaf5bab2bc193eea7e1a1e76644967b9ce Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sun, 24 Nov 2013 15:29:27 +0100 Subject: [IMP] many very small tweaks to pivot view (addon web_graph) bzr revid: ged@openerp.com-20131124142927-jnuqykwfp351337v --- addons/web_graph/static/src/js/charts.js | 4 ++++ addons/web_graph/static/src/js/graph.js | 16 +++++++++++++--- addons/web_graph/static/src/js/pivot.js | 19 +++++++++++++++---- 3 files changed, 32 insertions(+), 7 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 036299ebdfd..6944aef9672 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,4 +1,8 @@ +function draw_chart (svg, mode, pivot) { + Charts[mode](pivot); +} + function format_chart_data (pivot) { var values = _.map(pivot.rows.headers[0].children.reverse(), function (pt) { var val = pivot.get_value(pt.id, 2); diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index cd6cb44f93c..c0ccb80285a 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -63,8 +63,18 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.draw_table(); }, - 'click label.graph_clear_all' : function (event) { - this.pivot_table.clear_all(); + 'click label.graph_fold_all' : function (event) { + this.pivot_table.fold_all(); + this.draw_table(); + }, + + 'click label.graph_fold_rows' : function (event) { + this.pivot_table.fold_rows(); + this.draw_table(); + }, + + 'click label.graph_fold_cols' : function (event) { + this.pivot_table.fold_cols(); this.draw_table(); }, }, @@ -172,7 +182,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.svg.remove(); this.svg = $('
'); this.$el.filter('.graph_main_content').append(this.svg); - Charts[mode](this.pivot_table); + draw_chart(this.svg, mode, this.pivot_table); } }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index a4f8ad5246a..06b8a97a05d 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -154,7 +154,7 @@ var PivotTable = openerp.web.Class.extend({ children: [], domain: groups[0].model._domain, }; - parent.children.push(new_header); + parent.children.splice(0,0, new_header) insertAfter(header_list, parent, new_header); return new_header.id; }, @@ -169,7 +169,7 @@ var PivotTable = openerp.web.Class.extend({ return query_groups_data(this.model, this.visible_fields(), col.domain, this.rows.groupby, field_id) .then(function (groups) { - _.each(groups, function (group) { + _.each(groups.reverse(), function (group) { var new_col_id = self.make_header(group, col, self.cols.headers); _.each(group, function (data) { var row = _.find(self.rows.headers, function (c) { @@ -188,6 +188,8 @@ var PivotTable = openerp.web.Class.extend({ var temp = this.rows; this.rows = this.cols; this.cols = temp; + this.rows.main.name = "Total"; + this.cols.main.name = this.measure_label; _.each(this.cells, function (cell) { temp = cell.row_id; @@ -196,10 +198,19 @@ var PivotTable = openerp.web.Class.extend({ }); }, - clear_all: function () { + fold_rows: function () { this.fold_row(this.rows.main); + }, + + fold_cols: function () { this.fold_col(this.cols.main); - } + }, + + fold_all: function () { + this.fold_rows(); + this.fold_cols(); + }, + }); -- cgit v1.2.3 From 5173a56db659f91eb71255bcecb0cfe072f54cdb Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sun, 24 Nov 2013 15:52:40 +0100 Subject: [IMP] add heat map functionality to pivot table (addon web_graph) bzr revid: ged@openerp.com-20131124145240-dn5vq5ecb598gf4e --- addons/web_graph/static/src/js/graph.js | 21 +++++++++++++++++++-- addons/web_graph/static/src/js/pivot.js | 4 +++- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index c0ccb80285a..037a07c60ec 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -77,6 +77,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table.fold_cols(); this.draw_table(); }, + + 'click label.graph_heat_map' : function (event) { + this.heat_map_mode = !this.heat_map_mode; + this.draw_table(); + }, }, view_loading: function (fields_view_get) { @@ -90,6 +95,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ row_groupby = []; this.pivot_table = null; + this.heat_map_mode = false; // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { @@ -300,7 +306,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, draw_row: function (row) { - var pivot = this.pivot_table, + var self = this, + pivot = this.pivot_table, html_row = $(''), row_header = this.make_border_cell(1,1) .append(this.make_header_title(row).attr('data-row-id', row.id)) @@ -314,7 +321,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ _.each(pivot.cols.headers, function (col) { if (col.children.length === 0) { - var cell = $('').append(pivot.get_value(row.id, col.id)); + var value = pivot.get_value(row.id, col.id), + cell = $(''); + + cell.append((value === undefined) ? '' : value); + if ((self.heat_map_mode) && (value !== undefined)) { + // heat map + console.log("heat map", self.heat_map_mode, pivot.total); + var ratio = Math.floor(70 + 185*(pivot.total - value)/pivot.total); + console.log("ratio",ratio); + cell.css("background-color", "rgb(255," + ratio + "," + ratio + ")"); + } html_row.append(cell); } }); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 06b8a97a05d..99bc20b1015 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -38,6 +38,7 @@ var PivotTable = openerp.web.Class.extend({ this.domain = options.domain; this.measure = options.measure; this.measure_label = options.measure_label; + this.total = 0; }, // Load initial data into the rows, cols and cells array. @@ -50,6 +51,7 @@ var PivotTable = openerp.web.Class.extend({ .then(function (total) { var val = total[0].attributes.aggregates[self.measure]; self.set_value(self.rows.main.id, self.cols.main.id, val); + self.total = val; }); return $.when(total, initial_group); @@ -79,7 +81,7 @@ var PivotTable = openerp.web.Class.extend({ var cell = _.find(this.cells, function (c) { return ((c.row_id == row) && (c.col_id == col)); }); - return (cell) ? cell.value : ''; + return (cell === undefined) ? undefined : cell.value; }, get_col: function (id) { -- cgit v1.2.3 From 40889788d3bb6cfac6a0dab0bf2d48e59409fe5a Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sun, 24 Nov 2013 16:00:34 +0100 Subject: [REF] merge fold_row and fold_col methods into the fold method (addon web_graph) bzr revid: ged@openerp.com-20131124150034-0133mgww0nm3dfta --- addons/web_graph/static/src/js/graph.js | 4 +--- addons/web_graph/static/src/js/pivot.js | 36 +++++++++++---------------------- 2 files changed, 13 insertions(+), 27 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 037a07c60ec..5dbe4b780cb 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -199,7 +199,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ header = pivot['get_' + options.type](id); if (header.is_expanded) { - pivot['fold_' + options.type](header); + pivot.fold(header); this.draw_table(); } else { if (header.path.length < pivot[options.type + 's'].groupby.length) { @@ -327,9 +327,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ cell.append((value === undefined) ? '' : value); if ((self.heat_map_mode) && (value !== undefined)) { // heat map - console.log("heat map", self.heat_map_mode, pivot.total); var ratio = Math.floor(70 + 185*(pivot.total - value)/pivot.total); - console.log("ratio",ratio); cell.css("background-color", "rgb(255," + ratio + "," + ratio + ")"); } html_row.append(cell); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 99bc20b1015..cd1e0c550ac 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -33,6 +33,8 @@ var PivotTable = openerp.web.Class.extend({ headers: [main_col], }; + main_row.root = this.rows; + main_col.root = this.cols; this.cells = []; this.model = options.model; this.domain = options.domain; @@ -92,34 +94,19 @@ var PivotTable = openerp.web.Class.extend({ return _.find(this.rows.headers, function (row) { return row.id == id;}); }, - fold_row: function (row) { + fold: function (header) { var list = []; function tree_traversal(tree) { list.push(tree); _.each(tree.children, tree_traversal); } - tree_traversal(row); - this.rows.headers = _.difference(this.rows.headers, _.rest(list)); - row.is_expanded = false; - var fold_lvls = _.map(this.rows.headers, function(g) {return g.path.length;}); + tree_traversal(header); + header.root.headers = _.difference(header.root.headers, _.rest(list)); + header.is_expanded = false; + var fold_lvls = _.map(header.root.headers, function(g) {return g.path.length;}); var new_groupby_length = _.max(fold_lvls); - this.rows.groupby.splice(new_groupby_length); - row.children = []; - }, - - fold_col: function (col) { - var list = []; - function tree_traversal(tree) { - list.push(tree); - _.each(tree.children, tree_traversal); - } - tree_traversal(col); - this.cols.headers = _.difference(this.cols.headers, _.rest(list)); - col.is_expanded = false; - var fold_lvls = _.map(this.cols.headers, function(g) {return g.path.length;}); - var new_groupby_length = _.max(fold_lvls); - this.cols.groupby.splice(new_groupby_length); - col.children = []; + header.root.groupby.splice(new_groupby_length); + header.children = []; }, expand_row: function (row_id, field_id) { @@ -155,6 +142,7 @@ var PivotTable = openerp.web.Class.extend({ parent: parent.id, children: [], domain: groups[0].model._domain, + root: parent.root, }; parent.children.splice(0,0, new_header) insertAfter(header_list, parent, new_header); @@ -201,11 +189,11 @@ var PivotTable = openerp.web.Class.extend({ }, fold_rows: function () { - this.fold_row(this.rows.main); + this.fold(this.rows.main); }, fold_cols: function () { - this.fold_col(this.cols.main); + this.fold(this.cols.main); }, fold_all: function () { -- cgit v1.2.3 From 46ea9d29feb8d46eb5ee4d1900c955a219fca907 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sun, 24 Nov 2013 21:10:49 +0100 Subject: [REF] better code organization for chart drawing in addon web_graph bzr revid: ged@openerp.com-20131124201049-p7cealv5p11hofr2 --- addons/web_graph/static/src/js/charts.js | 126 ++++++++++++++++--------------- addons/web_graph/static/src/js/graph.js | 8 +- 2 files changed, 67 insertions(+), 67 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 6944aef9672..e0b41eaff41 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,75 +1,77 @@ -function draw_chart (svg, mode, pivot) { - Charts[mode](pivot); -} - -function format_chart_data (pivot) { - var values = _.map(pivot.rows.headers[0].children.reverse(), function (pt) { - var val = pivot.get_value(pt.id, 2); +function draw_chart (mode, pivot) { + var values = _.map(pivot.rows.main.children, function (pt) { + var val = pivot.get_value(pt.id, pivot.cols.main.id); return {x: pt.name, y: val}; }); - return [{key: 'Bar chart', values: values}]; -}; + switch (mode) { + case 'bar_chart': + bar_chart(values); + break; + case 'line_chart': + line_chart(values); + break; + case 'pie_chart': + pie_chart(values); + break; + } +} + +function bar_chart (data) { + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .tooltips(false) + .showValues(true) + .staggerLabels(true) + .width(650) + .height(400); -var Charts = { - bar_chart : function (pivot) { - var data = format_chart_data(pivot); - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .tooltips(false) - .showValues(true) - .staggerLabels(true) - .width(650) - .height(400); + d3.select('.graph_main_content svg') + .datum([{key: 'Bar chart', values:data}]) + .attr('width', 650) + .attr('height', 400) + .call(chart); - d3.select('.graph_main_content svg') - .datum(data) - .attr('width', 650) - .attr('height', 400) - .call(chart); + nv.utils.windowResize(chart.update); + return chart; + }); +}; - nv.utils.windowResize(chart.update); - return chart; - }); - }, +function line_chart (data) { + nv.addGraph(function () { + var chart = nv.models.lineChart() + .x(function (d,u) { return u; }) + .width(600) + .height(300) + .margin({top: 30, right: 20, bottom: 20, left: 60}); - line_chart: function (pivot) { - data = format_chart_data(pivot); - nv.addGraph(function () { - var chart = nv.models.lineChart() - .x(function (d,u) { return u; }) - .width(600) - .height(300) - .margin({top: 30, right: 20, bottom: 20, left: 60}); + d3.select('.graph_main_content svg') + .attr('width', 600) + .attr('height', 300) + .datum([{key: 'Bar chart', values: data}]) + .call(chart); - d3.select('.graph_main_content svg') - .attr('width', 600) - .attr('height', 300) - .datum(data) - .call(chart); + return chart; + }); +}; - return chart; - }); - }, +function pie_chart(data) { + nv.addGraph(function () { + var chart = nv.models.pieChart() + .color(d3.scale.category10().range()) + .width(650) + .height(400); - pie_chart: function (pivot) { - data = format_chart_data(pivot); - nv.addGraph(function () { - var chart = nv.models.pieChart() - .color(d3.scale.category10().range()) - .width(650) - .height(400); + d3.select('.graph_main_content svg') + .datum(data) + .transition().duration(1200) + .attr('width', 650) + .attr('height', 400) + .call(chart); - d3.select('.graph_main_content svg') - .datum(data[0].values) - .transition().duration(1200) - .attr('width', 650) - .attr('height', 400) - .call(chart); + nv.utils.windowResize(chart.update); + return chart; + }); +}; - nv.utils.windowResize(chart.update); - return chart; - }); - }, -}; \ No newline at end of file diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 5dbe4b780cb..0a1dcdd001b 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -178,7 +178,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, switch_mode: function (mode) { - var self = this; this.mode = mode; if (mode === 'pivot') { this.table.css('display', 'block'); @@ -188,7 +187,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.svg.remove(); this.svg = $('
'); this.$el.filter('.graph_main_content').append(this.svg); - draw_chart(this.svg, mode, this.pivot_table); + draw_chart(mode, this.pivot_table); } }, @@ -326,9 +325,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ cell.append((value === undefined) ? '' : value); if ((self.heat_map_mode) && (value !== undefined)) { - // heat map - var ratio = Math.floor(70 + 185*(pivot.total - value)/pivot.total); - cell.css("background-color", "rgb(255," + ratio + "," + ratio + ")"); + var color = Math.floor(50 + 205*(pivot.total - value)/pivot.total); + cell.css("background-color", "rgb(255," + color + "," + color + ")"); } html_row.append(cell); } -- cgit v1.2.3 From 5227f89396de7527906e7708d3559cc6576cabfe Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sun, 24 Nov 2013 21:58:55 +0100 Subject: [REF] merge expand_row and expand_col methods into the fold method, also some small code tweaks (addon web_graph) bzr revid: ged@openerp.com-20131124205855-eekx2gwhgl4ye9uj --- addons/web_graph/static/src/js/graph.js | 15 +++--- addons/web_graph/static/src/js/pivot.js | 95 +++++++++++++-------------------- 2 files changed, 43 insertions(+), 67 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 0a1dcdd001b..0ab02ccb51b 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -48,12 +48,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.dropdown.remove(); if (event.target.attributes['data-row-id'] !== undefined) { id = event.target.attributes['data-row-id'].nodeValue; - this.pivot_table.expand_row(id, field_id) + this.pivot_table.expand(id, field_id) .then(this.proxy('draw_table')); } if (event.target.attributes['data-col-id'] !== undefined) { id = event.target.attributes['data-col-id'].nodeValue; - this.pivot_table.expand_col(id, field_id) + this.pivot_table.expand(id, field_id) .then(this.proxy('draw_table')); } }, @@ -195,19 +195,16 @@ instance.web_graph.GraphView = instance.web.View.extend({ handle_header_event: function (options) { var pivot = this.pivot_table, id = options.event.target.attributes['data-' + options.type + '-id'].nodeValue, - header = pivot['get_' + options.type](id); + header = pivot.get_header(id); if (header.is_expanded) { pivot.fold(header); this.draw_table(); } else { - if (header.path.length < pivot[options.type + 's'].groupby.length) { - // expand the corresponding header - var field = pivot[options.type + 's'].groupby[header.path.length]; - pivot['expand_' + options.type](id, field) - .then(this.proxy('draw_table')); + if (header.path.length < header.root.groupby.length) { + var field = header.root.groupby[header.path.length]; + pivot.expand(id, field).then(this.proxy('draw_table')); } else { - // display dropdown to query field to expand this.display_dropdown({id:header.id, type: options.type, target: $(event.target), diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index cd1e0c550ac..f8c71e14975 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -48,7 +48,7 @@ var PivotTable = openerp.web.Class.extend({ // drawing the table (otherwise the data returned will be empty...) start: function () { var self = this, - initial_group = this.expand_row(this.rows.main.id, this.rows.groupby[0]), + initial_group = this.expand(this.rows.main.id, this.rows.groupby[0]), total = query_groups(this.model, this.measure, this.domain, []) .then(function (total) { var val = total[0].attributes.aggregates[self.measure]; @@ -68,30 +68,32 @@ var PivotTable = openerp.web.Class.extend({ return this.rows.groupby.concat(this.cols.groupby, this.measure); }, - set_value: function (row, col, value) { - var cell = _.find(this.cells, function (c) { - return ((c.row_id == row) && (c.col_id == col)); + set_value: function (id1, id2, value) { + var x = Math.min(id1, id2), + y = Math.max(id1, id2), + cell = _.find(this.cells, function (c) { + return ((c.x == x) && (c.y == y)); }); if (cell) { cell.value = value; } else { - this.cells.push({row_id: row, col_id: col, value: value}); + this.cells.push({x: x, y: y, value: value}); } }, - get_value: function (row, col) { - var cell = _.find(this.cells, function (c) { - return ((c.row_id == row) && (c.col_id == col)); + get_value: function (id1, id2) { + var x = Math.min(id1, id2), + y = Math.max(id1, id2), + cell = _.find(this.cells, function (c) { + return ((c.x == x) && (c.y == y)); }); return (cell === undefined) ? undefined : cell.value; }, - get_col: function (id) { - return _.find(this.cols.headers, function (col) { return col.id == id;}); - }, - - get_row: function (id) { - return _.find(this.rows.headers, function (row) { return row.id == id;}); + get_header: function (id) { + return _.find(this.rows.headers.concat(this.cols.headers), function (header) { + return header.id == id; + }); }, fold: function (header) { @@ -109,20 +111,26 @@ var PivotTable = openerp.web.Class.extend({ header.children = []; }, - expand_row: function (row_id, field_id) { + expand: function (row_id, field_id) { var self = this, - row = this.get_row(row_id); + row = this.get_header(row_id); - if (row.path.length == this.rows.groupby.length) { - this.rows.groupby.push(field_id); + if (row.path.length == row.root.groupby.length) { + row.root.groupby.push(field_id); } - return query_groups_data(this.model, this.visible_fields(), row.domain, this.cols.groupby, field_id) + + var otherDim = (row.root === this.cols) ? this.rows : this.cols; + return query_groups_data(this.model, this.visible_fields(), row.domain, otherDim.groupby, field_id) .then(function (groups) { _.each(groups.reverse(), function (group) { - var new_row_id = self.make_header(group, row, self.rows.headers); + var new_row_id = self.make_header(group, row); _.each(group, function (data) { - var col = _.find(self.cols.headers, function (c) { - return _.isEqual(_.rest(data.path), c.path); + var col = _.find(otherDim.headers, function (c) { + if (row.root === this.cols) { + return _.isEqual(data.path.slice(1), c.path); + } else { + return _.isEqual(_.rest(data.path), c.path); + } }); if (col) { self.set_value(new_row_id, col.id, data.attributes.aggregates[self.measure]); @@ -133,11 +141,12 @@ var PivotTable = openerp.web.Class.extend({ }); }, - make_header: function (groups, parent, header_list) { - var new_header = { + make_header: function (groups, parent) { + var name = (groups[0].attributes.value) ? groups[0].attributes.value[1] : 'Undefined', + new_header = { id: this.generate_id(), - path: parent.path.concat(groups[0].attributes.value[1]), - name: groups[0].attributes.value[1], + path: parent.path.concat(name), + name: name, is_expanded: false, parent: parent.id, children: [], @@ -145,47 +154,17 @@ var PivotTable = openerp.web.Class.extend({ root: parent.root, }; parent.children.splice(0,0, new_header) - insertAfter(header_list, parent, new_header); + insertAfter(parent.root.headers, parent, new_header); return new_header.id; }, - expand_col: function (col_id, field_id) { - var self = this, - col = this.get_col(col_id); - - if (col.path.length == this.cols.groupby.length) { - this.cols.groupby.push(field_id); - } - - return query_groups_data(this.model, this.visible_fields(), col.domain, this.rows.groupby, field_id) - .then(function (groups) { - _.each(groups.reverse(), function (group) { - var new_col_id = self.make_header(group, col, self.cols.headers); - _.each(group, function (data) { - var row = _.find(self.rows.headers, function (c) { - return _.isEqual(data.path.slice(1), c.path); - }); - if (row) { - self.set_value(row.id, new_col_id, data.attributes.aggregates[self.measure]); - } - }); - }); - col.is_expanded = true; - }); - }, - swap_axis: function () { var temp = this.rows; this.rows = this.cols; this.cols = temp; + this.rows.main.name = "Total"; this.cols.main.name = this.measure_label; - - _.each(this.cells, function (cell) { - temp = cell.row_id; - cell.row_id = cell.col_id; - cell.col_id = temp; - }); }, fold_rows: function () { -- cgit v1.2.3 From 2ff7dd16fe8446493efcb5aad6df06ce858de229 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sun, 24 Nov 2013 22:48:09 +0100 Subject: [REF] some more simplifications, using the symetry between cols and rows in addon web_graph bzr revid: ged@openerp.com-20131124214809-k08p4x4h0wm4owmq --- addons/web_graph/static/src/js/graph.js | 38 +++++++++++---------------------- 1 file changed, 12 insertions(+), 26 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 0ab02ccb51b..146a9d3e865 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -32,30 +32,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ 'click .web_graph_click' : function (event) { event.preventDefault(); - if (event.target.attributes['data-row-id'] !== undefined) { - this.handle_header_event({type:'row', event:event}); - - } - if (event.target.attributes['data-col-id'] !== undefined) { - this.handle_header_event({type:'col', event:event}); - } + var id = event.target.attributes['data-id'].nodeValue; + this.handle_header_event({id:id, event:event}); }, 'click a.field-selection' : function (event) { - var id, + var id = event.target.attributes['data-id'].nodeValue, field_id = event.target.attributes['data-field-id'].nodeValue; event.preventDefault(); this.dropdown.remove(); - if (event.target.attributes['data-row-id'] !== undefined) { - id = event.target.attributes['data-row-id'].nodeValue; - this.pivot_table.expand(id, field_id) - .then(this.proxy('draw_table')); - } - if (event.target.attributes['data-col-id'] !== undefined) { - id = event.target.attributes['data-col-id'].nodeValue; - this.pivot_table.expand(id, field_id) - .then(this.proxy('draw_table')); - } + this.pivot_table.expand(id, field_id) + .then(this.proxy('draw_table')); }, 'click label.graph_swap_axis' : function (event) { @@ -194,7 +181,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ handle_header_event: function (options) { var pivot = this.pivot_table, - id = options.event.target.attributes['data-' + options.type + '-id'].nodeValue, + id = options.id, header = pivot.get_header(id); if (header.is_expanded) { @@ -206,10 +193,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ pivot.expand(id, field).then(this.proxy('draw_table')); } else { this.display_dropdown({id:header.id, - type: options.type, - target: $(event.target), - x: event.pageX, - y: event.pageY}); + target: $(options.event.target), + x: options.event.pageX, + y: options.event.pageY}); } } }, @@ -220,10 +206,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ already_grouped = pivot.rows.groupby.concat(pivot.cols.groupby), possible_groups = _.difference(self.data.important_fields, already_grouped), dropdown_options = { + header_id: options.id, fields: _.map(possible_groups, function (field) { return {id: field, value: self.data.fields[field].string}; })}; - dropdown_options[options.type + '_id'] = options.id; this.dropdown = $(QWeb.render('field_selection', dropdown_options)); options.target.after(this.dropdown); @@ -272,7 +258,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ function make_col_header (col) { var cell = self.make_border_cell(col.width, col.height); - return cell.append(self.make_header_title(col).attr('data-col-id', col.id)); + return cell.append(self.make_header_title(col).attr('data-id', col.id)); } function make_cells (queue, level) { @@ -306,7 +292,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ pivot = this.pivot_table, html_row = $(''), row_header = this.make_border_cell(1,1) - .append(this.make_header_title(row).attr('data-row-id', row.id)) + .append(this.make_header_title(row).attr('data-id', row.id)) .addClass('graph_border'); for (var i in _.range(row.path.length)) { -- cgit v1.2.3 From 8396a03759741dfd6b10f7f5b339df8524cb80c6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Sun, 24 Nov 2013 23:03:10 +0100 Subject: [IMP] removes a cell when it has been folded (addon web_graph) bzr revid: ged@openerp.com-20131124220310-4o1okd02cotbqppq --- addons/web_graph/static/src/js/pivot.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index f8c71e14975..e310a7799f6 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -103,12 +103,17 @@ var PivotTable = openerp.web.Class.extend({ _.each(tree.children, tree_traversal); } tree_traversal(header); + var ids_to_remove = _.map(_.rest(list), function (h) { return h.id;}); + header.root.headers = _.difference(header.root.headers, _.rest(list)); header.is_expanded = false; var fold_lvls = _.map(header.root.headers, function(g) {return g.path.length;}); var new_groupby_length = _.max(fold_lvls); header.root.groupby.splice(new_groupby_length); header.children = []; + this.cells = _.reject(this.cells, function (cell) { + return (_.contains(ids_to_remove, cell.x) || _.contains(ids_to_remove, cell.y)); + }); }, expand: function (row_id, field_id) { -- cgit v1.2.3 From 2944752844ee3a98b4a5e0a2c35634a034b88acb Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 25 Nov 2013 08:42:00 +0100 Subject: [IMP] adds slight color to expanded rows to make it easier to see the subrows (addon web_graph) bzr revid: ged@openerp.com-20131125074200-6d3migzpl4x7c44s --- addons/web_graph/static/src/js/graph.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 146a9d3e865..e1234e6f489 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -310,7 +310,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ if ((self.heat_map_mode) && (value !== undefined)) { var color = Math.floor(50 + 205*(pivot.total - value)/pivot.total); cell.css("background-color", "rgb(255," + color + "," + color + ")"); - } + } + if (row.is_expanded && (row.path.length <= 2)) { + var color = row.path.length * 5 + 240; + cell.css("background-color", "rgb(" + [color, color, color].join() + ")"); + } html_row.append(cell); } }); -- cgit v1.2.3 From 86a2d41d24045e1ba020199c998d315a5c8d9b10 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 25 Nov 2013 09:06:53 +0100 Subject: [IMP] adds expand_all button and method to graph view. beware, the code is not efficient (it does lots of db queries) (addon web_graph) bzr revid: ged@openerp.com-20131125080653-n3lgq7lb3kb3ygg7 --- addons/web_graph/static/src/js/graph.js | 4 ++++ addons/web_graph/static/src/js/pivot.js | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index e1234e6f489..0a6a2fd15db 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -69,6 +69,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.heat_map_mode = !this.heat_map_mode; this.draw_table(); }, + + 'click label.graph_expand_all' : function (event) { + this.pivot_table.expand_all().then(this.proxy('draw_table')); + }, }, view_loading: function (fields_view_get) { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index e310a7799f6..0dfacf5cb06 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -185,6 +185,23 @@ var PivotTable = openerp.web.Class.extend({ this.fold_cols(); }, + expand_all: function () { + var self = this; + // temporary code, to use while waiting for correct code. + // this code expands all rows/cols by doing as many db queries. + // correct code widd do that with just 1 request. + var header_to_expand = _.find(this.rows.headers.concat(this.cols.headers), function (header) { + return ((!header.is_expanded) && (header.path.length < header.root.groupby.length)) + }); + if (header_to_expand === undefined) { + return $.when(); + } else { + return this.expand(header_to_expand.id, header_to_expand.root.groupby[header_to_expand.path.length]).then(function () { + return self.expand_all(); + }); + } + }, + }); -- cgit v1.2.3 From 7940ec40c65214a2bdcd800a1dd2291980abc25b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 25 Nov 2013 10:04:43 +0100 Subject: [IMP] add total to each rows in pivot table view (addon web_graph) bzr revid: ged@openerp.com-20131125090443-r5dbre9wn2jymu37 --- addons/web_graph/static/src/js/graph.js | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 0a6a2fd15db..69155e7b255 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -284,6 +284,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ make_cells(pivot.cols.headers, 0); } else { make_cells(pivot.cols.main.children, 1); + header_cells[0].push(self.make_border_cell(1, height).append('Total')); } _.each(header_cells, function (cells) { @@ -322,6 +323,16 @@ instance.web_graph.GraphView = instance.web.View.extend({ html_row.append(cell); } }); + var cell = $('').append(pivot.get_value(row.id,pivot.cols.main.id)); + if (row.is_expanded && (row.path.length <= 2)) { + var color = row.path.length * 5 + 240; + cell.css("background-color", "rgb(" + [color, color, color].join() + ")"); + } + + if (pivot.cols.main.children.length > 0) { + html_row.append(cell); + } + this.table.append(html_row); } }); -- cgit v1.2.3 From d8aa7a6551ddb0b540cd14c35d4482d79f746fb5 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 25 Nov 2013 10:15:05 +0100 Subject: [IMP] improves the look of the total in each rows in pivot table view (addon web_graph) bzr revid: ged@openerp.com-20131125091505-wts1llbdexhnl8fe --- addons/web_graph/static/src/js/graph.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 69155e7b255..2c3645341d8 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -284,7 +284,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ make_cells(pivot.cols.headers, 0); } else { make_cells(pivot.cols.main.children, 1); - header_cells[0].push(self.make_border_cell(1, height).append('Total')); + header_cells[0].push(self.make_border_cell(1, height).append('Total').css('font-weight', 'bold')); } _.each(header_cells, function (cells) { @@ -323,10 +323,16 @@ instance.web_graph.GraphView = instance.web.View.extend({ html_row.append(cell); } }); - var cell = $('').append(pivot.get_value(row.id,pivot.cols.main.id)); + var total = pivot.get_value(row.id, pivot.cols.main.id); + var cell = $('') + .append(total) + .css('font-weight', 'bold'); if (row.is_expanded && (row.path.length <= 2)) { var color = row.path.length * 5 + 240; cell.css("background-color", "rgb(" + [color, color, color].join() + ")"); + } else if (self.heat_map_mode) { + var color = Math.floor(50 + 205*(pivot.total - total)/pivot.total); + cell.css("background-color", "rgb(255," + color + "," + color + ")"); } if (pivot.cols.main.children.length > 0) { -- cgit v1.2.3 From 4eef57206502a1d3201f256027d370f3cf386c5f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 26 Nov 2013 16:19:06 +0100 Subject: [IMP] big commit: add query_all_values() method to pivot table, and uses it to add expand_all and update_values functionality to graph view (addon web_graph) bzr revid: ged@openerp.com-20131126151906-luj8ri6e4hj444h6 --- addons/web_graph/static/src/js/graph.js | 8 +- addons/web_graph/static/src/js/pivot.js | 279 +++++++++++++++++++++++++++++--- 2 files changed, 262 insertions(+), 25 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 2c3645341d8..2aeb68b9869 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -73,6 +73,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ 'click label.graph_expand_all' : function (event) { this.pivot_table.expand_all().then(this.proxy('draw_table')); }, + + 'click label.graph_update_values' : function (event) { + this.pivot_table.update_values().then(this.proxy('draw_table')); + }, }, view_loading: function (fields_view_get) { @@ -157,7 +161,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ self.pivot_table = new PivotTable(self.data); self.pivot_table.start().then(self.proxy('draw_table')); } else { - this.pivot_table.update_values.done(function () { + this.pivot_table.update_values().done(function () { self.draw_table(); }); } @@ -240,7 +244,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ .addClass('web_graph_click') .attr('href', '#') .addClass((header.is_expanded) ? 'icon-minus-sign' : 'icon-plus-sign') - .append(header.name); + .append((header.title !== undefined) ? header.title : 'Undefined'); }, draw_top_headers: function () { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 0dfacf5cb06..b918474be47 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -6,7 +6,7 @@ var PivotTable = openerp.web.Class.extend({ main_row = { id: this.generate_id(), path: [], - name: "Total", + title: "Total", is_expanded: false, parent: null, children: [], @@ -15,7 +15,7 @@ var PivotTable = openerp.web.Class.extend({ main_col = { id: this.generate_id(), path: [], - name: options.measure_label, + title: options.measure_label, is_expanded: false, parent: null, children: [], @@ -147,17 +147,17 @@ var PivotTable = openerp.web.Class.extend({ }, make_header: function (groups, parent) { - var name = (groups[0].attributes.value) ? groups[0].attributes.value[1] : 'Undefined', + var name = groups[0].attributes.value[1], new_header = { - id: this.generate_id(), - path: parent.path.concat(name), - name: name, - is_expanded: false, - parent: parent.id, - children: [], - domain: groups[0].model._domain, - root: parent.root, - }; + id: this.generate_id(), + path: parent.path.concat(name), + title: name, + is_expanded: false, + parent: parent.id, + children: [], + domain: groups[0].model._domain, + root: parent.root, + }; parent.children.splice(0,0, new_header) insertAfter(parent.root.headers, parent, new_header); return new_header.id; @@ -168,8 +168,8 @@ var PivotTable = openerp.web.Class.extend({ this.rows = this.cols; this.cols = temp; - this.rows.main.name = "Total"; - this.cols.main.name = this.measure_label; + this.rows.main.title = "Total"; + this.cols.main.title = this.measure_label; }, fold_rows: function () { @@ -187,17 +187,250 @@ var PivotTable = openerp.web.Class.extend({ expand_all: function () { var self = this; - // temporary code, to use while waiting for correct code. - // this code expands all rows/cols by doing as many db queries. - // correct code widd do that with just 1 request. - var header_to_expand = _.find(this.rows.headers.concat(this.cols.headers), function (header) { - return ((!header.is_expanded) && (header.path.length < header.root.groupby.length)) + + return this.query_all_values().then(function (result) { + self.rows.headers = result.row_headers; + self.cols.headers = result.col_headers; + self.cells = result.cells; + self.rows.main = self.rows.headers[0]; + self.cols.main = self.cols.headers[0]; + self.total = self.rows.main.total; + self.rows.main.title = "Total"; + self.cols.main.title = self.measure_label; + _.each(self.rows.headers, function (row) { + row.root = self.rows; + row.is_expanded = (row.children.length > 0) + }); + _.each(self.cols.headers, function (col) { + col.root = self.cols; + col.is_expanded = (col.children.length > 0) + }); + + }); + }, + + update_values: function () { + var self = this; + return this.query_all_values().then(function (result) { + var old_col_headers = self.cols.headers, + old_row_headers = self.rows.headers; + + // the next 30 lines replace this.cols.headers with the + // corresponding headers in result.col_headers + _.each(old_col_headers, function (header) { + var corresponding_col = _.find(result.col_headers, function (c) { + return _.isEqual(c.path, header.path); + }); + + if (corresponding_col !== undefined) { + if (header.is_expanded) { + corresponding_col.is_expanded = true; + _.each(corresponding_col.children, function (c) { + c.is_expanded = false; + }) + } else { + corresponding_col.is_expanded = false; + } + } + }); + + self.cols.headers = _.filter(result.col_headers, function (header) { + return (header.is_expanded !== undefined); + }); + + _.each(self.cols.headers, function (col) { + if (!col.is_expanded) { + col.children = []; + } + }); + self.cols.main = self.cols.headers[0]; + + // the next 30 lines replace this.rows.headers with the + // corresponding headers in result.row_headers + _.each(old_row_headers, function (header) { + var corresponding_row = _.find(result.row_headers, function (c) { + return _.isEqual(c.path, header.path); + }); + + if (corresponding_row !== undefined) { + if (header.is_expanded) { + corresponding_row.is_expanded = true; + _.each(corresponding_row.children, function (c) { + c.is_expanded = false; + }) + } else { + corresponding_row.is_expanded = false; + } + } + }); + + self.rows.headers = _.filter(result.row_headers, function (header) { + return (header.is_expanded !== undefined); + }); + + _.each(self.rows.headers, function (col) { + if (!col.is_expanded) { + col.children = []; + } + }); + self.rows.main = self.rows.headers[0]; + + + // now some more tweaks + self.total = self.rows.main.total; + _.each(self.rows.headers, function (row) { + row.root = self.rows; + }); + _.each(self.cols.headers, function (col) { + col.root = self.cols; + }); + self.cells = result.cells; + self.rows.main.title = "Total"; + self.cols.main.title = self.measure_label; + }); + }, + + // this method is a little tricky. In order 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. For example, if row.groupby = [r1, r2, r3] and + // col.groupby = [c1, c2, c3, c4], then a minimal set of calls is done + // with the following groupby: + // [] + // [c1, c2, c3, c4] + // [r1, c1, c2, c3, c4] + // [r1, r2, c1, c2, c3, c4] + // [r1, r2, r3, c1, c2, c3, c4] + // To simplify the code, we will always do 2 + row.groupby.length calls, + // unless col.groupby.length = 0, in which case we do 2 calls ([] and + // row_groupbys), but this can be optimized later. + query_all_values: function () { + var self = this, + cols = this.cols.groupby, + rows = this.rows.groupby, + def_array, + groupbys; + + if (cols.length > 0) { + groupbys = _.map(_.range(rows.length + 1), function (i) { + return rows.slice(0, i).concat(cols); + }); + groupbys.push([]); + } else { + groupbys = [rows, []]; + } + def_array = _.map(groupbys, function (groupby) { + return query_groups(self.model, self.visible_fields(), self.domain, groupby); }); - if (header_to_expand === undefined) { - return $.when(); + + return $.when.apply(null, def_array).then(function () { + var args = Array.prototype.slice.call(arguments), + col_data = _.first(args), + total = _.last(args)[0], + row_data = _.last(_.initial(args)), + cell_data = args; + + var result = self.format_data(total, col_data, row_data, cell_data); + console.log("result final",result); + return result; + + }); + + }, + + format_data: function (total, col_data, row_data, cell_data) { + var self = this, + dim_row = this.rows.groupby.length, + dim_col = this.cols.groupby.length, + col_headers = make_headers(col_data, dim_col), + row_headers = make_headers(row_data, dim_row); + cells = []; + + if (dim_col > 0) { + _.each(cell_data, function (data, index) { + make_cells(data, index, []); + }); // make it more functional? } else { - return this.expand(header_to_expand.id, header_to_expand.root.groupby[header_to_expand.path.length]).then(function () { - return self.expand_all(); + make_cells(cell_data[0], dim_row, []); + make_cells(cell_data[1], 0, []); + } + + return {col_headers: col_headers, + row_headers: row_headers, + cells: cells}; + + function make_headers (data, depth) { + var main = { + id: self.generate_id(), + count: total.attributes.length, + total: total.attributes.aggregates[self.measure], + path: [], + parent: null, + children: [], + title: '', + domain: self.domain, + }; + + if (depth > 0) { + main.children = _.map(data, function (data_pt) { + return make_tree_headers (data_pt, main, depth); + }); + } + + var result = [], + make_list = function (tree) { + result.push(tree); + _.each(tree.children, make_list); + }; + + make_list(main); + return result; + } + + function make_tree_headers (data_pt, parent, max_depth) { + var node = { + id: self.generate_id(), + count: data_pt.attributes.length, + total: data_pt.attributes.aggregates[self.measure], + path: parent.path.concat(data_pt.attributes.value[1]), + title: data_pt.attributes.value[1], + domain: data_pt.model._domain, + parent: parent, + children: [], + }; + if (node.path.length < max_depth) { + node.children = _.map(data_pt.subgroups_data, function (child) { + return make_tree_headers (child, node, max_depth); + }); + } + return node; + } + + function make_cells (data, index, current_path) { + _.each(data, function (group) { + var attr = group.attributes, + path = current_path, + value = attr.aggregates[self.measure]; + + if (attr.grouped_on !== undefined) { + path = path.concat(attr.value[1]); + } + var rowpath = path.slice(0, index), + colpath = path.slice(index); + + var row = _.find(row_headers, function (header) { + return _.isEqual(header.path, rowpath); + }); + var col = _.find(col_headers, function (header) { + return _.isEqual(header.path, colpath); + }); + cells.push({x: Math.min(row.id, col.id), + y: Math.max(row.id, col.id), + value: value}); + + if (attr.has_children) { + make_cells (group.subgroups_data, index, path); + } }); } }, -- cgit v1.2.3 From 857b48749b79bca158ddf1b5b4096dd6cf061d22 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 26 Nov 2013 16:57:06 +0100 Subject: [IMP] updates the pivot table domain when search view is activated bzr revid: ged@openerp.com-20131126155706-nqc6hgjbyty8jju2 --- addons/web_graph/static/src/js/graph.js | 1 + addons/web_graph/static/src/js/pivot.js | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 2aeb68b9869..3d218e38eba 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -161,6 +161,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ self.pivot_table = new PivotTable(self.data); self.pivot_table.start().then(self.proxy('draw_table')); } else { + this.pivot_table.domain = domain; this.pivot_table.update_values().done(function () { self.draw_table(); }); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index b918474be47..5516f5caf5c 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -330,10 +330,7 @@ var PivotTable = openerp.web.Class.extend({ row_data = _.last(_.initial(args)), cell_data = args; - var result = self.format_data(total, col_data, row_data, cell_data); - console.log("result final",result); - return result; - + return self.format_data(total, col_data, row_data, cell_data); }); }, -- cgit v1.2.3 From 99b7fa4272081ac74ce56fe534760ee40db88e17 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 26 Nov 2013 17:14:15 +0100 Subject: [FIX] gives the correct data to the charts function instead of undefined (addon web_graph) bzr revid: ged@openerp.com-20131126161415-3thwtp25wm1hvks0 --- addons/web_graph/static/src/js/charts.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index e0b41eaff41..16dfe2ed105 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -2,9 +2,11 @@ function draw_chart (mode, pivot) { var values = _.map(pivot.rows.main.children, function (pt) { var val = pivot.get_value(pt.id, pivot.cols.main.id); - return {x: pt.name, y: val}; + return {x: pt.title, y: val}; }); + console.log("values",values); + switch (mode) { case 'bar_chart': bar_chart(values); -- cgit v1.2.3 From 8ef078acb323766281f60f40796ae656343b581f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 26 Nov 2013 17:14:24 +0100 Subject: [FIX] gives the correct data to the charts function instead of undefined (addon web_graph) bzr revid: ged@openerp.com-20131126161424-c0dlaqunv18anlw5 --- addons/web_graph/static/src/js/charts.js | 2 -- 1 file changed, 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 16dfe2ed105..df59e69b742 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -5,8 +5,6 @@ function draw_chart (mode, pivot) { return {x: pt.title, y: val}; }); - console.log("values",values); - switch (mode) { case 'bar_chart': bar_chart(values); -- cgit v1.2.3 From 0b5ff7efff63c791cf0e5d8abe66653973391a16 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 10:10:53 +0100 Subject: [IMP] reorganizes all options in graph views (puts them in 4 dropdown menus) (addon web_graph) bzr revid: ged@openerp.com-20131127091053-ydbo89dj027ndm3o --- addons/web_graph/static/src/js/graph.js | 73 ++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 29 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 3d218e38eba..9cd2147d9fb 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -30,6 +30,43 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.switch_mode(mode); }, + 'click .graph_expand_selection li' : function (event) { + event.preventDefault(); + switch (event.target.attributes['data-choice'].nodeValue) { + case 'fold_columns': + this.pivot_table.fold_cols(); + this.draw_table(); + break; + case 'fold_rows': + this.pivot_table.fold_rows(); + this.draw_table(); + break; + case 'fold_all': + this.pivot_table.fold_all(); + this.draw_table(); + break; + case 'expand_all': + this.pivot_table.expand_all().then(this.proxy('draw_table')); + break; + } + }, + + 'click .graph_options_selection li' : function (event) { + event.preventDefault(); + switch (event.target.attributes['data-choice'].nodeValue) { + case 'swap_axis': + this.pivot_table.swap_axis(); + this.draw_table(); + break; + case 'update_values': + this.pivot_table.update_values().then(this.proxy('draw_table')); + break; + case 'export_data': + // Export code... To do... + break; + } + }, + 'click .web_graph_click' : function (event) { event.preventDefault(); var id = event.target.attributes['data-id'].nodeValue; @@ -45,38 +82,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ .then(this.proxy('draw_table')); }, - 'click label.graph_swap_axis' : function (event) { - this.pivot_table.swap_axis(); - this.draw_table(); - }, - - 'click label.graph_fold_all' : function (event) { - this.pivot_table.fold_all(); - this.draw_table(); - }, - - 'click label.graph_fold_rows' : function (event) { - this.pivot_table.fold_rows(); - this.draw_table(); - }, - - 'click label.graph_fold_cols' : function (event) { - this.pivot_table.fold_cols(); - this.draw_table(); - }, 'click label.graph_heat_map' : function (event) { this.heat_map_mode = !this.heat_map_mode; this.draw_table(); }, - - 'click label.graph_expand_all' : function (event) { - this.pivot_table.expand_all().then(this.proxy('draw_table')); - }, - - 'click label.graph_update_values' : function (event) { - this.pivot_table.update_values().then(this.proxy('draw_table')); - }, }, view_loading: function (fields_view_get) { @@ -91,6 +101,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table = null; this.heat_map_mode = false; + this.mode = 'pivot'; // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { @@ -175,7 +186,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ switch_mode: function (mode) { this.mode = mode; - if (mode === 'pivot') { + var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; + if (_.contains(table_modes, mode)) { + this.draw_table(); this.table.css('display', 'block'); this.svg.css('display','none'); } else { @@ -317,7 +330,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ cell = $(''); cell.append((value === undefined) ? '' : value); - if ((self.heat_map_mode) && (value !== undefined)) { + console.log("self.mode",self.mode); + if ((self.mode == 'heatmap') && (value !== undefined)) { + console.log("yop"); var color = Math.floor(50 + 205*(pivot.total - value)/pivot.total); cell.css("background-color", "rgb(255," + color + "," + color + ")"); } -- cgit v1.2.3 From 1f8b8165e8f563108eef32c30576b298fc26404f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 10:20:52 +0100 Subject: [REF] small code cleanups... removing old commented code, and small tweaks (addon web_graph) bzr revid: ged@openerp.com-20131127092052-n2ub66oczqrtmr33 --- addons/web_graph/static/src/js/graph.js | 29 ++++++++++------------------- addons/web_graph/static/src/js/pivot.js | 21 ++++++++++----------- 2 files changed, 20 insertions(+), 30 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 9cd2147d9fb..13a0d93c888 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -33,7 +33,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ 'click .graph_expand_selection li' : function (event) { event.preventDefault(); switch (event.target.attributes['data-choice'].nodeValue) { - case 'fold_columns': + case 'fold_columns': this.pivot_table.fold_cols(); this.draw_table(); break; @@ -54,7 +54,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ 'click .graph_options_selection li' : function (event) { event.preventDefault(); switch (event.target.attributes['data-choice'].nodeValue) { - case 'swap_axis': + case 'swap_axis': this.pivot_table.swap_axis(); this.draw_table(); break; @@ -81,12 +81,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table.expand(id, field_id) .then(this.proxy('draw_table')); }, - - - 'click label.graph_heat_map' : function (event) { - this.heat_map_mode = !this.heat_map_mode; - this.draw_table(); - }, }, view_loading: function (fields_view_get) { @@ -96,7 +90,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ measure = null, fields, important_fields = [], - col_groupby = [], row_groupby = []; this.pivot_table = null; @@ -214,9 +207,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ var field = header.root.groupby[header.path.length]; pivot.expand(id, field).then(this.proxy('draw_table')); } else { - this.display_dropdown({id:header.id, - target: $(options.event.target), - x: options.event.pageX, + this.display_dropdown({id:header.id, + target: $(options.event.target), + x: options.event.pageX, y: options.event.pageY}); } } @@ -306,7 +299,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ } _.each(header_cells, function (cells) { - self.table.append($("").append(cells)); + self.table.append($('').append(cells)); }); }, @@ -330,15 +323,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ cell = $(''); cell.append((value === undefined) ? '' : value); - console.log("self.mode",self.mode); if ((self.mode == 'heatmap') && (value !== undefined)) { - console.log("yop"); var color = Math.floor(50 + 205*(pivot.total - value)/pivot.total); - cell.css("background-color", "rgb(255," + color + "," + color + ")"); + cell.css('background-color', 'rgb(255,' + color + ',' + color + ')'); } if (row.is_expanded && (row.path.length <= 2)) { var color = row.path.length * 5 + 240; - cell.css("background-color", "rgb(" + [color, color, color].join() + ")"); + cell.css('background-color', 'rgb(' + [color, color, color].join() + ')'); } html_row.append(cell); } @@ -349,10 +340,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ .css('font-weight', 'bold'); if (row.is_expanded && (row.path.length <= 2)) { var color = row.path.length * 5 + 240; - cell.css("background-color", "rgb(" + [color, color, color].join() + ")"); + cell.css('background-color', 'rgb(' + [color, color, color].join() + ')'); } else if (self.heat_map_mode) { var color = Math.floor(50 + 205*(pivot.total - total)/pivot.total); - cell.css("background-color", "rgb(255," + color + "," + color + ")"); + cell.css('background-color', 'rgb(255,' + color + ',' + color + ')'); } if (pivot.cols.main.children.length > 0) { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 5516f5caf5c..7c61cba1723 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -11,7 +11,7 @@ var PivotTable = openerp.web.Class.extend({ parent: null, children: [], domain: options.domain, - }; + }; main_col = { id: this.generate_id(), path: [], @@ -19,7 +19,7 @@ var PivotTable = openerp.web.Class.extend({ is_expanded: false, parent: null, children: [], - domain: options.domain, + domain: options.domain, }; this.rows = { @@ -93,7 +93,7 @@ var PivotTable = openerp.web.Class.extend({ get_header: function (id) { return _.find(this.rows.headers.concat(this.cols.headers), function (header) { return header.id == id; - }); + }); }, fold: function (header) { @@ -108,7 +108,7 @@ var PivotTable = openerp.web.Class.extend({ header.root.headers = _.difference(header.root.headers, _.rest(list)); header.is_expanded = false; var fold_lvls = _.map(header.root.headers, function(g) {return g.path.length;}); - var new_groupby_length = _.max(fold_lvls); + var new_groupby_length = _.max(fold_lvls); header.root.groupby.splice(new_groupby_length); header.children = []; this.cells = _.reject(this.cells, function (cell) { @@ -118,7 +118,7 @@ var PivotTable = openerp.web.Class.extend({ expand: function (row_id, field_id) { var self = this, - row = this.get_header(row_id); + row = this.get_header(row_id); if (row.path.length == row.root.groupby.length) { row.root.groupby.push(field_id); @@ -158,7 +158,7 @@ var PivotTable = openerp.web.Class.extend({ domain: groups[0].model._domain, root: parent.root, }; - parent.children.splice(0,0, new_header) + parent.children.splice(0,0, new_header); insertAfter(parent.root.headers, parent, new_header); return new_header.id; }, @@ -199,11 +199,11 @@ var PivotTable = openerp.web.Class.extend({ self.cols.main.title = self.measure_label; _.each(self.rows.headers, function (row) { row.root = self.rows; - row.is_expanded = (row.children.length > 0) + row.is_expanded = (row.children.length > 0); }); _.each(self.cols.headers, function (col) { col.root = self.cols; - col.is_expanded = (col.children.length > 0) + col.is_expanded = (col.children.length > 0); }); }); @@ -227,7 +227,7 @@ var PivotTable = openerp.web.Class.extend({ corresponding_col.is_expanded = true; _.each(corresponding_col.children, function (c) { c.is_expanded = false; - }) + }); } else { corresponding_col.is_expanded = false; } @@ -257,7 +257,7 @@ var PivotTable = openerp.web.Class.extend({ corresponding_row.is_expanded = true; _.each(corresponding_row.children, function (c) { c.is_expanded = false; - }) + }); } else { corresponding_row.is_expanded = false; } @@ -275,7 +275,6 @@ var PivotTable = openerp.web.Class.extend({ }); self.rows.main = self.rows.headers[0]; - // now some more tweaks self.total = self.rows.main.total; _.each(self.rows.headers, function (row) { -- cgit v1.2.3 From 22162b5a10f9daefa81cd61a75ae12d2a508499c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 10:47:18 +0100 Subject: [IMP] puts everything into openerp.web_graph namespace, to avoid polluting global namespace (addon web_graph) bzr revid: ged@openerp.com-20131127094718-boii5ncxfq8agfv9 --- addons/web_graph/static/src/js/charts.js | 14 +++++++------- addons/web_graph/static/src/js/graph.js | 4 ++-- addons/web_graph/static/src/js/pivot.js | 28 ++++++++++++++-------------- 3 files changed, 23 insertions(+), 23 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index df59e69b742..66293414b59 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,5 +1,5 @@ -function draw_chart (mode, pivot) { +openerp.web_graph.draw_chart = function (mode, pivot) { var values = _.map(pivot.rows.main.children, function (pt) { var val = pivot.get_value(pt.id, pivot.cols.main.id); return {x: pt.title, y: val}; @@ -7,18 +7,18 @@ function draw_chart (mode, pivot) { switch (mode) { case 'bar_chart': - bar_chart(values); + openerp.web_graph.bar_chart(values); break; case 'line_chart': - line_chart(values); + openerp.web_graph.line_chart(values); break; case 'pie_chart': - pie_chart(values); + openerp.web_graph.pie_chart(values); break; } } -function bar_chart (data) { +openerp.web_graph.bar_chart = function (data) { nv.addGraph(function () { var chart = nv.models.discreteBarChart() .tooltips(false) @@ -38,7 +38,7 @@ function bar_chart (data) { }); }; -function line_chart (data) { +openerp.web_graph.line_chart = function (data) { nv.addGraph(function () { var chart = nv.models.lineChart() .x(function (d,u) { return u; }) @@ -56,7 +56,7 @@ function line_chart (data) { }); }; -function pie_chart(data) { +openerp.web_graph.pie_chart = function(data) { nv.addGraph(function () { var chart = nv.models.pieChart() .color(d3.scale.category10().range()) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 13a0d93c888..69e0fc19d15 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -162,7 +162,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.data.domain = new instance.web.CompoundDomain(domain); if (!this.pivot_table) { - self.pivot_table = new PivotTable(self.data); + self.pivot_table = new openerp.web_graph.PivotTable(self.data); self.pivot_table.start().then(self.proxy('draw_table')); } else { this.pivot_table.domain = domain; @@ -189,7 +189,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.svg.remove(); this.svg = $('
'); this.$el.filter('.graph_main_content').append(this.svg); - draw_chart(mode, this.pivot_table); + openerp.web_graph.draw_chart(mode, this.pivot_table); } }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 7c61cba1723..2359ed30601 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -1,5 +1,5 @@ -var PivotTable = openerp.web.Class.extend({ +openerp.web_graph.PivotTable = openerp.web.Class.extend({ id_seed: 0, init: function (options) { @@ -49,7 +49,7 @@ var PivotTable = openerp.web.Class.extend({ start: function () { var self = this, initial_group = this.expand(this.rows.main.id, this.rows.groupby[0]), - total = query_groups(this.model, this.measure, this.domain, []) + total = openerp.web_graph.query_groups(this.model, this.measure, this.domain, []) .then(function (total) { var val = total[0].attributes.aggregates[self.measure]; self.set_value(self.rows.main.id, self.cols.main.id, val); @@ -125,7 +125,7 @@ var PivotTable = openerp.web.Class.extend({ } var otherDim = (row.root === this.cols) ? this.rows : this.cols; - return query_groups_data(this.model, this.visible_fields(), row.domain, otherDim.groupby, field_id) + return openerp.web_graph.query_groups_data(this.model, this.visible_fields(), row.domain, otherDim.groupby, field_id) .then(function (groups) { _.each(groups.reverse(), function (group) { var new_row_id = self.make_header(group, row); @@ -159,7 +159,7 @@ var PivotTable = openerp.web.Class.extend({ root: parent.root, }; parent.children.splice(0,0, new_header); - insertAfter(parent.root.headers, parent, new_header); + openerp.web_graph.insertAfter(parent.root.headers, parent, new_header); return new_header.id; }, @@ -319,7 +319,7 @@ var PivotTable = openerp.web.Class.extend({ groupbys = [rows, []]; } def_array = _.map(groupbys, function (groupby) { - return query_groups(self.model, self.visible_fields(), self.domain, groupby); + return openerp.web_graph.query_groups(self.model, self.visible_fields(), self.domain, groupby); }); return $.when.apply(null, def_array).then(function () { @@ -434,14 +434,14 @@ var PivotTable = openerp.web.Class.extend({ }); -function removeFromArray(array, element) { +openerp.web_graph.removeFromArray = function (array, element) { var index = array.indexOf(element); if (index > -1) { array.splice(index, 1); } } -function insertAfter(array, after, elem) { +openerp.web_graph.insertAfter = function (array, after, elem) { array.splice(array.indexOf(after) + 1, 0, elem); } @@ -450,7 +450,7 @@ function insertAfter(array, after, elem) { * with all the groupbys applied (this is done for now, but the goal * is to modify read_group in order to allow eager and lazy groupbys */ -function query_groups (model, fields, domain, groupbys) { +openerp.web_graph.query_groups = function (model, fields, domain, groupbys) { return model.query(fields) .filter(domain) .group_by(groupbys) @@ -464,7 +464,7 @@ function query_groups (model, fields, domain, groupbys) { var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { var new_domain = result.model._domain; var new_groupings = groupbys.slice(1); - return query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { + return openerp.web_graph.query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { result.subgroups_data = subgroups; }); })); @@ -475,19 +475,19 @@ function query_groups (model, fields, domain, groupbys) { }); } -function query_groups_data(model, fields, domain, row_groupbys, col_groupby) { - return query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { +openerp.web_graph.query_groups_data = function (model, fields, domain, row_groupbys, col_groupby) { + return openerp.web_graph.query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { return _.map(groups, function (group) { - return format_group(group, []); + return openerp.web_graph.format_group(group, []); }); }); } -function format_group (group, path) { +openerp.web_graph.format_group = function (group, path) { group.path = path.concat(group.attributes.value[1]); result = [group]; _.each(group.subgroups_data, function (subgroup) { - result = result.concat(format_group (subgroup, group.path)); + result = result.concat(openerp.web_graph.format_group (subgroup, group.path)); }); return result; } -- cgit v1.2.3 From e0744a7427be939c1c9ac4a1629d67c40817795e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 12:05:38 +0100 Subject: [FIX] fixes an issue where the chart code didn't select the correct DOM node to display the chart (addon web_graph) bzr revid: ged@openerp.com-20131127110538-rsm6hl4lgdkxya3p --- addons/web_graph/static/src/js/charts.js | 20 ++++++++++---------- addons/web_graph/static/src/js/graph.js | 26 +++++++++++--------------- 2 files changed, 21 insertions(+), 25 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 66293414b59..3f4bed6e001 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,5 +1,5 @@ -openerp.web_graph.draw_chart = function (mode, pivot) { +openerp.web_graph.draw_chart = function (mode, pivot, svg) { var values = _.map(pivot.rows.main.children, function (pt) { var val = pivot.get_value(pt.id, pivot.cols.main.id); return {x: pt.title, y: val}; @@ -7,18 +7,18 @@ openerp.web_graph.draw_chart = function (mode, pivot) { switch (mode) { case 'bar_chart': - openerp.web_graph.bar_chart(values); + openerp.web_graph.bar_chart(values, svg); break; case 'line_chart': - openerp.web_graph.line_chart(values); + openerp.web_graph.line_chart(values, svg); break; case 'pie_chart': - openerp.web_graph.pie_chart(values); + openerp.web_graph.pie_chart(values, svg); break; } } -openerp.web_graph.bar_chart = function (data) { +openerp.web_graph.bar_chart = function (data, svg) { nv.addGraph(function () { var chart = nv.models.discreteBarChart() .tooltips(false) @@ -27,7 +27,7 @@ openerp.web_graph.bar_chart = function (data) { .width(650) .height(400); - d3.select('.graph_main_content svg') + d3.select(svg) .datum([{key: 'Bar chart', values:data}]) .attr('width', 650) .attr('height', 400) @@ -38,7 +38,7 @@ openerp.web_graph.bar_chart = function (data) { }); }; -openerp.web_graph.line_chart = function (data) { +openerp.web_graph.line_chart = function (data, svg) { nv.addGraph(function () { var chart = nv.models.lineChart() .x(function (d,u) { return u; }) @@ -46,7 +46,7 @@ openerp.web_graph.line_chart = function (data) { .height(300) .margin({top: 30, right: 20, bottom: 20, left: 60}); - d3.select('.graph_main_content svg') + d3.select(svg) .attr('width', 600) .attr('height', 300) .datum([{key: 'Bar chart', values: data}]) @@ -56,14 +56,14 @@ openerp.web_graph.line_chart = function (data) { }); }; -openerp.web_graph.pie_chart = function(data) { +openerp.web_graph.pie_chart = function(data, svg) { nv.addGraph(function () { var chart = nv.models.pieChart() .color(d3.scale.category10().range()) .width(650) .height(400); - d3.select('.graph_main_content svg') + d3.select(svg) .datum(data) .transition().duration(1200) .attr('width', 650) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 69e0fc19d15..33a7e8db83c 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -27,7 +27,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ 'click .graph_mode_selection li' : function (event) { event.preventDefault(); var mode = event.target.attributes['data-mode'].nodeValue; - this.switch_mode(mode); + this.mode = mode; + this.display_data(); }, 'click .graph_expand_selection li' : function (event) { @@ -151,9 +152,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ start: function () { this.table = $('
'); - this.svg = $('
'); - this.$el.filter('.graph_main_content').append(this.table); - this.$el.filter('.graph_main_content').append(this.svg); + this.$('.graph_main_content').append(this.table); return this.load_view(); }, @@ -177,20 +176,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ return this._super(); }, - switch_mode: function (mode) { - this.mode = mode; + display_data: function () { + this.$('.graph_main_content svg').remove(); + this.table.empty(); + var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; - if (_.contains(table_modes, mode)) { + if (_.contains(table_modes, this.mode)) { this.draw_table(); - this.table.css('display', 'block'); - this.svg.css('display','none'); } else { - this.table.css('display', 'none'); - this.svg.remove(); - this.svg = $('
'); - this.$el.filter('.graph_main_content').append(this.svg); - openerp.web_graph.draw_chart(mode, this.pivot_table); - + this.$('.graph_main_content').append($('
')); + var svg = this.$('.graph_main_content svg')[0]; + openerp.web_graph.draw_chart(this.mode, this.pivot_table, svg); } }, -- cgit v1.2.3 From 76216fd3f33fca6461bc96caf525cbcdc0f24d6a Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 12:19:53 +0100 Subject: [REF] puts helper functions inside a closure to simplify the calls to these functions (addon web_graph) bzr revid: ged@openerp.com-20131127111953-yfzdyllt1ty70xtu --- addons/web_graph/static/src/js/charts.js | 109 ++++++++++++++++--------------- addons/web_graph/static/src/js/pivot.js | 29 ++++---- 2 files changed, 71 insertions(+), 67 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 3f4bed6e001..2ac84085ce1 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,77 +1,78 @@ openerp.web_graph.draw_chart = function (mode, pivot, svg) { - var values = _.map(pivot.rows.main.children, function (pt) { + + var data = _.map(pivot.rows.main.children, function (pt) { var val = pivot.get_value(pt.id, pivot.cols.main.id); return {x: pt.title, y: val}; }); - + switch (mode) { case 'bar_chart': - openerp.web_graph.bar_chart(values, svg); + bar_chart(); break; case 'line_chart': - openerp.web_graph.line_chart(values, svg); + line_chart(); break; case 'pie_chart': - openerp.web_graph.pie_chart(values, svg); + pie_chart(); break; } -} -openerp.web_graph.bar_chart = function (data, svg) { - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .tooltips(false) - .showValues(true) - .staggerLabels(true) - .width(650) - .height(400); + function bar_chart () { + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .tooltips(false) + .showValues(true) + .staggerLabels(true) + .width(650) + .height(400); - d3.select(svg) - .datum([{key: 'Bar chart', values:data}]) - .attr('width', 650) - .attr('height', 400) - .call(chart); + d3.select(svg) + .datum([{key: 'Bar chart', values:data}]) + .attr('width', 650) + .attr('height', 400) + .call(chart); - nv.utils.windowResize(chart.update); - return chart; - }); -}; + nv.utils.windowResize(chart.update); + return chart; + }); + }; -openerp.web_graph.line_chart = function (data, svg) { - nv.addGraph(function () { - var chart = nv.models.lineChart() - .x(function (d,u) { return u; }) - .width(600) - .height(300) - .margin({top: 30, right: 20, bottom: 20, left: 60}); + function line_chart () { + nv.addGraph(function () { + var chart = nv.models.lineChart() + .x(function (d,u) { return u; }) + .width(600) + .height(300) + .margin({top: 30, right: 20, bottom: 20, left: 60}); - d3.select(svg) - .attr('width', 600) - .attr('height', 300) - .datum([{key: 'Bar chart', values: data}]) - .call(chart); + d3.select(svg) + .attr('width', 600) + .attr('height', 300) + .datum([{key: 'Bar chart', values: data}]) + .call(chart); - return chart; - }); -}; + return chart; + }); + }; -openerp.web_graph.pie_chart = function(data, svg) { - nv.addGraph(function () { - var chart = nv.models.pieChart() - .color(d3.scale.category10().range()) - .width(650) - .height(400); + function pie_chart () { + nv.addGraph(function () { + var chart = nv.models.pieChart() + .color(d3.scale.category10().range()) + .width(650) + .height(400); - d3.select(svg) - .datum(data) - .transition().duration(1200) - .attr('width', 650) - .attr('height', 400) - .call(chart); + d3.select(svg) + .datum(data) + .transition().duration(1200) + .attr('width', 650) + .attr('height', 400) + .call(chart); - nv.utils.windowResize(chart.update); - return chart; - }); -}; + nv.utils.windowResize(chart.update); + return chart; + }); + }; +} diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 2359ed30601..08b406661cd 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -1,4 +1,6 @@ +(function () { + openerp.web_graph.PivotTable = openerp.web.Class.extend({ id_seed: 0, @@ -49,7 +51,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ start: function () { var self = this, initial_group = this.expand(this.rows.main.id, this.rows.groupby[0]), - total = openerp.web_graph.query_groups(this.model, this.measure, this.domain, []) + total = query_groups(this.model, this.measure, this.domain, []) .then(function (total) { var val = total[0].attributes.aggregates[self.measure]; self.set_value(self.rows.main.id, self.cols.main.id, val); @@ -125,7 +127,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } var otherDim = (row.root === this.cols) ? this.rows : this.cols; - return openerp.web_graph.query_groups_data(this.model, this.visible_fields(), row.domain, otherDim.groupby, field_id) + return query_groups_data(this.model, this.visible_fields(), row.domain, otherDim.groupby, field_id) .then(function (groups) { _.each(groups.reverse(), function (group) { var new_row_id = self.make_header(group, row); @@ -159,7 +161,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ root: parent.root, }; parent.children.splice(0,0, new_header); - openerp.web_graph.insertAfter(parent.root.headers, parent, new_header); + insertAfter(parent.root.headers, parent, new_header); return new_header.id; }, @@ -319,7 +321,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ groupbys = [rows, []]; } def_array = _.map(groupbys, function (groupby) { - return openerp.web_graph.query_groups(self.model, self.visible_fields(), self.domain, groupby); + return query_groups(self.model, self.visible_fields(), self.domain, groupby); }); return $.when.apply(null, def_array).then(function () { @@ -434,14 +436,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); -openerp.web_graph.removeFromArray = function (array, element) { +removeFromArray = function (array, element) { var index = array.indexOf(element); if (index > -1) { array.splice(index, 1); } } -openerp.web_graph.insertAfter = function (array, after, elem) { +insertAfter = function (array, after, elem) { array.splice(array.indexOf(after) + 1, 0, elem); } @@ -450,7 +452,7 @@ openerp.web_graph.insertAfter = function (array, after, elem) { * with all the groupbys applied (this is done for now, but the goal * is to modify read_group in order to allow eager and lazy groupbys */ -openerp.web_graph.query_groups = function (model, fields, domain, groupbys) { +query_groups = function (model, fields, domain, groupbys) { return model.query(fields) .filter(domain) .group_by(groupbys) @@ -464,7 +466,7 @@ openerp.web_graph.query_groups = function (model, fields, domain, groupbys) { var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { var new_domain = result.model._domain; var new_groupings = groupbys.slice(1); - return openerp.web_graph.query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { + return query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { result.subgroups_data = subgroups; }); })); @@ -475,20 +477,21 @@ openerp.web_graph.query_groups = function (model, fields, domain, groupbys) { }); } -openerp.web_graph.query_groups_data = function (model, fields, domain, row_groupbys, col_groupby) { - return openerp.web_graph.query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { +query_groups_data = function (model, fields, domain, row_groupbys, col_groupby) { + return query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { return _.map(groups, function (group) { - return openerp.web_graph.format_group(group, []); + return format_group(group, []); }); }); } -openerp.web_graph.format_group = function (group, path) { +format_group = function (group, path) { group.path = path.concat(group.attributes.value[1]); result = [group]; _.each(group.subgroups_data, function (subgroup) { - result = result.concat(openerp.web_graph.format_group (subgroup, group.path)); + result = result.concat(format_group (subgroup, group.path)); }); return result; } +})(); \ No newline at end of file -- cgit v1.2.3 From 0dd3f715358391895a554238d386346e49bc54d4 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 12:25:13 +0100 Subject: [FIX] corrects issue where calling some functions such as swap axis when in chart view would display the table and the chart at the same time (addon web_graph) bzr revid: ged@openerp.com-20131127112513-6s342zmarkglt52s --- addons/web_graph/static/src/js/graph.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 33a7e8db83c..61b86036cfa 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -36,18 +36,18 @@ instance.web_graph.GraphView = instance.web.View.extend({ switch (event.target.attributes['data-choice'].nodeValue) { case 'fold_columns': this.pivot_table.fold_cols(); - this.draw_table(); + this.display_data(); break; case 'fold_rows': this.pivot_table.fold_rows(); - this.draw_table(); + this.display_data(); break; case 'fold_all': this.pivot_table.fold_all(); - this.draw_table(); + this.display_data(); break; case 'expand_all': - this.pivot_table.expand_all().then(this.proxy('draw_table')); + this.pivot_table.expand_all().then(this.proxy('display_data')); break; } }, @@ -57,10 +57,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ switch (event.target.attributes['data-choice'].nodeValue) { case 'swap_axis': this.pivot_table.swap_axis(); - this.draw_table(); + this.display_data(); break; case 'update_values': - this.pivot_table.update_values().then(this.proxy('draw_table')); + this.pivot_table.update_values().then(this.proxy('display_data')); break; case 'export_data': // Export code... To do... @@ -80,7 +80,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ event.preventDefault(); this.dropdown.remove(); this.pivot_table.expand(id, field_id) - .then(this.proxy('draw_table')); + .then(this.proxy('display_data')); }, }, @@ -162,11 +162,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (!this.pivot_table) { self.pivot_table = new openerp.web_graph.PivotTable(self.data); - self.pivot_table.start().then(self.proxy('draw_table')); + self.pivot_table.start().then(self.proxy('display_data')); } else { this.pivot_table.domain = domain; this.pivot_table.update_values().done(function () { - self.draw_table(); + self.display_data(); }); } }, @@ -197,11 +197,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (header.is_expanded) { pivot.fold(header); - this.draw_table(); + this.display_data(); } else { if (header.path.length < header.root.groupby.length) { var field = header.root.groupby[header.path.length]; - pivot.expand(id, field).then(this.proxy('draw_table')); + pivot.expand(id, field).then(this.proxy('display_data')); } else { this.display_dropdown({id:header.id, target: $(options.event.target), @@ -231,7 +231,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, draw_table: function () { - this.table.empty(); this.draw_top_headers(); _.each(this.pivot_table.rows.headers, this.proxy('draw_row')); }, -- cgit v1.2.3 From 761ff102265b69f0d0a4402480797c1b1f93e904 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 14:04:06 +0100 Subject: [FIX] properly closes the dropdown menu (field selection when expanding row/col) when the user clicks somewhere else (addon web_graph) bzr revid: ged@openerp.com-20131127130406-slj3rvp02y3utevm --- addons/web_graph/static/src/js/graph.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 61b86036cfa..6c1f5ae3f32 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -70,6 +70,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ 'click .web_graph_click' : function (event) { event.preventDefault(); + event.stopPropagation(); var id = event.target.attributes['data-id'].nodeValue; this.handle_header_event({id:id, event:event}); }, @@ -78,12 +79,21 @@ instance.web_graph.GraphView = instance.web.View.extend({ var id = event.target.attributes['data-id'].nodeValue, field_id = event.target.attributes['data-field-id'].nodeValue; event.preventDefault(); - this.dropdown.remove(); this.pivot_table.expand(id, field_id) .then(this.proxy('display_data')); }, }, + init: function(parent, dataset, view_id, options) { + this._super(parent); + this.dataset = dataset; + this.set_default_options(options); + this.dropdown = null; + this.pivot_table = null; + this.heat_map_mode = false; + this.mode = 'pivot'; + }, + view_loading: function (fields_view_get) { var self = this, model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}), @@ -93,9 +103,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ important_fields = [], row_groupby = []; - this.pivot_table = null; - this.heat_map_mode = false; - this.mode = 'pivot'; // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { @@ -153,6 +160,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ start: function () { this.table = $('
'); this.$('.graph_main_content').append(this.table); + instance.web.bus.on('click', this, function (ev) { + if (this.dropdown) { + this.dropdown.remove(); + this.dropdown = null; + } + }); return this.load_view(); }, @@ -227,7 +240,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.dropdown.css({position:'absolute', left:options.x, top:options.y}); - $('.field-selection').next('.dropdown-menu').toggle(); + this.$('.field-selection').next('.dropdown-menu').toggle(); }, draw_table: function () { -- cgit v1.2.3 From 0c7e530c9c5ca9277c19b24f78718b8fb8075217 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 14:10:46 +0100 Subject: [REF] simplify the start() method in pivot table by using the expand_all() method instead of manually loading data (addon web_graph) bzr revid: ged@openerp.com-20131127131046-hz33nqrjae1hwldf --- addons/web_graph/static/src/js/pivot.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 08b406661cd..b9c1e04d60c 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -45,20 +45,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.total = 0; }, - // Load initial data into the rows, cols and cells array. - // This function needs to be called after init and before - // drawing the table (otherwise the data returned will be empty...) start: function () { - var self = this, - initial_group = this.expand(this.rows.main.id, this.rows.groupby[0]), - total = query_groups(this.model, this.measure, this.domain, []) - .then(function (total) { - var val = total[0].attributes.aggregates[self.measure]; - self.set_value(self.rows.main.id, self.cols.main.id, val); - self.total = val; - }); - - return $.when(total, initial_group); + return this.expand_all(); }, generate_id: function () { -- cgit v1.2.3 From cef7c35476105496c57e37198ec9e74640ebe748 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 14:20:44 +0100 Subject: [REF] removes useless initialization code in pivot class (addon web_graph) bzr revid: ged@openerp.com-20131127132044-rdttrslfh6t5agkw --- addons/web_graph/static/src/js/pivot.js | 37 +++------------------------------ 1 file changed, 3 insertions(+), 34 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index b9c1e04d60c..43b849577f6 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -2,47 +2,16 @@ (function () { openerp.web_graph.PivotTable = openerp.web.Class.extend({ - id_seed: 0, - init: function (options) { - main_row = { - id: this.generate_id(), - path: [], - title: "Total", - is_expanded: false, - parent: null, - children: [], - domain: options.domain, - }; - main_col = { - id: this.generate_id(), - path: [], - title: options.measure_label, - is_expanded: false, - parent: null, - children: [], - domain: options.domain, - }; - - this.rows = { - groupby: options.row_groupby, - main: main_row, - headers: [main_row], - }; - this.cols = { - groupby: [], - main: main_col, - headers: [main_col], - }; - - main_row.root = this.rows; - main_col.root = this.cols; + this.rows = { groupby: options.row_groupby }; + this.cols = { groupby: [] }; this.cells = []; this.model = options.model; this.domain = options.domain; this.measure = options.measure; this.measure_label = options.measure_label; this.total = 0; + this.id_seed = 0; }, start: function () { -- cgit v1.2.3 From abc0bb3d87f4efd615ccaeecb95c295f64874231 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 14:36:32 +0100 Subject: [REF] code cleanup (using jshint). mainly removing trailing whitespace and adding a few semicolons (addon web_graph) bzr revid: ged@openerp.com-20131127133632-s8xvycu9660xj2pn --- addons/web_graph/static/src/js/pivot.js | 69 +++++++++++++++------------------ 1 file changed, 32 insertions(+), 37 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 43b849577f6..9171e1641f4 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -1,5 +1,8 @@ +/* jshint undef: false */ + (function () { +'use strict'; openerp.web_graph.PivotTable = openerp.web.Class.extend({ init: function (options) { @@ -71,7 +74,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ header.root.groupby.splice(new_groupby_length); header.children = []; this.cells = _.reject(this.cells, function (cell) { - return (_.contains(ids_to_remove, cell.x) || _.contains(ids_to_remove, cell.y)); + return (_.contains(ids_to_remove, cell.x) || _.contains(ids_to_remove, cell.y)); }); }, @@ -83,25 +86,25 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ row.root.groupby.push(field_id); } - var otherDim = (row.root === this.cols) ? this.rows : this.cols; + var otherDim = (row.root === this.cols) ? this.rows : this.cols; return query_groups_data(this.model, this.visible_fields(), row.domain, otherDim.groupby, field_id) .then(function (groups) { _.each(groups.reverse(), function (group) { - var new_row_id = self.make_header(group, row); + var new_row_id = self.make_header(group, row); _.each(group, function (data) { - var col = _.find(otherDim.headers, function (c) { - if (row.root === this.cols) { - return _.isEqual(data.path.slice(1), c.path); - } else { - return _.isEqual(_.rest(data.path), c.path); - } - }); - if (col) { - self.set_value(new_row_id, col.id, data.attributes.aggregates[self.measure]); - } - }); - }); - row.is_expanded = true; + var col = _.find(otherDim.headers, function (c) { + if (row.root === self.cols) { + return _.isEqual(data.path.slice(1), c.path); + } else { + return _.isEqual(_.rest(data.path), c.path); + } + }); + if (col) { + self.set_value(new_row_id, col.id, data.attributes.aggregates[self.measure]); + } + }); + }); + row.is_expanded = true; }); }, @@ -127,7 +130,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.rows = this.cols; this.cols = temp; - this.rows.main.title = "Total"; + this.rows.main.title = 'Total'; this.cols.main.title = this.measure_label; }, @@ -154,7 +157,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ self.rows.main = self.rows.headers[0]; self.cols.main = self.cols.headers[0]; self.total = self.rows.main.total; - self.rows.main.title = "Total"; + self.rows.main.title = 'Total'; self.cols.main.title = self.measure_label; _.each(self.rows.headers, function (row) { row.root = self.rows; @@ -243,7 +246,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ col.root = self.cols; }); self.cells = result.cells; - self.rows.main.title = "Total"; + self.rows.main.title = 'Total'; self.cols.main.title = self.measure_label; }); }, @@ -282,7 +285,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); return $.when.apply(null, def_array).then(function () { - var args = Array.prototype.slice.call(arguments), + var args = Array.prototype.slice.call(arguments), col_data = _.first(args), total = _.last(args)[0], row_data = _.last(_.initial(args)), @@ -298,7 +301,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ dim_row = this.rows.groupby.length, dim_col = this.cols.groupby.length, col_headers = make_headers(col_data, dim_col), - row_headers = make_headers(row_data, dim_row); + row_headers = make_headers(row_data, dim_row), cells = []; if (dim_col > 0) { @@ -310,8 +313,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ make_cells(cell_data[1], 0, []); } - return {col_headers: col_headers, - row_headers: row_headers, + return {col_headers: col_headers, + row_headers: row_headers, cells: cells}; function make_headers (data, depth) { @@ -379,7 +382,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var col = _.find(col_headers, function (header) { return _.isEqual(header.path, colpath); }); - cells.push({x: Math.min(row.id, col.id), + cells.push({x: Math.min(row.id, col.id), y: Math.max(row.id, col.id), value: value}); @@ -392,15 +395,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); - -removeFromArray = function (array, element) { - var index = array.indexOf(element); - if (index > -1) { - array.splice(index, 1); - } -} - -insertAfter = function (array, after, elem) { +function insertAfter(array, after, elem) { array.splice(array.indexOf(after) + 1, 0, elem); } @@ -409,7 +404,7 @@ insertAfter = function (array, after, elem) { * with all the groupbys applied (this is done for now, but the goal * is to modify read_group in order to allow eager and lazy groupbys */ -query_groups = function (model, fields, domain, groupbys) { +function query_groups (model, fields, domain, groupbys) { return model.query(fields) .filter(domain) .group_by(groupbys) @@ -434,7 +429,7 @@ query_groups = function (model, fields, domain, groupbys) { }); } -query_groups_data = function (model, fields, domain, row_groupbys, col_groupby) { +function query_groups_data (model, fields, domain, row_groupbys, col_groupby) { return query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { return _.map(groups, function (group) { return format_group(group, []); @@ -442,9 +437,9 @@ query_groups_data = function (model, fields, domain, row_groupbys, col_groupby) }); } -format_group = function (group, path) { +function format_group (group, path) { group.path = path.concat(group.attributes.value[1]); - result = [group]; + var result = [group]; _.each(group.subgroups_data, function (subgroup) { result = result.concat(format_group (subgroup, group.path)); }); -- cgit v1.2.3 From 6e88cce3fb48c9ee780bb043f7ba548eb6e98d77 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 15:07:01 +0100 Subject: [FIX] display message insteal of crashing when there are no records to display (addon web_graph) bzr revid: ged@openerp.com-20131127140701-9gej0qik7l4nzgni --- addons/web_graph/static/src/js/graph.js | 17 +++++++----- addons/web_graph/static/src/js/pivot.js | 47 +++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 23 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 6c1f5ae3f32..78fb16582a9 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -193,13 +193,18 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.$('.graph_main_content svg').remove(); this.table.empty(); - var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; - if (_.contains(table_modes, this.mode)) { - this.draw_table(); + if (this.pivot_table.no_data) { + var msg = 'No data available. Try to remove any filter or add some data.'; + this.table.append($('' + msg + '')); } else { - this.$('.graph_main_content').append($('
')); - var svg = this.$('.graph_main_content svg')[0]; - openerp.web_graph.draw_chart(this.mode, this.pivot_table, svg); + var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; + if (_.contains(table_modes, this.mode)) { + this.draw_table(); + } else { + this.$('.graph_main_content').append($('
')); + var svg = this.$('.graph_main_content svg')[0]; + openerp.web_graph.draw_chart(this.mode, this.pivot_table, svg); + } } }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 9171e1641f4..c7bf0ac492a 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -15,6 +15,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.measure_label = options.measure_label; this.total = 0; this.id_seed = 0; + this.no_data = true; }, start: function () { @@ -151,22 +152,27 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var self = this; return this.query_all_values().then(function (result) { - self.rows.headers = result.row_headers; - self.cols.headers = result.col_headers; - self.cells = result.cells; - self.rows.main = self.rows.headers[0]; - self.cols.main = self.cols.headers[0]; - self.total = self.rows.main.total; - self.rows.main.title = 'Total'; - self.cols.main.title = self.measure_label; - _.each(self.rows.headers, function (row) { - row.root = self.rows; - row.is_expanded = (row.children.length > 0); - }); - _.each(self.cols.headers, function (col) { - col.root = self.cols; - col.is_expanded = (col.children.length > 0); - }); + if (result) { + self.no_data = false; + self.rows.headers = result.row_headers; + self.cols.headers = result.col_headers; + self.cells = result.cells; + self.rows.main = self.rows.headers[0]; + self.cols.main = self.cols.headers[0]; + self.total = self.rows.main.total; + self.rows.main.title = 'Total'; + self.cols.main.title = self.measure_label; + _.each(self.rows.headers, function (row) { + row.root = self.rows; + row.is_expanded = (row.children.length > 0); + }); + _.each(self.cols.headers, function (col) { + col.root = self.cols; + col.is_expanded = (col.children.length > 0); + }); + } else { + self.no_data = true; + } }); }, @@ -174,6 +180,10 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ update_values: function () { var self = this; return this.query_all_values().then(function (result) { + if (!result) { + return undefined; + } + self.no_data = false; var old_col_headers = self.cols.headers, old_row_headers = self.rows.headers; @@ -291,7 +301,10 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ row_data = _.last(_.initial(args)), cell_data = args; - return self.format_data(total, col_data, row_data, cell_data); + if (total === undefined) { self.no_data = true;} + return (total === undefined) + ? undefined + : self.format_data(total, col_data, row_data, cell_data); }); }, -- cgit v1.2.3 From 574253bb63dc3d9a630033336c2d2dad9adf9e12 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 15:45:05 +0100 Subject: [REF] improves the draw_row method which will allow to support row_heat_map and col_heatmap in table view (addon web_graph) bzr revid: ged@openerp.com-20131127144505-fq1bb3xv97a2ek38 --- addons/web_graph/static/src/js/graph.js | 44 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 78fb16582a9..1b18e9cd181 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -333,38 +333,36 @@ instance.web_graph.GraphView = instance.web.View.extend({ _.each(pivot.cols.headers, function (col) { if (col.children.length === 0) { var value = pivot.get_value(row.id, col.id), - cell = $(''); - - cell.append((value === undefined) ? '' : value); - if ((self.mode == 'heatmap') && (value !== undefined)) { - var color = Math.floor(50 + 205*(pivot.total - value)/pivot.total); - cell.css('background-color', 'rgb(255,' + color + ',' + color + ')'); - } - if (row.is_expanded && (row.path.length <= 2)) { - var color = row.path.length * 5 + 240; - cell.css('background-color', 'rgb(' + [color, color, color].join() + ')'); - } + cell = make_cell(value); html_row.append(cell); } }); - var total = pivot.get_value(row.id, pivot.cols.main.id); - var cell = $('') - .append(total) - .css('font-weight', 'bold'); - if (row.is_expanded && (row.path.length <= 2)) { - var color = row.path.length * 5 + 240; - cell.css('background-color', 'rgb(' + [color, color, color].join() + ')'); - } else if (self.heat_map_mode) { - var color = Math.floor(50 + 205*(pivot.total - total)/pivot.total); - cell.css('background-color', 'rgb(255,' + color + ',' + color + ')'); - } if (pivot.cols.main.children.length > 0) { + var row_total = pivot.get_value(row.id, pivot.cols.main.id), + cell = make_cell(row_total).css('font-weight', 'bold'); html_row.append(cell); } this.table.append(html_row); - } + + function make_cell (value) { + var color, + cell = $(''); + if (value !== undefined) { + cell.append(value); + } + if ((self.mode === 'pivot') && (row.is_expanded) && (row.path.length <=2)) { + color = row.path.length * 5 + 240; + cell.css('background-color', $.Color(color, color, color)); + } + if (self.mode === 'heatmap') { + color = Math.floor(50 + 205*(pivot.total - value)/pivot.total); + cell.css('background-color', $.Color(255, color, color)); + } + return cell; + } + }, }); }; -- cgit v1.2.3 From c17791dd8274d8cd98fba8773fad50676e801b34 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 15:47:06 +0100 Subject: [FIX] corrects stupid bug with previous commit, where empty cells were colored in heatmap mode (addon web_graph) bzr revid: ged@openerp.com-20131127144706-w7amtjnnku214yih --- addons/web_graph/static/src/js/graph.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 1b18e9cd181..e9f0c8795ab 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -349,9 +349,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ function make_cell (value) { var color, cell = $(''); - if (value !== undefined) { - cell.append(value); + if (value === undefined) { + return cell; } + cell.append(value); if ((self.mode === 'pivot') && (row.is_expanded) && (row.path.length <=2)) { color = row.path.length * 5 + 240; cell.css('background-color', $.Color(color, color, color)); -- cgit v1.2.3 From f5514c70ab0d5980d139409e97d7947497f11902 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 16:06:28 +0100 Subject: [IMP] adds support for row_heatmap and col_heatmap mode to table view (addon web_graph) bzr revid: ged@openerp.com-20131127150628-lval018q5gc1d5ok --- addons/web_graph/static/src/js/graph.js | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index e9f0c8795ab..67c6a1dc26b 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -333,34 +333,46 @@ instance.web_graph.GraphView = instance.web.View.extend({ _.each(pivot.cols.headers, function (col) { if (col.children.length === 0) { var value = pivot.get_value(row.id, col.id), - cell = make_cell(value); + cell = make_cell(value, col); html_row.append(cell); } }); if (pivot.cols.main.children.length > 0) { var row_total = pivot.get_value(row.id, pivot.cols.main.id), - cell = make_cell(row_total).css('font-weight', 'bold'); + cell = make_cell(row_total, pivot.cols.main) + .css('font-weight', 'bold'); html_row.append(cell); } this.table.append(html_row); - function make_cell (value) { + function make_cell (value, col) { var color, + total, cell = $(''); - if (value === undefined) { - return cell; - } - cell.append(value); if ((self.mode === 'pivot') && (row.is_expanded) && (row.path.length <=2)) { color = row.path.length * 5 + 240; cell.css('background-color', $.Color(color, color, color)); } + if (value === undefined) { + return cell; + } + cell.append(value); if (self.mode === 'heatmap') { color = Math.floor(50 + 205*(pivot.total - value)/pivot.total); cell.css('background-color', $.Color(255, color, color)); } + if (self.mode === 'row_heatmap') { + total = pivot.get_value(row.id, pivot.cols.main.id); + color = Math.floor(50 + 205*(total - value)/total); + cell.css('background-color', $.Color(255, color, color)); + } + if (self.mode === 'col_heatmap') { + total = pivot.get_value(col.id, pivot.rows.main.id); + color = Math.floor(50 + 205*(total - value)/total); + cell.css('background-color', $.Color(255, color, color)); + } return cell; } }, -- cgit v1.2.3 From 0d47d906fdf780528fe16fd9ab6686545e6489b6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 27 Nov 2013 16:14:51 +0100 Subject: [REF] removes reference to rows in expand header method (pivot class) in addon web_graph bzr revid: ged@openerp.com-20131127151451-t361x3ufdcbtc54f --- addons/web_graph/static/src/js/pivot.js | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index c7bf0ac492a..c94aae5163d 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -79,34 +79,34 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, - expand: function (row_id, field_id) { + expand: function (header_id, field_id) { var self = this, - row = this.get_header(row_id); + header = this.get_header(header_id); - if (row.path.length == row.root.groupby.length) { - row.root.groupby.push(field_id); + if (header.path.length == header.root.groupby.length) { + header.root.groupby.push(field_id); } - var otherDim = (row.root === this.cols) ? this.rows : this.cols; - return query_groups_data(this.model, this.visible_fields(), row.domain, otherDim.groupby, field_id) + var otherDim = (header.root === this.cols) ? this.rows : this.cols; + return query_groups_data(this.model, this.visible_fields(), header.domain, otherDim.groupby, field_id) .then(function (groups) { _.each(groups.reverse(), function (group) { - var new_row_id = self.make_header(group, row); + var new_header_id = self.make_header(group, header); _.each(group, function (data) { - var col = _.find(otherDim.headers, function (c) { - if (row.root === self.cols) { - return _.isEqual(data.path.slice(1), c.path); - } else { - return _.isEqual(_.rest(data.path), c.path); - } - }); - if (col) { - self.set_value(new_row_id, col.id, data.attributes.aggregates[self.measure]); - } - }); - }); - row.is_expanded = true; - }); + var other = _.find(otherDim.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.set_value(new_header_id, other.id, data.attributes.aggregates[self.measure]); + } + }); + }); + header.is_expanded = true; + }); }, make_header: function (groups, parent) { -- cgit v1.2.3 From 51e4b240f841a76f562832cc84fcd0c6cd553721 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 09:27:54 +0100 Subject: [IMP] adds support for multiple measures in graph view (addon web_graph) bzr revid: ged@openerp.com-20131128082754-4l7nx8ooye1pmc53 --- addons/web_graph/static/src/js/graph.js | 57 ++++++++++++++++++++------------- addons/web_graph/static/src/js/pivot.js | 37 ++++++++++++++++++--- 2 files changed, 67 insertions(+), 27 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 67c6a1dc26b..1bcb0fd98d3 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -31,6 +31,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.display_data(); }, + 'click .graph_measure_selection li' : function (event) { + event.preventDefault(); + var measure = event.target.attributes['data-choice'].nodeValue; + this.pivot_table.set_measure(measure) + .then(this.proxy('display_data')); + }, + 'click .graph_expand_selection li' : function (event) { event.preventDefault(); switch (event.target.attributes['data-choice'].nodeValue) { @@ -92,23 +99,35 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table = null; this.heat_map_mode = false; this.mode = 'pivot'; + this.measure_list = []; + this.important_fields = []; + }, + + start: function () { + this.table = $('
'); + this.$('.graph_main_content').append(this.table); + instance.web.bus.on('click', this, function (ev) { + if (this.dropdown) { + this.dropdown.remove(); + this.dropdown = null; + } + }); + + return this.load_view(); }, view_loading: function (fields_view_get) { var self = this, model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}), domain = [], - measure = null, fields, - important_fields = [], row_groupby = []; - // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { if ('operator' in field.attrs) { - measure = field.attrs.name; + self.measure_list.push(field.attrs.name); } else { row_groupby.push(field.attrs.name); } @@ -130,7 +149,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ _.each(g.children, function (g) { if (g.attrs.context) { var field_id = py.eval(g.attrs.context).group_by; - important_fields.push(field_id); + self.important_fields.push(field_id); } }); }); @@ -146,27 +165,21 @@ instance.web_graph.GraphView = instance.web.View.extend({ model: model, domain: domain, fields: fields, - important_fields: important_fields, - measure: measure, - measure_label: fields[measure].string, + measure: self.measure_list[0], + measure_label: fields[self.measure_list[0]].string, col_groupby: [], row_groupby: row_groupby, groups: [], - total: null, }; - }); - }, + var measure_selection = self.$('.graph_measure_selection'); + _.each(self.measure_list, function (measure) { + var choice = $('').attr('data-choice', measure) + .attr('href', '#') + .append(fields[measure].string); + measure_selection.append($('
  • ').append(choice)); - start: function () { - this.table = $('
    '); - this.$('.graph_main_content').append(this.table); - instance.web.bus.on('click', this, function (ev) { - if (this.dropdown) { - this.dropdown.remove(); - this.dropdown = null; - } - }); - return this.load_view(); + }); + }); }, do_search: function (domain, context, group_by) { @@ -233,7 +246,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ var self = this, pivot = this.pivot_table, already_grouped = pivot.rows.groupby.concat(pivot.cols.groupby), - possible_groups = _.difference(self.data.important_fields, already_grouped), + possible_groups = _.difference(self.important_fields, already_grouped), dropdown_options = { header_id: options.id, fields: _.map(possible_groups, function (field) { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index c94aae5163d..d6ae2168bbf 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -28,7 +28,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, visible_fields: function () { - return this.rows.groupby.concat(this.cols.groupby, this.measure); + var result = this.rows.groupby.concat(this.cols.groupby); + if (this.measure) { + result = result.concat(this.measure); + } + return result; }, set_value: function (id1, id2, value) { @@ -53,6 +57,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return (cell === undefined) ? undefined : cell.value; }, + set_measure: function (measure) { + this.measure = (measure === '__count') ? null : measure; + return this.update_values(); + }, + get_header: function (id) { return _.find(this.rows.headers.concat(this.cols.headers), function (header) { return header.id == id; @@ -101,7 +110,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } }); if (other) { - self.set_value(new_header_id, other.id, data.attributes.aggregates[self.measure]); + if (self.measure) { + self.set_value(new_header_id, other.id, data.attributes.aggregates[self.measure]); + } else { + self.set_value(new_header_id, other.id, data.attributes.length); + } } }); }); @@ -333,14 +346,17 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ function make_headers (data, depth) { var main = { id: self.generate_id(), - count: total.attributes.length, - total: total.attributes.aggregates[self.measure], path: [], parent: null, children: [], title: '', domain: self.domain, }; + if (self.measure) { + main.total = total.attributes.aggregates[self.measure]; + } else { + main.total = total.attributes.length; + } if (depth > 0) { main.children = _.map(data, function (data_pt) { @@ -361,7 +377,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ function make_tree_headers (data_pt, parent, max_depth) { var node = { id: self.generate_id(), - count: data_pt.attributes.length, total: data_pt.attributes.aggregates[self.measure], path: parent.path.concat(data_pt.attributes.value[1]), title: data_pt.attributes.value[1], @@ -369,6 +384,12 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ parent: parent, children: [], }; + if (self.measure) { + node.total = data_pt.attributes.aggregates[self.measure]; + } else { + node.total = data_pt.attributes.length; + } + if (node.path.length < max_depth) { node.children = _.map(data_pt.subgroups_data, function (child) { return make_tree_headers (child, node, max_depth); @@ -381,7 +402,13 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ _.each(data, function (group) { var attr = group.attributes, path = current_path, + value; + + if (self.measure) { value = attr.aggregates[self.measure]; + } else { + value = attr.length; + } if (attr.grouped_on !== undefined) { path = path.concat(attr.value[1]); -- cgit v1.2.3 From be00aca052de10bbcfcf82ab00bac7802059e331 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 09:45:51 +0100 Subject: [REF] removes all references to measure label in pivot table (addon web_graph) bzr revid: ged@openerp.com-20131128084551-19hc23fmw3gvtoc9 --- addons/web_graph/static/src/js/graph.js | 17 ++++++++++++++--- addons/web_graph/static/src/js/pivot.js | 14 +++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 1bcb0fd98d3..119d0b12e16 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -34,7 +34,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ 'click .graph_measure_selection li' : function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; - this.pivot_table.set_measure(measure) + this.measure = (measure === '__count') ? null : measure; + this.pivot_table.set_measure(this.measure) .then(this.proxy('display_data')); }, @@ -99,6 +100,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table = null; this.heat_map_mode = false; this.mode = 'pivot'; + this.measure = null; this.measure_list = []; this.important_fields = []; }, @@ -133,6 +135,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ } } }); + if (this.measure_list.length > 0) { + this.measure = this.measure_list[0]; + } // get the most important fields (of the model) by looking at the // groupby filters defined in the search view @@ -161,12 +166,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ return $.when(important_fields_def, field_descr_def) .then(function () { + self.fields = fields; self.data = { model: model, domain: domain, fields: fields, - measure: self.measure_list[0], - measure_label: fields[self.measure_list[0]].string, + measure: self.measure, col_groupby: [], row_groupby: row_groupby, groups: [], @@ -261,7 +266,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.$('.field-selection').next('.dropdown-menu').toggle(); }, + measure_label: function () { + return (this.measure) ? this.fields[this.measure].string : 'Quantity'; + }, + draw_table: function () { + this.pivot_table.rows.main.title = 'Total'; + this.pivot_table.cols.main.title = this.measure_label(); this.draw_top_headers(); _.each(this.pivot_table.rows.headers, this.proxy('draw_row')); }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index d6ae2168bbf..40ee4f0acda 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -12,7 +12,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.model = options.model; this.domain = options.domain; this.measure = options.measure; - this.measure_label = options.measure_label; this.total = 0; this.id_seed = 0; this.no_data = true; @@ -58,7 +57,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, set_measure: function (measure) { - this.measure = (measure === '__count') ? null : measure; + this.measure = measure; return this.update_values(); }, @@ -143,9 +142,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var temp = this.rows; this.rows = this.cols; this.cols = temp; - - this.rows.main.title = 'Total'; - this.cols.main.title = this.measure_label; }, fold_rows: function () { @@ -173,8 +169,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ self.rows.main = self.rows.headers[0]; self.cols.main = self.cols.headers[0]; self.total = self.rows.main.total; - self.rows.main.title = 'Total'; - self.cols.main.title = self.measure_label; + self.rows.main.title = ''; + self.cols.main.title = ''; _.each(self.rows.headers, function (row) { row.root = self.rows; row.is_expanded = (row.children.length > 0); @@ -269,8 +265,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ col.root = self.cols; }); self.cells = result.cells; - self.rows.main.title = 'Total'; - self.cols.main.title = self.measure_label; + self.rows.main.title = ''; + self.cols.main.title = ''; }); }, -- cgit v1.2.3 From d790f8e96f2944ef120383d22696ec4038a56738 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 10:17:15 +0100 Subject: [REF] removes duplicated code in update_values method in pivot class (addon web_graph) bzr revid: ged@openerp.com-20131128091715-g1f29k60a0pvy8sd --- addons/web_graph/static/src/js/pivot.js | 82 ++++++++++----------------------- 1 file changed, 25 insertions(+), 57 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 40ee4f0acda..a87dfada7d5 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -193,68 +193,38 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return undefined; } self.no_data = false; - var old_col_headers = self.cols.headers, - old_row_headers = self.rows.headers; - - // the next 30 lines replace this.cols.headers with the - // corresponding headers in result.col_headers - _.each(old_col_headers, function (header) { - var corresponding_col = _.find(result.col_headers, function (c) { - return _.isEqual(c.path, header.path); - }); - - if (corresponding_col !== undefined) { - if (header.is_expanded) { - corresponding_col.is_expanded = true; - _.each(corresponding_col.children, function (c) { - c.is_expanded = false; - }); - } else { - corresponding_col.is_expanded = false; - } - } - }); - - self.cols.headers = _.filter(result.col_headers, function (header) { - return (header.is_expanded !== undefined); - }); - - _.each(self.cols.headers, function (col) { - if (!col.is_expanded) { - col.children = []; - } - }); + self.cols.headers = update_headers(self.cols.headers, result.col_headers); + self.rows.headers = update_headers(self.rows.headers, result.row_headers); self.cols.main = self.cols.headers[0]; + self.rows.main = self.rows.headers[0]; - // the next 30 lines replace this.rows.headers with the - // corresponding headers in result.row_headers - _.each(old_row_headers, function (header) { - var corresponding_row = _.find(result.row_headers, function (c) { - return _.isEqual(c.path, header.path); - }); - if (corresponding_row !== undefined) { - if (header.is_expanded) { - corresponding_row.is_expanded = true; - _.each(corresponding_row.children, function (c) { + function update_headers (old_headers, new_headers) { + _.each(old_headers, function (header) { + var corresponding_header = _.find(new_headers, function (h) { + return _.isEqual(h.path, header.path); + }); + if (corresponding_header && (header.is_expanded)) { + corresponding_header.is_expanded = true; + _.each(corresponding_header.children, function (c) { c.is_expanded = false; }); - } else { - corresponding_row.is_expanded = false; + } + if (corresponding_header && (!header.is_expanded)) { + corresponding_header.is_expanded = false; } - } - }); - - self.rows.headers = _.filter(result.row_headers, function (header) { - return (header.is_expanded !== undefined); - }); + }); + var updated_headers = _.filter(new_headers, function (header) { + return (header.is_expanded !== undefined); + }); + _.each(updated_headers, function (hdr) { + if (!hdr.is_expanded) { + hdr.children = []; + } + }); - _.each(self.rows.headers, function (col) { - if (!col.is_expanded) { - col.children = []; - } - }); - self.rows.main = self.rows.headers[0]; + return updated_headers; + } // now some more tweaks self.total = self.rows.main.total; @@ -265,8 +235,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ col.root = self.cols; }); self.cells = result.cells; - self.rows.main.title = ''; - self.cols.main.title = ''; }); }, -- cgit v1.2.3 From 4aa70638ef8418f18e05bd8ff7dba88724b886a6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 10:47:46 +0100 Subject: [REF] adds a 'get_total' method and simplify a few parts of the code using totals (addon web_graph) bzr revid: ged@openerp.com-20131128094746-mthch89zqx66flq7 --- addons/web_graph/static/src/js/graph.js | 10 +++++----- addons/web_graph/static/src/js/pivot.js | 14 +++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 119d0b12e16..c1c2b52f4b8 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -363,8 +363,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); if (pivot.cols.main.children.length > 0) { - var row_total = pivot.get_value(row.id, pivot.cols.main.id), - cell = make_cell(row_total, pivot.cols.main) + var cell = make_cell(pivot.get_total(row), pivot.cols.main) .css('font-weight', 'bold'); html_row.append(cell); } @@ -384,16 +383,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ } cell.append(value); if (self.mode === 'heatmap') { - color = Math.floor(50 + 205*(pivot.total - value)/pivot.total); + total = pivot.get_total(); + color = Math.floor(50 + 205*(total - value)/total); cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'row_heatmap') { - total = pivot.get_value(row.id, pivot.cols.main.id); + total = pivot.get_total(row); color = Math.floor(50 + 205*(total - value)/total); cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'col_heatmap') { - total = pivot.get_value(col.id, pivot.rows.main.id); + total = pivot.get_total(col); color = Math.floor(50 + 205*(total - value)/total); cell.css('background-color', $.Color(255, color, color)); } diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index a87dfada7d5..68c5ca43a3e 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -12,7 +12,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.model = options.model; this.domain = options.domain; this.measure = options.measure; - this.total = 0; this.id_seed = 0; this.no_data = true; }, @@ -168,7 +167,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ self.cells = result.cells; self.rows.main = self.rows.headers[0]; self.cols.main = self.cols.headers[0]; - self.total = self.rows.main.total; self.rows.main.title = ''; self.cols.main.title = ''; _.each(self.rows.headers, function (row) { @@ -186,6 +184,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, + get_total: function (header) { + if (header) { + var main = (header.root === this.rows) ? this.cols.main : this.rows.main; + return this.get_value(header.id, main.id); + } else { + return this.rows.main.total; + } + }, + update_values: function () { var self = this; return this.query_all_values().then(function (result) { @@ -226,8 +233,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return updated_headers; } - // now some more tweaks - self.total = self.rows.main.total; _.each(self.rows.headers, function (row) { row.root = self.rows; }); @@ -341,7 +346,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ function make_tree_headers (data_pt, parent, max_depth) { var node = { id: self.generate_id(), - total: data_pt.attributes.aggregates[self.measure], path: parent.path.concat(data_pt.attributes.value[1]), title: data_pt.attributes.value[1], domain: data_pt.model._domain, -- cgit v1.2.3 From e0920173a32f7889ce2b9bc49a7a83ad035ca60a Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 11:16:25 +0100 Subject: [REF] improves the initialization process of pivot table (addon web_graph) bzr revid: ged@openerp.com-20131128101625-7ig5lftk8wv8w6tj --- addons/web_graph/static/src/js/graph.js | 21 ++++++--------------- addons/web_graph/static/src/js/pivot.js | 3 +++ 2 files changed, 9 insertions(+), 15 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index c1c2b52f4b8..5d4eade76fb 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -114,7 +114,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.dropdown = null; } }); - return this.load_view(); }, @@ -167,7 +166,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ return $.when(important_fields_def, field_descr_def) .then(function () { self.fields = fields; - self.data = { + var data = { model: model, domain: domain, fields: fields, @@ -176,6 +175,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ row_groupby: row_groupby, groups: [], }; + self.pivot_table = new openerp.web_graph.PivotTable(data); + var measure_selection = self.$('.graph_measure_selection'); _.each(self.measure_list, function (measure) { var choice = $('').attr('data-choice', measure) @@ -188,18 +189,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { - var self = this; - this.data.domain = new instance.web.CompoundDomain(domain); - - if (!this.pivot_table) { - self.pivot_table = new openerp.web_graph.PivotTable(self.data); - self.pivot_table.start().then(self.proxy('display_data')); - } else { - this.pivot_table.domain = domain; - this.pivot_table.update_values().done(function () { - self.display_data(); - }); - } + this.pivot_table.domain = domain; + this.pivot_table.update_values().done(this.proxy('display_data')); }, do_show: function () { @@ -255,7 +246,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ dropdown_options = { header_id: options.id, fields: _.map(possible_groups, function (field) { - return {id: field, value: self.data.fields[field].string}; + return {id: field, value: self.fields[field].string}; })}; this.dropdown = $(QWeb.render('field_selection', dropdown_options)); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 68c5ca43a3e..80e5e95306b 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -194,6 +194,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, update_values: function () { + if (!this.rows.headers) { + return this.expand_all(); + } var self = this; return this.query_all_values().then(function (result) { if (!result) { -- cgit v1.2.3 From 6afd98516c4d18a146570184d3b667a3438ffdfc Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 11:49:29 +0100 Subject: [REF] removes a few useless lines in view_loading method (addon web_graph) bzr revid: ged@openerp.com-20131128104929-4ou50xebjub3bijh --- addons/web_graph/static/src/js/graph.js | 45 ++++++++++++++------------------- 1 file changed, 19 insertions(+), 26 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 5d4eade76fb..de4d40a923a 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -120,8 +120,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_loading: function (fields_view_get) { var self = this, model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}), - domain = [], - fields, row_groupby = []; // get the default groupbys and measure defined in the field view @@ -140,40 +138,35 @@ instance.web_graph.GraphView = instance.web.View.extend({ // get the most important fields (of the model) by looking at the // groupby filters defined in the search view - var load_view = instance.web.fields_view_get({ - model: model, - view_type: 'search', - }); - - var important_fields_def = $.when(load_view).then(function (search_view) { - var groups = _.select(search_view.arch.children, function (c) { - return (c.tag == 'group') && (c.attrs.string != 'Display'); - }); - _.each(groups, function(g) { - _.each(g.children, function (g) { - if (g.attrs.context) { - var field_id = py.eval(g.attrs.context).group_by; - self.important_fields.push(field_id); - } + var options = {model:model, view_type: 'search'}, + deferred1 = instance.web.fields_view_get(options).then(function (search_view) { + var groups = _.select(search_view.arch.children, function (c) { + return (c.tag == 'group') && (c.attrs.string != 'Display'); + }); + _.each(groups, function(g) { + _.each(g.children, function (g) { + if (g.attrs.context) { + var field_id = py.eval(g.attrs.context).group_by; + self.important_fields.push(field_id); + } + }); }); }); - }); // get the fields descriptions from the model - var field_descr_def = model.call('fields_get', []) - .then(function (fs) { fields = fs; }); + var deferred2 = model.call('fields_get', []).then(function (fs) { + self.fields = fs; + console.log("fiels",self.fields); + }); - return $.when(important_fields_def, field_descr_def) + return $.when(deferred1, deferred2) .then(function () { - self.fields = fields; var data = { model: model, - domain: domain, - fields: fields, + domain: [], measure: self.measure, col_groupby: [], row_groupby: row_groupby, - groups: [], }; self.pivot_table = new openerp.web_graph.PivotTable(data); @@ -181,7 +174,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ _.each(self.measure_list, function (measure) { var choice = $('').attr('data-choice', measure) .attr('href', '#') - .append(fields[measure].string); + .append(self.fields[measure].string); measure_selection.append($('
  • ').append(choice)); }); -- cgit v1.2.3 From 7b2109dcae11ac37afce0918390f61b348290c02 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 11:54:02 +0100 Subject: [REF] removes a few useless lines in view_loading method (addon web_graph) bzr revid: ged@openerp.com-20131128105402-eb3pqksd5v9ixaxn --- addons/web_graph/static/src/js/graph.js | 39 +++++++++++++++------------------ 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index de4d40a923a..689cccaab14 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -156,29 +156,26 @@ instance.web_graph.GraphView = instance.web.View.extend({ // get the fields descriptions from the model var deferred2 = model.call('fields_get', []).then(function (fs) { self.fields = fs; - console.log("fiels",self.fields); - }); - - return $.when(deferred1, deferred2) - .then(function () { - var data = { - model: model, - domain: [], - measure: self.measure, - col_groupby: [], - row_groupby: row_groupby, - }; - self.pivot_table = new openerp.web_graph.PivotTable(data); - - var measure_selection = self.$('.graph_measure_selection'); - _.each(self.measure_list, function (measure) { - var choice = $('').attr('data-choice', measure) - .attr('href', '#') - .append(self.fields[measure].string); - measure_selection.append($('
  • ').append(choice)); + var measure_selection = self.$('.graph_measure_selection'); + _.each(self.measure_list, function (measure) { + var choice = $('').attr('data-choice', measure) + .attr('href', '#') + .append(self.fields[measure].string); + measure_selection.append($('
  • ').append(choice)); - }); }); + }); + + return $.when(deferred1, deferred2).then(function () { + var data = { + model: model, + domain: [], + measure: self.measure, + col_groupby: [], + row_groupby: row_groupby, + }; + self.pivot_table = new openerp.web_graph.PivotTable(data); + }); }, do_search: function (domain, context, group_by) { -- cgit v1.2.3 From 2ff2fc4c9e55934ff2caf010816849165d32eb5d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 13:38:30 +0100 Subject: [REF] removes a few useless lines (addon web_graph) bzr revid: ged@openerp.com-20131128123830-vaqaeoizit8x8jq9 --- addons/web_graph/static/src/js/pivot.js | 2 -- 1 file changed, 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 80e5e95306b..5d5b70ebc45 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -167,8 +167,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ self.cells = result.cells; self.rows.main = self.rows.headers[0]; self.cols.main = self.cols.headers[0]; - self.rows.main.title = ''; - self.cols.main.title = ''; _.each(self.rows.headers, function (row) { row.root = self.rows; row.is_expanded = (row.children.length > 0); -- cgit v1.2.3 From d41ca29475074bfccf79d9206019913e0c16f5ff Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 14:01:46 +0100 Subject: [IMP] adds some rudimentary support to the integration of search bar groupby into the graph view (addon web_graph) bzr revid: ged@openerp.com-20131128130146-33i0ydw9gbjqgc0v --- addons/web_graph/static/src/js/graph.js | 6 ++- addons/web_graph/static/src/js/pivot.js | 84 +++++++++++++++++++++------------ 2 files changed, 59 insertions(+), 31 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 689cccaab14..94c5a4011f9 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -180,7 +180,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { this.pivot_table.domain = domain; - this.pivot_table.update_values().done(this.proxy('display_data')); + if (group_by.length > 0) { + this.pivot_table.set_row_groupby(group_by).done(this.proxy('display_data')); + } else { + this.pivot_table.update_values().done(this.proxy('display_data')); + } }, do_show: function () { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 5d5b70ebc45..621d3fbeb3d 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -182,6 +182,31 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, + set_row_groupby: function (groupby) { + var self = this; + this.rows.groupby = groupby; + return this.query_all_values().then(function (result) { + if (result) { + self.no_data = false; + self.rows.headers = result.row_headers; + self.cols.headers = self.update_headers(self.cols.headers, result.col_headers); + self.cells = result.cells; + self.cols.main = self.cols.headers[0]; + self.rows.main = self.rows.headers[0]; + _.each(self.rows.headers, function (row) { + row.root = self.rows; + row.is_expanded = (row.children.length > 0); + }); + _.each(self.cols.headers, function (col) { + col.root = self.cols; + }); + + } else { + self.no_data = true; + } + }); + }, + get_total: function (header) { if (header) { var main = (header.root === this.rows) ? this.cols.main : this.rows.main; @@ -191,6 +216,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } }, + update_values: function () { if (!this.rows.headers) { return this.expand_all(); @@ -201,39 +227,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return undefined; } self.no_data = false; - self.cols.headers = update_headers(self.cols.headers, result.col_headers); - self.rows.headers = update_headers(self.rows.headers, result.row_headers); + self.cols.headers = self.update_headers(self.cols.headers, result.col_headers); + self.rows.headers = self.update_headers(self.rows.headers, result.row_headers); self.cols.main = self.cols.headers[0]; self.rows.main = self.rows.headers[0]; - - function update_headers (old_headers, new_headers) { - _.each(old_headers, function (header) { - var corresponding_header = _.find(new_headers, function (h) { - return _.isEqual(h.path, header.path); - }); - if (corresponding_header && (header.is_expanded)) { - corresponding_header.is_expanded = true; - _.each(corresponding_header.children, function (c) { - c.is_expanded = false; - }); - } - if (corresponding_header && (!header.is_expanded)) { - corresponding_header.is_expanded = false; - } - }); - var updated_headers = _.filter(new_headers, function (header) { - return (header.is_expanded !== undefined); - }); - _.each(updated_headers, function (hdr) { - if (!hdr.is_expanded) { - hdr.children = []; - } - }); - - return updated_headers; - } - _.each(self.rows.headers, function (row) { row.root = self.rows; }); @@ -244,6 +242,32 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, + update_headers: function (old_headers, new_headers) { + _.each(old_headers, function (header) { + var corresponding_header = _.find(new_headers, function (h) { + return _.isEqual(h.path, header.path); + }); + if (corresponding_header && (header.is_expanded)) { + corresponding_header.is_expanded = true; + _.each(corresponding_header.children, function (c) { + c.is_expanded = false; + }); + } + if (corresponding_header && (!header.is_expanded)) { + corresponding_header.is_expanded = false; + } + }); + var updated_headers = _.filter(new_headers, function (header) { + return (header.is_expanded !== undefined); + }); + _.each(updated_headers, function (hdr) { + if (!hdr.is_expanded) { + hdr.children = []; + } + }); + return updated_headers; + }, + // this method is a little tricky. In order 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) -- cgit v1.2.3 From 2a3eb6c336a66fd27721898474b5d12d1e87c72d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 14:38:54 +0100 Subject: [REF] removes duplicated code in update/expand methods (addon web_graph) bzr revid: ged@openerp.com-20131128133854-28k6utrer7cdsz4z --- addons/web_graph/static/src/js/pivot.js | 59 +++++++++++---------------------- 1 file changed, 20 insertions(+), 39 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 621d3fbeb3d..a9ef922819f 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -158,23 +158,12 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ expand_all: function () { var self = this; - return this.query_all_values().then(function (result) { if (result) { self.no_data = false; - self.rows.headers = result.row_headers; - self.cols.headers = result.col_headers; + self.expand_headers(self.rows, result.row_headers); + self.expand_headers(self.cols, result.col_headers); self.cells = result.cells; - self.rows.main = self.rows.headers[0]; - self.cols.main = self.cols.headers[0]; - _.each(self.rows.headers, function (row) { - row.root = self.rows; - row.is_expanded = (row.children.length > 0); - }); - _.each(self.cols.headers, function (col) { - col.root = self.cols; - col.is_expanded = (col.children.length > 0); - }); } else { self.no_data = true; } @@ -182,25 +171,24 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, + expand_headers: function (root, new_headers) { + root.headers = new_headers; + root.main = new_headers[0]; + _.each(root.headers, function (header) { + header.root = root; + header.is_expanded = (header.children.length > 0); + }); + }, + set_row_groupby: function (groupby) { var self = this; this.rows.groupby = groupby; return this.query_all_values().then(function (result) { if (result) { self.no_data = false; - self.rows.headers = result.row_headers; - self.cols.headers = self.update_headers(self.cols.headers, result.col_headers); + self.expand_headers(self.rows, result.row_headers); + self.update_headers(self.cols, result.col_headers); self.cells = result.cells; - self.cols.main = self.cols.headers[0]; - self.rows.main = self.rows.headers[0]; - _.each(self.rows.headers, function (row) { - row.root = self.rows; - row.is_expanded = (row.children.length > 0); - }); - _.each(self.cols.headers, function (col) { - col.root = self.cols; - }); - } else { self.no_data = true; } @@ -227,23 +215,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return undefined; } self.no_data = false; - self.cols.headers = self.update_headers(self.cols.headers, result.col_headers); - self.rows.headers = self.update_headers(self.rows.headers, result.row_headers); - self.cols.main = self.cols.headers[0]; - self.rows.main = self.rows.headers[0]; - - _.each(self.rows.headers, function (row) { - row.root = self.rows; - }); - _.each(self.cols.headers, function (col) { - col.root = self.cols; - }); + self.update_headers(self.cols, result.col_headers); + self.update_headers(self.rows, result.row_headers); self.cells = result.cells; }); }, - update_headers: function (old_headers, new_headers) { - _.each(old_headers, function (header) { + 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); }); @@ -264,8 +243,10 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ if (!hdr.is_expanded) { hdr.children = []; } + hdr.root = root; }); - return updated_headers; + root.headers = updated_headers; + root.main = root.headers[0]; }, // this method is a little tricky. In order to obtain all the values -- cgit v1.2.3 From 55bbabaf46cbc50e959192fdb8310a07afe77aef Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 14:49:04 +0100 Subject: [IMP] changes the set_row_groupby method into set_groupby (more generic, works for rows and cols) (addon web_graph) bzr revid: ged@openerp.com-20131128134904-ubkxdowr29is2o86 --- addons/web_graph/static/src/js/graph.js | 3 ++- addons/web_graph/static/src/js/pivot.js | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 94c5a4011f9..450a86a470a 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -181,7 +181,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { this.pivot_table.domain = domain; if (group_by.length > 0) { - this.pivot_table.set_row_groupby(group_by).done(this.proxy('display_data')); + this.pivot_table.set_groupby(this.pivot_table.rows, group_by) + .done(this.proxy('display_data')); } else { this.pivot_table.update_values().done(this.proxy('display_data')); } diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index a9ef922819f..bca759a13e5 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -180,14 +180,24 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, - set_row_groupby: function (groupby) { + set_groupby: function (root, groupby) { var self = this; - this.rows.groupby = groupby; + var other_root = (root === this.cols) ? this.rows : this.cols; + + root.groupby = groupby; return this.query_all_values().then(function (result) { if (result) { + var new_root_headers, new_other_root_headers; + if (root === this.cols) { + new_root_headers = result.col_headers; + new_other_root_headers = result.how_headers; + } else { + new_root_headers = result.row_headers; + new_other_root_headers = result.col_headers; + } self.no_data = false; - self.expand_headers(self.rows, result.row_headers); - self.update_headers(self.cols, result.col_headers); + self.expand_headers(root, new_root_headers); + self.update_headers(other_root, new_other_root_headers); self.cells = result.cells; } else { self.no_data = true; -- cgit v1.2.3 From 8013a154b80766779cbe2cbad101bc3669e0e41f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 15:18:03 +0100 Subject: [FIX] fixes a crash that occurred when a graph view had a starting groupby (given by the search view) (in addon web_graph) bzr revid: ged@openerp.com-20131128141803-j0ttpgedic84quvy --- addons/web_graph/static/src/js/pivot.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index bca759a13e5..38dad2c33cb 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -232,6 +232,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, update_headers: function (root, new_headers) { + if (!root.main) { + return this.expand_headers(root, new_headers); + } _.each(root.headers, function (header) { var corresponding_header = _.find(new_headers, function (h) { return _.isEqual(h.path, header.path); -- cgit v1.2.3 From e2d2d51b7a7e9a77cb8b89e4adee35763e61201a Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 28 Nov 2013 15:51:55 +0100 Subject: [IMP] supports the attribute 'type' in the xml definition of the graph view, at least for bar_charts (addon web_graph) bzr revid: ged@openerp.com-20131128145155-b5w4fhw9vrp9txuc --- addons/web_graph/static/src/js/charts.js | 5 +++-- addons/web_graph/static/src/js/graph.js | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 2ac84085ce1..35585c73c09 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -2,8 +2,9 @@ openerp.web_graph.draw_chart = function (mode, pivot, svg) { var data = _.map(pivot.rows.main.children, function (pt) { - var val = pivot.get_value(pt.id, pivot.cols.main.id); - return {x: pt.title, y: val}; + var value = pivot.get_value(pt.id, pivot.cols.main.id), + title = (pt.title !== undefined) ? pt.title : 'Undefined'; + return {x: title, y: value}; }); switch (mode) { diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 450a86a470a..77f444948b5 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -122,6 +122,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}), row_groupby = []; + if (fields_view_get.arch.attrs.type === 'bar') { + this.mode = 'bar_chart'; + } + // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { -- cgit v1.2.3 From 15547d9267178493a22074b20b68099eb5948abb Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 5 Dec 2013 11:07:10 +0100 Subject: [REF] refactors the event handling code and prepare the way for supporting col_groupby and groupby in the searchbar (addon web_graph) bzr revid: ged@openerp.com-20131205100710-5owdxv0m971ymwbs --- addons/web_graph/static/src/js/charts.js | 1 - addons/web_graph/static/src/js/graph.js | 248 ++++++++++++++++++++++--------- addons/web_graph/static/src/js/pivot.js | 15 ++ 3 files changed, 191 insertions(+), 73 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 35585c73c09..5f17cce4aef 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -18,7 +18,6 @@ openerp.web_graph.draw_chart = function (mode, pivot, svg) { pie_chart(); break; } - function bar_chart () { nv.addGraph(function () { var chart = nv.models.discreteBarChart() diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 77f444948b5..f1c9b62e137 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -15,8 +15,7 @@ var QWeb = instance.web.qweb; instance.web.views.add('graph', 'instance.web_graph.GraphView'); /** - * GraphView view. It mostly contains a widget (PivotTable), some data, and - * calls to charts function. + * GraphView */ instance.web_graph.GraphView = instance.web.View.extend({ template: 'GraphView', @@ -24,72 +23,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_type: 'graph', events: { - 'click .graph_mode_selection li' : function (event) { - event.preventDefault(); - var mode = event.target.attributes['data-mode'].nodeValue; - this.mode = mode; - this.display_data(); - }, - - 'click .graph_measure_selection li' : function (event) { - event.preventDefault(); - var measure = event.target.attributes['data-choice'].nodeValue; - this.measure = (measure === '__count') ? null : measure; - this.pivot_table.set_measure(this.measure) - .then(this.proxy('display_data')); - }, - - 'click .graph_expand_selection li' : function (event) { - event.preventDefault(); - switch (event.target.attributes['data-choice'].nodeValue) { - case 'fold_columns': - this.pivot_table.fold_cols(); - this.display_data(); - break; - case 'fold_rows': - this.pivot_table.fold_rows(); - this.display_data(); - break; - case 'fold_all': - this.pivot_table.fold_all(); - this.display_data(); - break; - case 'expand_all': - this.pivot_table.expand_all().then(this.proxy('display_data')); - break; - } - }, - - 'click .graph_options_selection li' : function (event) { - event.preventDefault(); - switch (event.target.attributes['data-choice'].nodeValue) { - case 'swap_axis': - this.pivot_table.swap_axis(); - this.display_data(); - break; - case 'update_values': - this.pivot_table.update_values().then(this.proxy('display_data')); - break; - case 'export_data': - // Export code... To do... - break; - } - }, - - 'click .web_graph_click' : function (event) { - event.preventDefault(); - event.stopPropagation(); - var id = event.target.attributes['data-id'].nodeValue; - this.handle_header_event({id:id, event:event}); - }, - - 'click a.field-selection' : function (event) { - var id = event.target.attributes['data-id'].nodeValue, - field_id = event.target.attributes['data-field-id'].nodeValue; - event.preventDefault(); - this.pivot_table.expand(id, field_id) - .then(this.proxy('display_data')); - }, + 'click .graph_mode_selection li' : 'mode_selection', + 'click .graph_measure_selection li' : 'measure_selection', + 'click .graph_expand_selection li' : 'expand_selection', + 'click .graph_options_selection li' : 'option_selection', + 'click .web_graph_click' : 'cell_click_callback', + 'click a.field-selection' : 'field_selection', }, init: function(parent, dataset, view_id, options) { @@ -103,6 +42,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.measure = null; this.measure_list = []; this.important_fields = []; + this.search_view = parent.searchview; + this.search_field = { + get_context: function () { }, + get_domain: function () { }, + get_groupby: function () { }, + }; }, start: function () { @@ -183,12 +128,38 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { + console.log("START DO SEARCH",group_by); + var self = this; + this.pivot_table.domain = domain; if (group_by.length > 0) { this.pivot_table.set_groupby(this.pivot_table.rows, group_by) .done(this.proxy('display_data')); } else { - this.pivot_table.update_values().done(this.proxy('display_data')); + this.pivot_table.update_values().done(this.proxy('display_data')); + } + + var colgroupby = get_search_col_groupby(); + console.log ("colgroupby", colgroupby); + console.log("pivot cbh",this.pivot_table.cols.groupby); + + if (!_.isEqual(colgroupby, this.pivot_table.cols.groupby)) { + // console.log ('yop'); + // this.pivot_table.set_groupby(this.pivot_table.cols, colgroupby) + // .done(this.proxy('display_data')); + } + // console.log("query",this.search_view.query.models); + function get_search_col_groupby() { + var colgroupby = [], + search = _.find(self.search_view.query.models, function (model) { + return model.attributes.category == 'ColGroupBy'; + }); + if (search) { + colgroupby = _.map(search.values.models, function (val) { + return val.attributes.value; + }); + } + return colgroupby; } }, @@ -198,6 +169,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, display_data: function () { + console.log('displaying data'); this.$('.graph_main_content svg').remove(); this.table.empty(); @@ -216,6 +188,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }, + +/****************************************************************************** + * Event handling methods... + ******************************************************************************/ + handle_header_event: function (options) { var pivot = this.pivot_table, id = options.id, @@ -237,6 +214,127 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }, + + mode_selection: function (event) { + event.preventDefault(); + var mode = event.target.attributes['data-mode'].nodeValue; + this.mode = mode; + this.display_data(); + // console.log('yop'); + // var self = this; + // var attr = [{label: self.fields['user_id'].string, value: 'user_id'}]; + // var attr2 = [{label: self.fields['user_id'].string, value: { + // attrs: {domain: [], context: {'group_by':'user_id'}} + // }}]; + // var groupbytest = { + // category: 'GroupBy', + // values: attr2, + // icon: 'u', + // field: self.search_view._s_groupby, + // }; + + // // console.log("rnst",self.search_view); + // var test = { + // values: attr, + // icon: 'u', + // field: self.search_field, + // category: _t("ColGroupBy"), + // }; + // self.search_view.query.add(test); + // self.search_view.query.add(groupbytest, {}); + + }, + + + measure_selection: function (event) { + event.preventDefault(); + var measure = event.target.attributes['data-choice'].nodeValue; + this.measure = (measure === '__count') ? null : measure; + this.pivot_table.set_measure(this.measure) + .then(this.proxy('display_data')); + }, + + expand_selection: function (event) { + event.preventDefault(); + switch (event.target.attributes['data-choice'].nodeValue) { + case 'fold_columns': + this.pivot_table.fold_cols(); + this.display_data(); + break; + case 'fold_rows': + this.pivot_table.fold_rows(); + this.display_data(); + break; + case 'fold_all': + this.pivot_table.fold_all(); + this.display_data(); + break; + case 'expand_all': + this.pivot_table.expand_all().then(this.proxy('display_data')); + break; + } + }, + + option_selection: function (event) { + event.preventDefault(); + switch (event.target.attributes['data-choice'].nodeValue) { + case 'swap_axis': + this.pivot_table.swap_axis(); + this.display_data(); + break; + case 'update_values': + this.pivot_table.update_values().then(this.proxy('display_data')); + break; + case 'export_data': + // Export code... To do... + break; + } + }, + + + cell_click_callback: function (event) { + event.preventDefault(); + event.stopPropagation(); + var id = event.target.attributes['data-id'].nodeValue; + this.handle_header_event({id:id, event:event}); + }, + + field_selection: function (event) { + var self = this, + id = event.target.attributes['data-id'].nodeValue, + field_id = event.target.attributes['data-field-id'].nodeValue; + event.preventDefault(); + this.pivot_table.expand(id, field_id).then(function () { + + var attr = [{label: self.fields[field_id].string, value: field_id}]; + var attr2 = [{label: self.fields[field_id].string, value: { + attrs: {domain: [], context: {'group_by':'stage_id'}} + }}]; + + var test = { + values: attr, + icon: 'u', + field: self.search_field, + category: _t("ColGroupBy"), + }; + + var groupbytest = { + category: 'GroupBy', + values: attr2, + icon: 'u', + field: self.search_view._s_groupby, + }; + + // console.log("rnst",self.search_view); + console.log('BEF ADD CGB'); + // self.search_view.query.add(test); + console.log('BEF ADD RGB'); + // self.search_view.query.add(groupbytest, {}); + console.log('AFTER ADD GB'); + self.display_data(); + }); + }, + display_dropdown: function (options) { var self = this, pivot = this.pivot_table, @@ -256,9 +354,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.$('.field-selection').next('.dropdown-menu').toggle(); }, - measure_label: function () { - return (this.measure) ? this.fields[this.measure].string : 'Quantity'; - }, +/****************************************************************************** + * Drawing pivot table methods... + ******************************************************************************/ draw_table: function () { this.pivot_table.rows.main.title = 'Total'; @@ -267,6 +365,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ _.each(this.pivot_table.rows.headers, this.proxy('draw_row')); }, + measure_label: function () { + return (this.measure) ? this.fields[this.measure].string : 'Quantity'; + }, + make_border_cell: function (colspan, rowspan) { return $('').addClass('graph_border') .attr('colspan', colspan) @@ -392,4 +494,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, }); + + }; diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 38dad2c33cb..f412d59474b 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -1,6 +1,9 @@ /* jshint undef: false */ + +// TO DO : use _.uniqueID() + (function () { 'use strict'; @@ -60,6 +63,18 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return this.update_values(); }, + is_row: function (id) { + return !!_.find(this.rows.headers, function (header) { + return header.id == id; + }); + }, + + is_col: function (id) { + return !!_.find(this.cols.headers, function (header) { + return header.id == id; + }); + }, + get_header: function (id) { return _.find(this.rows.headers.concat(this.cols.headers), function (header) { return header.id == id; -- cgit v1.2.3 From d3fffbff509f171fe658181891d90f0476f5145b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 5 Dec 2013 16:19:45 +0100 Subject: [IMP] beginning of searchbar integration in graph view (addon web_graph) bzr revid: ged@openerp.com-20131205151945-8yo2vkykztvlru3g --- addons/web_graph/static/src/js/graph.js | 202 ++++++++++++++++++-------------- addons/web_graph/static/src/js/pivot.js | 145 ++++++++++++----------- 2 files changed, 194 insertions(+), 153 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index f1c9b62e137..83f9ee4e33c 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -33,12 +33,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ init: function(parent, dataset, view_id, options) { this._super(parent); + + this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); this.dataset = dataset; + + this.pivot_table = new openerp.web_graph.PivotTable(this.model, dataset.domain); this.set_default_options(options); this.dropdown = null; - this.pivot_table = null; - this.heat_map_mode = false; - this.mode = 'pivot'; + this.mode = 'pivot'; // pivot, bar_chart, line_chart, pie_chart, heatmap, row_heatmap, col_heatmap this.measure = null; this.measure_list = []; this.important_fields = []; @@ -48,6 +50,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ get_domain: function () { }, get_groupby: function () { }, }; + this.groupby_mode = 'default'; // 'default' or 'manual' + this.default_row_groupby = []; }, start: function () { @@ -64,8 +68,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_loading: function (fields_view_get) { var self = this, - model = new instance.web.Model(fields_view_get.model, {group_by_no_leaf: true}), - row_groupby = []; + measure = null; if (fields_view_get.arch.attrs.type === 'bar') { this.mode = 'bar_chart'; @@ -77,17 +80,18 @@ instance.web_graph.GraphView = instance.web.View.extend({ if ('operator' in field.attrs) { self.measure_list.push(field.attrs.name); } else { - row_groupby.push(field.attrs.name); + self.default_row_groupby.push(field.attrs.name); } } }); if (this.measure_list.length > 0) { - this.measure = this.measure_list[0]; + measure = this.measure_list[0]; + this.pivot_table.set_measure(measure); } // get the most important fields (of the model) by looking at the // groupby filters defined in the search view - var options = {model:model, view_type: 'search'}, + var options = {model:this.model, view_type: 'search'}, deferred1 = instance.web.fields_view_get(options).then(function (search_view) { var groups = _.select(search_view.arch.children, function (c) { return (c.tag == 'group') && (c.attrs.string != 'Display'); @@ -103,8 +107,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); // get the fields descriptions from the model - var deferred2 = model.call('fields_get', []).then(function (fs) { - self.fields = fs; + var deferred2 = this.model.call('fields_get', []).then(function (fs) { + self.fields = fs; var measure_selection = self.$('.graph_measure_selection'); _.each(self.measure_list, function (measure) { var choice = $('').attr('data-choice', measure) @@ -115,51 +119,41 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); }); - return $.when(deferred1, deferred2).then(function () { - var data = { - model: model, - domain: [], - measure: self.measure, - col_groupby: [], - row_groupby: row_groupby, - }; - self.pivot_table = new openerp.web_graph.PivotTable(data); - }); + return $.when(deferred1, deferred2); }, do_search: function (domain, context, group_by) { - console.log("START DO SEARCH",group_by); - var self = this; + var self = this, + col_groupby = get_col_groupby('ColGroupBy'); - this.pivot_table.domain = domain; - if (group_by.length > 0) { - this.pivot_table.set_groupby(this.pivot_table.rows, group_by) - .done(this.proxy('display_data')); - } else { - this.pivot_table.update_values().done(this.proxy('display_data')); + if (group_by.length || col_groupby.length) { + this.groupby_mode = 'manual'; + if (!group_by.length) { + group_by = this.default_row_groupby; + } } - var colgroupby = get_search_col_groupby(); - console.log ("colgroupby", colgroupby); - console.log("pivot cbh",this.pivot_table.cols.groupby); - - if (!_.isEqual(colgroupby, this.pivot_table.cols.groupby)) { - // console.log ('yop'); - // this.pivot_table.set_groupby(this.pivot_table.cols, colgroupby) - // .done(this.proxy('display_data')); + this.pivot_table.set_domain(domain); + if (this.groupby_mode === 'manual') { + this.pivot_table.set_row_groupby(group_by); + this.pivot_table.set_col_groupby(col_groupby); + } else { + this.pivot_table.set_row_groupby(this.default_row_groupby); + this.pivot_table.set_col_groupby([]); } - // console.log("query",this.search_view.query.models); - function get_search_col_groupby() { - var colgroupby = [], + this.display_data(); + + function get_col_groupby() { + var groupby = [], search = _.find(self.search_view.query.models, function (model) { return model.attributes.category == 'ColGroupBy'; }); if (search) { - colgroupby = _.map(search.values.models, function (val) { + groupby = _.map(search.values.models, function (val) { return val.attributes.value; }); } - return colgroupby; + return groupby; } }, @@ -169,21 +163,25 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, display_data: function () { - console.log('displaying data'); - this.$('.graph_main_content svg').remove(); - this.table.empty(); - - if (this.pivot_table.no_data) { - var msg = 'No data available. Try to remove any filter or add some data.'; - this.table.append($('' + msg + '')); + var pivot = this.pivot_table; + if (pivot.stale_data) { + pivot.update_data().done(this.proxy('display_data')); } else { - var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; - if (_.contains(table_modes, this.mode)) { - this.draw_table(); + this.$('.graph_main_content svg').remove(); + this.table.empty(); + + if (pivot.no_data) { + var msg = 'No data available. Try to remove any filter or add some data.'; + this.table.append($('' + msg + '')); } else { - this.$('.graph_main_content').append($('
    ')); - var svg = this.$('.graph_main_content svg')[0]; - openerp.web_graph.draw_chart(this.mode, this.pivot_table, svg); + var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; + if (_.contains(table_modes, this.mode)) { + this.draw_table(); + } else { + this.$('.graph_main_content').append($('
    ')); + var svg = this.$('.graph_main_content svg')[0]; + openerp.web_graph.draw_chart(this.mode, this.pivot_table, svg); + } } } }, @@ -221,8 +219,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.mode = mode; this.display_data(); // console.log('yop'); - // var self = this; - // var attr = [{label: self.fields['user_id'].string, value: 'user_id'}]; // var attr2 = [{label: self.fields['user_id'].string, value: { // attrs: {domain: [], context: {'group_by':'user_id'}} // }}]; @@ -234,24 +230,48 @@ instance.web_graph.GraphView = instance.web.View.extend({ // }; // // console.log("rnst",self.search_view); + // var self = this; + // var attr = [{label: self.fields['user_id'].string, value: 'user_id'}]; // var test = { // values: attr, // icon: 'u', // field: self.search_field, // category: _t("ColGroupBy"), // }; - // self.search_view.query.add(test); + // self.search_view.query.add(test); // self.search_view.query.add(groupbytest, {}); }, + register_groupby: function (category, field) { + var groupby; + if (category === 'ColGroupBy') { + groupby = { + category: 'ColGroupBy', + values: [{label: this.fields[field].string, value: field}], + icon: 'u', + field: this.search_field, + }; + this.search_view.query.add(groupby); + } + if (category === 'GroupBy') { + var value = {attrs: {domain: [], context: {'group_by':field}}}; + groupby = { + category: 'GroupBy', + values: [{label: this.fields[field].string, value: value}], + icon: 'u', + field: this.search_view._s_groupby, + }; + this.search_view.query.add(groupby); + } + }, measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; this.measure = (measure === '__count') ? null : measure; - this.pivot_table.set_measure(this.measure) - .then(this.proxy('display_data')); + this.pivot_table.set_measure(this.measure); + this.display_data(); }, expand_selection: function (event) { @@ -270,7 +290,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.display_data(); break; case 'expand_all': - this.pivot_table.expand_all().then(this.proxy('display_data')); + this.pivot_table.invalidate_data(); + this.display_data(); break; } }, @@ -283,7 +304,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.display_data(); break; case 'update_values': - this.pivot_table.update_values().then(this.proxy('display_data')); + this.pivot_table.stale_data = true; + this.display_data(); break; case 'export_data': // Export code... To do... @@ -306,32 +328,38 @@ instance.web_graph.GraphView = instance.web.View.extend({ event.preventDefault(); this.pivot_table.expand(id, field_id).then(function () { - var attr = [{label: self.fields[field_id].string, value: field_id}]; - var attr2 = [{label: self.fields[field_id].string, value: { - attrs: {domain: [], context: {'group_by':'stage_id'}} - }}]; - - var test = { - values: attr, - icon: 'u', - field: self.search_field, - category: _t("ColGroupBy"), - }; - - var groupbytest = { - category: 'GroupBy', - values: attr2, - icon: 'u', - field: self.search_view._s_groupby, - }; - - // console.log("rnst",self.search_view); - console.log('BEF ADD CGB'); - // self.search_view.query.add(test); - console.log('BEF ADD RGB'); - // self.search_view.query.add(groupbytest, {}); - console.log('AFTER ADD GB'); - self.display_data(); + if (self.pivot_table.is_col(id)) { + self.register_groupby('ColGroupBy', field_id); + } else { + self.register_groupby('GroupBy', field_id); + // self.display_data(); + } + // var attr = [{label: self.fields[field_id].string, value: field_id}]; + // var attr2 = [{label: self.fields[field_id].string, value: { + // attrs: {domain: [], context: {'group_by':'stage_id'}} + // }}]; + + // var test = { + // values: attr, + // icon: 'u', + // field: self.search_field, + // category: _t("ColGroupBy"), + // }; + + // var groupbytest = { + // category: 'GroupBy', + // values: attr2, + // icon: 'u', + // field: self.search_view._s_groupby, + // }; + + // // console.log("rnst",self.search_view); + // console.log('BEF ADD CGB'); + // // self.search_view.query.add(test); + // console.log('BEF ADD RGB'); + // // self.search_view.query.add(groupbytest, {}); + // console.log('AFTER ADD GB'); + // self.display_data(); }); }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index f412d59474b..5446fd36fb3 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -8,19 +8,17 @@ 'use strict'; openerp.web_graph.PivotTable = openerp.web.Class.extend({ - init: function (options) { - this.rows = { groupby: options.row_groupby }; - this.cols = { groupby: [] }; + init: function (model, domain) { + this.rows = { groupby: [], main: null, headers: null }; + this.cols = { groupby: [], main: null, headers: null }; this.cells = []; - this.model = options.model; - this.domain = options.domain; - this.measure = options.measure; + this.model = model; + this.domain = domain; + this.measure = null; + this.id_seed = 0; this.no_data = true; - }, - - start: function () { - return this.expand_all(); + this.stale_data = true; }, generate_id: function () { @@ -36,6 +34,34 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return result; }, + set_domain: function (domain) { + if (!_.isEqual(domain, this.domain)) { + this.domain = domain; + this.stale_data = true; + } + }, + + set_measure: function (measure) { + if (measure !== this.measure) { + this.measure = measure; + this.stale_data = true; + } + }, + + set_row_groupby: function (groupby) { + if (!_.isEqual(groupby, this.rows.groupby)) { + this.rows.groupby = groupby; + this.stale_data = true; + } + }, + + set_col_groupby: function (groupby) { + if (!_.isEqual(groupby, this.cols.groupby)) { + this.cols.groupby = groupby; + this.stale_data = true; + } + }, + set_value: function (id1, id2, value) { var x = Math.min(id1, id2), y = Math.max(id1, id2), @@ -58,11 +84,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return (cell === undefined) ? undefined : cell.value; }, - set_measure: function (measure) { - this.measure = measure; - return this.update_values(); - }, - is_row: function (id) { return !!_.find(this.rows.headers, function (header) { return header.id == id; @@ -118,26 +139,26 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var other = _.find(otherDim.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) { - if (self.measure) { - self.set_value(new_header_id, other.id, data.attributes.aggregates[self.measure]); - } else { - self.set_value(new_header_id, other.id, data.attributes.length); - } - } - }); - }); - header.is_expanded = true; - }); + } else { + return _.isEqual(_.rest(data.path), h.path); + } + }); + if (other) { + if (self.measure) { + self.set_value(new_header_id, other.id, data.attributes.aggregates[self.measure]); + } else { + self.set_value(new_header_id, other.id, data.attributes.length); + } + } + }); + }); + header.is_expanded = true; + }); }, make_header: function (groups, parent) { var name = groups[0].attributes.value[1], - new_header = { + new_header = { id: this.generate_id(), path: parent.path.concat(name), title: name, @@ -171,21 +192,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.fold_cols(); }, - expand_all: function () { - var self = this; - return this.query_all_values().then(function (result) { - if (result) { - self.no_data = false; - self.expand_headers(self.rows, result.row_headers); - self.expand_headers(self.cols, result.col_headers); - self.cells = result.cells; - } else { - self.no_data = true; - } - - }); - }, - expand_headers: function (root, new_headers) { root.headers = new_headers; root.main = new_headers[0]; @@ -229,27 +235,36 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } }, + invalidate_data: function () { + this.cells = null; + this.rows.main = null; + this.cols.main = null; + this.rows.headers = null; + this.cols.headers = null; + this.stale_data = true; + }, - update_values: function () { - if (!this.rows.headers) { - return this.expand_all(); - } + update_data: function () { var self = this; return this.query_all_values().then(function (result) { - if (!result) { - return undefined; + self.stale_data = false; + if (result) { + self.no_data = false; + if (self.cols.headers) { + self.update_headers(self.cols, result.col_headers); + self.update_headers(self.rows, result.row_headers); + } else { + self.expand_headers(self.cols, result.col_headers); + self.expand_headers(self.rows, result.row_headers); + } + self.cells = result.cells; + } else { + self.no_data = true; } - self.no_data = false; - self.update_headers(self.cols, result.col_headers); - self.update_headers(self.rows, result.row_headers); - self.cells = result.cells; }); }, update_headers: function (root, new_headers) { - if (!root.main) { - return this.expand_headers(root, new_headers); - } _.each(root.headers, function (header) { var corresponding_header = _.find(new_headers, function (h) { return _.isEqual(h.path, header.path); @@ -279,7 +294,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ // this method is a little tricky. In order 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) + // 2 + min(row.groupby.length, col.groupby.length) // calls to readgroup. For example, if row.groupby = [r1, r2, r3] and // col.groupby = [c1, c2, c3, c4], then a minimal set of calls is done // with the following groupby: @@ -317,10 +332,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ row_data = _.last(_.initial(args)), cell_data = args; - if (total === undefined) { self.no_data = true;} - return (total === undefined) - ? undefined - : self.format_data(total, col_data, row_data, cell_data); + return (total === undefined) ? undefined + : self.format_data(total, col_data, row_data, cell_data); }); }, @@ -343,8 +356,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } return {col_headers: col_headers, - row_headers: row_headers, - cells: cells}; + row_headers: row_headers, + cells: cells}; function make_headers (data, depth) { var main = { -- cgit v1.2.3 From d1caee2a5f04ff5919e5a6f1240a867832a480f6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 6 Dec 2013 13:44:37 +0100 Subject: [IMP] supports search bar integration in graph view (but not everything works yet) (addon web_graph) bzr revid: ged@openerp.com-20131206124437-8m1gnhz3ill6w1eo --- addons/web_graph/static/src/js/graph.js | 164 ++++++++++++++++++-------------- addons/web_graph/static/src/js/pivot.js | 30 +----- 2 files changed, 97 insertions(+), 97 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 83f9ee4e33c..bd4842eac41 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -123,14 +123,20 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { + console.log('dgb', this.default_row_groupby); + if (this.groupby_mode === 'getting_ready') { + this.groupby_mode = 'manual'; + return; + } + var self = this, col_groupby = get_col_groupby('ColGroupBy'); if (group_by.length || col_groupby.length) { this.groupby_mode = 'manual'; - if (!group_by.length) { - group_by = this.default_row_groupby; - } + // if (!group_by.length) { + // group_by = this.default_row_groupby; + // } } this.pivot_table.set_domain(domain); @@ -138,7 +144,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table.set_row_groupby(group_by); this.pivot_table.set_col_groupby(col_groupby); } else { - this.pivot_table.set_row_groupby(this.default_row_groupby); + this.pivot_table.set_row_groupby(_.toArray(this.default_row_groupby)); this.pivot_table.set_col_groupby([]); } this.display_data(); @@ -190,15 +196,37 @@ instance.web_graph.GraphView = instance.web.View.extend({ /****************************************************************************** * Event handling methods... ******************************************************************************/ - handle_header_event: function (options) { var pivot = this.pivot_table, id = options.id, - header = pivot.get_header(id); + header = pivot.get_header(id), + dim = header.root.groupby.length; + console.log('test'); + // debugger; if (header.is_expanded) { + this.groupby_mode = 'manual'; pivot.fold(header); - this.display_data(); + if (header.root.groupby.length < dim) { + if (pivot.is_row(header.id)) { + this.clear_groupby('GroupBy'); + if (header.root.groupby.length) { + this.register_groupby('GroupBy', header.root.groupby); + } else { + + this.display_data(); + } + } else { + this.clear_groupby('ColGroupBy'); + if (header.root.groupby.length) { + this.register_groupby('ColGroupBy', header.root.groupby); + } else { + this.display_data(); + } + } + } else { + this.display_data(); + } } else { if (header.path.length < header.root.groupby.length) { var field = header.root.groupby[header.path.length]; @@ -212,60 +240,60 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }, - mode_selection: function (event) { event.preventDefault(); var mode = event.target.attributes['data-mode'].nodeValue; this.mode = mode; this.display_data(); - // console.log('yop'); - // var attr2 = [{label: self.fields['user_id'].string, value: { - // attrs: {domain: [], context: {'group_by':'user_id'}} - // }}]; - // var groupbytest = { - // category: 'GroupBy', - // values: attr2, - // icon: 'u', - // field: self.search_view._s_groupby, - // }; - - // // console.log("rnst",self.search_view); - // var self = this; - // var attr = [{label: self.fields['user_id'].string, value: 'user_id'}]; - // var test = { - // values: attr, - // icon: 'u', - // field: self.search_field, - // category: _t("ColGroupBy"), - // }; - // self.search_view.query.add(test); - // self.search_view.query.add(groupbytest, {}); }, register_groupby: function (category, field) { - var groupby; + var self = this, + values, + groupby; if (category === 'ColGroupBy') { + if (!(field instanceof Array)) { + field = [field]; + } + values = _.map(field, function (f) { + return {label: self.fields[f].string, value: f}; + }); + // values = [{label: this.fields[field].string, value: field}]; groupby = { category: 'ColGroupBy', - values: [{label: this.fields[field].string, value: field}], - icon: 'u', + values: values, + icon: 'f', field: this.search_field, }; this.search_view.query.add(groupby); } if (category === 'GroupBy') { - var value = {attrs: {domain: [], context: {'group_by':field}}}; + if (!(field instanceof Array)) { + field = [field]; + } + values = _.map(field, function (f) { + return {label: self.fields[f].string, value: {attrs:{domain: [], context: {'group_by':f}}}}; + }); + // var value = {attrs: {domain: [], context: {'group_by':field}}}; + // var value2 = {attrs: {domain: [], context: {'group_by':'user_id'}}}; [{label: this.fields[field].string, value: value}, {label: 'test', value:value2}] groupby = { category: 'GroupBy', - values: [{label: this.fields[field].string, value: value}], - icon: 'u', + values: values, + icon: 'w', field: this.search_view._s_groupby, }; this.search_view.query.add(groupby); } }, + clear_groupby: function (category) { + // debugger; + this.search_view.query.models = _.filter(this.search_view.query.models, function (model) { + return model.attributes.category !== category; + }); + }, + measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; @@ -297,11 +325,27 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, option_selection: function (event) { + var pivot = this.pivot_table; event.preventDefault(); switch (event.target.attributes['data-choice'].nodeValue) { case 'swap_axis': this.pivot_table.swap_axis(); - this.display_data(); + this.clear_groupby('GroupBy'); + this.clear_groupby('ColGroupBy'); + if (pivot.rows.groupby.length && pivot.cols.groupby.length) { + this.groupby_mode = 'getting_ready'; + this.register_groupby('GroupBy', pivot.rows.groupby); + this.register_groupby('ColGroupBy', pivot.cols.groupby); + } else { + this.groupby_mode = 'manual'; + if (pivot.rows.groupby.length) { + this.register_groupby('GroupBy', pivot.rows.groupby); + } else { + this.register_groupby('ColGroupBy', pivot.cols.groupby); + } + } + + // this.display_data(); break; case 'update_values': this.pivot_table.stale_data = true; @@ -328,38 +372,21 @@ instance.web_graph.GraphView = instance.web.View.extend({ event.preventDefault(); this.pivot_table.expand(id, field_id).then(function () { - if (self.pivot_table.is_col(id)) { - self.register_groupby('ColGroupBy', field_id); + + if (self.pivot_table.is_row(id)) { + if (self.groupby_mode === 'default') { + self.groupby_mode = 'manual'; + self.register_groupby('GroupBy', self.default_row_groupby.concat([field_id])); + } else { + self.register_groupby('GroupBy', field_id); + } } else { - self.register_groupby('GroupBy', field_id); - // self.display_data(); + if (self.groupby_mode === 'default') { + self.groupby_mode = 'getting_ready'; + self.register_groupby('GroupBy', self.default_row_groupby); + } + self.register_groupby('ColGroupBy', field_id); } - // var attr = [{label: self.fields[field_id].string, value: field_id}]; - // var attr2 = [{label: self.fields[field_id].string, value: { - // attrs: {domain: [], context: {'group_by':'stage_id'}} - // }}]; - - // var test = { - // values: attr, - // icon: 'u', - // field: self.search_field, - // category: _t("ColGroupBy"), - // }; - - // var groupbytest = { - // category: 'GroupBy', - // values: attr2, - // icon: 'u', - // field: self.search_view._s_groupby, - // }; - - // // console.log("rnst",self.search_view); - // console.log('BEF ADD CGB'); - // // self.search_view.query.add(test); - // console.log('BEF ADD RGB'); - // // self.search_view.query.add(groupbytest, {}); - // console.log('AFTER ADD GB'); - // self.display_data(); }); }, @@ -385,7 +412,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ /****************************************************************************** * Drawing pivot table methods... ******************************************************************************/ - draw_table: function () { this.pivot_table.rows.main.title = 'Total'; this.pivot_table.cols.main.title = this.measure_label(); @@ -522,6 +548,4 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, }); - - }; diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 5446fd36fb3..8748de7dda0 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -51,14 +51,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ set_row_groupby: function (groupby) { if (!_.isEqual(groupby, this.rows.groupby)) { this.rows.groupby = groupby; - this.stale_data = true; + this.invalidate_data(); } }, set_col_groupby: function (groupby) { if (!_.isEqual(groupby, this.cols.groupby)) { this.cols.groupby = groupby; - this.stale_data = true; + this.invalidate_data(); } }, @@ -201,31 +201,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, - set_groupby: function (root, groupby) { - var self = this; - var other_root = (root === this.cols) ? this.rows : this.cols; - - root.groupby = groupby; - return this.query_all_values().then(function (result) { - if (result) { - var new_root_headers, new_other_root_headers; - if (root === this.cols) { - new_root_headers = result.col_headers; - new_other_root_headers = result.how_headers; - } else { - new_root_headers = result.row_headers; - new_other_root_headers = result.col_headers; - } - self.no_data = false; - self.expand_headers(root, new_root_headers); - self.update_headers(other_root, new_other_root_headers); - self.cells = result.cells; - } else { - self.no_data = true; - } - }); - }, - get_total: function (header) { if (header) { var main = (header.root === this.rows) ? this.cols.main : this.rows.main; @@ -265,6 +240,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, update_headers: function (root, new_headers) { + console.log('updateheader', root, new_headers); _.each(root.headers, function (header) { var corresponding_header = _.find(new_headers, function (h) { return _.isEqual(h.path, header.path); -- cgit v1.2.3 From 6a06f0d0eeee1efe7417d3a73eb2e4b8661d73d6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 6 Dec 2013 16:43:19 +0100 Subject: [IMP] properly supports searchbar integration in graph view (addon web_graph) bzr revid: ged@openerp.com-20131206154319-6ci7ljmp2hd9q072 --- addons/web_graph/static/src/js/graph.js | 161 ++++++++++---------------------- addons/web_graph/static/src/js/pivot.js | 1 - 2 files changed, 47 insertions(+), 115 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index bd4842eac41..344899032d6 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -4,7 +4,6 @@ /* jshint undef: false */ - openerp.web_graph = function (instance) { 'use strict'; @@ -33,10 +32,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ init: function(parent, dataset, view_id, options) { this._super(parent); - this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); this.dataset = dataset; - this.pivot_table = new openerp.web_graph.PivotTable(this.model, dataset.domain); this.set_default_options(options); this.dropdown = null; @@ -45,13 +42,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.measure_list = []; this.important_fields = []; this.search_view = parent.searchview; - this.search_field = { - get_context: function () { }, - get_domain: function () { }, - get_groupby: function () { }, - }; this.groupby_mode = 'default'; // 'default' or 'manual' this.default_row_groupby = []; + this.search_field = { + get_context: function () { }, + get_domain: function () { }, + get_groupby: function () { }, + }; }, start: function () { @@ -123,12 +120,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { - console.log('dgb', this.default_row_groupby); - if (this.groupby_mode === 'getting_ready') { - this.groupby_mode = 'manual'; - return; - } - var self = this, col_groupby = get_col_groupby('ColGroupBy'); @@ -156,7 +147,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); if (search) { groupby = _.map(search.values.models, function (val) { - return val.attributes.value; + return val.attributes.value.attrs.context.col_group_by; }); } return groupby; @@ -202,35 +193,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ header = pivot.get_header(id), dim = header.root.groupby.length; - console.log('test'); - // debugger; if (header.is_expanded) { - this.groupby_mode = 'manual'; pivot.fold(header); - if (header.root.groupby.length < dim) { - if (pivot.is_row(header.id)) { - this.clear_groupby('GroupBy'); - if (header.root.groupby.length) { - this.register_groupby('GroupBy', header.root.groupby); - } else { - - this.display_data(); - } - } else { - this.clear_groupby('ColGroupBy'); - if (header.root.groupby.length) { - this.register_groupby('ColGroupBy', header.root.groupby); - } else { - this.display_data(); - } - } - } else { - this.display_data(); - } + this.register_groupby(); } else { if (header.path.length < header.root.groupby.length) { var field = header.root.groupby[header.path.length]; - pivot.expand(id, field).then(this.proxy('display_data')); + pivot.expand(id, field).then(this.proxy('register_groupby')); } else { this.display_dropdown({id:header.id, target: $(options.event.target), @@ -248,52 +217,45 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, - register_groupby: function (category, field) { + register_groupby: function() { var self = this, - values, - groupby; - if (category === 'ColGroupBy') { - if (!(field instanceof Array)) { - field = [field]; - } - values = _.map(field, function (f) { - return {label: self.fields[f].string, value: f}; - }); - // values = [{label: this.fields[field].string, value: field}]; - groupby = { - category: 'ColGroupBy', - values: values, - icon: 'f', - field: this.search_field, - }; - this.search_view.query.add(groupby); - } - if (category === 'GroupBy') { - if (!(field instanceof Array)) { - field = [field]; + query = this.search_view.query; + this.groupby_mode = 'manual'; + + + var rows = _.map(this.pivot_table.rows.groupby, function (group) { + return make_facet('GroupBy', group); + }); + var cols = _.map(this.pivot_table.cols.groupby, function (group) { + return make_facet('ColGroupBy', group); + }); + + query.reset(rows.concat(cols)); + + function make_facet (category, fields) { + var values, + icon, + backbone_field, + cat_name; + if (!(fields instanceof Array)) { fields = [fields]; } + if (category === 'GroupBy') { + cat_name = 'group_by'; + icon = 'w'; + backbone_field = self.search_view._s_groupby; + } else { + cat_name = 'col_group_by'; + icon = 'f'; + backbone_field = self.search_field; } - values = _.map(field, function (f) { - return {label: self.fields[f].string, value: {attrs:{domain: [], context: {'group_by':f}}}}; + values = _.map(fields, function (field) { + var context = {}; + context[cat_name] = field; + return {label: self.fields[field].string, value: {attrs:{domain: [], context: context}}}; }); - // var value = {attrs: {domain: [], context: {'group_by':field}}}; - // var value2 = {attrs: {domain: [], context: {'group_by':'user_id'}}}; [{label: this.fields[field].string, value: value}, {label: 'test', value:value2}] - groupby = { - category: 'GroupBy', - values: values, - icon: 'w', - field: this.search_view._s_groupby, - }; - this.search_view.query.add(groupby); + return {category:category, values: values, icon:icon, field: backbone_field}; } }, - clear_groupby: function (category) { - // debugger; - this.search_view.query.models = _.filter(this.search_view.query.models, function (model) { - return model.attributes.category !== category; - }); - }, - measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; @@ -307,15 +269,15 @@ instance.web_graph.GraphView = instance.web.View.extend({ switch (event.target.attributes['data-choice'].nodeValue) { case 'fold_columns': this.pivot_table.fold_cols(); - this.display_data(); + this.register_groupby(); break; case 'fold_rows': this.pivot_table.fold_rows(); - this.display_data(); + this.register_groupby(); break; case 'fold_all': this.pivot_table.fold_all(); - this.display_data(); + this.register_groupby(); break; case 'expand_all': this.pivot_table.invalidate_data(); @@ -330,28 +292,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ switch (event.target.attributes['data-choice'].nodeValue) { case 'swap_axis': this.pivot_table.swap_axis(); - this.clear_groupby('GroupBy'); - this.clear_groupby('ColGroupBy'); - if (pivot.rows.groupby.length && pivot.cols.groupby.length) { - this.groupby_mode = 'getting_ready'; - this.register_groupby('GroupBy', pivot.rows.groupby); - this.register_groupby('ColGroupBy', pivot.cols.groupby); - } else { - this.groupby_mode = 'manual'; - if (pivot.rows.groupby.length) { - this.register_groupby('GroupBy', pivot.rows.groupby); - } else { - this.register_groupby('ColGroupBy', pivot.cols.groupby); - } - } - - // this.display_data(); + this.register_groupby(); break; case 'update_values': this.pivot_table.stale_data = true; this.display_data(); break; case 'export_data': + this.register_groupby(); // Export code... To do... break; } @@ -371,22 +319,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ field_id = event.target.attributes['data-field-id'].nodeValue; event.preventDefault(); this.pivot_table.expand(id, field_id).then(function () { - - - if (self.pivot_table.is_row(id)) { - if (self.groupby_mode === 'default') { - self.groupby_mode = 'manual'; - self.register_groupby('GroupBy', self.default_row_groupby.concat([field_id])); - } else { - self.register_groupby('GroupBy', field_id); - } - } else { - if (self.groupby_mode === 'default') { - self.groupby_mode = 'getting_ready'; - self.register_groupby('GroupBy', self.default_row_groupby); - } - self.register_groupby('ColGroupBy', field_id); - } + self.register_groupby(); }); }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 8748de7dda0..b334dbe32aa 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -240,7 +240,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, update_headers: function (root, new_headers) { - console.log('updateheader', root, new_headers); _.each(root.headers, function (header) { var corresponding_header = _.find(new_headers, function (h) { return _.isEqual(h.path, header.path); -- cgit v1.2.3 From 5c04caf2ee2050bb0607f3ebf066e744b398d21f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 6 Dec 2013 17:04:11 +0100 Subject: [REF] many small code cleanups in addon web_graph bzr revid: ged@openerp.com-20131206160411-9ajcschidssftb49 --- addons/web_graph/static/src/js/graph.js | 17 +++++------------ addons/web_graph/static/src/js/pivot.js | 19 +++---------------- 2 files changed, 8 insertions(+), 28 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 344899032d6..8cf0ffd4877 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -38,7 +38,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.set_default_options(options); this.dropdown = null; this.mode = 'pivot'; // pivot, bar_chart, line_chart, pie_chart, heatmap, row_heatmap, col_heatmap - this.measure = null; this.measure_list = []; this.important_fields = []; this.search_view = parent.searchview; @@ -125,9 +124,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (group_by.length || col_groupby.length) { this.groupby_mode = 'manual'; - // if (!group_by.length) { - // group_by = this.default_row_groupby; - // } } this.pivot_table.set_domain(domain); @@ -214,7 +210,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ var mode = event.target.attributes['data-mode'].nodeValue; this.mode = mode; this.display_data(); - }, register_groupby: function() { @@ -222,7 +217,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ query = this.search_view.query; this.groupby_mode = 'manual'; - var rows = _.map(this.pivot_table.rows.groupby, function (group) { return make_facet('GroupBy', group); }); @@ -259,8 +253,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; - this.measure = (measure === '__count') ? null : measure; - this.pivot_table.set_measure(this.measure); + this.pivot_table.set_measure((measure === '__count') ? null : measure); this.display_data(); }, @@ -276,7 +269,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.register_groupby(); break; case 'fold_all': - this.pivot_table.fold_all(); + this.pivot_table.fold_cols(); + this.pivot_table.fold_rows(); this.register_groupby(); break; case 'expand_all': @@ -287,7 +281,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, option_selection: function (event) { - var pivot = this.pivot_table; event.preventDefault(); switch (event.target.attributes['data-choice'].nodeValue) { case 'swap_axis': @@ -299,7 +292,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.display_data(); break; case 'export_data': - this.register_groupby(); // Export code... To do... break; } @@ -353,7 +345,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, measure_label: function () { - return (this.measure) ? this.fields[this.measure].string : 'Quantity'; + var pivot = this.pivot_table; + return (pivot.measure) ? this.fields[pivot.measure].string : 'Quantity'; }, make_border_cell: function (colspan, rowspan) { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index b334dbe32aa..10bbf6a7240 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -1,9 +1,6 @@ /* jshint undef: false */ - -// TO DO : use _.uniqueID() - (function () { 'use strict'; @@ -21,11 +18,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.stale_data = true; }, - generate_id: function () { - this.id_seed += 1; - return this.id_seed; - }, - visible_fields: function () { var result = this.rows.groupby.concat(this.cols.groupby); if (this.measure) { @@ -159,7 +151,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ make_header: function (groups, parent) { var name = groups[0].attributes.value[1], new_header = { - id: this.generate_id(), + id: _.uniqueId(), path: parent.path.concat(name), title: name, is_expanded: false, @@ -187,11 +179,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.fold(this.cols.main); }, - fold_all: function () { - this.fold_rows(); - this.fold_cols(); - }, - expand_headers: function (root, new_headers) { root.headers = new_headers; root.main = new_headers[0]; @@ -336,7 +323,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ function make_headers (data, depth) { var main = { - id: self.generate_id(), + id: _.uniqueId(), path: [], parent: null, children: [], @@ -367,7 +354,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ function make_tree_headers (data_pt, parent, max_depth) { var node = { - id: self.generate_id(), + id: _.uniqueId(), path: parent.path.concat(data_pt.attributes.value[1]), title: data_pt.attributes.value[1], domain: data_pt.model._domain, -- cgit v1.2.3 From 476d0f4f38e597cf7479d6245d4eab4955d7a0c6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 6 Dec 2013 17:23:01 +0100 Subject: [FIX] fixes a small bug where the columns would expand all headers when the user clears the rows groupby in the search view (addon web_graph) bzr revid: ged@openerp.com-20131206162301-fbq5mgqhg65yqi96 --- addons/web_graph/static/src/js/pivot.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 10bbf6a7240..9b1901e3817 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -41,6 +41,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, set_row_groupby: function (groupby) { + if ((!groupby.length) && (this.rows.main)) { + this.fold(this.rows.main); + } if (!_.isEqual(groupby, this.rows.groupby)) { this.rows.groupby = groupby; this.invalidate_data(); @@ -48,6 +51,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, set_col_groupby: function (groupby) { + if ((!groupby.length) && (this.cols.main)) { + this.fold(this.cols.main); + } if (!_.isEqual(groupby, this.cols.groupby)) { this.cols.groupby = groupby; this.invalidate_data(); -- cgit v1.2.3 From 65a0a97d67e02b5a659838bf54cd2accb892bc89 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 6 Dec 2013 17:25:49 +0100 Subject: [IMP] usability fix, makes sure that the dropdown menu displayed when expanding a field in graph view has always the same choices (addon web_graph) bzr revid: ged@openerp.com-20131206162549-08aw50z4zdelzxgc --- addons/web_graph/static/src/js/graph.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 8cf0ffd4877..7efc482f2dd 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -179,7 +179,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }, - /****************************************************************************** * Event handling methods... ******************************************************************************/ @@ -318,11 +317,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ display_dropdown: function (options) { var self = this, pivot = this.pivot_table, - already_grouped = pivot.rows.groupby.concat(pivot.cols.groupby), - possible_groups = _.difference(self.important_fields, already_grouped), + // already_grouped = pivot.rows.groupby.concat(pivot.cols.groupby), + // possible_groups = _.difference(self.important_fields, already_grouped), dropdown_options = { header_id: options.id, - fields: _.map(possible_groups, function (field) { + fields: _.map(self.important_fields, function (field) { return {id: field, value: self.fields[field].string}; })}; -- cgit v1.2.3 From 66c8114768376670408a856a3c10bb342b40de5e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 6 Dec 2013 17:26:41 +0100 Subject: [REF] removes two useless lines (addon web_graph) bzr revid: ged@openerp.com-20131206162641-27rerhfa56y6nf4e --- addons/web_graph/static/src/js/graph.js | 3 --- 1 file changed, 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7efc482f2dd..a5de9f2dde7 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -317,14 +317,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ display_dropdown: function (options) { var self = this, pivot = this.pivot_table, - // already_grouped = pivot.rows.groupby.concat(pivot.cols.groupby), - // possible_groups = _.difference(self.important_fields, already_grouped), dropdown_options = { header_id: options.id, fields: _.map(self.important_fields, function (field) { return {id: field, value: self.fields[field].string}; })}; - this.dropdown = $(QWeb.render('field_selection', dropdown_options)); options.target.after(this.dropdown); this.dropdown.css({position:'absolute', -- cgit v1.2.3 From 9f99fbdae7483ae8e73c4f6525ab8f3d23137126 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 9 Dec 2013 14:08:58 +0100 Subject: [FIX] properly writes the col group_by in the context (with the facets) which allows the filter to work correctly, in graph view (addon web_graph) bzr revid: ged@openerp.com-20131209130858-o8pqocw7otpqr8l0 --- addons/web_graph/static/src/js/graph.js | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index a5de9f2dde7..d64918aee56 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -44,12 +44,19 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.groupby_mode = 'default'; // 'default' or 'manual' this.default_row_groupby = []; this.search_field = { - get_context: function () { }, - get_domain: function () { }, + get_context: this.proxy('get_context'), + get_domain: function () {}, get_groupby: function () { }, }; }, + get_context: function (facet) { + var col_group_by = _.map(facet.values.models, function (model) { + return model.attributes.value.attrs.context.col_group_by; + }); + return {col_group_by : col_group_by}; + }, + start: function () { this.table = $('
    '); this.$('.graph_main_content').append(this.table); @@ -120,7 +127,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { var self = this, - col_groupby = get_col_groupby('ColGroupBy'); + col_groupby = context.col_group_by || []; // get_col_groupby('ColGroupBy'); if (group_by.length || col_groupby.length) { this.groupby_mode = 'manual'; @@ -135,19 +142,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table.set_col_groupby([]); } this.display_data(); - - function get_col_groupby() { - var groupby = [], - search = _.find(self.search_view.query.models, function (model) { - return model.attributes.category == 'ColGroupBy'; - }); - if (search) { - groupby = _.map(search.values.models, function (val) { - return val.attributes.value.attrs.context.col_group_by; - }); - } - return groupby; - } }, do_show: function () { -- cgit v1.2.3 From f24a1b487a65dd0d565d536aa2708b315b5845f6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 10 Dec 2013 10:21:25 +0100 Subject: [IMP] improves the chart code to display correct bar chart when no groupby are selected (graph view, addon web_graph) bzr revid: ged@openerp.com-20131210092125-fqv9by5xons81uo1 --- addons/web_graph/static/src/js/charts.js | 150 +++++++++++++++++-------------- 1 file changed, 85 insertions(+), 65 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 5f17cce4aef..8ef16d92b3e 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,78 +1,98 @@ openerp.web_graph.draw_chart = function (mode, pivot, svg) { + openerp.web_graph[mode](pivot, svg); +}; - var data = _.map(pivot.rows.main.children, function (pt) { - var value = pivot.get_value(pt.id, pivot.cols.main.id), - title = (pt.title !== undefined) ? pt.title : 'Undefined'; - return {x: title, y: value}; - }); - - switch (mode) { - case 'bar_chart': - bar_chart(); - break; - case 'line_chart': - line_chart(); - break; - case 'pie_chart': - pie_chart(); - break; - } - function bar_chart () { - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .tooltips(false) - .showValues(true) - .staggerLabels(true) - .width(650) - .height(400); - d3.select(svg) - .datum([{key: 'Bar chart', values:data}]) - .attr('width', 650) - .attr('height', 400) - .call(chart); +openerp.web_graph.bar_chart = function (pivot, svg) { + var dim_x = pivot.rows.groupby.length, + dim_y = pivot.cols.groupby.length, + data; - nv.utils.windowResize(chart.update); - return chart; + if ((dim_x === 0) && (dim_y === 0)) { + data = [{key: 'Expected Revenue', values:[{ + title: 'Total', + value: pivot.get_value(pivot.rows.main.id, pivot.cols.main.id), + }]}]; + // debugger; + } else if ((dim_x === 0) && (dim_y === 1)){ + + } else + { + data = _.map(pivot.rows.main.children, function (pt) { + var value = pivot.get_value(pt.id, pivot.cols.main.id), + title = (pt.title !== undefined) ? pt.title : 'Undefined'; + return {title: title, value: value}; }); - }; + data = [{key: 'Bar chart', values:data}]; + } + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .x(function(d) { return d.title;}) + .y(function(d) { return d.value;}) + .tooltips(false) + .showValues(true) + .staggerLabels(true) + .width(650) + .height(400); + + d3.select(svg) + .datum(data) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); +}; - function line_chart () { - nv.addGraph(function () { - var chart = nv.models.lineChart() - .x(function (d,u) { return u; }) - .width(600) - .height(300) - .margin({top: 30, right: 20, bottom: 20, left: 60}); - d3.select(svg) - .attr('width', 600) - .attr('height', 300) - .datum([{key: 'Bar chart', values: data}]) - .call(chart); +openerp.web_graph.line_chart = function (pivot, svg) { + var data = _.map(pivot.rows.main.children, function (pt) { + var value = pivot.get_value(pt.id, pivot.cols.main.id), + title = (pt.title !== undefined) ? pt.title : 'Undefined'; + return {x: title, y: value}; + }); - return chart; - }); - }; + nv.addGraph(function () { + var chart = nv.models.lineChart() + .x(function (d,u) { return u; }) + .width(600) + .height(300) + .margin({top: 30, right: 20, bottom: 20, left: 60}); - function pie_chart () { - nv.addGraph(function () { - var chart = nv.models.pieChart() - .color(d3.scale.category10().range()) - .width(650) - .height(400); + d3.select(svg) + .attr('width', 600) + .attr('height', 300) + .datum([{key: 'Bar chart', values: data}]) + .call(chart); - d3.select(svg) - .datum(data) - .transition().duration(1200) - .attr('width', 650) - .attr('height', 400) - .call(chart); + return chart; + }); +}; - nv.utils.windowResize(chart.update); - return chart; - }); - }; +openerp.web_graph.pie_chart = function (pivot, svg) { + var data = _.map(pivot.rows.main.children, function (pt) { + var value = pivot.get_value(pt.id, pivot.cols.main.id), + title = (pt.title !== undefined) ? pt.title : 'Undefined'; + return {x: title, y: value}; + }); + + nv.addGraph(function () { + var chart = nv.models.pieChart() + .color(d3.scale.category10().range()) + .width(650) + .height(400); -} + d3.select(svg) + .datum(data) + .transition().duration(1200) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); +}; -- cgit v1.2.3 From fe5543a04335aa9a58dad3654318341776fe9e3e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 10 Dec 2013 11:07:23 +0100 Subject: [IMP] improves the chart code to display correct bar chart when no row groupby are selected and a positive number of col groupbys are selected (graph view, addon web_graph) bzr revid: ged@openerp.com-20131210100723-0arehl16k54wln0z --- addons/web_graph/static/src/js/charts.js | 35 ++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 8ef16d92b3e..b56f06acd9f 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -7,16 +7,43 @@ openerp.web_graph.draw_chart = function (mode, pivot, svg) { openerp.web_graph.bar_chart = function (pivot, svg) { var dim_x = pivot.rows.groupby.length, dim_y = pivot.cols.groupby.length, - data; + data = []; if ((dim_x === 0) && (dim_y === 0)) { data = [{key: 'Expected Revenue', values:[{ title: 'Total', value: pivot.get_value(pivot.rows.main.id, pivot.cols.main.id), }]}]; - // debugger; - } else if ((dim_x === 0) && (dim_y === 1)){ - + } else if ((dim_x === 0) && (dim_y >= 1)){ + _.each(pivot.cols.headers, function (header) { + if (header.path.length === 1) { + data.push({ + key: header.title, + values: [{x:header.root.main.title, y: pivot.get_total(header)}] + }); + } + }); + nv.addGraph(function() { + var chart = nv.models.multiBarChart() + .stacked(true) + .tooltips(false) + .showControls(false) + .width(400) + .height(500); + + d3.select(svg) + .datum(data) + .attr('width', 400) + .attr('height', 500) + .transition() + .duration(500) + .call(chart); + + nv.utils.windowResize(chart.update); + + return chart; + }); + return; } else { data = _.map(pivot.rows.main.children, function (pt) { -- cgit v1.2.3 From 1419b0793939de96bf67fc2e48d05a4fc55773d7 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 10 Dec 2013 12:16:46 +0100 Subject: [IMP] improves the way the chart view understands the xml descr of the view, so that nows fields after the operator = + are considered col groupbys (addon web_graph) bzr revid: ged@openerp.com-20131210111646-9d8l78npv72pqfp8 --- addons/web_graph/static/src/js/graph.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index d64918aee56..e35b8516dd4 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -43,6 +43,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.search_view = parent.searchview; this.groupby_mode = 'default'; // 'default' or 'manual' this.default_row_groupby = []; + this.default_col_groupby = []; this.search_field = { get_context: this.proxy('get_context'), get_domain: function () {}, @@ -83,7 +84,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ if ('operator' in field.attrs) { self.measure_list.push(field.attrs.name); } else { - self.default_row_groupby.push(field.attrs.name); + if (self.measure_list.length) { + self.default_col_groupby.push(field.attrs.name); + } else { + self.default_row_groupby.push(field.attrs.name); + } } } }); @@ -139,7 +144,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.pivot_table.set_col_groupby(col_groupby); } else { this.pivot_table.set_row_groupby(_.toArray(this.default_row_groupby)); - this.pivot_table.set_col_groupby([]); + this.pivot_table.set_col_groupby(_.toArray(this.default_col_groupby)); } this.display_data(); }, -- cgit v1.2.3 From 28f27da6387b3f852cc2bc0408e2fd9f21b88d0a Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 10 Dec 2013 16:39:51 +0100 Subject: [IMP] makes the graph view much smarter about the way it displays bar charts depending on the various groupby compbinations (addon web_graph) bzr revid: ged@openerp.com-20131210153951-d36yymirvo09wbxd --- addons/web_graph/static/src/js/charts.js | 143 ++++++++++++++++++++++++++----- addons/web_graph/static/src/js/pivot.js | 4 +- 2 files changed, 123 insertions(+), 24 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index b56f06acd9f..b714e42392e 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -9,11 +9,32 @@ openerp.web_graph.bar_chart = function (pivot, svg) { dim_y = pivot.cols.groupby.length, data = []; + // No groupby ************************************************************** if ((dim_x === 0) && (dim_y === 0)) { - data = [{key: 'Expected Revenue', values:[{ + data = [{key: 'Total', values:[{ title: 'Total', value: pivot.get_value(pivot.rows.main.id, pivot.cols.main.id), }]}]; + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .x(function(d) { return d.title;}) + .y(function(d) { return d.value;}) + .tooltips(false) + .showValues(true) + .staggerLabels(true) + .width(650) + .height(400); + + d3.select(svg) + .datum(data) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + // Only column groupbys **************************************************** } else if ((dim_x === 0) && (dim_y >= 1)){ _.each(pivot.cols.headers, function (header) { if (header.path.length === 1) { @@ -43,35 +64,113 @@ openerp.web_graph.bar_chart = function (pivot, svg) { return chart; }); - return; - } else - { + // Just 1 row groupby ****************************************************** + } else if ((dim_x === 1) && (dim_y === 0)) { data = _.map(pivot.rows.main.children, function (pt) { var value = pivot.get_value(pt.id, pivot.cols.main.id), title = (pt.title !== undefined) ? pt.title : 'Undefined'; return {title: title, value: value}; }); data = [{key: 'Bar chart', values:data}]; - } - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .x(function(d) { return d.title;}) - .y(function(d) { return d.value;}) - .tooltips(false) - .showValues(true) - .staggerLabels(true) - .width(650) - .height(400); + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .x(function(d) { return d.title;}) + .y(function(d) { return d.value;}) + .tooltips(false) + .showValues(true) + .staggerLabels(true) + .width(650) + .height(400); - d3.select(svg) - .datum(data) - .attr('width', 650) - .attr('height', 400) - .call(chart); + d3.select(svg) + .datum(data) + .attr('width', 650) + .attr('height', 400) + .call(chart); - nv.utils.windowResize(chart.update); - return chart; - }); + nv.utils.windowResize(chart.update); + return chart; + }); + // 1 row groupby and some col groupbys************************************** + } else if ((dim_x === 1) && (dim_y >= 1)) { + data = []; + _.each(pivot.cols.headers, function (colhdr) { + if (colhdr.path.length === 1) { + var values = []; + _.each(pivot.rows.headers, function (header) { + if (header.path.length === 1) { + values.push({ + x: header.title || 'Undefined', + y: pivot.get_value(header.id, colhdr.id, 0) + }); + } + }); + data.push({key: colhdr.title || 'Undefined', values: values}); + } + }); + + nv.addGraph(function () { + var chart = nv.models.multiBarChart() + .stacked(true) + .staggerLabels(true) + .tooltips(false) + .width(650) + .height(400); + + d3.select(svg) + .datum(data) + .attr('width', 650) + .attr('height', 400) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + // At least two row groupby************************************************* + } else { + data = []; + var keys = _.uniq(_.map(_.filter(pivot.rows.headers, function (hdr) { + return hdr.path.length === 2; + }), function (hdr) { + return hdr.title || 'Undefined'; + })); + data = _.map(keys, function (key) { + var values = []; + _.each(pivot.rows.headers, function (hdr) { + if (hdr.path.length === 1) { + var subhdr = _.find(hdr.children, function (child) { + return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); + }); + values.push({ + x: hdr.title || 'Undefined', + y: (subhdr) ? pivot.get_total(subhdr) : 0 + }); + } + }); + + return {key:key, values: values}; + }); + + nv.addGraph(function () { + var chart = nv.models.multiBarChart() + .stacked(true) + .staggerLabels(true) + .tooltips(false) + .transitionDuration(0) + .width(650) + .height(400); + + d3.select(svg) + .datum(data) + .attr('width', 650) + .attr('height', 400) + .call(chart); + debugger; + + nv.utils.windowResize(chart.update); + return chart; + }); + } }; diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 9b1901e3817..b73939193a0 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -73,13 +73,13 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } }, - get_value: function (id1, id2) { + get_value: function (id1, id2, default_value) { var x = Math.min(id1, id2), y = Math.max(id1, id2), cell = _.find(this.cells, function (c) { return ((c.x == x) && (c.y == y)); }); - return (cell === undefined) ? undefined : cell.value; + return (cell === undefined) ? default_value : cell.value; }, is_row: function (id) { -- cgit v1.2.3 From 4416acaa5391860a010a03a05d82fa7c5f6b9b57 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 11:12:24 +0100 Subject: [IMP] makes line charts smarter when multiple columns exists, in graph view (addon web_graph) bzr revid: ged@openerp.com-20131211101224-eul3hvm0dt7kdz41 --- addons/web_graph/static/src/js/charts.js | 32 ++++++++++++++++++++------------ addons/web_graph/static/src/js/graph.js | 2 +- addons/web_graph/static/src/js/pivot.js | 14 ++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index b714e42392e..7478668865c 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,10 +1,10 @@ -openerp.web_graph.draw_chart = function (mode, pivot, svg) { - openerp.web_graph[mode](pivot, svg); +openerp.web_graph.draw_chart = function (mode, pivot, svg, measure_label) { + openerp.web_graph[mode](pivot, svg, measure_label); }; -openerp.web_graph.bar_chart = function (pivot, svg) { +openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { var dim_x = pivot.rows.groupby.length, dim_y = pivot.cols.groupby.length, data = []; @@ -156,7 +156,6 @@ openerp.web_graph.bar_chart = function (pivot, svg) { .stacked(true) .staggerLabels(true) .tooltips(false) - .transitionDuration(0) .width(650) .height(400); @@ -165,7 +164,6 @@ openerp.web_graph.bar_chart = function (pivot, svg) { .attr('width', 650) .attr('height', 400) .call(chart); - debugger; nv.utils.windowResize(chart.update); return chart; @@ -174,12 +172,22 @@ openerp.web_graph.bar_chart = function (pivot, svg) { }; -openerp.web_graph.line_chart = function (pivot, svg) { - var data = _.map(pivot.rows.main.children, function (pt) { - var value = pivot.get_value(pt.id, pivot.cols.main.id), - title = (pt.title !== undefined) ? pt.title : 'Undefined'; - return {x: title, y: value}; - }); +openerp.web_graph.line_chart = function (pivot, svg, measure_label) { + var data = [], + dim_x = pivot.rows.groupby.length, + dim_y = pivot.cols.groupby.length; + + if (dim_y === 0) { + pivot.cols.main.title = measure_label; + } + _.each(pivot.cols.headers, function (col) { + if (!col.is_expanded) { + var values = _.map(pivot.get_rows_depth(dim_x), function (row) { + return {x: row.title, y: pivot.get_value(row.id,col.id, 0)}; + }); + data.push({values: values, key: col.title || 'Undefined'}); + } + }); nv.addGraph(function () { var chart = nv.models.lineChart() @@ -191,7 +199,7 @@ openerp.web_graph.line_chart = function (pivot, svg) { d3.select(svg) .attr('width', 600) .attr('height', 300) - .datum([{key: 'Bar chart', values: data}]) + .datum(data) .call(chart); return chart; diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index e35b8516dd4..07c0e578b83 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -172,7 +172,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ } else { this.$('.graph_main_content').append($('
    ')); var svg = this.$('.graph_main_content svg')[0]; - openerp.web_graph.draw_chart(this.mode, this.pivot_table, svg); + openerp.web_graph.draw_chart(this.mode, this.pivot_table, svg, this.measure_label()); } } } diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index b73939193a0..78f95548106 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -100,6 +100,20 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, + // return all columns with a path length of 'depth' + get_columns_depth: function (depth) { + return _.filter(this.cols.headers, function (hdr) { + return hdr.path.length === depth; + }); + }, + + // return all rows with a path length of 'depth' + get_rows_depth: function (depth) { + return _.filter(this.rows.headers, function (hdr) { + return hdr.path.length === depth; + }); + }, + fold: function (header) { var list = []; function tree_traversal(tree) { -- cgit v1.2.3 From 2cf5049cf170f2560ce398f401adae9d7c2f1614 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 11:22:46 +0100 Subject: [IMP] improves the way line chart format the different titles in the legend (addon web_graph) bzr revid: ged@openerp.com-20131211102246-88y7r63d6wgvz4u5 --- addons/web_graph/static/src/js/charts.js | 22 +++++++++++----------- addons/web_graph/static/src/js/pivot.js | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 11 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 7478668865c..b4a958ded5b 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -173,20 +173,20 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { openerp.web_graph.line_chart = function (pivot, svg, measure_label) { - var data = [], - dim_x = pivot.rows.groupby.length, + var dim_x = pivot.rows.groupby.length, dim_y = pivot.cols.groupby.length; - if (dim_y === 0) { - pivot.cols.main.title = measure_label; - } - _.each(pivot.cols.headers, function (col) { - if (!col.is_expanded) { - var values = _.map(pivot.get_rows_depth(dim_x), function (row) { - return {x: row.title, y: pivot.get_value(row.id,col.id, 0)}; - }); - data.push({values: values, key: col.title || 'Undefined'}); + var data = _.map(pivot.get_cols_leaves(), function (col) { + var values = _.map(pivot.get_rows_depth(dim_x), function (row) { + return {x: row.title, y: pivot.get_value(row.id,col.id, 0)}; + }); + var title = _.map(col.path, function (p) { + return p || 'Undefined'; + }).join('/'); + if (dim_y === 0) { + title = measure_label } + return {values: values, key: title}; }); nv.addGraph(function () { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 78f95548106..cc43329e0b1 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -114,6 +114,20 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, + // return all non expanded rows + get_rows_leaves: function () { + return _.filter(this.rows.headers, function (hdr) { + return !hdr.is_expanded; + }); + }, + + // return all non expanded cols + get_cols_leaves: function () { + return _.filter(this.cols.headers, function (hdr) { + return !hdr.is_expanded; + }); + }, + fold: function (header) { var list = []; function tree_traversal(tree) { -- cgit v1.2.3 From 4ab861699179e35e513c2cd6ac2c0e77c8e513bb Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 11:30:32 +0100 Subject: [IMP] makes pie charts smarter when dealing with multiple levels of rows, in graph view (addon web_graph) bzr revid: ged@openerp.com-20131211103032-6vl1nys24zufuk5w --- addons/web_graph/static/src/js/charts.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index b4a958ded5b..f0025510f9c 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -184,7 +184,7 @@ openerp.web_graph.line_chart = function (pivot, svg, measure_label) { return p || 'Undefined'; }).join('/'); if (dim_y === 0) { - title = measure_label + title = measure_label; } return {values: values, key: title}; }); @@ -206,13 +206,20 @@ openerp.web_graph.line_chart = function (pivot, svg, measure_label) { }); }; -openerp.web_graph.pie_chart = function (pivot, svg) { - var data = _.map(pivot.rows.main.children, function (pt) { - var value = pivot.get_value(pt.id, pivot.cols.main.id), - title = (pt.title !== undefined) ? pt.title : 'Undefined'; - return {x: title, y: value}; +openerp.web_graph.pie_chart = function (pivot, svg, measure_label) { + var dim_x = pivot.rows.groupby.length, + dim_y = pivot.cols.groupby.length; + + var data = _.map(pivot.get_rows_leaves(), function (row) { + var title = _.map(row.path, function (p) { + return p || 'Undefined'; + }).join('/'); + if (dim_x === 0) { + title = measure_label; + } + return {x: title, y: pivot.get_total(row)}; }); - + nv.addGraph(function () { var chart = nv.models.pieChart() .color(d3.scale.category10().range()) -- cgit v1.2.3 From 3453d9da01dc22c704181942530e8abf7dcab95b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 12:08:36 +0100 Subject: [REF] improves the charting code by using get_rows_depth and get_columns_depth methods (addon web_graph) bzr revid: ged@openerp.com-20131211110836-8sq83pcksjm5sboq --- addons/web_graph/static/src/js/charts.js | 59 ++++++++++++-------------------- 1 file changed, 22 insertions(+), 37 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index f0025510f9c..42bb7599912 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -36,13 +36,11 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { }); // Only column groupbys **************************************************** } else if ((dim_x === 0) && (dim_y >= 1)){ - _.each(pivot.cols.headers, function (header) { - if (header.path.length === 1) { - data.push({ - key: header.title, - values: [{x:header.root.main.title, y: pivot.get_total(header)}] - }); - } + data = _.map(pivot.get_columns_depth(1), function (header) { + return { + key: header.title, + values: [{x:header.root.main.title, y: pivot.get_total(header)}] + }; }); nv.addGraph(function() { var chart = nv.models.multiBarChart() @@ -93,20 +91,14 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { }); // 1 row groupby and some col groupbys************************************** } else if ((dim_x === 1) && (dim_y >= 1)) { - data = []; - _.each(pivot.cols.headers, function (colhdr) { - if (colhdr.path.length === 1) { - var values = []; - _.each(pivot.rows.headers, function (header) { - if (header.path.length === 1) { - values.push({ - x: header.title || 'Undefined', - y: pivot.get_value(header.id, colhdr.id, 0) - }); - } - }); - data.push({key: colhdr.title || 'Undefined', values: values}); - } + data = _.map(pivot.get_columns_depth(1), function (colhdr) { + var values = _.map(pivot.get_rows_depth(1), function (header) { + return { + x: header.title || 'Undefined', + y: pivot.get_value(header.id, colhdr.id, 0) + }; + }); + return {key: colhdr.title || 'Undefined', values: values}; }); nv.addGraph(function () { @@ -128,26 +120,19 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { }); // At least two row groupby************************************************* } else { - data = []; - var keys = _.uniq(_.map(_.filter(pivot.rows.headers, function (hdr) { - return hdr.path.length === 2; - }), function (hdr) { + var keys = _.uniq(_.map(pivot.get_rows_depth(2), function (hdr) { return hdr.title || 'Undefined'; })); data = _.map(keys, function (key) { - var values = []; - _.each(pivot.rows.headers, function (hdr) { - if (hdr.path.length === 1) { - var subhdr = _.find(hdr.children, function (child) { - return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); - }); - values.push({ - x: hdr.title || 'Undefined', - y: (subhdr) ? pivot.get_total(subhdr) : 0 - }); - } + var values = _.map(pivot.get_rows_depth(1), function (hdr) { + var subhdr = _.find(hdr.children, function (child) { + return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); + }); + return { + x: hdr.title || 'Undefined', + y: (subhdr) ? pivot.get_total(subhdr) : 0 + }; }); - return {key:key, values: values}; }); -- cgit v1.2.3 From 14d0a6e74c0cceb1af75377a314369122bd152c9 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 13:43:07 +0100 Subject: [IMP] makes sure that the values displayed in the pivot table are properly formatted according to their types (addon web_graph) bzr revid: ged@openerp.com-20131211124307-z9lxbn39spahlxpw --- addons/web_graph/static/src/js/graph.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 07c0e578b83..53f0308f24c 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -407,9 +407,15 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); }, + get_measure_type: function () { + var measure = this.pivot_table.measure; + return (measure) ? this.fields[measure].type : 'integer'; + }, + draw_row: function (row) { var self = this, pivot = this.pivot_table, + measure_type = this.get_measure_type(), html_row = $(''), row_header = this.make_border_cell(1,1) .append(this.make_header_title(row).attr('data-id', row.id)) @@ -448,7 +454,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (value === undefined) { return cell; } - cell.append(value); + cell.append(instance.web.format_value(value, {type: measure_type})); if (self.mode === 'heatmap') { total = pivot.get_total(); color = Math.floor(50 + 205*(total - value)/total); -- cgit v1.2.3 From b8a5b2d2b509bd19ef580f6c137327dbbae924f5 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 14:11:48 +0100 Subject: [IMP] takes all integer and float field from model as possible measure (addon web_graph) bzr revid: ged@openerp.com-20131211131148-vdfhmf96fn2txvcj --- addons/web_graph/static/src/js/graph.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 53f0308f24c..8070bb152ce 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -82,9 +82,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { if ('operator' in field.attrs) { - self.measure_list.push(field.attrs.name); + measure = field.attrs.name; } else { - if (self.measure_list.length) { + if (measure) { self.default_col_groupby.push(field.attrs.name); } else { self.default_row_groupby.push(field.attrs.name); @@ -92,10 +92,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ } } }); - if (this.measure_list.length > 0) { - measure = this.measure_list[0]; - this.pivot_table.set_measure(measure); - } + this.pivot_table.set_measure(measure); // get the most important fields (of the model) by looking at the // groupby filters defined in the search view @@ -117,6 +114,16 @@ instance.web_graph.GraphView = instance.web.View.extend({ // get the fields descriptions from the model var deferred2 = this.model.call('fields_get', []).then(function (fs) { self.fields = fs; + var temp = _.map(fs, function (field, name) { + return {name:name, type: field.type}; + }); + temp = _.filter(temp, function (field) { + return (((field.type === 'integer') || (field.type === 'float')) && (field.name !== 'id')); + }); + self.measure_list = _.map(temp, function (field) { + return field.name; + }); + var measure_selection = self.$('.graph_measure_selection'); _.each(self.measure_list, function (measure) { var choice = $('').attr('data-choice', measure) -- cgit v1.2.3 From b04f21ea12406fc28e7a74494af0397f6ce9e6d1 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 15:01:40 +0100 Subject: [IMP] finally uses the full width and height to draw charts, instead of hardcoded numbers (in graph view) (addon web_graph) bzr revid: ged@openerp.com-20131211140140-shlpos1jt3z8wj41 --- addons/web_graph/static/src/js/charts.js | 107 ++++++++++++++++--------------- addons/web_graph/static/src/js/graph.js | 13 +++- 2 files changed, 66 insertions(+), 54 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js index 42bb7599912..9e6c40eb866 100644 --- a/addons/web_graph/static/src/js/charts.js +++ b/addons/web_graph/static/src/js/charts.js @@ -1,11 +1,12 @@ -openerp.web_graph.draw_chart = function (mode, pivot, svg, measure_label) { - openerp.web_graph[mode](pivot, svg, measure_label); +openerp.web_graph.draw_chart = function (options) { + openerp.web_graph[options.mode](options); }; -openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { - var dim_x = pivot.rows.groupby.length, +openerp.web_graph.bar_chart = function (options) { + var pivot = options.pivot, + dim_x = pivot.rows.groupby.length, dim_y = pivot.cols.groupby.length, data = []; @@ -13,7 +14,7 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { if ((dim_x === 0) && (dim_y === 0)) { data = [{key: 'Total', values:[{ title: 'Total', - value: pivot.get_value(pivot.rows.main.id, pivot.cols.main.id), + value: options.pivot.get_value(pivot.rows.main.id, pivot.cols.main.id), }]}]; nv.addGraph(function () { var chart = nv.models.discreteBarChart() @@ -21,14 +22,14 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { .y(function(d) { return d.value;}) .tooltips(false) .showValues(true) - .staggerLabels(true) - .width(650) - .height(400); + .width(options.width) + .height(options.height) + .staggerLabels(true); - d3.select(svg) + d3.select(options.svg) .datum(data) - .attr('width', 650) - .attr('height', 400) + .attr('width', options.width) + .attr('height', options.height) .call(chart); nv.utils.windowResize(chart.update); @@ -46,14 +47,14 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { var chart = nv.models.multiBarChart() .stacked(true) .tooltips(false) - .showControls(false) - .width(400) - .height(500); + .width(options.width) + .height(options.height) + .showControls(false); - d3.select(svg) + d3.select(options.svg) .datum(data) - .attr('width', 400) - .attr('height', 500) + .attr('width', options.width) + .attr('height', options.height) .transition() .duration(500) .call(chart); @@ -69,21 +70,21 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { title = (pt.title !== undefined) ? pt.title : 'Undefined'; return {title: title, value: value}; }); - data = [{key: 'Bar chart', values:data}]; + data = [{key: options.measure_label, values:data}]; nv.addGraph(function () { var chart = nv.models.discreteBarChart() .x(function(d) { return d.title;}) .y(function(d) { return d.value;}) .tooltips(false) .showValues(true) - .staggerLabels(true) - .width(650) - .height(400); + .width(options.width) + .height(options.height) + .staggerLabels(true); - d3.select(svg) + d3.select(options.svg) .datum(data) - .attr('width', 650) - .attr('height', 400) + .attr('width', options.width) + .attr('height', options.height) .call(chart); nv.utils.windowResize(chart.update); @@ -105,14 +106,14 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { var chart = nv.models.multiBarChart() .stacked(true) .staggerLabels(true) - .tooltips(false) - .width(650) - .height(400); + .width(options.width) + .height(options.height) + .tooltips(false); - d3.select(svg) + d3.select(options.svg) .datum(data) - .attr('width', 650) - .attr('height', 400) + .attr('width', options.width) + .attr('height', options.height) .call(chart); nv.utils.windowResize(chart.update); @@ -140,14 +141,14 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { var chart = nv.models.multiBarChart() .stacked(true) .staggerLabels(true) - .tooltips(false) - .width(650) - .height(400); + .width(options.width) + .height(options.height) + .tooltips(false); - d3.select(svg) + d3.select(options.svg) .datum(data) - .attr('width', 650) - .attr('height', 400) + .attr('width', options.width) + .attr('height', options.height) .call(chart); nv.utils.windowResize(chart.update); @@ -157,8 +158,9 @@ openerp.web_graph.bar_chart = function (pivot, svg, measure_label) { }; -openerp.web_graph.line_chart = function (pivot, svg, measure_label) { - var dim_x = pivot.rows.groupby.length, +openerp.web_graph.line_chart = function (options) { + var pivot = options.pivot, + dim_x = pivot.rows.groupby.length, dim_y = pivot.cols.groupby.length; var data = _.map(pivot.get_cols_leaves(), function (col) { @@ -169,7 +171,7 @@ openerp.web_graph.line_chart = function (pivot, svg, measure_label) { return p || 'Undefined'; }).join('/'); if (dim_y === 0) { - title = measure_label; + title = options.measure_label; } return {values: values, key: title}; }); @@ -177,13 +179,13 @@ openerp.web_graph.line_chart = function (pivot, svg, measure_label) { nv.addGraph(function () { var chart = nv.models.lineChart() .x(function (d,u) { return u; }) - .width(600) - .height(300) + .width(options.width) + .height(options.height) .margin({top: 30, right: 20, bottom: 20, left: 60}); - d3.select(svg) - .attr('width', 600) - .attr('height', 300) + d3.select(options.svg) + .attr('width', options.width) + .attr('height', options.height) .datum(data) .call(chart); @@ -191,8 +193,9 @@ openerp.web_graph.line_chart = function (pivot, svg, measure_label) { }); }; -openerp.web_graph.pie_chart = function (pivot, svg, measure_label) { - var dim_x = pivot.rows.groupby.length, +openerp.web_graph.pie_chart = function (options) { + var pivot = options.pivot, + dim_x = pivot.rows.groupby.length, dim_y = pivot.cols.groupby.length; var data = _.map(pivot.get_rows_leaves(), function (row) { @@ -200,7 +203,7 @@ openerp.web_graph.pie_chart = function (pivot, svg, measure_label) { return p || 'Undefined'; }).join('/'); if (dim_x === 0) { - title = measure_label; + title = options.measure_label; } return {x: title, y: pivot.get_total(row)}; }); @@ -208,14 +211,14 @@ openerp.web_graph.pie_chart = function (pivot, svg, measure_label) { nv.addGraph(function () { var chart = nv.models.pieChart() .color(d3.scale.category10().range()) - .width(650) - .height(400); + .width(options.width) + .height(options.height); - d3.select(svg) + d3.select(options.svg) .datum(data) .transition().duration(1200) - .attr('width', 650) - .attr('height', 400) + .attr('width', options.width) + .attr('height', options.height) .call(chart); nv.utils.windowResize(chart.update); diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 8070bb152ce..f1d08968626 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -61,6 +61,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ start: function () { this.table = $('
    '); this.$('.graph_main_content').append(this.table); + this.width = this.$el.width(); + this.height = this.$el.parent().parent().height(); // to get view manager body instance.web.bus.on('click', this, function (ev) { if (this.dropdown) { this.dropdown.remove(); @@ -178,8 +180,15 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.draw_table(); } else { this.$('.graph_main_content').append($('
    ')); - var svg = this.$('.graph_main_content svg')[0]; - openerp.web_graph.draw_chart(this.mode, this.pivot_table, svg, this.measure_label()); + var options = { + svg: this.$('.graph_main_content svg')[0], + mode: this.mode, + pivot: this.pivot_table, + width: this.width, + height: this.height - 30, + measure_label: this.measure_label() + }; + openerp.web_graph.draw_chart(options); } } } -- cgit v1.2.3 From 8da86807b6d459a7c6d010e447ea006c61790923 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 15:50:56 +0100 Subject: [FIX] quick fix to make sure charts have a minimal height that is not too small (addon web_graph) bzr revid: ged@openerp.com-20131211145056-nzpnir06xx3q0n9y --- addons/web_graph/static/src/js/graph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index f1d08968626..0b0078e7ff1 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -185,7 +185,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ mode: this.mode, pivot: this.pivot_table, width: this.width, - height: this.height - 30, + height: Math.max(this.height - 45, 250), measure_label: this.measure_label() }; openerp.web_graph.draw_chart(options); -- cgit v1.2.3 From 945719fb7dc9c63933dfbd0a27d557b4e0d2c3c6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 17:00:11 +0100 Subject: [FIX] correctly computes the height and the width of the graph view (addon web_graph) bzr revid: ged@openerp.com-20131211160011-fhv7ah63hlnyg7l0 --- addons/web_graph/static/src/js/graph.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 0b0078e7ff1..364014288c1 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -61,8 +61,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ start: function () { this.table = $('
    '); this.$('.graph_main_content').append(this.table); - this.width = this.$el.width(); - this.height = this.$el.parent().parent().height(); // to get view manager body instance.web.bus.on('click', this, function (ev) { if (this.dropdown) { this.dropdown.remove(); @@ -180,12 +178,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.draw_table(); } else { this.$('.graph_main_content').append($('
    ')); + // console.log('this.perentaui', this.getParent().$el); + // this.width = this.$el.width(); + // this.height = this.$el.parent().parent().height(); // to get view manager body + + // debugger; var options = { svg: this.$('.graph_main_content svg')[0], mode: this.mode, pivot: this.pivot_table, - width: this.width, - height: Math.max(this.height - 45, 250), + width: this.$el.width(), + height: Math.max(this.$el.parent().parent().height() - 45, 250), measure_label: this.measure_label() }; openerp.web_graph.draw_chart(options); -- cgit v1.2.3 From 7a672064c02d56f7c833c727e596b098caa5bf08 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 11 Dec 2013 17:28:50 +0100 Subject: [FIX] improves the handling of headers titles when the db query returns false or undefined (addon web_graph) bzr revid: ged@openerp.com-20131211162850-mgqs5csnw8wca974 --- addons/web_graph/static/src/js/graph.js | 7 +----- addons/web_graph/static/src/js/pivot.js | 41 ++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 17 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 364014288c1..808f944c5f7 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -178,17 +178,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.draw_table(); } else { this.$('.graph_main_content').append($('
    ')); - // console.log('this.perentaui', this.getParent().$el); - // this.width = this.$el.width(); - // this.height = this.$el.parent().parent().height(); // to get view manager body - - // debugger; var options = { svg: this.$('.graph_main_content svg')[0], mode: this.mode, pivot: this.pivot_table, width: this.$el.width(), - height: Math.max(this.$el.parent().parent().height() - 45, 250), + height: Math.max(document.documentElement.clientHeight - 116 - 60, 250), measure_label: this.measure_label() }; openerp.web_graph.draw_chart(options); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index cc43329e0b1..243997229df 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -183,7 +183,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, make_header: function (groups, parent) { - var name = groups[0].attributes.value[1], + var name = get_attribute_value(groups[0]), new_header = { id: _.uniqueId(), path: parent.path.concat(name), @@ -387,14 +387,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } function make_tree_headers (data_pt, parent, max_depth) { - var node = { - id: _.uniqueId(), - path: parent.path.concat(data_pt.attributes.value[1]), - title: data_pt.attributes.value[1], - domain: data_pt.model._domain, - parent: parent, - children: [], - }; + var value = get_attribute_value(data_pt), + node = { + id: _.uniqueId(), + path: parent.path.concat(value), + title: value, + domain: data_pt.model._domain, + parent: parent, + children: [], + }; if (self.measure) { node.total = data_pt.attributes.aggregates[self.measure]; } else { @@ -412,9 +413,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ function make_cells (data, index, current_path) { _.each(data, function (group) { var attr = group.attributes, + group_val = (attr.value instanceof Array) ? attr.value[1] : attr.value, path = current_path, value; + if (group_val === false) { + group_val = undefined; + } + if (self.measure) { value = attr.aggregates[self.measure]; } else { @@ -422,8 +428,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } if (attr.grouped_on !== undefined) { - path = path.concat(attr.value[1]); + if (attr.value === false) { + path = path.concat('undefined'); + } else { + path = path.concat(group_val); + } } + + console.log('attr', attr); var rowpath = path.slice(0, index), colpath = path.slice(index); @@ -433,6 +445,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var col = _.find(col_headers, function (header) { return _.isEqual(header.path, colpath); }); + debugger; cells.push({x: Math.min(row.id, col.id), y: Math.max(row.id, col.id), value: value}); @@ -489,7 +502,7 @@ function query_groups_data (model, fields, domain, row_groupbys, col_groupby) { } function format_group (group, path) { - group.path = path.concat(group.attributes.value[1]); + group.path = path.concat(get_attribute_value(group)); var result = [group]; _.each(group.subgroups_data, function (subgroup) { result = result.concat(format_group (subgroup, group.path)); @@ -497,4 +510,10 @@ function format_group (group, path) { return result; } +function get_attribute_value (group) { + var value = group.attributes.value; + if (value === false) return 'undefined'; + return (value instanceof Array) ? value[1] : value; +} + })(); \ No newline at end of file -- cgit v1.2.3 From f24f38ca880754ea6d514abe4d692b263c95605b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 12 Dec 2013 09:39:36 +0100 Subject: [FIX] removes a debugger statement (addon web_graph) bzr revid: ged@openerp.com-20131212083936-5s8xi6ays4xq9jul --- addons/web_graph/static/src/js/graph.js | 2 +- addons/web_graph/static/src/js/pivot.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 808f944c5f7..918a698e7b7 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -183,7 +183,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ mode: this.mode, pivot: this.pivot_table, width: this.$el.width(), - height: Math.max(document.documentElement.clientHeight - 116 - 60, 250), + height: Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())), measure_label: this.measure_label() }; openerp.web_graph.draw_chart(options); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 243997229df..a8ed2ae6ef5 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -445,7 +445,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var col = _.find(col_headers, function (header) { return _.isEqual(header.path, colpath); }); - debugger; cells.push({x: Math.min(row.id, col.id), y: Math.max(row.id, col.id), value: value}); -- cgit v1.2.3 From e0ee9a58c547cd06d2d33018e43b02e549c10e9e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 12 Dec 2013 11:55:33 +0100 Subject: [IMP] removes the expand/fold menu, because the search view covers the same functionality (addon web_graph) bzr revid: ged@openerp.com-20131212105533-uawad2hgqopfkygo --- addons/web_graph/static/src/js/graph.js | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 918a698e7b7..912f56e79fc 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -24,7 +24,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ events: { 'click .graph_mode_selection li' : 'mode_selection', 'click .graph_measure_selection li' : 'measure_selection', - 'click .graph_expand_selection li' : 'expand_selection', 'click .graph_options_selection li' : 'option_selection', 'click .web_graph_click' : 'cell_click_callback', 'click a.field-selection' : 'field_selection', @@ -269,36 +268,17 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.display_data(); }, - expand_selection: function (event) { + option_selection: function (event) { event.preventDefault(); switch (event.target.attributes['data-choice'].nodeValue) { - case 'fold_columns': - this.pivot_table.fold_cols(); - this.register_groupby(); - break; - case 'fold_rows': - this.pivot_table.fold_rows(); - this.register_groupby(); - break; - case 'fold_all': - this.pivot_table.fold_cols(); - this.pivot_table.fold_rows(); + case 'swap_axis': + this.pivot_table.swap_axis(); this.register_groupby(); break; case 'expand_all': this.pivot_table.invalidate_data(); this.display_data(); break; - } - }, - - option_selection: function (event) { - event.preventDefault(); - switch (event.target.attributes['data-choice'].nodeValue) { - case 'swap_axis': - this.pivot_table.swap_axis(); - this.register_groupby(); - break; case 'update_values': this.pivot_table.stale_data = true; this.display_data(); @@ -368,7 +348,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ return $(' ') .addClass('web_graph_click') .attr('href', '#') - .addClass((header.is_expanded) ? 'icon-minus-sign' : 'icon-plus-sign') + .addClass((header.is_expanded) ? 'fa fa-minus-square' : 'fa fa-plus-square') .append((header.title !== undefined) ? header.title : 'Undefined'); }, -- cgit v1.2.3 From a22648c083e6fc9ef5170a6458bb52da5123faa6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 16 Dec 2013 15:27:57 +0100 Subject: [REF] adds DataLoader class to graph view (addon web_graph) bzr revid: ged@openerp.com-20131216142757-anqt11ccrwswdify --- addons/web_graph/static/src/js/pivot.js | 139 +++++++++++++++++--------------- 1 file changed, 76 insertions(+), 63 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index a8ed2ae6ef5..1c7ae27fc31 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -9,10 +9,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.rows = { groupby: [], main: null, headers: null }; this.cols = { groupby: [], main: null, headers: null }; this.cells = []; - this.model = model; this.domain = domain; this.measure = null; + this.data_loader = new openerp.web_graph.DataLoader(model); + this.id_seed = 0; this.no_data = true; this.stale_data = true; @@ -157,7 +158,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } var otherDim = (header.root === this.cols) ? this.rows : this.cols; - return query_groups_data(this.model, this.visible_fields(), header.domain, otherDim.groupby, field_id) + return this.data_loader.get_groups(this.visible_fields(), header.domain, otherDim.groupby, {first_groupby:field_id, add_path:true}) .then(function (groups) { _.each(groups.reverse(), function (group) { var new_header_id = self.make_header(group, header); @@ -183,7 +184,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, make_header: function (groups, parent) { - var name = get_attribute_value(groups[0]), + var name = groups[0].attributes.value, new_header = { id: _.uniqueId(), path: parent.path.concat(name), @@ -195,7 +196,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ root: parent.root, }; parent.children.splice(0,0, new_header); - insertAfter(parent.root.headers, parent, new_header); + parent.root.headers.splice(parent.root.headers.indexOf(parent) + 1, 0, new_header); return new_header.id; }, @@ -270,7 +271,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ _.each(corresponding_header.children, function (c) { c.is_expanded = false; }); - } + } if (corresponding_header && (!header.is_expanded)) { corresponding_header.is_expanded = false; } @@ -318,7 +319,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ groupbys = [rows, []]; } def_array = _.map(groupbys, function (groupby) { - return query_groups(self.model, self.visible_fields(), self.domain, groupby); + return self.data_loader.get_groups(self.visible_fields(), self.domain, groupby); }); return $.when.apply(null, def_array).then(function () { @@ -387,7 +388,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } function make_tree_headers (data_pt, parent, max_depth) { - var value = get_attribute_value(data_pt), + var value = data_pt.attributes.value, //get_attribute_value(data_pt), node = { id: _.uniqueId(), path: parent.path.concat(value), @@ -435,7 +436,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } } - console.log('attr', attr); var rowpath = path.slice(0, index), colpath = path.slice(index); @@ -458,61 +458,74 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); -function insertAfter(array, after, elem) { - array.splice(array.indexOf(after) + 1, 0, elem); -} - -/** - * Query the server and return a deferred which will return the data - * with all the groupbys applied (this is done for now, but the goal - * is to modify read_group in order to allow eager and lazy groupbys - */ -function query_groups (model, fields, domain, groupbys) { - return model.query(fields) - .filter(domain) - .group_by(groupbys) - .then(function (results) { - var non_empty_results = _.filter(results, function (group) { - return group.attributes.length > 0; - }); - if (groupbys.length <= 1) { - return non_empty_results; - } else { - var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { - var new_domain = result.model._domain; - var new_groupings = groupbys.slice(1); - return query_groups(model, fields,new_domain, new_groupings).then(function (subgroups) { - result.subgroups_data = subgroups; - }); - })); - return get_subgroups.then(function () { - return non_empty_results; - }); - } - }); -} +openerp.web_graph.DataLoader = openerp.web.Class.extend({ + init: function (model) { + this.model = model; + }, + + get_groups: function (fields, domain, groupbys, options) { + var self = this, + options = (options) ? options : {}, + groupings = (options.first_groupby) ? [options.first_groupby].concat(groupbys) : groupbys; + + return this._query_db(fields, domain, groupings).then(function (groups) { + return _.map(groups, function (group) { + return (options.add_path) ?self._add_path(group, []) : group; + }); + }); + + }, + + _query_db: function (fields, domain, groupbys) { + var self = this; + return this.model.query(fields) + .filter(domain) + .group_by(groupbys) + .then(function (results) { + var non_empty_results = _.filter(results, function (group) { + return group.attributes.length > 0; + }); + _.each(non_empty_results, self._sanitize_value); + if (groupbys.length <= 1) { + return non_empty_results; + } else { + var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { + var new_domain = result.model._domain; + var new_groupings = groupbys.slice(1); + return self._query_db(fields,new_domain, new_groupings).then(function (subgroups) { + result.subgroups_data = subgroups; + }); + })); + return get_subgroups.then(function () { + return non_empty_results; + }); + } + }); + }, + + _sanitize_value: function (group) { + var value = group.attributes.value; + if (value === false) { + group.attributes.value = 'undefined'; + } else if (value instanceof Array) { + group.attributes.value = value[1]; + } else { + group.attributes.value = value; + } + }, + + _add_path: function (group, current_path) { + var self = this; + + group.path = current_path.concat(group.attributes.value); + var result = [group]; + _.each(group.subgroups_data, function (subgroup) { + result = result.concat(self._add_path(subgroup, group.path)); + }); + return result; + }, + +}); -function query_groups_data (model, fields, domain, row_groupbys, col_groupby) { - return query_groups(model, fields, domain, [col_groupby].concat(row_groupbys)).then(function (groups) { - return _.map(groups, function (group) { - return format_group(group, []); - }); - }); -} - -function format_group (group, path) { - group.path = path.concat(get_attribute_value(group)); - var result = [group]; - _.each(group.subgroups_data, function (subgroup) { - result = result.concat(format_group (subgroup, group.path)); - }); - return result; -} - -function get_attribute_value (group) { - var value = group.attributes.value; - if (value === false) return 'undefined'; - return (value instanceof Array) ? value[1] : value; -} })(); \ No newline at end of file -- cgit v1.2.3 From c256cd4f14d1f1cde45f5eecdd705fe758295b4d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 16 Dec 2013 15:49:35 +0100 Subject: [REF] merges update_data and query_all_values method into load_data, to simplify code (addon web_graph) bzr revid: ged@openerp.com-20131216144935-2ur7pgk7ml2064j0 --- addons/web_graph/static/src/js/graph.js | 2 +- addons/web_graph/static/src/js/pivot.js | 108 +++++++++++++++----------------- 2 files changed, 50 insertions(+), 60 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 912f56e79fc..8433e560cfd 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -163,7 +163,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ display_data: function () { var pivot = this.pivot_table; if (pivot.stale_data) { - pivot.update_data().done(this.proxy('display_data')); + pivot.load_data().done(this.proxy('display_data')); } else { this.$('.graph_main_content svg').remove(); this.table.empty(); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 1c7ae27fc31..793c9f50454 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -214,15 +214,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.fold(this.cols.main); }, - expand_headers: function (root, new_headers) { - root.headers = new_headers; - root.main = new_headers[0]; - _.each(root.headers, function (header) { - header.root = root; - header.is_expanded = (header.children.length > 0); - }); - }, - get_total: function (header) { if (header) { var main = (header.root === this.rows) ? this.cols.main : this.rows.main; @@ -241,9 +232,45 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.stale_data = true; }, - update_data: function () { - var self = this; - return this.query_all_values().then(function (result) { + // 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. For example, if row.groupby = [r1, r2, r3] and + // col.groupby = [c1, c2, c3, c4], then a minimal set of calls is done + // with the following groupby: + // [], [c1, c2, c3, c4], r1, c1, c2, c3, c4], [r1, r2, c1, c2, c3, c4], + // [r1, r2, r3, c1, c2, c3, c4] + // To simplify the code, we will always do 2 + row.groupby.length calls, + // unless col.groupby.length = 0, in which case we do 2 calls ([] and + // row_groupbys), but this can be optimized later. + load_data: function () { + var self = this, + cols = this.cols.groupby, + rows = this.rows.groupby, + def_array, + groupbys; + + if (cols.length > 0) { + groupbys = _.map(_.range(rows.length + 1), function (i) { + return rows.slice(0, i).concat(cols); + }); + groupbys.push([]); + } else { + groupbys = [rows, []]; + } + def_array = _.map(groupbys, function (groupby) { + return self.data_loader.get_groups(self.visible_fields(), self.domain, groupby); + }); + + return $.when.apply(null, def_array).then(function () { + var args = Array.prototype.slice.call(arguments), + col_data = _.first(args), + total = _.last(args)[0], + row_data = _.last(_.initial(args)), + cell_data = args; + + return (total === undefined) ? undefined + : self.format_data(total, col_data, row_data, cell_data); + }).then(function (result) { self.stale_data = false; if (result) { self.no_data = false; @@ -261,6 +288,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, + expand_headers: function (root, new_headers) { + root.headers = new_headers; + root.main = new_headers[0]; + _.each(root.headers, function (header) { + header.root = root; + header.is_expanded = (header.children.length > 0); + }); + }, + update_headers: function (root, new_headers) { _.each(root.headers, function (header) { var corresponding_header = _.find(new_headers, function (h) { @@ -289,52 +325,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ root.main = root.headers[0]; }, - // this method is a little tricky. In order 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. For example, if row.groupby = [r1, r2, r3] and - // col.groupby = [c1, c2, c3, c4], then a minimal set of calls is done - // with the following groupby: - // [] - // [c1, c2, c3, c4] - // [r1, c1, c2, c3, c4] - // [r1, r2, c1, c2, c3, c4] - // [r1, r2, r3, c1, c2, c3, c4] - // To simplify the code, we will always do 2 + row.groupby.length calls, - // unless col.groupby.length = 0, in which case we do 2 calls ([] and - // row_groupbys), but this can be optimized later. - query_all_values: function () { - var self = this, - cols = this.cols.groupby, - rows = this.rows.groupby, - def_array, - groupbys; - - if (cols.length > 0) { - groupbys = _.map(_.range(rows.length + 1), function (i) { - return rows.slice(0, i).concat(cols); - }); - groupbys.push([]); - } else { - groupbys = [rows, []]; - } - def_array = _.map(groupbys, function (groupby) { - return self.data_loader.get_groups(self.visible_fields(), self.domain, groupby); - }); - - return $.when.apply(null, def_array).then(function () { - var args = Array.prototype.slice.call(arguments), - col_data = _.first(args), - total = _.last(args)[0], - row_data = _.last(_.initial(args)), - cell_data = args; - - return (total === undefined) ? undefined - : self.format_data(total, col_data, row_data, cell_data); - }); - - }, - format_data: function (total, col_data, row_data, cell_data) { var self = this, dim_row = this.rows.groupby.length, @@ -388,7 +378,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } function make_tree_headers (data_pt, parent, max_depth) { - var value = data_pt.attributes.value, //get_attribute_value(data_pt), + var value = data_pt.attributes.value, node = { id: _.uniqueId(), path: parent.path.concat(value), -- cgit v1.2.3 From de51e3c35a4ada3bc29c3de2abd371e43569f814 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 17 Dec 2013 12:15:01 +0100 Subject: [REF] moves more code to dataLoader class to simplify pivot class (clean separation between pivot code and loading code) (addon web_graph) bzr revid: ged@openerp.com-20131217111501-wu0nbid36bncy4wz --- addons/web_graph/static/src/js/graph.js | 2 +- addons/web_graph/static/src/js/pivot.js | 262 +++++++++++++++++--------------- 2 files changed, 142 insertions(+), 122 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 8433e560cfd..912f56e79fc 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -163,7 +163,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ display_data: function () { var pivot = this.pivot_table; if (pivot.stale_data) { - pivot.load_data().done(this.proxy('display_data')); + pivot.update_data().done(this.proxy('display_data')); } else { this.$('.graph_main_content svg').remove(); this.table.empty(); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 793c9f50454..b95e60509e8 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -117,15 +117,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ // return all non expanded rows get_rows_leaves: function () { - return _.filter(this.rows.headers, function (hdr) { - return !hdr.is_expanded; + return _.filter(this.rows.headers, function (hdr) { + return !hdr.is_expanded; }); }, // return all non expanded cols get_cols_leaves: function () { - return _.filter(this.cols.headers, function (hdr) { - return !hdr.is_expanded; + return _.filter(this.cols.headers, function (hdr) { + return !hdr.is_expanded; }); }, @@ -232,54 +232,25 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.stale_data = true; }, - // 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. For example, if row.groupby = [r1, r2, r3] and - // col.groupby = [c1, c2, c3, c4], then a minimal set of calls is done - // with the following groupby: - // [], [c1, c2, c3, c4], r1, c1, c2, c3, c4], [r1, r2, c1, c2, c3, c4], - // [r1, r2, r3, c1, c2, c3, c4] - // To simplify the code, we will always do 2 + row.groupby.length calls, - // unless col.groupby.length = 0, in which case we do 2 calls ([] and - // row_groupbys), but this can be optimized later. - load_data: function () { + update_data: function () { var self = this, - cols = this.cols.groupby, - rows = this.rows.groupby, - def_array, - groupbys; - - if (cols.length > 0) { - groupbys = _.map(_.range(rows.length + 1), function (i) { - return rows.slice(0, i).concat(cols); - }); - groupbys.push([]); - } else { - groupbys = [rows, []]; - } - def_array = _.map(groupbys, function (groupby) { - return self.data_loader.get_groups(self.visible_fields(), self.domain, groupby); - }); - - return $.when.apply(null, def_array).then(function () { - var args = Array.prototype.slice.call(arguments), - col_data = _.first(args), - total = _.last(args)[0], - row_data = _.last(_.initial(args)), - cell_data = args; + options = { + col_groupby: this.cols.groupby, + row_groupby: this.rows.groupby, + measure: this.measure, + domain: this.domain, + }; - return (total === undefined) ? undefined - : self.format_data(total, col_data, row_data, cell_data); - }).then(function (result) { + return this.data_loader.load_data(options).then (function (result) { self.stale_data = false; if (result) { self.no_data = false; if (self.cols.headers) { self.update_headers(self.cols, result.col_headers); - self.update_headers(self.rows, result.row_headers); + self.update_headers(self.rows, result.row_headers); } else { self.expand_headers(self.cols, result.col_headers); - self.expand_headers(self.rows, result.row_headers); + self.expand_headers(self.rows, result.row_headers); } self.cells = result.cells; } else { @@ -325,10 +296,127 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ root.main = root.headers[0]; }, - format_data: function (total, col_data, row_data, cell_data) { +}); + +openerp.web_graph.DataLoader = openerp.web.Class.extend({ + init: function (model) { + this.model = model; + }, + + get_groups: function (fields, domain, groupbys, options) { var self = this, - dim_row = this.rows.groupby.length, - dim_col = this.cols.groupby.length, + options = (options) ? options : {}, + groupings = (options.first_groupby) ? [options.first_groupby].concat(groupbys) : groupbys; + + return this.query_db(fields, domain, groupings).then(function (groups) { + return _.map(groups, function (group) { + return (options.add_path) ?self.add_path(group, []) : group; + }); + }); + + }, + + query_db: function (fields, domain, groupbys) { + var self = this; + return this.model.query(fields) + .filter(domain) + .group_by(groupbys) + .then(function (results) { + var non_empty_results = _.filter(results, function (group) { + return group.attributes.length > 0; + }); + _.each(non_empty_results, self.sanitize_value); + if (groupbys.length <= 1) { + return non_empty_results; + } else { + var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { + var new_domain = result.model._domain; + var new_groupings = groupbys.slice(1); + return self.query_db(fields,new_domain, new_groupings).then(function (subgroups) { + result.subgroups_data = subgroups; + }); + })); + return get_subgroups.then(function () { + return non_empty_results; + }); + } + }); + }, + + sanitize_value: function (group) { + var value = group.attributes.value; + if (value === false) { + group.attributes.value = 'undefined'; + } else if (value instanceof Array) { + group.attributes.value = value[1]; + } else { + group.attributes.value = value; + } + }, + + add_path: function (group, current_path) { + var self = this; + + group.path = current_path.concat(group.attributes.value); + var result = [group]; + _.each(group.subgroups_data, function (subgroup) { + result = result.concat(self.add_path(subgroup, group.path)); + }); + return result; + }, + + // 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. For example, if row.groupby = [r1, r2, r3] and + // col.groupby = [c1, c2, c3, c4], then a minimal set of calls is done + // with the following groupby: + // [], [c1, c2, c3, c4], r1, c1, c2, c3, c4], [r1, r2, c1, c2, c3, c4], + // [r1, r2, r3, c1, c2, c3, c4] + // To simplify the code, we will always do 2 + row.groupby.length calls, + // unless col.groupby.length = 0, in which case we do 2 calls ([] and + // row_groupbys), but this can be optimized later. + load_data: function (options) { + var self = this, + cols = options.col_groupby, + rows = options.row_groupby, + measure = options.measure, + domain = options.domain, + visible_fields = rows.concat(cols), + def_array, + groupbys; + + if (measure) { visible_fields = visible_fields.concat(measure); } + + if (cols.length > 0) { + groupbys = _.map(_.range(rows.length + 1), function (i) { + return rows.slice(0, i).concat(cols); + }); + groupbys.push([]); + } else { + groupbys = [rows, []]; + } + def_array = _.map(groupbys, function (groupby) { + return self.get_groups(visible_fields, domain, groupby); + }); + + return $.when.apply(null, def_array).then(function () { + var args = Array.prototype.slice.call(arguments), + col_data = _.first(args), + total = _.last(args)[0], + row_data = _.last(_.initial(args)), + cell_data = args; + + return (total === undefined) ? undefined + : self.format_data(total, col_data, row_data, cell_data, options); + }); + }, + + + format_data: function (total, col_data, row_data, cell_data, options) { + var self = this, + dim_row = options.row_groupby.length, + dim_col = options.col_groupby.length, + measure = options.measure, col_headers = make_headers(col_data, dim_col), row_headers = make_headers(row_data, dim_row), cells = []; @@ -353,10 +441,10 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ parent: null, children: [], title: '', - domain: self.domain, + domain: options.domain, }; - if (self.measure) { - main.total = total.attributes.aggregates[self.measure]; + if (measure) { + main.total = total.attributes.aggregates[measure]; } else { main.total = total.attributes.length; } @@ -387,8 +475,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ parent: parent, children: [], }; - if (self.measure) { - node.total = data_pt.attributes.aggregates[self.measure]; + if (measure) { + node.total = data_pt.attributes.aggregates[measure]; } else { node.total = data_pt.attributes.length; } @@ -412,8 +500,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ group_val = undefined; } - if (self.measure) { - value = attr.aggregates[self.measure]; + if (measure) { + value = attr.aggregates[measure]; } else { value = attr.length; } @@ -446,74 +534,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } }, -}); - -openerp.web_graph.DataLoader = openerp.web.Class.extend({ - init: function (model) { - this.model = model; - }, - - get_groups: function (fields, domain, groupbys, options) { - var self = this, - options = (options) ? options : {}, - groupings = (options.first_groupby) ? [options.first_groupby].concat(groupbys) : groupbys; - - return this._query_db(fields, domain, groupings).then(function (groups) { - return _.map(groups, function (group) { - return (options.add_path) ?self._add_path(group, []) : group; - }); - }); - - }, - - _query_db: function (fields, domain, groupbys) { - var self = this; - return this.model.query(fields) - .filter(domain) - .group_by(groupbys) - .then(function (results) { - var non_empty_results = _.filter(results, function (group) { - return group.attributes.length > 0; - }); - _.each(non_empty_results, self._sanitize_value); - if (groupbys.length <= 1) { - return non_empty_results; - } else { - var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { - var new_domain = result.model._domain; - var new_groupings = groupbys.slice(1); - return self._query_db(fields,new_domain, new_groupings).then(function (subgroups) { - result.subgroups_data = subgroups; - }); - })); - return get_subgroups.then(function () { - return non_empty_results; - }); - } - }); - }, - - _sanitize_value: function (group) { - var value = group.attributes.value; - if (value === false) { - group.attributes.value = 'undefined'; - } else if (value instanceof Array) { - group.attributes.value = value[1]; - } else { - group.attributes.value = value; - } - }, - - _add_path: function (group, current_path) { - var self = this; - - group.path = current_path.concat(group.attributes.value); - var result = [group]; - _.each(group.subgroups_data, function (subgroup) { - result = result.concat(self._add_path(subgroup, group.path)); - }); - return result; - }, }); -- cgit v1.2.3 From 9596340bc52235e1a835e30a2e1e02b7a92fceed Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 17 Dec 2013 12:19:41 +0100 Subject: [REF] removes useless line in addon web_graph bzr revid: ged@openerp.com-20131217111941-vlzn0ener6zjk737 --- addons/web_graph/static/src/js/pivot.js | 1 - 1 file changed, 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index b95e60509e8..dd675270132 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -14,7 +14,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.data_loader = new openerp.web_graph.DataLoader(model); - this.id_seed = 0; this.no_data = true; this.stale_data = true; }, -- cgit v1.2.3 From 79250f0c077e3c463fd2d644b5fe398f82048a3f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 17 Dec 2013 16:32:04 +0100 Subject: [REF] adds event handling to pivot table class (triggers 'redraw_required' and 'groupby_changed' event when necessary (addon web_graph) bzr revid: ged@openerp.com-20131217153204-43la1m8eqw632j05 --- addons/web_graph/static/src/js/graph.js | 14 ++++++---- addons/web_graph/static/src/js/pivot.js | 47 +++++++++++++++------------------ 2 files changed, 31 insertions(+), 30 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 912f56e79fc..6805bce1793 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -138,20 +138,24 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { var self = this, - col_groupby = context.col_group_by || []; // get_col_groupby('ColGroupBy'); + col_groupby = context.col_group_by || []; if (group_by.length || col_groupby.length) { this.groupby_mode = 'manual'; } this.pivot_table.set_domain(domain); + + var options; if (this.groupby_mode === 'manual') { - this.pivot_table.set_row_groupby(group_by); - this.pivot_table.set_col_groupby(col_groupby); + options = {row: group_by, col: col_groupby}; } else { - this.pivot_table.set_row_groupby(_.toArray(this.default_row_groupby)); - this.pivot_table.set_col_groupby(_.toArray(this.default_col_groupby)); + options = { + row: _.toArray(this.default_row_groupby), + col: _.toArray(this.default_col_groupby), + }; } + this.pivot_table.set_groupby(options); this.display_data(); }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index dd675270132..3938acb501e 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -4,8 +4,9 @@ (function () { 'use strict'; -openerp.web_graph.PivotTable = openerp.web.Class.extend({ +openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { init: function (model, domain) { + openerp.EventDispatcherMixin.init.call(this); this.rows = { groupby: [], main: null, headers: null }; this.cols = { groupby: [], main: null, headers: null }; this.cells = []; @@ -40,23 +41,16 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } }, - set_row_groupby: function (groupby) { - if ((!groupby.length) && (this.rows.main)) { - this.fold(this.rows.main); - } - if (!_.isEqual(groupby, this.rows.groupby)) { - this.rows.groupby = groupby; - this.invalidate_data(); - } - }, + set_groupby: function (groupbys) { + var col_changed = !_.isEqual(groupbys.col, this.cols.groupby), + row_changed = !_.isEqual(groupbys.row, this.rows.groupby); - set_col_groupby: function (groupby) { - if ((!groupby.length) && (this.cols.main)) { - this.fold(this.cols.main); - } - if (!_.isEqual(groupby, this.cols.groupby)) { - this.cols.groupby = groupby; - this.invalidate_data(); + this.rows.groupby = groupbys.row; + this.cols.groupby = groupbys.col; + + if (col_changed || row_changed) { + this.invalidate_data(); + this.trigger('groupby_changed'); } }, @@ -141,11 +135,17 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ header.is_expanded = false; var fold_lvls = _.map(header.root.headers, function(g) {return g.path.length;}); var new_groupby_length = _.max(fold_lvls); + + if (new_groupby_length < header.root.groupby.length) { + this.trigger('groupby_changed'); + } + header.root.groupby.splice(new_groupby_length); header.children = []; this.cells = _.reject(this.cells, function (cell) { return (_.contains(ids_to_remove, cell.x) || _.contains(ids_to_remove, cell.y)); }); + this.trigger('redraw_required'); }, expand: function (header_id, field_id) { @@ -154,6 +154,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ if (header.path.length == header.root.groupby.length) { header.root.groupby.push(field_id); + this.trigger('groupby_changed'); } var otherDim = (header.root === this.cols) ? this.rows : this.cols; @@ -179,6 +180,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }); header.is_expanded = true; + self.trigger('redraw_required'); }); }, @@ -203,14 +205,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var temp = this.rows; this.rows = this.cols; this.cols = temp; - }, - - fold_rows: function () { - this.fold(this.rows.main); - }, - - fold_cols: function () { - this.fold(this.cols.main); + this.trigger('groupby_changed'); + this.trigger('redraw_required'); }, get_total: function (header) { @@ -255,6 +251,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } else { self.no_data = true; } + self.trigger('redraw_required'); }); }, -- cgit v1.2.3 From 7bb84af05f978f02dc9a8a01d9f73bbea7784d67 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 18 Dec 2013 14:40:40 +0100 Subject: [REF] large refactoring of graphview: it separates the drawing code into a widget that can be used independently of the view (addon web_graph) bzr revid: ged@openerp.com-20131218134040-63fcm5a68gsk3hry --- addons/web_graph/static/src/js/graph.js | 373 ++++++++++++++++---------------- addons/web_graph/static/src/js/pivot.js | 85 ++++---- 2 files changed, 234 insertions(+), 224 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 6805bce1793..f4d93305f41 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -13,32 +13,14 @@ var QWeb = instance.web.qweb; instance.web.views.add('graph', 'instance.web_graph.GraphView'); - /** - * GraphView - */ instance.web_graph.GraphView = instance.web.View.extend({ - template: 'GraphView', display_name: _lt('Graph'), view_type: 'graph', - events: { - 'click .graph_mode_selection li' : 'mode_selection', - 'click .graph_measure_selection li' : 'measure_selection', - 'click .graph_options_selection li' : 'option_selection', - 'click .web_graph_click' : 'cell_click_callback', - 'click a.field-selection' : 'field_selection', - }, - init: function(parent, dataset, view_id, options) { this._super(parent); - this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); this.dataset = dataset; - this.pivot_table = new openerp.web_graph.PivotTable(this.model, dataset.domain); - this.set_default_options(options); - this.dropdown = null; - this.mode = 'pivot'; // pivot, bar_chart, line_chart, pie_chart, heatmap, row_heatmap, col_heatmap - this.measure_list = []; - this.important_fields = []; + this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); this.search_view = parent.searchview; this.groupby_mode = 'default'; // 'default' or 'manual' this.default_row_groupby = []; @@ -58,14 +40,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, start: function () { - this.table = $('
    '); - this.$('.graph_main_content').append(this.table); - instance.web.bus.on('click', this, function (ev) { - if (this.dropdown) { - this.dropdown.remove(); - this.dropdown = null; - } - }); + var options = {enabled:false}; + this.graph_widget = new openerp.web_graph.Graph(this, this.model, options); + this.graph_widget.appendTo(this.$el); + this.graph_widget.pivot.on('groupby_changed', this, this.proxy('register_groupby')); return this.load_view(); }, @@ -77,7 +55,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.mode = 'bar_chart'; } - // get the default groupbys and measure defined in the field view _.each(fields_view_get.arch.children, function (field) { if ('name' in field.attrs) { if ('operator' in field.attrs) { @@ -91,8 +68,116 @@ instance.web_graph.GraphView = instance.web.View.extend({ } } }); - this.pivot_table.set_measure(measure); + this.graph_widget.pivot.config({measure:measure, update:false}); + }, + + do_search: function (domain, context, group_by) { + var self = this, + col_groupby = context.col_group_by || [], + options = {domain:domain}; + + if (group_by.length || col_groupby.length) { + this.groupby_mode = 'manual'; + } + if (!this.graph_widget.enabled) { + options.update = false; + options.silent = true; + } + + if (this.groupby_mode === 'manual') { + options.row_groupby = group_by; + options.col_groupby = col_groupby; + } else { + options.row_groupby = _.toArray(this.default_row_groupby); + options.col_groupby = _.toArray(this.default_col_groupby); + } + this.graph_widget.pivot.config(options); + + if (!this.graph_widget.enabled) { + this.graph_widget.activate_display(); + } + }, + + do_show: function () { + this.do_push_state({}); + return this._super(); + }, + + register_groupby: function() { + var self = this, + query = this.search_view.query; + this.groupby_mode = 'manual'; + + var rows = _.map(this.graph_widget.pivot.rows.groupby, function (group) { + return make_facet('GroupBy', group); + }); + var cols = _.map(this.graph_widget.pivot.cols.groupby, function (group) { + return make_facet('ColGroupBy', group); + }); + + query.reset(rows.concat(cols)); + + function make_facet (category, fields) { + var values, + icon, + backbone_field, + cat_name; + if (!(fields instanceof Array)) { fields = [fields]; } + if (category === 'GroupBy') { + cat_name = 'group_by'; + icon = 'w'; + backbone_field = self.search_view._s_groupby; + } else { + cat_name = 'col_group_by'; + icon = 'f'; + backbone_field = self.search_field; + } + values = _.map(fields, function (field) { + var context = {}; + context[cat_name] = field; + return {label: self.graph_widget.fields[field].string, value: {attrs:{domain: [], context: context}}}; + }); + return {category:category, values: values, icon:icon, field: backbone_field}; + } + }, +}); + +instance.web_graph.Graph = instance.web.Widget.extend({ + template: "GraphWidget", + + events: { + 'click .graph_mode_selection li' : 'mode_selection', + 'click .graph_measure_selection li' : 'measure_selection', + 'click .graph_options_selection li' : 'option_selection', + 'click .web_graph_click' : 'header_cell_clicked', + 'click a.field-selection' : 'field_selection', + }, + + init: function(parent, model, options) { + this._super(parent); + this.model = model; + this.mode = 'pivot'; + this.important_fields = []; + this.measure_list = []; + this.fields = []; + this.enabled = true; + this.dropdown = null; + + this.pivot = new openerp.web_graph.PivotTable(model, []); + + options = options || {}; + + // show_ui, hide ui ?, default stacked/grouped? + if (_.has(options, 'mode')) { this.mode = mode; } + if (_.has(options, 'measure')) { this.pivot.set_measure(options.measure); } + if (_.has(options, 'enabled')) { this.enabled = options.enabled; } + }, + + start: function() { + var self = this; + this.table = $('
    '); + this.$('.graph_main_content').append(this.table); // get the most important fields (of the model) by looking at the // groupby filters defined in the search view var options = {model:this.model, view_type: 'search'}, @@ -110,7 +195,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); }); - // get the fields descriptions from the model + // get the fields descriptions and measure list from the model var deferred2 = this.model.call('fields_get', []).then(function (fs) { self.fields = fs; var temp = _.map(fs, function (field, name) { @@ -133,89 +218,48 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); }); - return $.when(deferred1, deferred2); - }, - - do_search: function (domain, context, group_by) { - var self = this, - col_groupby = context.col_group_by || []; - - if (group_by.length || col_groupby.length) { - this.groupby_mode = 'manual'; - } - - this.pivot_table.set_domain(domain); - - var options; - if (this.groupby_mode === 'manual') { - options = {row: group_by, col: col_groupby}; - } else { - options = { - row: _.toArray(this.default_row_groupby), - col: _.toArray(this.default_col_groupby), - }; - } - this.pivot_table.set_groupby(options); - this.display_data(); - }, - - do_show: function () { - this.do_push_state({}); - return this._super(); + return $.when(deferred1, deferred2).then(function () { + if (this.enabled) { + this.activate_display(); + } + }); }, - display_data: function () { - var pivot = this.pivot_table; - if (pivot.stale_data) { - pivot.update_data().done(this.proxy('display_data')); - } else { - this.$('.graph_main_content svg').remove(); - this.table.empty(); - - if (pivot.no_data) { - var msg = 'No data available. Try to remove any filter or add some data.'; - this.table.append($('' + msg + '')); - } else { - var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; - if (_.contains(table_modes, this.mode)) { - this.draw_table(); - } else { - this.$('.graph_main_content').append($('
    ')); - var options = { - svg: this.$('.graph_main_content svg')[0], - mode: this.mode, - pivot: this.pivot_table, - width: this.$el.width(), - height: Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())), - measure_label: this.measure_label() - }; - openerp.web_graph.draw_chart(options); - } + activate_display: function () { + this.pivot.on('redraw_required', this, this.proxy('display_data')); + this.pivot.update_data(); + this.enabled = true; + instance.web.bus.on('click', this, function (ev) { + if (this.dropdown) { + this.dropdown.remove(); + this.dropdown = null; } - } + }); }, -/****************************************************************************** - * Event handling methods... - ******************************************************************************/ - handle_header_event: function (options) { - var pivot = this.pivot_table, - id = options.id, - header = pivot.get_header(id), - dim = header.root.groupby.length; + display_data: function () { + var pivot = this.pivot; + this.$('.graph_main_content svg').remove(); + this.table.empty(); - if (header.is_expanded) { - pivot.fold(header); - this.register_groupby(); + if (pivot.no_data) { + var msg = 'No data available. Try to remove any filter or add some data.'; + this.table.append($('' + msg + '')); } else { - if (header.path.length < header.root.groupby.length) { - var field = header.root.groupby[header.path.length]; - pivot.expand(id, field).then(this.proxy('register_groupby')); + var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; + if (_.contains(table_modes, this.mode)) { + this.draw_table(); } else { - this.display_dropdown({id:header.id, - target: $(options.event.target), - x: options.event.pageX, - y: options.event.pageY}); + this.$('.graph_main_content').append($('
    ')); + var options = { + svg: this.$('.graph_main_content svg')[0], + mode: this.mode, + pivot: this.pivot, + width: this.$el.width(), + height: Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())), + measure_label: this.measure_label() + }; + openerp.web_graph.draw_chart(options); } } }, @@ -227,65 +271,26 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.display_data(); }, - register_groupby: function() { - var self = this, - query = this.search_view.query; - this.groupby_mode = 'manual'; - - var rows = _.map(this.pivot_table.rows.groupby, function (group) { - return make_facet('GroupBy', group); - }); - var cols = _.map(this.pivot_table.cols.groupby, function (group) { - return make_facet('ColGroupBy', group); - }); - - query.reset(rows.concat(cols)); - - function make_facet (category, fields) { - var values, - icon, - backbone_field, - cat_name; - if (!(fields instanceof Array)) { fields = [fields]; } - if (category === 'GroupBy') { - cat_name = 'group_by'; - icon = 'w'; - backbone_field = self.search_view._s_groupby; - } else { - cat_name = 'col_group_by'; - icon = 'f'; - backbone_field = self.search_field; - } - values = _.map(fields, function (field) { - var context = {}; - context[cat_name] = field; - return {label: self.fields[field].string, value: {attrs:{domain: [], context: context}}}; - }); - return {category:category, values: values, icon:icon, field: backbone_field}; - } - }, - measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; - this.pivot_table.set_measure((measure === '__count') ? null : measure); - this.display_data(); + var actual_measure = (measure === '__count') ? null : measure + this.pivot.config({measure:actual_measure}); }, option_selection: function (event) { event.preventDefault(); switch (event.target.attributes['data-choice'].nodeValue) { case 'swap_axis': - this.pivot_table.swap_axis(); - this.register_groupby(); + this.pivot.swap_axis(); break; case 'expand_all': - this.pivot_table.invalidate_data(); - this.display_data(); + this.pivot.rows.headers = null; + this.pivot.cols.headers = null; + this.pivot.update_data(); break; case 'update_values': - this.pivot_table.stale_data = true; - this.display_data(); + this.pivot.update_data(); break; case 'export_data': // Export code... To do... @@ -293,12 +298,32 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }, - - cell_click_callback: function (event) { + header_cell_clicked: function (event) { event.preventDefault(); event.stopPropagation(); - var id = event.target.attributes['data-id'].nodeValue; - this.handle_header_event({id:id, event:event}); + var id = event.target.attributes['data-id'].nodeValue, + header = this.pivot.get_header(id), + self = this, + dim = header.root.groupby.length; + + if (header.is_expanded) { + this.pivot.fold(header); + } else { + if (header.path.length < header.root.groupby.length) { + var field = header.root.groupby[header.path.length]; + this.pivot.expand(id, field); + } else { + var fields = _.map(this.important_fields, function (field) { + return {id: field, value: self.fields[field].string}; + }); + this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); + $(event.target).after(this.dropdown); + this.dropdown.css({position:'absolute', + left:event.pageX, + top:event.pageY}); + this.$('.field-selection').next('.dropdown-menu').toggle(); + } + } }, field_selection: function (event) { @@ -306,40 +331,21 @@ instance.web_graph.GraphView = instance.web.View.extend({ id = event.target.attributes['data-id'].nodeValue, field_id = event.target.attributes['data-field-id'].nodeValue; event.preventDefault(); - this.pivot_table.expand(id, field_id).then(function () { - self.register_groupby(); - }); - }, - - display_dropdown: function (options) { - var self = this, - pivot = this.pivot_table, - dropdown_options = { - header_id: options.id, - fields: _.map(self.important_fields, function (field) { - return {id: field, value: self.fields[field].string}; - })}; - this.dropdown = $(QWeb.render('field_selection', dropdown_options)); - options.target.after(this.dropdown); - this.dropdown.css({position:'absolute', - left:options.x, - top:options.y}); - this.$('.field-selection').next('.dropdown-menu').toggle(); + this.pivot.expand(id, field_id); }, /****************************************************************************** * Drawing pivot table methods... ******************************************************************************/ draw_table: function () { - this.pivot_table.rows.main.title = 'Total'; - this.pivot_table.cols.main.title = this.measure_label(); + this.pivot.rows.main.title = 'Total'; + this.pivot.cols.main.title = this.measure_label(); this.draw_top_headers(); - _.each(this.pivot_table.rows.headers, this.proxy('draw_row')); + _.each(this.pivot.rows.headers, this.proxy('draw_row')); }, measure_label: function () { - var pivot = this.pivot_table; - return (pivot.measure) ? this.fields[pivot.measure].string : 'Quantity'; + return (this.pivot.measure) ? this.fields[this.pivot.measure].string : 'Quantity'; }, make_border_cell: function (colspan, rowspan) { @@ -358,7 +364,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ draw_top_headers: function () { var self = this, - pivot = this.pivot_table, + pivot = this.pivot, height = _.max(_.map(pivot.cols.headers, function(g) {return g.path.length;})), header_cells = [[this.make_border_cell(1, height)]]; @@ -406,13 +412,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, get_measure_type: function () { - var measure = this.pivot_table.measure; + var measure = this.pivot.measure; return (measure) ? this.fields[measure].type : 'integer'; }, draw_row: function (row) { var self = this, - pivot = this.pivot_table, + pivot = this.pivot, measure_type = this.get_measure_type(), html_row = $(''), row_header = this.make_border_cell(1,1) @@ -471,6 +477,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ return cell; } }, + }); -}; +}; \ No newline at end of file diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 3938acb501e..a38ee51bc78 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -5,6 +5,9 @@ 'use strict'; openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { + + // PivotTable require a 'update_data' after init to be ready + // to do: add an option to enable/disable update_data at the end of init init: function (model, domain) { openerp.EventDispatcherMixin.init.call(this); this.rows = { groupby: [], main: null, headers: null }; @@ -16,7 +19,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.data_loader = new openerp.web_graph.DataLoader(model); this.no_data = true; - this.stale_data = true; }, visible_fields: function () { @@ -27,31 +29,42 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM return result; }, - set_domain: function (domain) { - if (!_.isEqual(domain, this.domain)) { - this.domain = domain; - this.stale_data = true; - } - }, + config: function (options) { + var changed = false; + var groupby_changed = false; + var default_options = { + update:true, + domain:this.domain, + col_groupby: this.cols.groupby, + row_groupby: this.rows.groupby, + measure: this.measure, + silent:false + }; + var options = _.extend(default_options, options); - set_measure: function (measure) { - if (measure !== this.measure) { - this.measure = measure; - this.stale_data = true; + if (!_.isEqual(options.domain, this.domain)) { + this.domain = options.domain; + changed = true; } - }, - - set_groupby: function (groupbys) { - var col_changed = !_.isEqual(groupbys.col, this.cols.groupby), - row_changed = !_.isEqual(groupbys.row, this.rows.groupby); - - this.rows.groupby = groupbys.row; - this.cols.groupby = groupbys.col; - - if (col_changed || row_changed) { - this.invalidate_data(); - this.trigger('groupby_changed'); + if (options.measure !== this.measure) { + this.measure = options.measure; + changed = true; } + if (!_.isEqual(options.col_groupby, this.cols.groupby)) { + this.cols.groupby = options.col_groupby; + changed = true; + this.cols.headers = null; + groupby_changed = true; + } + if (!_.isEqual(options.row_groupby, this.rows.groupby)) { + this.rows.groupby = options.row_groupby; + this.rows.headers = null; + changed = true; + groupby_changed = true; + } + + if (!options.silent && groupby_changed) { this.trigger('groupby_changed'); } + if (options.update && changed) { this.update_data(); } }, set_value: function (id1, id2, value) { @@ -136,15 +149,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var fold_lvls = _.map(header.root.headers, function(g) {return g.path.length;}); var new_groupby_length = _.max(fold_lvls); - if (new_groupby_length < header.root.groupby.length) { - this.trigger('groupby_changed'); - } - - header.root.groupby.splice(new_groupby_length); header.children = []; this.cells = _.reject(this.cells, function (cell) { return (_.contains(ids_to_remove, cell.x) || _.contains(ids_to_remove, cell.y)); }); + if (new_groupby_length < header.root.groupby.length) { + header.root.groupby.splice(new_groupby_length); + this.trigger('groupby_changed'); + } this.trigger('redraw_required'); }, @@ -218,15 +230,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM } }, - invalidate_data: function () { - this.cells = null; - this.rows.main = null; - this.cols.main = null; - this.rows.headers = null; - this.cols.headers = null; - this.stale_data = true; - }, - update_data: function () { var self = this, options = { @@ -237,14 +240,16 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }; return this.data_loader.load_data(options).then (function (result) { - self.stale_data = false; if (result) { self.no_data = false; if (self.cols.headers) { self.update_headers(self.cols, result.col_headers); - self.update_headers(self.rows, result.row_headers); } else { self.expand_headers(self.cols, result.col_headers); + } + if (self.rows.headers) { + self.update_headers(self.rows, result.row_headers); + } else { self.expand_headers(self.rows, result.row_headers); } self.cells = result.cells; @@ -530,8 +535,6 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ } }, - }); - })(); \ No newline at end of file -- cgit v1.2.3 From 0e8a8517f8ec74690c8819b00194efb667e04429 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 18 Dec 2013 16:07:56 +0100 Subject: [REF] moves all the charts code from chart.js into the graph widget (in file graph.js) (addon web_graph) bzr revid: ged@openerp.com-20131218150756-ol0or9m6pg61ye2c --- addons/web_graph/static/src/js/charts.js | 227 ------------------------- addons/web_graph/static/src/js/graph.js | 282 ++++++++++++++++++++++++++++--- 2 files changed, 262 insertions(+), 247 deletions(-) delete mode 100644 addons/web_graph/static/src/js/charts.js (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/charts.js b/addons/web_graph/static/src/js/charts.js deleted file mode 100644 index 9e6c40eb866..00000000000 --- a/addons/web_graph/static/src/js/charts.js +++ /dev/null @@ -1,227 +0,0 @@ - -openerp.web_graph.draw_chart = function (options) { - openerp.web_graph[options.mode](options); -}; - - -openerp.web_graph.bar_chart = function (options) { - var pivot = options.pivot, - dim_x = pivot.rows.groupby.length, - dim_y = pivot.cols.groupby.length, - data = []; - - // No groupby ************************************************************** - if ((dim_x === 0) && (dim_y === 0)) { - data = [{key: 'Total', values:[{ - title: 'Total', - value: options.pivot.get_value(pivot.rows.main.id, pivot.cols.main.id), - }]}]; - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .x(function(d) { return d.title;}) - .y(function(d) { return d.value;}) - .tooltips(false) - .showValues(true) - .width(options.width) - .height(options.height) - .staggerLabels(true); - - d3.select(options.svg) - .datum(data) - .attr('width', options.width) - .attr('height', options.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - // Only column groupbys **************************************************** - } else if ((dim_x === 0) && (dim_y >= 1)){ - data = _.map(pivot.get_columns_depth(1), function (header) { - return { - key: header.title, - values: [{x:header.root.main.title, y: pivot.get_total(header)}] - }; - }); - nv.addGraph(function() { - var chart = nv.models.multiBarChart() - .stacked(true) - .tooltips(false) - .width(options.width) - .height(options.height) - .showControls(false); - - d3.select(options.svg) - .datum(data) - .attr('width', options.width) - .attr('height', options.height) - .transition() - .duration(500) - .call(chart); - - nv.utils.windowResize(chart.update); - - return chart; - }); - // Just 1 row groupby ****************************************************** - } else if ((dim_x === 1) && (dim_y === 0)) { - data = _.map(pivot.rows.main.children, function (pt) { - var value = pivot.get_value(pt.id, pivot.cols.main.id), - title = (pt.title !== undefined) ? pt.title : 'Undefined'; - return {title: title, value: value}; - }); - data = [{key: options.measure_label, values:data}]; - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .x(function(d) { return d.title;}) - .y(function(d) { return d.value;}) - .tooltips(false) - .showValues(true) - .width(options.width) - .height(options.height) - .staggerLabels(true); - - d3.select(options.svg) - .datum(data) - .attr('width', options.width) - .attr('height', options.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - // 1 row groupby and some col groupbys************************************** - } else if ((dim_x === 1) && (dim_y >= 1)) { - data = _.map(pivot.get_columns_depth(1), function (colhdr) { - var values = _.map(pivot.get_rows_depth(1), function (header) { - return { - x: header.title || 'Undefined', - y: pivot.get_value(header.id, colhdr.id, 0) - }; - }); - return {key: colhdr.title || 'Undefined', values: values}; - }); - - nv.addGraph(function () { - var chart = nv.models.multiBarChart() - .stacked(true) - .staggerLabels(true) - .width(options.width) - .height(options.height) - .tooltips(false); - - d3.select(options.svg) - .datum(data) - .attr('width', options.width) - .attr('height', options.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - // At least two row groupby************************************************* - } else { - var keys = _.uniq(_.map(pivot.get_rows_depth(2), function (hdr) { - return hdr.title || 'Undefined'; - })); - data = _.map(keys, function (key) { - var values = _.map(pivot.get_rows_depth(1), function (hdr) { - var subhdr = _.find(hdr.children, function (child) { - return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); - }); - return { - x: hdr.title || 'Undefined', - y: (subhdr) ? pivot.get_total(subhdr) : 0 - }; - }); - return {key:key, values: values}; - }); - - nv.addGraph(function () { - var chart = nv.models.multiBarChart() - .stacked(true) - .staggerLabels(true) - .width(options.width) - .height(options.height) - .tooltips(false); - - d3.select(options.svg) - .datum(data) - .attr('width', options.width) - .attr('height', options.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - } -}; - - -openerp.web_graph.line_chart = function (options) { - var pivot = options.pivot, - dim_x = pivot.rows.groupby.length, - dim_y = pivot.cols.groupby.length; - - var data = _.map(pivot.get_cols_leaves(), function (col) { - var values = _.map(pivot.get_rows_depth(dim_x), function (row) { - return {x: row.title, y: pivot.get_value(row.id,col.id, 0)}; - }); - var title = _.map(col.path, function (p) { - return p || 'Undefined'; - }).join('/'); - if (dim_y === 0) { - title = options.measure_label; - } - return {values: values, key: title}; - }); - - nv.addGraph(function () { - var chart = nv.models.lineChart() - .x(function (d,u) { return u; }) - .width(options.width) - .height(options.height) - .margin({top: 30, right: 20, bottom: 20, left: 60}); - - d3.select(options.svg) - .attr('width', options.width) - .attr('height', options.height) - .datum(data) - .call(chart); - - return chart; - }); -}; - -openerp.web_graph.pie_chart = function (options) { - var pivot = options.pivot, - dim_x = pivot.rows.groupby.length, - dim_y = pivot.cols.groupby.length; - - var data = _.map(pivot.get_rows_leaves(), function (row) { - var title = _.map(row.path, function (p) { - return p || 'Undefined'; - }).join('/'); - if (dim_x === 0) { - title = options.measure_label; - } - return {x: title, y: pivot.get_total(row)}; - }); - - nv.addGraph(function () { - var chart = nv.models.pieChart() - .color(d3.scale.category10().range()) - .width(options.width) - .height(options.height); - - d3.select(options.svg) - .datum(data) - .transition().duration(1200) - .attr('width', options.width) - .attr('height', options.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); -}; diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index f4d93305f41..3c0fe1a8be5 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -156,23 +156,25 @@ instance.web_graph.Graph = instance.web.Widget.extend({ init: function(parent, model, options) { this._super(parent); this.model = model; - this.mode = 'pivot'; this.important_fields = []; this.measure_list = []; this.fields = []; - this.enabled = true; - this.dropdown = null; - this.pivot = new openerp.web_graph.PivotTable(model, []); - - options = options || {}; - - // show_ui, hide ui ?, default stacked/grouped? + this.mode = 'pivot'; if (_.has(options, 'mode')) { this.mode = mode; } - if (_.has(options, 'measure')) { this.pivot.set_measure(options.measure); } + this.enabled = true; if (_.has(options, 'enabled')) { this.enabled = options.enabled; } + this.visible_ui = true; + this.config(options || {}); }, + // hide ui/show, stacked/grouped + config: function (options) { + if (_.has(options, 'visible_ui')) { + this.visible_ui = options.visible_ui; + } + this.pivot.config(options); + }, start: function() { var self = this; @@ -242,6 +244,11 @@ instance.web_graph.Graph = instance.web.Widget.extend({ this.$('.graph_main_content svg').remove(); this.table.empty(); + if (this.visible_ui) { + this.$('.graph_header').css('display', 'block'); + } else { + this.$('.graph_header').css('display', 'none'); + } if (pivot.no_data) { var msg = 'No data available. Try to remove any filter or add some data.'; this.table.append($('' + msg + '')); @@ -251,15 +258,18 @@ instance.web_graph.Graph = instance.web.Widget.extend({ this.draw_table(); } else { this.$('.graph_main_content').append($('
    ')); - var options = { - svg: this.$('.graph_main_content svg')[0], - mode: this.mode, - pivot: this.pivot, - width: this.$el.width(), - height: Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())), - measure_label: this.measure_label() - }; - openerp.web_graph.draw_chart(options); + this.svg = this.$('.graph_main_content svg')[0]; + this.width = this.$el.width(); + this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); + // var options = { + // svg: + // mode: this.mode, + // width: this.$el.width(), + // height: Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())), + // measure_label: this.measure_label() + // }; + this[this.mode](); + // openerp.web_graph.draw_chart(options); } } }, @@ -274,7 +284,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; - var actual_measure = (measure === '__count') ? null : measure + var actual_measure = (measure === '__count') ? null : measure; this.pivot.config({measure:actual_measure}); }, @@ -478,6 +488,238 @@ instance.web_graph.Graph = instance.web.Widget.extend({ } }, +/****************************************************************************** + * Drawing charts methods... + ******************************************************************************/ + bar_chart: function () { + var self = this, + dim_x = this.pivot.rows.groupby.length, + dim_y = this.pivot.cols.groupby.length, + data = []; + + // No groupby ************************************************************** + if ((dim_x === 0) && (dim_y === 0)) { + data = [{key: 'Total', values:[{ + title: 'Total', + value: this.pivot.get_value(this.pivot.rows.main.id, this.pivot.cols.main.id), + }]}]; + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .x(function(d) { return d.title;}) + .y(function(d) { return d.value;}) + .tooltips(false) + .showValues(true) + .width(self.width) + .height(self.height) + .staggerLabels(true); + + d3.select(self.svg) + .datum(data) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + // Only column groupbys **************************************************** + } else if ((dim_x === 0) && (dim_y >= 1)){ + data = _.map(this.pivot.get_columns_depth(1), function (header) { + return { + key: header.title, + values: [{x:header.root.main.title, y: self.pivot.get_total(header)}] + }; + }); + nv.addGraph(function() { + var chart = nv.models.multiBarChart() + .stacked(true) + .tooltips(false) + .width(self.width) + .height(self.height) + .showControls(false); + + d3.select(self.svg) + .datum(data) + .attr('width', self.width) + .attr('height', self.height) + .transition() + .duration(500) + .call(chart); + + nv.utils.windowResize(chart.update); + + return chart; + }); + // Just 1 row groupby ****************************************************** + } else if ((dim_x === 1) && (dim_y === 0)) { + data = _.map(this.pivot.rows.main.children, function (pt) { + var value = self.pivot.get_value(pt.id, self.pivot.cols.main.id), + title = (pt.title !== undefined) ? pt.title : 'Undefined'; + return {title: title, value: value}; + }); + data = [{key: this.measure_label(), values:data}]; + nv.addGraph(function () { + var chart = nv.models.discreteBarChart() + .x(function(d) { return d.title;}) + .y(function(d) { return d.value;}) + .tooltips(false) + .showValues(true) + .width(self.width) + .height(self.height) + .staggerLabels(true); + + d3.select(self.svg) + .datum(data) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + // 1 row groupby and some col groupbys************************************** + } else if ((dim_x === 1) && (dim_y >= 1)) { + data = _.map(this.pivot.get_columns_depth(1), function (colhdr) { + var values = _.map(self.pivot.get_rows_depth(1), function (header) { + return { + x: header.title || 'Undefined', + y: self.pivot.get_value(header.id, colhdr.id, 0) + }; + }); + return {key: colhdr.title || 'Undefined', values: values}; + }); + + nv.addGraph(function () { + var chart = nv.models.multiBarChart() + .stacked(true) + .staggerLabels(true) + .width(self.width) + .height(self.height) + .tooltips(false); + + d3.select(self.svg) + .datum(data) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + // At least two row groupby************************************************* + } else { + var keys = _.uniq(_.map(this.pivot.get_rows_depth(2), function (hdr) { + return hdr.title || 'Undefined'; + })); + data = _.map(keys, function (key) { + var values = _.map(self.pivot.get_rows_depth(1), function (hdr) { + var subhdr = _.find(hdr.children, function (child) { + return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); + }); + return { + x: hdr.title || 'Undefined', + y: (subhdr) ? self.pivot.get_total(subhdr) : 0 + }; + }); + return {key:key, values: values}; + }); + + nv.addGraph(function () { + var chart = nv.models.multiBarChart() + .stacked(true) + .staggerLabels(true) + .width(self.width) + .height(self.height) + .tooltips(false); + + d3.select(self.svg) + .datum(data) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + } + }, + + line_chart: function () { + var self = this, + dim_x = this.pivot.rows.groupby.length, + dim_y = this.pivot.cols.groupby.length; + + var data = _.map(this.pivot.get_cols_leaves(), function (col) { + var values = _.map(self.pivot.get_rows_depth(dim_x), function (row) { + return {x: row.title, y: self.pivot.get_value(row.id,col.id, 0)}; + }); + var title = _.map(col.path, function (p) { + return p || 'Undefined'; + }).join('/'); + if (dim_y === 0) { + title = self.measure_label(); + } + return {values: values, key: title}; + }); + + nv.addGraph(function () { + var chart = nv.models.lineChart() + .x(function (d,u) { return u; }) + .width(self.width) + .height(self.height) + .margin({top: 30, right: 20, bottom: 20, left: 60}); + + d3.select(self.svg) + .attr('width', self.width) + .attr('height', self.height) + .datum(data) + .call(chart); + + return chart; + }); + }, + + pie_chart: function () { + var self = this, + dim_x = this.pivot.rows.groupby.length, + dim_y = this.pivot.cols.groupby.length; + + var data = _.map(this.pivot.get_rows_leaves(), function (row) { + var title = _.map(row.path, function (p) { + return p || 'Undefined'; + }).join('/'); + if (dim_x === 0) { + title = self.measure_label; + } + return {x: title, y: self.pivot.get_total(row)}; + }); + + nv.addGraph(function () { + var chart = nv.models.pieChart() + .color(d3.scale.category10().range()) + .width(self.width) + .height(self.height); + + d3.select(self.svg) + .datum(data) + .transition().duration(1200) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + }, + }); -}; \ No newline at end of file +}; + + + + + + + + -- cgit v1.2.3 From 1323c2c25b01d894f731fd1c2f76d5fabd610223 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 18 Dec 2013 16:20:48 +0100 Subject: [IMP] adds stacked/grouped setting to chart widget (addon web_graph) bzr revid: ged@openerp.com-20131218152048-36no38nud6a5ft10 --- addons/web_graph/static/src/js/graph.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 3c0fe1a8be5..145ee079c07 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -165,6 +165,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ this.enabled = true; if (_.has(options, 'enabled')) { this.enabled = options.enabled; } this.visible_ui = true; + this.bar_ui = 'group'; // group or stack this.config(options || {}); }, @@ -173,6 +174,9 @@ instance.web_graph.Graph = instance.web.Widget.extend({ if (_.has(options, 'visible_ui')) { this.visible_ui = options.visible_ui; } + if (_.has(options, 'bar_ui')) { + this.bar_ui = options.bar_ui; + } this.pivot.config(options); }, @@ -532,7 +536,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ }); nv.addGraph(function() { var chart = nv.models.multiBarChart() - .stacked(true) + .stacked(self.bar_ui === 'stacked') .tooltips(false) .width(self.width) .height(self.height) @@ -591,7 +595,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ nv.addGraph(function () { var chart = nv.models.multiBarChart() - .stacked(true) + .stacked(self.bar_ui === 'stacked') .staggerLabels(true) .width(self.width) .height(self.height) @@ -626,7 +630,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ nv.addGraph(function () { var chart = nv.models.multiBarChart() - .stacked(true) + .stacked(self.bar_ui === 'stacked') .staggerLabels(true) .width(self.width) .height(self.height) -- cgit v1.2.3 From d7fdeec72fca399dfc28687d78e28bf5793d501e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 18 Dec 2013 16:49:49 +0100 Subject: [REF] refactors bar_chart method in graph widget. basically, it removes 80 duplicated lines (addon web_graph) bzr revid: ged@openerp.com-20131218154949-9jno1wb4s549jyl7 --- addons/web_graph/static/src/js/graph.js | 121 ++++++-------------------------- 1 file changed, 23 insertions(+), 98 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 145ee079c07..336be536346 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -499,33 +499,14 @@ instance.web_graph.Graph = instance.web.Widget.extend({ var self = this, dim_x = this.pivot.rows.groupby.length, dim_y = this.pivot.cols.groupby.length, - data = []; + data; // No groupby ************************************************************** if ((dim_x === 0) && (dim_y === 0)) { data = [{key: 'Total', values:[{ - title: 'Total', - value: this.pivot.get_value(this.pivot.rows.main.id, this.pivot.cols.main.id), + x: 'Total', + y: this.pivot.get_value(this.pivot.rows.main.id, this.pivot.cols.main.id), }]}]; - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .x(function(d) { return d.title;}) - .y(function(d) { return d.value;}) - .tooltips(false) - .showValues(true) - .width(self.width) - .height(self.height) - .staggerLabels(true); - - d3.select(self.svg) - .datum(data) - .attr('width', self.width) - .attr('height', self.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); // Only column groupbys **************************************************** } else if ((dim_x === 0) && (dim_y >= 1)){ data = _.map(this.pivot.get_columns_depth(1), function (header) { @@ -534,53 +515,14 @@ instance.web_graph.Graph = instance.web.Widget.extend({ values: [{x:header.root.main.title, y: self.pivot.get_total(header)}] }; }); - nv.addGraph(function() { - var chart = nv.models.multiBarChart() - .stacked(self.bar_ui === 'stacked') - .tooltips(false) - .width(self.width) - .height(self.height) - .showControls(false); - - d3.select(self.svg) - .datum(data) - .attr('width', self.width) - .attr('height', self.height) - .transition() - .duration(500) - .call(chart); - - nv.utils.windowResize(chart.update); - - return chart; - }); // Just 1 row groupby ****************************************************** } else if ((dim_x === 1) && (dim_y === 0)) { data = _.map(this.pivot.rows.main.children, function (pt) { var value = self.pivot.get_value(pt.id, self.pivot.cols.main.id), title = (pt.title !== undefined) ? pt.title : 'Undefined'; - return {title: title, value: value}; + return {x: title, y: value}; }); data = [{key: this.measure_label(), values:data}]; - nv.addGraph(function () { - var chart = nv.models.discreteBarChart() - .x(function(d) { return d.title;}) - .y(function(d) { return d.value;}) - .tooltips(false) - .showValues(true) - .width(self.width) - .height(self.height) - .staggerLabels(true); - - d3.select(self.svg) - .datum(data) - .attr('width', self.width) - .attr('height', self.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); // 1 row groupby and some col groupbys************************************** } else if ((dim_x === 1) && (dim_y >= 1)) { data = _.map(this.pivot.get_columns_depth(1), function (colhdr) { @@ -592,24 +534,6 @@ instance.web_graph.Graph = instance.web.Widget.extend({ }); return {key: colhdr.title || 'Undefined', values: values}; }); - - nv.addGraph(function () { - var chart = nv.models.multiBarChart() - .stacked(self.bar_ui === 'stacked') - .staggerLabels(true) - .width(self.width) - .height(self.height) - .tooltips(false); - - d3.select(self.svg) - .datum(data) - .attr('width', self.width) - .attr('height', self.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); // At least two row groupby************************************************* } else { var keys = _.uniq(_.map(this.pivot.get_rows_depth(2), function (hdr) { @@ -627,25 +551,26 @@ instance.web_graph.Graph = instance.web.Widget.extend({ }); return {key:key, values: values}; }); - - nv.addGraph(function () { - var chart = nv.models.multiBarChart() - .stacked(self.bar_ui === 'stacked') - .staggerLabels(true) - .width(self.width) - .height(self.height) - .tooltips(false); - - d3.select(self.svg) - .datum(data) - .attr('width', self.width) - .attr('height', self.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); } + + nv.addGraph(function () { + var chart = nv.models.multiBarChart() + .tooltips(false) + .width(self.width) + .height(self.height) + .stacked(self.bar_ui === 'stacked') + .staggerLabels(true); + + d3.select(self.svg) + .datum(data) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + }, line_chart: function () { -- cgit v1.2.3 From 007dfea7022ace13c2bb90593ea980e393b4401f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 19 Dec 2013 09:03:39 +0100 Subject: [REF] small refactoring, it simplify the make_cells method in pivot.js (addon web_graph) bzr revid: ged@openerp.com-20131219080339-7aqnuibtfk1y71a3 --- addons/web_graph/static/src/js/pivot.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index a38ee51bc78..04f82492d18 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -495,24 +495,12 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ var attr = group.attributes, group_val = (attr.value instanceof Array) ? attr.value[1] : attr.value, path = current_path, - value; + value = (measure) ? attr.aggregates[measure] : attr.length; - if (group_val === false) { - group_val = undefined; - } - - if (measure) { - value = attr.aggregates[measure]; - } else { - value = attr.length; - } + group_val = (group_val === false) ? undefined : group_val; if (attr.grouped_on !== undefined) { - if (attr.value === false) { - path = path.concat('undefined'); - } else { - path = path.concat(group_val); - } + path = path.concat((attr.value === false) ? 'undefined' : group_val); } var rowpath = path.slice(0, index), -- cgit v1.2.3 From dd71f5e84bbbe159baef0294c10d76ffadd0a22b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 19 Dec 2013 09:47:22 +0100 Subject: [REF] small improvement to simplify two similar methods in pivot.js. goal is to prepare a larger refactoring (addon web_graph) bzr revid: ged@openerp.com-20131219084722-00p29m61vu51rdbb --- addons/web_graph/static/src/js/pivot.js | 40 ++++++++++++++------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 04f82492d18..edbcd9d9b18 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -371,7 +371,7 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ // calls to readgroup. For example, if row.groupby = [r1, r2, r3] and // col.groupby = [c1, c2, c3, c4], then a minimal set of calls is done // with the following groupby: - // [], [c1, c2, c3, c4], r1, c1, c2, c3, c4], [r1, r2, c1, c2, c3, c4], + // [], [c1, c2, c3, c4], [r1, c1, c2, c3, c4], [r1, r2, c1, c2, c3, c4], // [r1, r2, r3, c1, c2, c3, c4] // To simplify the code, we will always do 2 + row.groupby.length calls, // unless col.groupby.length = 0, in which case we do 2 calls ([] and @@ -412,6 +412,10 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ }); }, + get_value: function (data, measure) { + var attr = data.attributes; + return (measure) ? attr.aggregates[measure] : attr.length; + }, format_data: function (total, col_data, row_data, cell_data, options) { var self = this, @@ -430,25 +434,20 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ make_cells(cell_data[0], dim_row, []); make_cells(cell_data[1], 0, []); } - return {col_headers: col_headers, row_headers: row_headers, cells: cells}; function make_headers (data, depth) { var main = { - id: _.uniqueId(), - path: [], - parent: null, - children: [], - title: '', - domain: options.domain, - }; - if (measure) { - main.total = total.attributes.aggregates[measure]; - } else { - main.total = total.attributes.length; - } + id: _.uniqueId(), + path: [], + parent: null, + children: [], + title: '', + domain: options.domain, + total: self.get_value(total, measure), + }; if (depth > 0) { main.children = _.map(data, function (data_pt) { @@ -467,20 +466,15 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ } function make_tree_headers (data_pt, parent, max_depth) { - var value = data_pt.attributes.value, - node = { + var node = { id: _.uniqueId(), - path: parent.path.concat(value), - title: value, + path: parent.path.concat(data_pt.attributes.value), + title: data_pt.attributes.value, domain: data_pt.model._domain, parent: parent, children: [], + total : self.get_value(data_pt, measure), }; - if (measure) { - node.total = data_pt.attributes.aggregates[measure]; - } else { - node.total = data_pt.attributes.length; - } if (node.path.length < max_depth) { node.children = _.map(data_pt.subgroups_data, function (child) { -- cgit v1.2.3 From a41835e296f94dea16b471b0d58349a0575d5de5 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 19 Dec 2013 10:57:08 +0100 Subject: [REF] refactoring in progress... simplify the load_data and format_data methods in pivot table (addon web_graph) bzr revid: ged@openerp.com-20131219095708-c164shdvv59hyj9l --- addons/web_graph/static/src/js/pivot.js | 61 +++++++++++++-------------------- 1 file changed, 23 insertions(+), 38 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index edbcd9d9b18..852d902cdc9 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -380,35 +380,27 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ var self = this, cols = options.col_groupby, rows = options.row_groupby, - measure = options.measure, - domain = options.domain, - visible_fields = rows.concat(cols), - def_array, - groupbys; + visible_fields = rows.concat(cols); - if (measure) { visible_fields = visible_fields.concat(measure); } + if (options.measure) { visible_fields = visible_fields.concat(options.measure); } - if (cols.length > 0) { - groupbys = _.map(_.range(rows.length + 1), function (i) { - return rows.slice(0, i).concat(cols); - }); - groupbys.push([]); - } else { - groupbys = [rows, []]; - } - def_array = _.map(groupbys, function (groupby) { - return self.get_groups(visible_fields, domain, groupby); + var groupbys = _.map(_.range(cols.length + 1), function (i) { + return cols.slice(0, i).concat(rows); + }); + groupbys.push([]); + + var def_array = _.map(groupbys, function (groupby) { + return self.get_groups(visible_fields, options.domain, groupby); }); return $.when.apply(null, def_array).then(function () { - var args = Array.prototype.slice.call(arguments), - col_data = _.first(args), - total = _.last(args)[0], - row_data = _.last(_.initial(args)), - cell_data = args; + var data = Array.prototype.slice.call(arguments), + row_data = data[0], + col_data = (cols.length !== 0) ? data[data.length - 2] : [], + total = data[data.length - 1][0]; return (total === undefined) ? undefined - : self.format_data(total, col_data, row_data, cell_data, options); + : self.format_data(total, col_data, row_data, data, options); }); }, @@ -426,14 +418,10 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ row_headers = make_headers(row_data, dim_row), cells = []; - if (dim_col > 0) { - _.each(cell_data, function (data, index) { - make_cells(data, index, []); - }); // make it more functional? - } else { - make_cells(cell_data[0], dim_row, []); - make_cells(cell_data[1], 0, []); - } + _.each(cell_data, function (data, index) { + make_cells(data, index, []); + }); // make it more functional? + return {col_headers: col_headers, row_headers: row_headers, cells: cells}; @@ -449,11 +437,9 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ total: self.get_value(total, measure), }; - if (depth > 0) { - main.children = _.map(data, function (data_pt) { - return make_tree_headers (data_pt, main, depth); - }); - } + main.children = _.map(data, function (data_pt) { + return make_tree_headers (data_pt, main, depth); + }); var result = [], make_list = function (tree) { @@ -497,9 +483,8 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ path = path.concat((attr.value === false) ? 'undefined' : group_val); } - var rowpath = path.slice(0, index), - colpath = path.slice(index); - + var colpath = path.slice(0, index), + rowpath = path.slice(index); var row = _.find(row_headers, function (header) { return _.isEqual(header.path, rowpath); }); -- cgit v1.2.3 From 5e1aebc4b5c720205307467b6af390f0b1f261d1 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 19 Dec 2013 12:16:06 +0100 Subject: [REF] simplify the format_data method in pivot table (addon web_graph) bzr revid: ged@openerp.com-20131219111606-u140yaf9y56q1uhg --- addons/web_graph/static/src/js/pivot.js | 139 +++++++++++++------------------- 1 file changed, 56 insertions(+), 83 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 852d902cdc9..cca5d6d691d 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -40,7 +40,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM measure: this.measure, silent:false }; - var options = _.extend(default_options, options); + options = _.extend(default_options, options); if (!_.isEqual(options.domain, this.domain)) { this.domain = options.domain; @@ -306,12 +306,11 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ get_groups: function (fields, domain, groupbys, options) { var self = this, - options = (options) ? options : {}, - groupings = (options.first_groupby) ? [options.first_groupby].concat(groupbys) : groupbys; + groupings = ((options || {}).first_groupby) ? [(options || {}).first_groupby].concat(groupbys) : groupbys; return this.query_db(fields, domain, groupings).then(function (groups) { return _.map(groups, function (group) { - return (options.add_path) ?self.add_path(group, []) : group; + return ((options || {}).add_path) ? self.add_path(group, []) : group; }); }); @@ -368,14 +367,10 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ // 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. For example, if row.groupby = [r1, r2, r3] and - // col.groupby = [c1, c2, c3, c4], then a minimal set of calls is done - // with the following groupby: - // [], [c1, c2, c3, c4], [r1, c1, c2, c3, c4], [r1, r2, c1, c2, c3, c4], - // [r1, r2, r3, c1, c2, c3, c4] - // To simplify the code, we will always do 2 + row.groupby.length calls, - // unless col.groupby.length = 0, in which case we do 2 calls ([] and - // row_groupbys), but this can be optimized later. + // 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 (options) { var self = this, cols = options.col_groupby, @@ -399,6 +394,7 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ col_data = (cols.length !== 0) ? data[data.length - 2] : [], total = data[data.length - 1][0]; + options.total = total; return (total === undefined) ? undefined : self.format_data(total, col_data, row_data, data, options); }); @@ -413,93 +409,70 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ var self = this, dim_row = options.row_groupby.length, dim_col = options.col_groupby.length, - measure = options.measure, - col_headers = make_headers(col_data, dim_col), - row_headers = make_headers(row_data, dim_row), + col_headers = make_list(this.make_headers(col_data, dim_col, options)), + row_headers = make_list(this.make_headers(row_data, dim_row, options)), cells = []; _.each(cell_data, function (data, index) { - make_cells(data, index, []); + self.make_cells(data, index, [], cells, row_headers, col_headers, options); }); // make it more functional? return {col_headers: col_headers, row_headers: row_headers, cells: cells}; - function make_headers (data, depth) { - var main = { - id: _.uniqueId(), - path: [], - parent: null, - children: [], - title: '', - domain: options.domain, - total: self.get_value(total, measure), - }; - - main.children = _.map(data, function (data_pt) { - return make_tree_headers (data_pt, main, depth); - }); - - var result = [], - make_list = function (tree) { - result.push(tree); - _.each(tree.children, make_list); - }; + function make_list (tree) { + return [].concat.apply([tree], _.map(tree.children, make_list)); + } + }, - make_list(main); - return result; - } + make_headers: function (data, depth, options, parent) { + var self = this, + main = { + id: _.uniqueId(), + path: (parent) ? parent.path.concat(data.attributes.value) : [], + parent: parent, + children: [], + title: (parent) ? data.attributes.value : '', + domain: (parent) ? data.model._domain : options.domain, + total: this.get_value(options.total, options.measure), + }; - function make_tree_headers (data_pt, parent, max_depth) { - var node = { - id: _.uniqueId(), - path: parent.path.concat(data_pt.attributes.value), - title: data_pt.attributes.value, - domain: data_pt.model._domain, - parent: parent, - children: [], - total : self.get_value(data_pt, measure), - }; - - if (node.path.length < max_depth) { - node.children = _.map(data_pt.subgroups_data, function (child) { - return make_tree_headers (child, node, max_depth); - }); - } - return node; + if (main.path.length < depth) { + main.children = _.map(data.subgroups_data || data, function (data_pt) { + return self.make_headers (data_pt, depth, options, main); + }); } + return main; + }, - function make_cells (data, index, current_path) { - _.each(data, function (group) { - var attr = group.attributes, - group_val = (attr.value instanceof Array) ? attr.value[1] : attr.value, - path = current_path, - value = (measure) ? attr.aggregates[measure] : attr.length; - - group_val = (group_val === false) ? undefined : group_val; + make_cells: function (data, index, current_path, current_cells, rows, cols, options) { + var self = this; + _.each(data, function (group) { + var attr = group.attributes, + group_val = (attr.value instanceof Array) ? attr.value[1] : attr.value, + path = current_path, + value = (options.measure) ? attr.aggregates[options.measure] : attr.length; - if (attr.grouped_on !== undefined) { - path = path.concat((attr.value === false) ? 'undefined' : group_val); - } + group_val = (group_val === false) ? undefined : group_val; - var colpath = path.slice(0, index), - rowpath = path.slice(index); - var row = _.find(row_headers, function (header) { - return _.isEqual(header.path, rowpath); - }); - var col = _.find(col_headers, function (header) { - return _.isEqual(header.path, colpath); - }); - cells.push({x: Math.min(row.id, col.id), - y: Math.max(row.id, col.id), - value: value}); - - if (attr.has_children) { - make_cells (group.subgroups_data, index, path); - } + if (attr.grouped_on !== undefined) { + path = path.concat((attr.value === false) ? 'undefined' : group_val); + } + var row = _.find(rows, function (header) { + return _.isEqual(header.path, path.slice(index)); }); - } + var col = _.find(cols, function (header) { + return _.isEqual(header.path, path.slice(0, index)); + }); + current_cells.push({x: Math.min(row.id, col.id), + y: Math.max(row.id, col.id), + value: value}); + + if (attr.has_children) { + self.make_cells (group.subgroups_data, index, path, current_cells, rows, cols, options); + } + }); }, }); -- cgit v1.2.3 From 7fc2afc5162124e213af84327b87cdc97ec9dec0 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 19 Dec 2013 13:54:22 +0100 Subject: [FIX] properly handles the situation where a user selected twice the same field in the search view groupbys (it simply added the field twice to groupbys instead of removing it (addon web_graph) bzr revid: ged@openerp.com-20131219125422-n2rpzbekyg7e0eyh --- addons/web_graph/static/src/js/graph.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 336be536346..a473e4df042 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -22,6 +22,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.dataset = dataset; this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); this.search_view = parent.searchview; + this.search_view_groupby = []; this.groupby_mode = 'default'; // 'default' or 'manual' this.default_row_groupby = []; this.default_col_groupby = []; @@ -76,6 +77,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ col_groupby = context.col_group_by || [], options = {domain:domain}; + this.search_view_groupby = group_by; if (group_by.length || col_groupby.length) { this.groupby_mode = 'manual'; } @@ -106,8 +108,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ register_groupby: function() { var self = this, query = this.search_view.query; - this.groupby_mode = 'manual'; + this.groupby_mode = 'manual'; + if (_.isEqual(this.search_view_groupby, this.graph_widget.pivot.rows.groupby)) { + return; + } var rows = _.map(this.graph_widget.pivot.rows.groupby, function (group) { return make_facet('GroupBy', group); }); -- cgit v1.2.3 From 1d92fc0353c7faad27d0e3a11c1591ce5b71d46e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 19 Dec 2013 14:10:58 +0100 Subject: [FIX] correctly honors the 'bar' setting in graph views descriptions (addon web_graph) bzr revid: ged@openerp.com-20131219131058-ng9fix57v5hqu8pq --- addons/web_graph/static/src/js/graph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index a473e4df042..234fffc5449 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -53,7 +53,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ measure = null; if (fields_view_get.arch.attrs.type === 'bar') { - this.mode = 'bar_chart'; + this.graph_widget.mode = 'bar_chart'; } _.each(fields_view_get.arch.children, function (field) { -- cgit v1.2.3 From 261b17d7b86702bdfb77403daf93ca8f3537b64c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 19 Dec 2013 14:49:58 +0100 Subject: [REF] removes old useless comments (addon web_graph) bzr revid: ged@openerp.com-20131219134958-tdgcu3ytbsqszczw --- addons/web_graph/static/src/js/graph.js | 8 -------- 1 file changed, 8 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 234fffc5449..189ce801732 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -270,15 +270,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ this.svg = this.$('.graph_main_content svg')[0]; this.width = this.$el.width(); this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); - // var options = { - // svg: - // mode: this.mode, - // width: this.$el.width(), - // height: Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())), - // measure_label: this.measure_label() - // }; this[this.mode](); - // openerp.web_graph.draw_chart(options); } } }, -- cgit v1.2.3 From 828d06f174b6892cfbe11fe454eb659589b17720 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 20 Dec 2013 12:02:43 +0100 Subject: [IMP] makes the graph view accept a new way to define graphs (supports type='col', type='row' and type='measure' attributes to fields, also supports 'stacked' attribute in (addon web_graph) bzr revid: ged@openerp.com-20131220110243-sccxichm0mgm21uz --- addons/web_graph/static/src/js/graph.js | 42 +++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 189ce801732..4eeaec194eb 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -50,26 +50,43 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_loading: function (fields_view_get) { var self = this, - measure = null; + arch = fields_view_get.arch, + measure = null, + stacked = false; - if (fields_view_get.arch.attrs.type === 'bar') { + if (arch.attrs.type === 'bar' || !_.has(arch.attrs, 'type')) { this.graph_widget.mode = 'bar_chart'; } + if (arch.attrs.stacked === "True") { + stacked = true; + } - _.each(fields_view_get.arch.children, function (field) { - if ('name' in field.attrs) { + _.each(arch.children, function (field) { + if (_.has(field.attrs, 'type')) { + switch (field.attrs.type) { + case "row": + self.default_row_groupby.push(field.attrs.name); + break; + case "col": + self.default_col_groupby.push(field.attrs.name); + break; + case "measure": + measure = field.attrs.name; + break; + } + } else { // old style, kept for backward compatibility if ('operator' in field.attrs) { measure = field.attrs.name; } else { - if (measure) { - self.default_col_groupby.push(field.attrs.name); - } else { - self.default_row_groupby.push(field.attrs.name); - } + self.default_row_groupby.push(field.attrs.name); } } }); - this.graph_widget.pivot.config({measure:measure, update:false}); + this.graph_widget.config({ + measure:measure, + update:false, + bar_ui: (stacked) ? 'stack' : 'group' + }); }, do_search: function (domain, context, group_by) { @@ -249,7 +266,6 @@ instance.web_graph.Graph = instance.web.Widget.extend({ }, display_data: function () { - var pivot = this.pivot; this.$('.graph_main_content svg').remove(); this.table.empty(); @@ -258,7 +274,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ } else { this.$('.graph_header').css('display', 'none'); } - if (pivot.no_data) { + if (this.pivot.no_data) { var msg = 'No data available. Try to remove any filter or add some data.'; this.table.append($('' + msg + '')); } else { @@ -555,7 +571,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ .tooltips(false) .width(self.width) .height(self.height) - .stacked(self.bar_ui === 'stacked') + .stacked(self.bar_ui === 'stack') .staggerLabels(true); d3.select(self.svg) -- cgit v1.2.3 From e844ba1040aa3ea52792324272e3a39a9df2ea6e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 20 Dec 2013 13:39:25 +0100 Subject: [FIX] prevents a crash happening in some cases when the searchview does not initialize a groupbygroup instance before the method register_groupby in graph view used it (addon web_graph) bzr revid: ged@openerp.com-20131220123925-qycdvanm51nkc4uo --- addons/web_graph/static/src/js/graph.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 4eeaec194eb..b966a38e898 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -127,7 +127,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ query = this.search_view.query; this.groupby_mode = 'manual'; - if (_.isEqual(this.search_view_groupby, this.graph_widget.pivot.rows.groupby)) { + if (_.isEqual(this.search_view_groupby, this.graph_widget.pivot.rows.groupby) || + (!_.has(this.search_view, '_s_groupby'))) { return; } var rows = _.map(this.graph_widget.pivot.rows.groupby, function (group) { @@ -340,6 +341,9 @@ instance.web_graph.Graph = instance.web.Widget.extend({ var field = header.root.groupby[header.path.length]; this.pivot.expand(id, field); } else { + if (!this.important_fields.length) { + return; + } var fields = _.map(this.important_fields, function (field) { return {id: field, value: self.fields[field].string}; }); -- cgit v1.2.3 From db9cdb7eb0c7c6e8a26c89fd314dd016d8f8ab03 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 24 Dec 2013 11:09:42 +0100 Subject: [IMP] makes some small changes to improves backward compatibility in some edge cases (takes the first 'operator' as a measure instead of the last, ...) in graph view (addon web_graph) bzr revid: ged@openerp.com-20131224100942-jnrdjeb9lg7rx8d2 --- addons/web_graph/static/src/js/graph.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index b966a38e898..991b21980e6 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -76,7 +76,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ } } else { // old style, kept for backward compatibility if ('operator' in field.attrs) { - measure = field.attrs.name; + measure = (measure) ? measure : field.attrs.name; } else { self.default_row_groupby.push(field.attrs.name); } @@ -95,6 +95,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ options = {domain:domain}; this.search_view_groupby = group_by; + + if (group_by.length && this.groupby_mode !== 'manual') { + if (_.isEqual(col_groupby, [])) { + col_groupby = this.default_col_groupby; + } + } if (group_by.length || col_groupby.length) { this.groupby_mode = 'manual'; } @@ -243,7 +249,6 @@ instance.web_graph.Graph = instance.web.Widget.extend({ .attr('href', '#') .append(self.fields[measure].string); measure_selection.append($('
  • ').append(choice)); - }); }); @@ -572,7 +577,6 @@ instance.web_graph.Graph = instance.web.Widget.extend({ nv.addGraph(function () { var chart = nv.models.multiBarChart() - .tooltips(false) .width(self.width) .height(self.height) .stacked(self.bar_ui === 'stack') -- cgit v1.2.3 From 457090c1a3bbf4931ef3579cc7ca6d4a6c5765b3 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 24 Dec 2013 12:22:24 +0100 Subject: [REF] removes some useless variables and some other cleaning to please jshint (addon web_graph) bzr revid: ged@openerp.com-20131224112224-q1o0hmp1s2ryi9bn --- addons/web_graph/static/src/js/graph.js | 30 +++++++++++++----------------- addons/web_graph/static/src/js/pivot.js | 4 ++-- 2 files changed, 15 insertions(+), 19 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 991b21980e6..8a7ac4811b6 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -57,20 +57,20 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (arch.attrs.type === 'bar' || !_.has(arch.attrs, 'type')) { this.graph_widget.mode = 'bar_chart'; } - if (arch.attrs.stacked === "True") { + if (arch.attrs.stacked === 'True') { stacked = true; } _.each(arch.children, function (field) { if (_.has(field.attrs, 'type')) { switch (field.attrs.type) { - case "row": + case 'row': self.default_row_groupby.push(field.attrs.name); break; - case "col": + case 'col': self.default_col_groupby.push(field.attrs.name); break; - case "measure": + case 'measure': measure = field.attrs.name; break; } @@ -83,15 +83,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }); this.graph_widget.config({ - measure:measure, + measure:measure, update:false, bar_ui: (stacked) ? 'stack' : 'group' }); }, do_search: function (domain, context, group_by) { - var self = this, - col_groupby = context.col_group_by || [], + var col_groupby = context.col_group_by || [], options = {domain:domain}; this.search_view_groupby = group_by; @@ -99,12 +98,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (group_by.length && this.groupby_mode !== 'manual') { if (_.isEqual(col_groupby, [])) { col_groupby = this.default_col_groupby; - } + } } if (group_by.length || col_groupby.length) { this.groupby_mode = 'manual'; } - if (!this.graph_widget.enabled) { + if (!this.graph_widget.enabled) { options.update = false; options.silent = true; } @@ -172,7 +171,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); instance.web_graph.Graph = instance.web.Widget.extend({ - template: "GraphWidget", + template: 'GraphWidget', events: { 'click .graph_mode_selection li' : 'mode_selection', @@ -263,7 +262,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ this.pivot.on('redraw_required', this, this.proxy('display_data')); this.pivot.update_data(); this.enabled = true; - instance.web.bus.on('click', this, function (ev) { + instance.web.bus.on('click', this, function () { if (this.dropdown) { this.dropdown.remove(); this.dropdown = null; @@ -336,8 +335,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ event.stopPropagation(); var id = event.target.attributes['data-id'].nodeValue, header = this.pivot.get_header(id), - self = this, - dim = header.root.groupby.length; + self = this; if (header.is_expanded) { this.pivot.fold(header); @@ -363,8 +361,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ }, field_selection: function (event) { - var self = this, - id = event.target.attributes['data-id'].nodeValue, + var id = event.target.attributes['data-id'].nodeValue, field_id = event.target.attributes['data-field-id'].nodeValue; event.preventDefault(); this.pivot.expand(id, field_id); @@ -631,8 +628,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ pie_chart: function () { var self = this, - dim_x = this.pivot.rows.groupby.length, - dim_y = this.pivot.cols.groupby.length; + dim_x = this.pivot.rows.groupby.length; var data = _.map(this.pivot.get_rows_leaves(), function (row) { var title = _.map(row.path, function (p) { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index cca5d6d691d..a9a6a4f465e 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -33,8 +33,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var changed = false; var groupby_changed = false; var default_options = { - update:true, - domain:this.domain, + update:true, + domain:this.domain, col_groupby: this.cols.groupby, row_groupby: this.rows.groupby, measure: this.measure, -- cgit v1.2.3 From 69f6efa000e5368462fa3a0c66577d0f405334f0 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 24 Dec 2013 15:09:42 +0100 Subject: [IMP] hides controls (stacked/grouped) in graph view when they are useless (i.e., when there's only one dimension which can't be stacked/grouped (addon web_graph) bzr revid: ged@openerp.com-20131224140942-w0dwy3ck6yslbhxy --- addons/web_graph/static/src/js/graph.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 8a7ac4811b6..c155337d90e 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -579,6 +579,8 @@ instance.web_graph.Graph = instance.web.Widget.extend({ .stacked(self.bar_ui === 'stack') .staggerLabels(true); + if (dim_x === 1 && dim_y === 0) { chart.showControls(false); } + d3.select(self.svg) .datum(data) .attr('width', self.width) -- cgit v1.2.3 From d145c7a8c4bd828d741fdd6fd9f3d8d0fee0fa84 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 24 Dec 2013 16:37:35 +0100 Subject: [IMP] displays a nice message when the graph view has no data to display (addon web_graph) bzr revid: ged@openerp.com-20131224153735-on6cx12v7x2r1ln0 --- addons/web_graph/static/src/js/graph.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index c155337d90e..17a0721fd82 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -272,6 +272,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ display_data: function () { this.$('.graph_main_content svg').remove(); + this.$('.graph_main_content div').remove(); this.table.empty(); if (this.visible_ui) { @@ -280,8 +281,9 @@ instance.web_graph.Graph = instance.web.Widget.extend({ this.$('.graph_header').css('display', 'none'); } if (this.pivot.no_data) { - var msg = 'No data available. Try to remove any filter or add some data.'; - this.table.append($('' + msg + '')); + this.$('.graph_main_content').append($(QWeb.render('graph_no_data'))); + // var msg = 'No data available. Try to remove any filter or add some data.'; + // this.table.append($('' + msg + '')); } else { var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; if (_.contains(table_modes, this.mode)) { -- cgit v1.2.3 From 5a2ddfdf8053f2166ddcbcd04299e5788f64b786 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 26 Dec 2013 13:34:49 +0100 Subject: [FIX] forces an update when the user switches back to the graph view, to make sure the data displayed are up to date (graph view, addon web_graph) bzr revid: ged@openerp.com-20131226123449-qjm7hvkhfsdvi7pw --- addons/web_graph/static/src/js/graph.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 17a0721fd82..18432d9fa61 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -119,6 +119,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (!this.graph_widget.enabled) { this.graph_widget.activate_display(); + this.ViewManager.on('switch_mode', this, function () {this.graph_widget.pivot.update_data(); }); } }, -- cgit v1.2.3 From c44786804d289f768606c29f1dd48451370f0e32 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 26 Dec 2013 14:37:35 +0100 Subject: [IMP] adds an image when a graph view has no data to display (it uses the same image as an empty dashboard) (addon web_graph) bzr revid: ged@openerp.com-20131226133735-x2g7veg6d9p77y2d --- addons/web_graph/static/src/js/graph.js | 2 -- 1 file changed, 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 18432d9fa61..b56a2cde7a3 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -283,8 +283,6 @@ instance.web_graph.Graph = instance.web.Widget.extend({ } if (this.pivot.no_data) { this.$('.graph_main_content').append($(QWeb.render('graph_no_data'))); - // var msg = 'No data available. Try to remove any filter or add some data.'; - // this.table.append($('' + msg + '')); } else { var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; if (_.contains(table_modes, this.mode)) { -- cgit v1.2.3 From e1e676d737a2f682ed6a106e99b63a4dd377c5d5 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 26 Dec 2013 17:14:57 +0100 Subject: [FIX] correctly calls the parent of the graph view in the constructor (now, the view manager gets the correct view_id) (graph view, addon web_graph) bzr revid: ged@openerp.com-20131226161457-a4k3iflz61fiaqj4 --- addons/web_graph/static/src/js/graph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index b56a2cde7a3..9806e7011a4 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -18,7 +18,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_type: 'graph', init: function(parent, dataset, view_id, options) { - this._super(parent); + this._super(parent, dataset, view_id, options); this.dataset = dataset; this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); this.search_view = parent.searchview; -- cgit v1.2.3 From 0650d9d7380ec1885e6f9bd6627b7d14fd2eeded Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 27 Dec 2013 11:22:40 +0100 Subject: [FIX] correctly displays fields of type 'selection' in graph view. Previously, the code only displayed the key and not the value (addon web_graph) bzr revid: ged@openerp.com-20131227102240-gmgik0p5lujssm3w --- addons/web_graph/static/src/js/graph.js | 1 + addons/web_graph/static/src/js/pivot.js | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 9806e7011a4..cfac0ea02f6 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -233,6 +233,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ // get the fields descriptions and measure list from the model var deferred2 = this.model.call('fields_get', []).then(function (fs) { self.fields = fs; + self.pivot.config({fields:fs}); var temp = _.map(fs, function (field, name) { return {name:name, type: field.type}; }); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index a9a6a4f465e..e94b82df389 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -42,6 +42,10 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }; options = _.extend(default_options, options); + if (options.fields) { + this.data_loader.fields = options.fields; + } + if (!_.isEqual(options.domain, this.domain)) { this.domain = options.domain; changed = true; @@ -302,6 +306,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM openerp.web_graph.DataLoader = openerp.web.Class.extend({ init: function (model) { this.model = model; + this.fields = null; }, get_groups: function (fields, domain, groupbys, options) { @@ -325,7 +330,7 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ var non_empty_results = _.filter(results, function (group) { return group.attributes.length > 0; }); - _.each(non_empty_results, self.sanitize_value); + _.each(non_empty_results, self.sanitize_value.bind(self)); if (groupbys.length <= 1) { return non_empty_results; } else { @@ -345,6 +350,17 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ sanitize_value: function (group) { var value = group.attributes.value; + + if (this.fields && + group.attributes.grouped_on && + this.fields[group.attributes.grouped_on].type === 'selection') { + var selection = this.fields[group.attributes.grouped_on].selection; + var value_lookup = _.find(selection, function (val) { + return val[0] === value; + }); + group.attributes.value = (value_lookup) ? value_lookup[1] : 'undefined'; + return; + } if (value === false) { group.attributes.value = 'undefined'; } else if (value instanceof Array) { -- cgit v1.2.3 From ed4fdc51080c88c6cc289eedb86407c0587d1648 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 27 Dec 2013 11:25:10 +0100 Subject: [REF] simplifies a for loop to make the code simpler (addon web_graph) bzr revid: ged@openerp.com-20131227102510-dwpjth4fng4ze14e --- addons/web_graph/static/src/js/graph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index cfac0ea02f6..3a6d5e8ffed 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -460,7 +460,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ .append(this.make_header_title(row).attr('data-id', row.id)) .addClass('graph_border'); - for (var i in _.range(row.path.length)) { + for (var i = 0; i < row.path.length; i++) { row_header.prepend($('', {class:'web_graph_indent'})); } -- cgit v1.2.3 From 868be53bae50a49d86658102baa092c81e048691 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 27 Dec 2013 15:28:14 +0100 Subject: [IMP] incline the x-axis text by 15 degree when there are too many bars to display in a bar chart. Also, reduces the number of 'ticks' displayed (addon web_graph) bzr revid: ged@openerp.com-20131227142814-8ktqqxlthfa5hxe8 --- addons/web_graph/static/src/js/graph.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 3a6d5e8ffed..33d17e2b059 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -578,9 +578,15 @@ instance.web_graph.Graph = instance.web.Widget.extend({ var chart = nv.models.multiBarChart() .width(self.width) .height(self.height) + .reduceXTicks(false) .stacked(self.bar_ui === 'stack') .staggerLabels(true); + if (self.width / data[0].values.length < 100) { + chart.rotateLabels(-15); + chart.reduceXTicks(true); + chart.margin({bottom:40}); + } if (dim_x === 1 && dim_y === 0) { chart.showControls(false); } d3.select(self.svg) -- cgit v1.2.3 From 66ee322d0ff749cbbc8ba382ebb89a755bed66d4 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 27 Dec 2013 15:35:08 +0100 Subject: [FIX] fixes a crash happening when the context of some attributes does not have a 'group_by' attribute (in the group fields of the search view) bzr revid: ged@openerp.com-20131227143508-3g04fn2s5u9vxams --- addons/web_graph/static/src/js/graph.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 33d17e2b059..7dc6d261b0d 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -224,7 +224,9 @@ instance.web_graph.Graph = instance.web.Widget.extend({ _.each(g.children, function (g) { if (g.attrs.context) { var field_id = py.eval(g.attrs.context).group_by; - self.important_fields.push(field_id); + if (field_id) { + self.important_fields.push(field_id); + } } }); }); -- cgit v1.2.3 From 650d792413ebb6fa0af8783a97f7de032dd47d42 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 27 Dec 2013 15:55:01 +0100 Subject: [IMP] removes the 'group/stack' buttons from the bar chart ui and adds 'group/stack' controls in the option menu of the graph widget. It makes small graphs much cleaner (addon web_graph) bzr revid: ged@openerp.com-20131227145501-0hf21nieyl8mgomm --- addons/web_graph/static/src/js/graph.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7dc6d261b0d..6a70a9c4459 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -317,6 +317,18 @@ instance.web_graph.Graph = instance.web.Widget.extend({ option_selection: function (event) { event.preventDefault(); switch (event.target.attributes['data-choice'].nodeValue) { + case 'bar_grouped': + this.bar_ui = 'group'; + if (this.mode === 'bar_chart') { + this.display_data(); + } + break; + case 'bar_stacked': + this.bar_ui = 'stack'; + if (this.mode === 'bar_chart') { + this.display_data(); + } + break; case 'swap_axis': this.pivot.swap_axis(); break; @@ -582,6 +594,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ .height(self.height) .reduceXTicks(false) .stacked(self.bar_ui === 'stack') + .showControls(false) .staggerLabels(true); if (self.width / data[0].values.length < 100) { @@ -589,7 +602,6 @@ instance.web_graph.Graph = instance.web.Widget.extend({ chart.reduceXTicks(true); chart.margin({bottom:40}); } - if (dim_x === 1 && dim_y === 0) { chart.showControls(false); } d3.select(self.svg) .datum(data) -- cgit v1.2.3 From fb63eb63ededd5dd5c747728cd0d23a3b409f77b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 27 Dec 2013 16:07:19 +0100 Subject: [IMP] removes the stagger labels in bar charts, only uses the inclined labels when necessary (addon web_graph) bzr revid: ged@openerp.com-20131227150719-olinm65mh515quc2 --- addons/web_graph/static/src/js/graph.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 6a70a9c4459..ffc94e6dd84 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -594,10 +594,9 @@ instance.web_graph.Graph = instance.web.Widget.extend({ .height(self.height) .reduceXTicks(false) .stacked(self.bar_ui === 'stack') - .showControls(false) - .staggerLabels(true); + .showControls(false); - if (self.width / data[0].values.length < 100) { + if (self.width / data[0].values.length < 80) { chart.rotateLabels(-15); chart.reduceXTicks(true); chart.margin({bottom:40}); -- cgit v1.2.3 From e69f4d1af6180f95d22f52e735f1f716b28de45f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 27 Dec 2013 16:20:55 +0100 Subject: [FIX] fixes a rendering bug which happened when the rowspan (or colspan) attributes were set to 0. Now, it is always set to a value >= 1 (addon web_graph) bzr revid: ged@openerp.com-20131227152055-77fvsc27mzs0x5t9 --- addons/web_graph/static/src/js/graph.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index ffc94e6dd84..80b7eb07d6c 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -399,8 +399,8 @@ instance.web_graph.Graph = instance.web.Widget.extend({ make_border_cell: function (colspan, rowspan) { return $('').addClass('graph_border') - .attr('colspan', colspan) - .attr('rowspan', rowspan); + .attr('colspan', (colspan) ? colspan : 1) + .attr('rowspan', (rowspan) ? rowspan : 1); }, make_header_title: function (header) { -- cgit v1.2.3 From 3d5b03af08409caf78f3deef263ebebb894d9e61 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 31 Dec 2013 10:02:57 +0100 Subject: [IMP] changes the css of the pivot table to make it look decent (at least, not as awful as before), (addon web_graph) bzr revid: ged@openerp.com-20131231090257-y0os22omx0pgjaqb --- addons/web_graph/static/src/js/graph.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 80b7eb07d6c..9fcb7f3ea8e 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -397,8 +397,9 @@ instance.web_graph.Graph = instance.web.Widget.extend({ return (this.pivot.measure) ? this.fields[this.pivot.measure].string : 'Quantity'; }, - make_border_cell: function (colspan, rowspan) { - return $('').addClass('graph_border') + make_border_cell: function (colspan, rowspan, headercell) { + var tag = (headercell) ? $('') : $(''); + return tag.addClass('graph_border') .attr('colspan', (colspan) ? colspan : 1) .attr('rowspan', (rowspan) ? rowspan : 1); }, @@ -413,9 +414,10 @@ instance.web_graph.Graph = instance.web.Widget.extend({ draw_top_headers: function () { var self = this, + thead = $(''), pivot = this.pivot, height = _.max(_.map(pivot.cols.headers, function(g) {return g.path.length;})), - header_cells = [[this.make_border_cell(1, height)]]; + header_cells = [[this.make_border_cell(1, height, true)]]; function set_dim (cols) { _.each(cols.children, set_dim); @@ -429,7 +431,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ } function make_col_header (col) { - var cell = self.make_border_cell(col.width, col.height); + var cell = self.make_border_cell(col.width, col.height, true); return cell.append(self.make_header_title(col).attr('data-id', col.id)); } @@ -452,12 +454,13 @@ instance.web_graph.Graph = instance.web.Widget.extend({ make_cells(pivot.cols.headers, 0); } else { make_cells(pivot.cols.main.children, 1); - header_cells[0].push(self.make_border_cell(1, height).append('Total').css('font-weight', 'bold')); + header_cells[0].push(self.make_border_cell(1, height, true).append('Total').css('font-weight', 'bold')); } _.each(header_cells, function (cells) { - self.table.append($('').append(cells)); + thead.append($('').append(cells)); }); + self.table.append(thead); }, get_measure_type: function () { @@ -500,10 +503,6 @@ instance.web_graph.Graph = instance.web.Widget.extend({ var color, total, cell = $(''); - if ((self.mode === 'pivot') && (row.is_expanded) && (row.path.length <=2)) { - color = row.path.length * 5 + 240; - cell.css('background-color', $.Color(color, color, color)); - } if (value === undefined) { return cell; } -- cgit v1.2.3 From d63db7b67f817178a3698904cacdd655676ed673 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 31 Dec 2013 10:49:29 +0100 Subject: [IMP] makes sure that the graph view properly honors default mode request as described in the xml (addon web_graph) bzr revid: ged@openerp.com-20131231094929-giqkzmean1lralow --- addons/web_graph/static/src/js/graph.js | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 9fcb7f3ea8e..8c652239d2a 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -54,9 +54,28 @@ instance.web_graph.GraphView = instance.web.View.extend({ measure = null, stacked = false; - if (arch.attrs.type === 'bar' || !_.has(arch.attrs, 'type')) { + if (!_.has(arch.attrs, 'type')) { this.graph_widget.mode = 'bar_chart'; + } else { + switch (arch.attrs.type) { + case 'bar': + this.graph_widget.mode = 'bar_chart'; + break; + case 'pie': + this.graph_widget.mode = 'pie_chart'; + break; + case 'line': + this.graph_widget.mode = 'line_chart'; + break; + case 'pivot': + case 'heatmap': + case 'row_heatmap': + case 'col_heatmap': + this.graph_widget.mode = arch.attrs.type; + break; + } } + if (arch.attrs.stacked === 'True') { stacked = true; } @@ -190,7 +209,6 @@ instance.web_graph.Graph = instance.web.Widget.extend({ this.fields = []; this.pivot = new openerp.web_graph.PivotTable(model, []); this.mode = 'pivot'; - if (_.has(options, 'mode')) { this.mode = mode; } this.enabled = true; if (_.has(options, 'enabled')) { this.enabled = options.enabled; } this.visible_ui = true; @@ -200,6 +218,9 @@ instance.web_graph.Graph = instance.web.Widget.extend({ // hide ui/show, stacked/grouped config: function (options) { + // Possible modes: pivot, heatmap, row_heatmap, col_heatmap, + // bar_chart, pie_chart, line_chart + if (_.has(options, 'mode')) { this.mode = mode; } if (_.has(options, 'visible_ui')) { this.visible_ui = options.visible_ui; } @@ -509,17 +530,17 @@ instance.web_graph.Graph = instance.web.Widget.extend({ cell.append(instance.web.format_value(value, {type: measure_type})); if (self.mode === 'heatmap') { total = pivot.get_total(); - color = Math.floor(50 + 205*(total - value)/total); + color = Math.floor(90 + 165*(total - value)/total); cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'row_heatmap') { total = pivot.get_total(row); - color = Math.floor(50 + 205*(total - value)/total); + color = Math.floor(90 + 165*(total - value)/total); cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'col_heatmap') { total = pivot.get_total(col); - color = Math.floor(50 + 205*(total - value)/total); + color = Math.floor(90 + 165*(total - value)/total); cell.css('background-color', $.Color(255, color, color)); } return cell; -- cgit v1.2.3 From 8347c44966b3718a23fc1d7867a6db0de8d09731 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 2 Jan 2014 11:01:27 +0100 Subject: [FIX] fixes a crash when the graph view receives an array of values instead of a single value describing a field (addon web_graph) bzr revid: ged@openerp.com-20140102100127-7bmviyzujjmlfg02 --- addons/web_graph/static/src/js/graph.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 8c652239d2a..cba45302050 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -246,7 +246,11 @@ instance.web_graph.Graph = instance.web.Widget.extend({ if (g.attrs.context) { var field_id = py.eval(g.attrs.context).group_by; if (field_id) { - self.important_fields.push(field_id); + if (field_id instanceof Array) { + self.important_fields.concat(field_id); + } else { + self.important_fields.push(field_id); + } } } }); -- cgit v1.2.3 From 2514343b52ecf98adb72333edcb4b8434f07d82c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 3 Jan 2014 15:22:15 +0100 Subject: [IMP] adds support for more than one measure in graph view. (addon web_graph) bzr revid: ged@openerp.com-20140103142215-z19pnxmnla8xugx0 --- addons/web_graph/static/src/js/graph.js | 109 +++++++++++++++++++++++--------- addons/web_graph/static/src/js/pivot.js | 55 ++++++++-------- 2 files changed, 107 insertions(+), 57 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index cba45302050..978c893db19 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -51,7 +51,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_loading: function (fields_view_get) { var self = this, arch = fields_view_get.arch, - measure = null, + measures = [], + title = arch.attrs.string, stacked = false; if (!_.has(arch.attrs, 'type')) { @@ -90,20 +91,24 @@ instance.web_graph.GraphView = instance.web.View.extend({ self.default_col_groupby.push(field.attrs.name); break; case 'measure': - measure = field.attrs.name; + measures.push(field.attrs.name); break; } } else { // old style, kept for backward compatibility if ('operator' in field.attrs) { - measure = (measure) ? measure : field.attrs.name; + measures.push(field.attrs.name); } else { self.default_row_groupby.push(field.attrs.name); } } }); + if (measures.length === 0) { + measures.push('__count'); + } this.graph_widget.config({ - measure:measure, + measures:measures, update:false, + title: title, bar_ui: (stacked) ? 'stack' : 'group' }); }, @@ -214,6 +219,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ this.visible_ui = true; this.bar_ui = 'group'; // group or stack this.config(options || {}); + this.title = 'Graph'; }, // hide ui/show, stacked/grouped @@ -227,6 +233,9 @@ instance.web_graph.Graph = instance.web.Widget.extend({ if (_.has(options, 'bar_ui')) { this.bar_ui = options.bar_ui; } + if (_.has(options, 'title')) { + this.title = options.title; + } this.pivot.config(options); }, @@ -335,8 +344,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; - var actual_measure = (measure === '__count') ? null : measure; - this.pivot.config({measure:actual_measure}); + this.pivot.config({measures:[measure]}); }, option_selection: function (event) { @@ -413,13 +421,13 @@ instance.web_graph.Graph = instance.web.Widget.extend({ ******************************************************************************/ draw_table: function () { this.pivot.rows.main.title = 'Total'; - this.pivot.cols.main.title = this.measure_label(); + this.pivot.cols.main.title = this.title; this.draw_top_headers(); _.each(this.pivot.rows.headers, this.proxy('draw_row')); }, - measure_label: function () { - return (this.pivot.measure) ? this.fields[this.pivot.measure].string : 'Quantity'; + measure_label: function (measure) { + return (measure !== '__count') ? this.fields[measure].string : 'Quantity'; }, make_border_cell: function (colspan, rowspan, headercell) { @@ -456,7 +464,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ } function make_col_header (col) { - var cell = self.make_border_cell(col.width, col.height, true); + 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)); } @@ -479,24 +487,62 @@ instance.web_graph.Graph = instance.web.Widget.extend({ make_cells(pivot.cols.headers, 0); } else { make_cells(pivot.cols.main.children, 1); - header_cells[0].push(self.make_border_cell(1, height, true).append('Total').css('font-weight', 'bold')); + if (pivot.get_cols_leaves().length > 1) { + header_cells[0].push(self.make_border_cell(pivot.measures.length, height, true).append('Total').css('font-weight', 'bold')); + } } _.each(header_cells, function (cells) { thead.append($('').append(cells)); }); + + if (pivot.measures.length >= 2) { + thead.append(self.make_measure_row()); + } + self.table.append(thead); }, - get_measure_type: function () { - var measure = this.pivot.measure; - return (measure) ? this.fields[measure].type : 'integer'; + make_measure_row: function() { + var self = this, + measures = this.pivot.measures, + cols = this.pivot.cols.headers, + measure_cells, + measure_row = $(''); + + measure_row.append($('')); + + _.each(cols, function (col) { + if (!col.children.length) { + for (var i = 0; i < measures.length; i++) { + measure_cells = $('').addClass('measure_row'); + measure_cells.append(self.measure_label(measures[i])); + measure_row.append(measure_cells); + } + } + }); + + if (this.pivot.get_cols_leaves().length > 1) { + for (var i = 0; i < measures.length; i++) { + measure_cells = $('').addClass('measure_row'); + measure_cells.append(self.measure_label(measures[i])); + measure_row.append(measure_cells); + } + } + return measure_row; + }, + + get_measure_types: function () { + var self = this; + return _.map(this.pivot.measures, function (measure) { + return (measure !== '__count') ? self.fields[measure].type : 'integer'; + }); }, draw_row: function (row) { var self = this, pivot = this.pivot, - measure_type = this.get_measure_type(), + measure_types = this.get_measure_types(), html_row = $(''), row_header = this.make_border_cell(1,1) .append(this.make_header_title(row).attr('data-id', row.id)) @@ -510,21 +556,24 @@ instance.web_graph.Graph = instance.web.Widget.extend({ _.each(pivot.cols.headers, function (col) { if (col.children.length === 0) { - var value = pivot.get_value(row.id, col.id), - cell = make_cell(value, col); - html_row.append(cell); + var values = pivot.get_value(row.id, col.id, new Array(measure_types.length)); + for (var i = 0; i < values.length; i++) { + html_row.append(make_cell(values[i], measure_types[i], col)); + } } }); - if (pivot.cols.main.children.length > 0) { - var cell = make_cell(pivot.get_total(row), pivot.cols.main) - .css('font-weight', 'bold'); - html_row.append(cell); + 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], pivot.cols.main).css('font-weight', 'bold'); + html_row.append(cell); + } } this.table.append(html_row); - function make_cell (value, col) { + function make_cell (value, measure_type, col) { var color, total, cell = $(''); @@ -564,31 +613,31 @@ instance.web_graph.Graph = instance.web.Widget.extend({ if ((dim_x === 0) && (dim_y === 0)) { data = [{key: 'Total', values:[{ x: 'Total', - y: this.pivot.get_value(this.pivot.rows.main.id, this.pivot.cols.main.id), + y: this.pivot.get_value(this.pivot.rows.main.id, this.pivot.cols.main.id)[0], }]}]; // Only column groupbys **************************************************** } else if ((dim_x === 0) && (dim_y >= 1)){ data = _.map(this.pivot.get_columns_depth(1), function (header) { return { key: header.title, - values: [{x:header.root.main.title, y: self.pivot.get_total(header)}] + values: [{x:header.root.main.title, y: self.pivot.get_total(header)[0]}] }; }); // Just 1 row groupby ****************************************************** } else if ((dim_x === 1) && (dim_y === 0)) { data = _.map(this.pivot.rows.main.children, function (pt) { - var value = self.pivot.get_value(pt.id, self.pivot.cols.main.id), + var value = self.pivot.get_value(pt.id, self.pivot.cols.main.id)[0], title = (pt.title !== undefined) ? pt.title : 'Undefined'; return {x: title, y: value}; }); - data = [{key: this.measure_label(), values:data}]; + data = [{key: self.measure_label(self.pivot.measures[0]), values:data}]; // 1 row groupby and some col groupbys************************************** } else if ((dim_x === 1) && (dim_y >= 1)) { data = _.map(this.pivot.get_columns_depth(1), function (colhdr) { var values = _.map(self.pivot.get_rows_depth(1), function (header) { return { x: header.title || 'Undefined', - y: self.pivot.get_value(header.id, colhdr.id, 0) + y: self.pivot.get_value(header.id, colhdr.id, 0)[0] }; }); return {key: colhdr.title || 'Undefined', values: values}; @@ -605,7 +654,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ }); return { x: hdr.title || 'Undefined', - y: (subhdr) ? self.pivot.get_total(subhdr) : 0 + y: (subhdr) ? self.pivot.get_total(subhdr)[0] : 0 }; }); return {key:key, values: values}; @@ -651,7 +700,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ return p || 'Undefined'; }).join('/'); if (dim_y === 0) { - title = self.measure_label(); + title = self.measure_label(self.pivot.measures[0]); } return {values: values, key: title}; }); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index e94b82df389..4e1359339dd 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -14,7 +14,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.cols = { groupby: [], main: null, headers: null }; this.cells = []; this.domain = domain; - this.measure = null; + this.measures = ['__count']; this.data_loader = new openerp.web_graph.DataLoader(model); @@ -22,11 +22,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }, visible_fields: function () { - var result = this.rows.groupby.concat(this.cols.groupby); - if (this.measure) { - result = result.concat(this.measure); - } - return result; + var result = this.rows.groupby.concat(this.cols.groupby, this.measures); + return _.without(result, '__count'); }, config: function (options) { @@ -37,7 +34,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM domain:this.domain, col_groupby: this.cols.groupby, row_groupby: this.rows.groupby, - measure: this.measure, + measures: this.measures, silent:false }; options = _.extend(default_options, options); @@ -50,8 +47,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.domain = options.domain; changed = true; } - if (options.measure !== this.measure) { - this.measure = options.measure; + if (!_.isEqual(options.measures, this.measures)) { + this.measures = options.measures; changed = true; } if (!_.isEqual(options.col_groupby, this.cols.groupby)) { @@ -71,26 +68,26 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM if (options.update && changed) { this.update_data(); } }, - set_value: function (id1, id2, value) { + set_value: function (id1, id2, values) { var x = Math.min(id1, id2), y = Math.max(id1, id2), cell = _.find(this.cells, function (c) { return ((c.x == x) && (c.y == y)); }); if (cell) { - cell.value = value; + cell.values = values; } else { - this.cells.push({x: x, y: y, value: value}); + this.cells.push({x: x, y: y, values: values}); } }, - get_value: function (id1, id2, default_value) { + get_value: function (id1, id2, default_values) { var x = Math.min(id1, id2), y = Math.max(id1, id2), cell = _.find(this.cells, function (c) { return ((c.x == x) && (c.y == y)); }); - return (cell === undefined) ? default_value : cell.value; + return (cell === undefined) ? default_values : cell.values; }, is_row: function (id) { @@ -187,11 +184,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM } }); if (other) { - if (self.measure) { - self.set_value(new_header_id, other.id, data.attributes.aggregates[self.measure]); - } else { - self.set_value(new_header_id, other.id, data.attributes.length); - } + self.set_value(new_header_id, other.id, _.map(self.measures, function (measure) { + return (measure === '__count') ? data.attributes.length : data.attributes.aggregates[measure]; + })); } }); }); @@ -239,7 +234,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM options = { col_groupby: this.cols.groupby, row_groupby: this.rows.groupby, - measure: this.measure, + measures: this.measures, domain: this.domain, }; @@ -391,9 +386,9 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ var self = this, cols = options.col_groupby, rows = options.row_groupby, - visible_fields = rows.concat(cols); + visible_fields = _.without(rows.concat(cols, options.measures), '__count'); - if (options.measure) { visible_fields = visible_fields.concat(options.measure); } + // if (options.measure) { visible_fields = visible_fields.concat(options.measure); } var groupbys = _.map(_.range(cols.length + 1), function (i) { return cols.slice(0, i).concat(rows); @@ -416,9 +411,13 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ }); }, - get_value: function (data, measure) { + get_value: function (data, measures) { var attr = data.attributes; - return (measure) ? attr.aggregates[measure] : attr.length; + var result = _.map(measures, function (measure) { + return (measure === '__count') ? attr.length : attr.aggregates[measure]; + }); + return result; + // return (measure) ? attr.aggregates[measure] : attr.length; }, format_data: function (total, col_data, row_data, cell_data, options) { @@ -451,7 +450,7 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ children: [], title: (parent) ? data.attributes.value : '', domain: (parent) ? data.model._domain : options.domain, - total: this.get_value(options.total, options.measure), + total: this.get_value(options.total, options.measures), }; if (main.path.length < depth) { @@ -468,7 +467,9 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ var attr = group.attributes, group_val = (attr.value instanceof Array) ? attr.value[1] : attr.value, path = current_path, - value = (options.measure) ? attr.aggregates[options.measure] : attr.length; + values = _.map(options.measures, function (measure) { + return (measure === '__count') ? attr.length : attr.aggregates[measure]; + }); group_val = (group_val === false) ? undefined : group_val; @@ -483,7 +484,7 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ }); current_cells.push({x: Math.min(row.id, col.id), y: Math.max(row.id, col.id), - value: value}); + values: values}); if (attr.has_children) { self.make_cells (group.subgroups_data, index, path, current_cells, rows, cols, options); -- cgit v1.2.3 From 64775d40988ebff185a01797ac502e2ca12167bf Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 3 Jan 2014 15:32:36 +0100 Subject: [IMP] improves the rendering of heatmap modes when multiple measures are displayed (addon web_graph) bzr revid: ged@openerp.com-20140103143236-80zmxauy75b0n205 --- addons/web_graph/static/src/js/graph.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 978c893db19..93cac5146ec 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -558,7 +558,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ if (col.children.length === 0) { var values = pivot.get_value(row.id, col.id, new Array(measure_types.length)); for (var i = 0; i < values.length; i++) { - html_row.append(make_cell(values[i], measure_types[i], col)); + html_row.append(make_cell(values[i], measure_types[i], i, col)); } } }); @@ -566,14 +566,14 @@ instance.web_graph.Graph = instance.web.Widget.extend({ 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], pivot.cols.main).css('font-weight', 'bold'); + var cell = make_cell(total_vals[j], measure_types[j], i, pivot.cols.main).css('font-weight', 'bold'); html_row.append(cell); } } this.table.append(html_row); - function make_cell (value, measure_type, col) { + function make_cell (value, measure_type, index, col) { var color, total, cell = $(''); @@ -582,18 +582,18 @@ instance.web_graph.Graph = instance.web.Widget.extend({ } cell.append(instance.web.format_value(value, {type: measure_type})); if (self.mode === 'heatmap') { - total = pivot.get_total(); - color = Math.floor(90 + 165*(total - value)/total); + total = pivot.get_total()[i]; + color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'row_heatmap') { - total = pivot.get_total(row); - color = Math.floor(90 + 165*(total - value)/total); + total = pivot.get_total(row)[i]; + color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'col_heatmap') { - total = pivot.get_total(col); - color = Math.floor(90 + 165*(total - value)/total); + total = pivot.get_total(col)[i]; + color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); } return cell; -- cgit v1.2.3 From 47762dfca2c49a8da9f9fd1b57f966a27d96f602 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 3 Jan 2014 15:44:18 +0100 Subject: [IMP] allows the selection of multiple measures in graph view (addon web_graph) bzr revid: ged@openerp.com-20140103144418-7mstnfwah6v6jkkx --- addons/web_graph/static/src/js/graph.js | 8 ++++++-- addons/web_graph/static/src/js/pivot.js | 8 ++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 93cac5146ec..e8e4e561ef4 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -344,7 +344,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; - this.pivot.config({measures:[measure]}); + this.pivot.config({toggle_measure:measure}); }, option_selection: function (event) { @@ -421,7 +421,11 @@ instance.web_graph.Graph = instance.web.Widget.extend({ ******************************************************************************/ draw_table: function () { this.pivot.rows.main.title = 'Total'; - this.pivot.cols.main.title = this.title; + if (this.pivot.measures.length == 1) { + this.pivot.cols.main.title = this.measure_label(this.pivot.measures[0]); + } else { + this.pivot.cols.main.title = this.title; + } this.draw_top_headers(); _.each(this.pivot.rows.headers, this.proxy('draw_row')); }, diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 4e1359339dd..e112082e018 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -51,6 +51,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.measures = options.measures; changed = true; } + if (options.toggle_measure) { + if (_.contains(this.measures, options.toggle_measure)) { + this.measures = _.without(this.measures, options.toggle_measure); + } else { + this.measures.push(options.toggle_measure); + } + changed = true; + } if (!_.isEqual(options.col_groupby, this.cols.groupby)) { this.cols.groupby = options.col_groupby; changed = true; -- cgit v1.2.3 From 6a422f27d7bffd8457f275e2cc3c41f58e37a66d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 6 Jan 2014 09:37:34 +0100 Subject: [FIX] fixes the computation of the color displayed in heatmap modes in graph view. (addon web_graph) bzr revid: ged@openerp.com-20140106083734-qkrvuhe7398me2d2 --- addons/web_graph/static/src/js/graph.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index e8e4e561ef4..7973a5646bc 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -570,7 +570,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ 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], i, pivot.cols.main).css('font-weight', 'bold'); + var cell = make_cell(total_vals[j], measure_types[j], j, pivot.cols.main).css('font-weight', 'bold'); html_row.append(cell); } } @@ -586,17 +586,17 @@ instance.web_graph.Graph = instance.web.Widget.extend({ } cell.append(instance.web.format_value(value, {type: measure_type})); if (self.mode === 'heatmap') { - total = pivot.get_total()[i]; + total = pivot.get_total()[index]; color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'row_heatmap') { - total = pivot.get_total(row)[i]; + total = pivot.get_total(row)[index]; color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'col_heatmap') { - total = pivot.get_total(col)[i]; + total = pivot.get_total(col)[index]; color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); } -- cgit v1.2.3 From 0aa0ea9e6c3dc6ba8b9e55f5fe04c762fcdabfae Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 7 Jan 2014 11:59:54 +0100 Subject: [REF] merges the dataloader and pivot table classes together, where they truly belong. (addon web_graph) bzr revid: ged@openerp.com-20140107105954-beb16wspdl6ikemw --- addons/web_graph/static/src/js/pivot.js | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index e112082e018..e7e37afc679 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -15,10 +15,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.cells = []; this.domain = domain; this.measures = ['__count']; - - this.data_loader = new openerp.web_graph.DataLoader(model); - this.no_data = true; + this.model = model; + this.fields = null; }, visible_fields: function () { @@ -40,7 +39,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM options = _.extend(default_options, options); if (options.fields) { - this.data_loader.fields = options.fields; + this.fields = options.fields; } if (!_.isEqual(options.domain, this.domain)) { @@ -179,7 +178,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM } var otherDim = (header.root === this.cols) ? this.rows : this.cols; - return this.data_loader.get_groups(this.visible_fields(), header.domain, otherDim.groupby, {first_groupby:field_id, add_path:true}) + return this.get_groups(this.visible_fields(), header.domain, otherDim.groupby, {first_groupby:field_id, add_path:true}) .then(function (groups) { _.each(groups.reverse(), function (group) { var new_header_id = self.make_header(group, header); @@ -246,7 +245,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM domain: this.domain, }; - return this.data_loader.load_data(options).then (function (result) { + return this.load_data(options).then (function (result) { if (result) { self.no_data = false; if (self.cols.headers) { @@ -304,14 +303,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM root.main = root.headers[0]; }, -}); - -openerp.web_graph.DataLoader = openerp.web.Class.extend({ - init: function (model) { - this.model = model; - this.fields = null; - }, - + //*************************************************************** + // Data loading code from db... + //*************************************************************** get_groups: function (fields, domain, groupbys, options) { var self = this, groupings = ((options || {}).first_groupby) ? [(options || {}).first_groupby].concat(groupbys) : groupbys; @@ -419,13 +413,12 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ }); }, - get_value: function (data, measures) { + get_value_from_data: function (data, measures) { var attr = data.attributes; var result = _.map(measures, function (measure) { return (measure === '__count') ? attr.length : attr.aggregates[measure]; }); return result; - // return (measure) ? attr.aggregates[measure] : attr.length; }, format_data: function (total, col_data, row_data, cell_data, options) { @@ -458,7 +451,7 @@ openerp.web_graph.DataLoader = openerp.web.Class.extend({ children: [], title: (parent) ? data.attributes.value : '', domain: (parent) ? data.model._domain : options.domain, - total: this.get_value(options.total, options.measures), + total: this.get_value_from_data(options.total, options.measures), }; if (main.path.length < depth) { -- cgit v1.2.3 From f62567507929c64725e2baf28c6881d6eb657916 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 10 Jan 2014 12:35:57 +0100 Subject: [REF] large refactoring in graph view: changes the underlying data structure of Pivot class and simplifies a lot of code (addon web_graph) bzr revid: ged@openerp.com-20140110113557-6bs77dg7qcdofy40 --- addons/web_graph/static/src/js/graph.js | 448 ++++++++++++++----------- addons/web_graph/static/src/js/pivot.js | 557 +++++++++++++++++--------------- 2 files changed, 546 insertions(+), 459 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 7973a5646bc..84a7d147ac2 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -33,52 +33,39 @@ instance.web_graph.GraphView = instance.web.View.extend({ }; }, - get_context: function (facet) { - var col_group_by = _.map(facet.values.models, function (model) { - return model.attributes.value.attrs.context.col_group_by; - }); - return {col_group_by : col_group_by}; - }, - - start: function () { - var options = {enabled:false}; - this.graph_widget = new openerp.web_graph.Graph(this, this.model, options); - this.graph_widget.appendTo(this.$el); - this.graph_widget.pivot.on('groupby_changed', this, this.proxy('register_groupby')); - return this.load_view(); - }, - view_loading: function (fields_view_get) { var self = this, arch = fields_view_get.arch, measures = [], - title = arch.attrs.string, stacked = false; + this.widget_config = { title: arch.attrs.string }; + + debugger; if (!_.has(arch.attrs, 'type')) { - this.graph_widget.mode = 'bar_chart'; + this.widget_config.mode = 'bar_chart'; } else { switch (arch.attrs.type) { case 'bar': - this.graph_widget.mode = 'bar_chart'; + this.widget_config.mode = 'bar_chart'; break; case 'pie': - this.graph_widget.mode = 'pie_chart'; + this.widget_config.mode = 'pie_chart'; break; case 'line': - this.graph_widget.mode = 'line_chart'; + this.widget_config.mode = 'line_chart'; break; case 'pivot': case 'heatmap': case 'row_heatmap': case 'col_heatmap': - this.graph_widget.mode = arch.attrs.type; + this.widget_config.mode = arch.attrs.type; break; } } if (arch.attrs.stacked === 'True') { - stacked = true; + this.widget_config.stacked = true; } _.each(arch.children, function (field) { @@ -105,18 +92,32 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (measures.length === 0) { measures.push('__count'); } - this.graph_widget.config({ - measures:measures, - update:false, - title: title, - bar_ui: (stacked) ? 'stack' : 'group' + this.widget_config.row_groupby = self.default_row_groupby; + this.widget_config.col_groupby = self.default_col_groupby; + this.widget_config.measures = measures; + // measures:measures, + // update:false, + // title: title, + // bar_ui: (stacked) ? 'stack' : 'group' + // }); + }, + + get_context: function (facet) { + var col_group_by = _.map(facet.values.models, function (model) { + return model.attributes.value.attrs.context.col_group_by; }); + return {col_group_by : col_group_by}; }, do_search: function (domain, context, group_by) { var col_groupby = context.col_group_by || [], options = {domain:domain}; + if (!this.graph_widget) { + this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); + this.graph_widget.appendTo(this.$el); + this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); + } this.search_view_groupby = group_by; if (group_by.length && this.groupby_mode !== 'manual') { @@ -139,7 +140,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ options.row_groupby = _.toArray(this.default_row_groupby); options.col_groupby = _.toArray(this.default_col_groupby); } - this.graph_widget.pivot.config(options); + this.graph_widget.set_domain(domain); + this.graph_widget.set_col_groupby(options.col_groupby); + this.graph_widget.set_row_groupby(options.row_groupby); + + // this.graph_widget.pivot.config(options); if (!this.graph_widget.enabled) { this.graph_widget.activate_display(); @@ -153,49 +158,50 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, register_groupby: function() { - var self = this, - query = this.search_view.query; - - this.groupby_mode = 'manual'; - if (_.isEqual(this.search_view_groupby, this.graph_widget.pivot.rows.groupby) || - (!_.has(this.search_view, '_s_groupby'))) { - return; - } - var rows = _.map(this.graph_widget.pivot.rows.groupby, function (group) { - return make_facet('GroupBy', group); - }); - var cols = _.map(this.graph_widget.pivot.cols.groupby, function (group) { - return make_facet('ColGroupBy', group); - }); - - query.reset(rows.concat(cols)); - - function make_facet (category, fields) { - var values, - icon, - backbone_field, - cat_name; - if (!(fields instanceof Array)) { fields = [fields]; } - if (category === 'GroupBy') { - cat_name = 'group_by'; - icon = 'w'; - backbone_field = self.search_view._s_groupby; - } else { - cat_name = 'col_group_by'; - icon = 'f'; - backbone_field = self.search_field; - } - values = _.map(fields, function (field) { - var context = {}; - context[cat_name] = field; - return {label: self.graph_widget.fields[field].string, value: {attrs:{domain: [], context: context}}}; - }); - return {category:category, values: values, icon:icon, field: backbone_field}; - } + // var self = this, + // query = this.search_view.query; + + // this.groupby_mode = 'manual'; + // if (_.isEqual(this.search_view_groupby, this.graph_widget.pivot.rows.groupby) || + // (!_.has(this.search_view, '_s_groupby'))) { + // return; + // } + // var rows = _.map(this.graph_widget.pivot.rows.groupby, function (group) { + // return make_facet('GroupBy', group); + // }); + // var cols = _.map(this.graph_widget.pivot.cols.groupby, function (group) { + // return make_facet('ColGroupBy', group); + // }); + + // query.reset(rows.concat(cols)); + + // function make_facet (category, fields) { + // var values, + // icon, + // backbone_field, + // cat_name; + // if (!(fields instanceof Array)) { fields = [fields]; } + // if (category === 'GroupBy') { + // cat_name = 'group_by'; + // icon = 'w'; + // backbone_field = self.search_view._s_groupby; + // } else { + // cat_name = 'col_group_by'; + // icon = 'f'; + // backbone_field = self.search_field; + // } + // values = _.map(fields, function (field) { + // var context = {}; + // context[cat_name] = field; + // return {label: self.graph_widget.fields[field].string, value: {attrs:{domain: [], context: context}}}; + // }); + // return {category:category, values: values, icon:icon, field: backbone_field}; + // } }, }); -instance.web_graph.Graph = instance.web.Widget.extend({ +// important_fields = [field], field = {field: _,type: _, string: _} +instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMixin, { template: 'GraphWidget', events: { @@ -206,108 +212,181 @@ instance.web_graph.Graph = instance.web.Widget.extend({ 'click a.field-selection' : 'field_selection', }, - init: function(parent, model, options) { + init: function(parent, model, domain, options) { + var self = this; + this._super(parent); this.model = model; - this.important_fields = []; - this.measure_list = []; - this.fields = []; - this.pivot = new openerp.web_graph.PivotTable(model, []); - this.mode = 'pivot'; - this.enabled = true; - if (_.has(options, 'enabled')) { this.enabled = options.enabled; } - this.visible_ui = true; - this.bar_ui = 'group'; // group or stack - this.config(options || {}); - this.title = 'Graph'; - }, - - // hide ui/show, stacked/grouped - config: function (options) { - // Possible modes: pivot, heatmap, row_heatmap, col_heatmap, - // bar_chart, pie_chart, line_chart - if (_.has(options, 'mode')) { this.mode = mode; } - if (_.has(options, 'visible_ui')) { - this.visible_ui = options.visible_ui; - } - if (_.has(options, 'bar_ui')) { - this.bar_ui = options.bar_ui; - } - if (_.has(options, 'title')) { - this.title = options.title; - } - this.pivot.config(options); + this.domain = domain; + this.mode = options.mode || 'pivot'; + this.title = options.title || 'Graph'; + this.visible_ui = options.visible_ui || true; + this.pivot_options = options; }, start: function() { var self = this; this.table = $('
    '); this.$('.graph_main_content').append(this.table); - // get the most important fields (of the model) by looking at the - // groupby filters defined in the search view - var options = {model:this.model, view_type: 'search'}, - deferred1 = instance.web.fields_view_get(options).then(function (search_view) { - var groups = _.select(search_view.arch.children, function (c) { - return (c.tag == 'group') && (c.attrs.string != 'Display'); - }); - _.each(groups, function(g) { - _.each(g.children, function (g) { - if (g.attrs.context) { - var field_id = py.eval(g.attrs.context).group_by; - if (field_id) { - if (field_id instanceof Array) { - self.important_fields.concat(field_id); - } else { - self.important_fields.push(field_id); - } - } - } - }); - }); - }); + var def1 = this.get_search_fields().then(function (f) { + self.important_fields = f; + }); - // get the fields descriptions and measure list from the model - var deferred2 = this.model.call('fields_get', []).then(function (fs) { - self.fields = fs; - self.pivot.config({fields:fs}); - var temp = _.map(fs, function (field, name) { - return {name:name, type: field.type}; + var def2 = this.get_model_fields().then(function (f) { + self.fields = f; + self.measure_list = self.get_measures(); + self.add_measures_to_options(); + }); + + $.when(def1, def2).then(function () { + self.pivot = new openerp.web_graph.PivotTable(self.model, self.domain, self.fields, self.pivot_options); + self.pivot.on('redraw_required', self, self.proxy('display_data')); + self.pivot.on('groupby_changed', self, function () { self.trigger('groupby_changed'); }); + instance.web.bus.on('click', self, function () { + if (self.dropdown) { + self.dropdown.remove(); + self.dropdown = null; + } }); - temp = _.filter(temp, function (field) { - return (((field.type === 'integer') || (field.type === 'float')) && (field.name !== 'id')); + self.pivot.activate(); + }); + }, + + get_search_fields: function () { + var self = this, + options = {model:this.model, view_type: 'search'}, + result = []; + + return instance.web.fields_view_get(options).then(function (search_view) { + var groups = _.select(search_view.arch.children, function (c) { + return (c.tag === 'group') && (c.attrs.string != 'Display'); }); - self.measure_list = _.map(temp, function (field) { - return field.name; + _.each(groups, function(g) { + _.each(g.children, function (g) { + if (g.attrs.context) { + var field_id = py.eval(g.attrs.context).group_by; + if (field_id) { + if (field_id instanceof Array) { + result.concat(field_id); + } else { + result.push(field_id); + } + } + } + }); }); + return result; + }); + }, - var measure_selection = self.$('.graph_measure_selection'); - _.each(self.measure_list, function (measure) { - var choice = $('').attr('data-choice', measure) - .attr('href', '#') - .append(self.fields[measure].string); - measure_selection.append($('
  • ').append(choice)); - }); + get_model_fields: function () { + return this.model.call('fields_get', []).then(function (fs) { + return fs; }); + }, - return $.when(deferred1, deferred2).then(function () { - if (this.enabled) { - this.activate_display(); + get_measures: function(fields) { + var measures = []; + _.each(this.fields, function (f, id) { + if (((f.type === 'integer') || (f.type === 'float')) && (id !== 'id')) { + measures.push({field:id, type: f.type, string: f.string}); } }); + return measures; }, - activate_display: function () { - this.pivot.on('redraw_required', this, this.proxy('display_data')); - this.pivot.update_data(); - this.enabled = true; - instance.web.bus.on('click', this, function () { - if (this.dropdown) { - this.dropdown.remove(); - this.dropdown = null; - } + set_domain: function (domain) { + if (this.pivot) { + this.pivot.set_domain(domain); + } else { + this.pivot_options.domain = domain; + } + }, + + set_row_groupby: function (groupby) { + if (this.pivot) { + this.pivot.set_row_groupby(groupby); + } else { + this.pivot_options.row_groupby = groupby; + } + }, + + set_col_groupby: function (groupby) { + if (this.pivot) { + this.pivot.set_col_groupby(groupby); + } else { + this.pivot_options.col_groupby = groupby; + } + }, + + add_measures_to_options: function() { + var measure_selection = this.$('.graph_measure_selection'); + _.each(this.measure_list, function (measure) { + var choice = $('').attr('data-choice', measure.field) + .attr('href', '#') + .append(measure.string); + measure_selection.append($('
  • ').append(choice)); }); }, + // self.fields = fs; + // var temp = _.map(fs, function (field, name) { + // return {name:name, type: field.type}; + // }); + // temp = _.filter(temp, function (field) { + // return (((field.type === 'integer') || (field.type === 'float')) && (field.name !== 'id')); + // }); + // self.measure_list = _.map(temp, function (field) { + // return field.name; + // }); + + // var measure_selection = self.$('.graph_measure_selection'); + // _.each(self.measure_list, function (measure) { + // var choice = $('').attr('data-choice', measure) + // .attr('href', '#') + // .append(self.fields[measure].string); + // measure_selection.append($('
  • ').append(choice)); + // }); + // }); + // }, + + // hide ui/show, stacked/grouped + // config: function (options) { + // Possible modes: pivot, heatmap, row_heatmap, col_heatmap, + // bar_chart, pie_chart, line_chart + // if (_.has(options, 'mode')) { this.mode = mode; } + // if (_.has(options, 'visible_ui')) { + // this.visible_ui = options.visible_ui; + // } + // if (_.has(options, 'bar_ui')) { + // this.bar_ui = options.bar_ui; + // } + // if (_.has(options, 'title')) { + // this.title = options.title; + // } + // debugger; + // this.pivot.config(options); + // }, + + + // get the most important fields (of the model) by looking at the + // groupby filters defined in the search view + + // get the fields descriptions and measure list from the model + + // return $.when(deferred1, deferred2).then(function () { + // self.pivot = new openerp.web_graph.PivotTable(self.model, self.fields); + // self.activate_display(); + // }); + // }, + + set_mode: function (mode) { + + }, + + activate_display: function () { + }, + display_data: function () { this.$('.graph_main_content svg').remove(); this.$('.graph_main_content div').remove(); @@ -344,7 +423,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ measure_selection: function (event) { event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; - this.pivot.config({toggle_measure:measure}); + this.pivot.toggle_measure(measure); }, option_selection: function (event) { @@ -386,12 +465,11 @@ instance.web_graph.Graph = instance.web.Widget.extend({ header = this.pivot.get_header(id), self = this; - if (header.is_expanded) { + if (header.expanded) { this.pivot.fold(header); } else { if (header.path.length < header.root.groupby.length) { - var field = header.root.groupby[header.path.length]; - this.pivot.expand(id, field); + this.pivot.expand(id); } else { if (!this.important_fields.length) { return; @@ -420,20 +498,16 @@ instance.web_graph.Graph = instance.web.Widget.extend({ * Drawing pivot table methods... ******************************************************************************/ draw_table: function () { - this.pivot.rows.main.title = 'Total'; + this.pivot.main_row().title = 'Total'; if (this.pivot.measures.length == 1) { - this.pivot.cols.main.title = this.measure_label(this.pivot.measures[0]); + this.pivot.main_col().title = this.pivot.measures[0].string; } else { - this.pivot.cols.main.title = this.title; + this.pivot.main_col().title = this.title; } this.draw_top_headers(); _.each(this.pivot.rows.headers, this.proxy('draw_row')); }, - measure_label: function (measure) { - return (measure !== '__count') ? this.fields[measure].string : 'Quantity'; - }, - make_border_cell: function (colspan, rowspan, headercell) { var tag = (headercell) ? $('') : $(''); return tag.addClass('graph_border') @@ -445,7 +519,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ return $(' ') .addClass('web_graph_click') .attr('href', '#') - .addClass((header.is_expanded) ? 'fa fa-minus-square' : 'fa fa-plus-square') + .addClass((header.expanded) ? 'fa fa-minus-square' : 'fa fa-plus-square') .append((header.title !== undefined) ? header.title : 'Undefined'); }, @@ -486,11 +560,11 @@ instance.web_graph.Graph = instance.web.Widget.extend({ } } - set_dim(pivot.cols.main); // add width and height info to columns headers - if (pivot.cols.main.children.length === 0) { + 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); } else { - make_cells(pivot.cols.main.children, 1); + 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).append('Total').css('font-weight', 'bold')); } @@ -520,7 +594,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ if (!col.children.length) { for (var i = 0; i < measures.length; i++) { measure_cells = $('').addClass('measure_row'); - measure_cells.append(self.measure_label(measures[i])); + measure_cells.append(measures[i].string); measure_row.append(measure_cells); } } @@ -529,24 +603,17 @@ instance.web_graph.Graph = instance.web.Widget.extend({ if (this.pivot.get_cols_leaves().length > 1) { for (var i = 0; i < measures.length; i++) { measure_cells = $('').addClass('measure_row'); - measure_cells.append(self.measure_label(measures[i])); + measure_cells.append(measures[i].string); measure_row.append(measure_cells); } } return measure_row; }, - get_measure_types: function () { - var self = this; - return _.map(this.pivot.measures, function (measure) { - return (measure !== '__count') ? self.fields[measure].type : 'integer'; - }); - }, - draw_row: function (row) { var self = this, pivot = this.pivot, - measure_types = this.get_measure_types(), + measure_types = _.pluck(this.pivot.measures, 'type'), html_row = $(''), row_header = this.make_border_cell(1,1) .append(this.make_header_title(row).attr('data-id', row.id)) @@ -560,7 +627,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ _.each(pivot.cols.headers, function (col) { if (col.children.length === 0) { - var values = pivot.get_value(row.id, col.id, new Array(measure_types.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)); } @@ -570,7 +637,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ 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.main).css('font-weight', 'bold'); + var cell = make_cell(total_vals[j], measure_types[j], j, pivot.cols[0]).css('font-weight', 'bold'); html_row.append(cell); } } @@ -596,6 +663,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ cell.css('background-color', $.Color(255, color, color)); } if (self.mode === 'col_heatmap') { + debugger; total = pivot.get_total(col)[index]; color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); @@ -617,42 +685,42 @@ instance.web_graph.Graph = instance.web.Widget.extend({ if ((dim_x === 0) && (dim_y === 0)) { data = [{key: 'Total', values:[{ x: 'Total', - y: this.pivot.get_value(this.pivot.rows.main.id, this.pivot.cols.main.id)[0], + y: this.pivot.get_total(), }]}]; // Only column groupbys **************************************************** } else if ((dim_x === 0) && (dim_y >= 1)){ - data = _.map(this.pivot.get_columns_depth(1), function (header) { + data = _.map(this.pivot.get_columns_with_depth(1), function (header) { return { key: header.title, - values: [{x:header.root.main.title, y: self.pivot.get_total(header)[0]}] + values: [{x:header.root[0].title, y: self.pivot.get_total(header)[0]}] }; }); // Just 1 row groupby ****************************************************** } else if ((dim_x === 1) && (dim_y === 0)) { - data = _.map(this.pivot.rows.main.children, function (pt) { - var value = self.pivot.get_value(pt.id, self.pivot.cols.main.id)[0], + data = _.map(this.pivot.main_row().children, function (pt) { + var value = self.pivot.get_total(pt), title = (pt.title !== undefined) ? pt.title : 'Undefined'; return {x: title, y: value}; }); - data = [{key: self.measure_label(self.pivot.measures[0]), values:data}]; + data = [{key: self.pivot.measures[0].string, values:data}]; // 1 row groupby and some col groupbys************************************** } else if ((dim_x === 1) && (dim_y >= 1)) { - data = _.map(this.pivot.get_columns_depth(1), function (colhdr) { - var values = _.map(self.pivot.get_rows_depth(1), function (header) { + data = _.map(this.pivot.get_cols_with_depth(1), function (colhdr) { + var values = _.map(self.pivot.get_rows_with_depth(1), function (header) { return { x: header.title || 'Undefined', - y: self.pivot.get_value(header.id, colhdr.id, 0)[0] + y: self.pivot.get_values(header.id, colhdr.id, 0)[0] }; }); return {key: colhdr.title || 'Undefined', values: values}; }); // At least two row groupby************************************************* } else { - var keys = _.uniq(_.map(this.pivot.get_rows_depth(2), function (hdr) { + var keys = _.uniq(_.map(this.pivot.get_rows_with_depth(2), function (hdr) { return hdr.title || 'Undefined'; })); data = _.map(keys, function (key) { - var values = _.map(self.pivot.get_rows_depth(1), function (hdr) { + var values = _.map(self.pivot.get_rows_with_depth(1), function (hdr) { var subhdr = _.find(hdr.children, function (child) { return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); }); @@ -697,14 +765,14 @@ instance.web_graph.Graph = instance.web.Widget.extend({ dim_y = this.pivot.cols.groupby.length; var data = _.map(this.pivot.get_cols_leaves(), function (col) { - var values = _.map(self.pivot.get_rows_depth(dim_x), function (row) { - return {x: row.title, y: self.pivot.get_value(row.id,col.id, 0)}; + var values = _.map(self.pivot.get_rows_with_depth(dim_x), function (row) { + return {x: row.title, y: self.pivot.get_values(row.id,col.id, 0)}; }); var title = _.map(col.path, function (p) { return p || 'Undefined'; }).join('/'); if (dim_y === 0) { - title = self.measure_label(self.pivot.measures[0]); + title = self.pivot.measures[0].string; } return {values: values, key: title}; }); @@ -729,7 +797,7 @@ instance.web_graph.Graph = instance.web.Widget.extend({ pie_chart: function () { var self = this, dim_x = this.pivot.rows.groupby.length; - + debugger; var data = _.map(this.pivot.get_rows_leaves(), function (row) { var title = _.map(row.path, function (p) { return p || 'Undefined'; diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index e7e37afc679..49f2ff4b2d5 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -4,163 +4,245 @@ (function () { 'use strict'; +// Pivot Table +// +// Here is a short description of the way the data is organized: +// Main fields: +// cells = [cell] +// cell = {x: _, y: _, values: [value]} +// value = {type: _, value: _} +// measures = [measure] +// measure = {field: _, string: _, type: _} +// rows, cols = {groupby: [groupby], headers: [header]} +// groupby = {field: _, string: _, type: _, interval: _} (interval only if type = date/datetime) +// header = { +// id: _, +// path: _, +// title: _, +// expanded: _, +// parent: _, +// children: _, +// domain: _, +// root: _, +// } +// +// Pivot Table emits the events 'groupby_changed' and 'redraw_required' when necessary. +// PivotTable require a 'update_data' after init to be ready +// to do: add an option to enable/disable update_data at the end of init openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { - // PivotTable require a 'update_data' after init to be ready - // to do: add an option to enable/disable update_data at the end of init - init: function (model, domain) { + init: function (model, domain, fields, options) { openerp.EventDispatcherMixin.init.call(this); - this.rows = { groupby: [], main: null, headers: null }; - this.cols = { groupby: [], main: null, headers: null }; + this.rows = { groupby: [], headers: null }; + this.cols = { groupby: [], headers: null }; this.cells = []; this.domain = domain; - this.measures = ['__count']; this.no_data = true; this.model = model; - this.fields = null; + this.fields = fields; + this.fields.__count = {type: 'integer', string:'Quantity'}; + this.measures = [{field:'__count', type: this.fields.type, string:this.fields.string}]; + this.active = false; + if (options.measures) { this.set_measures(options.measures); } + if (options.col_groupby) { this.set_col_groupby(options.col_groupby); } + if (options.row_groupby) { this.set_row_groupby(options.row_groupby); } }, - visible_fields: function () { - var result = this.rows.groupby.concat(this.cols.groupby, this.measures); - return _.without(result, '__count'); + // ---------------------------------------------------------------------- + // Configuration methods + // ---------------------------------------------------------------------- + activate: function() { + this.active = true; + this.update_data(); }, - config: function (options) { - var changed = false; - var groupby_changed = false; - var default_options = { - update:true, - domain:this.domain, - col_groupby: this.cols.groupby, - row_groupby: this.rows.groupby, - measures: this.measures, - silent:false - }; - options = _.extend(default_options, options); + set_domain: function (domain) { + this.domain = domain; + if (this.active) { this.update_data(); } + }, - if (options.fields) { - this.fields = options.fields; + set_measures: function (measures) { + var self = this; + if (!_.isEqual(measures, this.measures)) { + this.measures = []; + _.each(measures, function (m) { self._add_measure(m); }); + if (this.active) { this.update_data(); } } + }, - if (!_.isEqual(options.domain, this.domain)) { - this.domain = options.domain; - changed = true; - } - if (!_.isEqual(options.measures, this.measures)) { - this.measures = options.measures; - changed = true; - } - if (options.toggle_measure) { - if (_.contains(this.measures, options.toggle_measure)) { - this.measures = _.without(this.measures, options.toggle_measure); - } else { - this.measures.push(options.toggle_measure); - } - changed = true; + _add_measure: function (measure) { + if (measure.field && measure.string && measure.type) { + this.measures.push(measure); + } else { + this.measures.push({ + field: measure, + string: this.fields[measure].string, + type: this.fields[measure].type, + }); } - if (!_.isEqual(options.col_groupby, this.cols.groupby)) { - this.cols.groupby = options.col_groupby; - changed = true; + }, + + toggle_measure: function (field_id) { + var current_measure = _.findWhere(this.measures, {field:field_id}); + if (current_measure) { + this.measures = _.without(this.measures, current_measure); + } else { + this.measures.push({ + field: field_id, + type: this.fields[field_id].type, + string: this.fields[field_id].string + }); + } + if (this.active) { this.update_data(); } + }, + + set_col_groupby: function (groupbys) { + var self = this; + if (!_.isEqual(groupbys, this.cols.groupby)) { + this.cols.groupby = []; + _.each(groupbys, function (g) { self._add_groupby(self.cols.groupby, g); }); this.cols.headers = null; - groupby_changed = true; + if (this.active) { + this.trigger('groupby_changed'); + this.update_data(); + } } - if (!_.isEqual(options.row_groupby, this.rows.groupby)) { - this.rows.groupby = options.row_groupby; + }, + + set_row_groupby: function (groupbys) { + var self = this; + if (!_.isEqual(groupbys, this.rows.groupby)) { + this.rows.groupby = []; + _.each(groupbys, function (g) { self._add_groupby(self.rows.groupby, g); }); this.rows.headers = null; - changed = true; - groupby_changed = true; + if (this.active) { + this.trigger('groupby_changed'); + this.update_data(); + } } - - if (!options.silent && groupby_changed) { this.trigger('groupby_changed'); } - if (options.update && changed) { this.update_data(); } }, - set_value: function (id1, id2, values) { - var x = Math.min(id1, id2), - y = Math.max(id1, id2), - cell = _.find(this.cells, function (c) { - return ((c.x == x) && (c.y == y)); - }); - if (cell) { - cell.values = values; + _add_groupby: function(groupby_list, groupby) { + if (groupby.field && groupby.string && groupby.type) { + groupby_list.push(groupby); } else { - this.cells.push({x: x, y: y, values: values}); + groupby_list.push({ + field:groupby, + string: this.fields[groupby].string, + type: this.fields[groupby].type + }); } }, - get_value: function (id1, id2, default_values) { + // ---------------------------------------------------------------------- + // Cells manipulation methods + // ---------------------------------------------------------------------- + add_cell : function (id1, id2, values) { + var x = Math.min(id1, id2), + y = Math.max(id1, id2); + this.cells.push({x: x, y: y, values: values}); + }, + + get_values: function (id1, id2, default_values) { var x = Math.min(id1, id2), y = Math.max(id1, id2), cell = _.find(this.cells, function (c) { - return ((c.x == x) && (c.y == y)); - }); - return (cell === undefined) ? default_values : cell.values; + return ((c.x == x) && (c.y == y)); + }); + return (cell !== undefined) ? cell.values : (default_values || new Array(this.measures.length)); }, + // ---------------------------------------------------------------------- + // Headers/Rows/Cols manipulation methods + // ---------------------------------------------------------------------- is_row: function (id) { return !!_.find(this.rows.headers, function (header) { - return header.id == id; + return header.id === id; }); }, is_col: function (id) { return !!_.find(this.cols.headers, function (header) { - return header.id == id; + return header.id === id; }); }, get_header: function (id) { return _.find(this.rows.headers.concat(this.cols.headers), function (header) { - return header.id == id; + return header.id === id; }); }, // return all columns with a path length of 'depth' - get_columns_depth: function (depth) { - return _.filter(this.cols.headers, function (hdr) { - return hdr.path.length === depth; + get_cols_with_depth: function (depth) { + return _.filter(this.cols.headers, function (header) { + return header.path.length === depth; }); }, // return all rows with a path length of 'depth' - get_rows_depth: function (depth) { - return _.filter(this.rows.headers, function (hdr) { - return hdr.path.length === depth; + get_rows_with_depth: function (depth) { + return _.filter(this.rows.headers, function (header) { + return header.path.length === depth; }); }, // return all non expanded rows get_rows_leaves: function () { - return _.filter(this.rows.headers, function (hdr) { - return !hdr.is_expanded; + return _.filter(this.rows.headers, function (header) { + return !header.expanded; }); }, // return all non expanded cols get_cols_leaves: function () { - return _.filter(this.cols.headers, function (hdr) { - return !hdr.is_expanded; + return _.filter(this.cols.headers, function (header) { + return !header.expanded; }); }, - fold: function (header) { - var list = []; - function tree_traversal(tree) { - list.push(tree); - _.each(tree.children, tree_traversal); + 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); })); + }, + + 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); })); + }, + + get_total: function (header) { + if (header) { + return this.get_values(header.id, this.get_other_root(header).headers[0].id); } - tree_traversal(header); - var ids_to_remove = _.map(_.rest(list), function (h) { return h.id;}); + return this.get_values(this.rows.headers[0].id, this.cols.headers[0].id); + }, + + get_other_root: function (header) { + return (header.root === this.rows) ? this.cols : this.rows; + }, - header.root.headers = _.difference(header.root.headers, _.rest(list)); - header.is_expanded = false; - var fold_lvls = _.map(header.root.headers, function(g) {return g.path.length;}); - var new_groupby_length = _.max(fold_lvls); + main_row: function () { return this.rows.headers[0]; }, + + main_col: function () { return this.cols.headers[0]; }, + // ---------------------------------------------------------------------- + // Table manipulation methods + // ---------------------------------------------------------------------- + fold: function (header) { + var ancestors = this.get_ancestors(header), + removed_ids = _.pluck(ancestors, 'id'); + + header.root.headers = _.difference(header.root.headers, ancestors); header.children = []; + header.expanded = false; + this.cells = _.reject(this.cells, function (cell) { - return (_.contains(ids_to_remove, cell.x) || _.contains(ids_to_remove, cell.y)); + return (_.contains(removed_ids, cell.x) || _.contains(removed_ids, cell.y)); }); + + var new_groupby_length = _.max(_.map(header.root.headers, function(g) {return g.path.length;})); if (new_groupby_length < header.root.groupby.length) { header.root.groupby.splice(new_groupby_length); this.trigger('groupby_changed'); @@ -168,50 +250,54 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.trigger('redraw_required'); }, - expand: function (header_id, field_id) { + expand: function (header_id, groupby) { var self = this, - header = this.get_header(header_id); + header = this.get_header(header_id), + otherRoot = this.get_other_root(header), + fields = otherRoot.groupby.concat(this.measures); - if (header.path.length == header.root.groupby.length) { - header.root.groupby.push(field_id); + if (header.path.length === header.root.groupby.length) { + self._add_groupby(header.root.groupby, groupby); this.trigger('groupby_changed'); } + groupby = [header.root.groupby[header.path.length]].concat(otherRoot.groupby); - var otherDim = (header.root === this.cols) ? this.rows : this.cols; - return this.get_groups(this.visible_fields(), header.domain, otherDim.groupby, {first_groupby:field_id, add_path:true}) + return this.get_groups(groupby, fields, header.domain) .then(function (groups) { _.each(groups.reverse(), function (group) { - var new_header_id = self.make_header(group, header); - _.each(group, function (data) { - var other = _.find(otherDim.headers, function (h) { - if (header.root === self.cols) { - return _.isEqual(data.path.slice(1), h.path); + var child_id = self.make_header(group, header); + // 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.set_value(new_header_id, other.id, _.map(self.measures, function (measure) { - return (measure === '__count') ? data.attributes.length : data.attributes.aggregates[measure]; - })); + self.add_cell(child_id, other.id, values); } }); }); - header.is_expanded = true; + header.expanded = true; self.trigger('redraw_required'); }); }, - make_header: function (groups, parent) { - var name = groups[0].attributes.value, + make_header: function (group, parent) { + var title = group.attributes.value, new_header = { id: _.uniqueId(), - path: parent.path.concat(name), - title: name, - is_expanded: false, - parent: parent.id, + path: parent.path.concat(title), + title: title, + expanded: false, children: [], - domain: groups[0].model._domain, + domain: group.model._domain, root: parent.root, }; parent.children.splice(0,0, new_header); @@ -227,38 +313,17 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.trigger('redraw_required'); }, - get_total: function (header) { - if (header) { - var main = (header.root === this.rows) ? this.cols.main : this.rows.main; - return this.get_value(header.id, main.id); - } else { - return this.rows.main.total; - } - }, - + // ---------------------------------------------------------------------- + // Data loading methods + // ---------------------------------------------------------------------- update_data: function () { - var self = this, - options = { - col_groupby: this.cols.groupby, - row_groupby: this.rows.groupby, - measures: this.measures, - domain: this.domain, - }; + var self = this; - return this.load_data(options).then (function (result) { + return this.load_data().then (function (result) { if (result) { self.no_data = false; - if (self.cols.headers) { - self.update_headers(self.cols, result.col_headers); - } else { - self.expand_headers(self.cols, result.col_headers); - } - if (self.rows.headers) { - self.update_headers(self.rows, result.row_headers); - } else { - self.expand_headers(self.rows, result.row_headers); - } - self.cells = result.cells; + 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; } @@ -268,10 +333,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM expand_headers: function (root, new_headers) { root.headers = new_headers; - root.main = new_headers[0]; _.each(root.headers, function (header) { header.root = root; - header.is_expanded = (header.children.length > 0); + header.expanded = (header.children.length > 0); }); }, @@ -280,102 +344,84 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var corresponding_header = _.find(new_headers, function (h) { return _.isEqual(h.path, header.path); }); - if (corresponding_header && (header.is_expanded)) { - corresponding_header.is_expanded = true; + if (corresponding_header && header.expanded) { + corresponding_header.expanded = true; _.each(corresponding_header.children, function (c) { - c.is_expanded = false; + c.expanded = false; }); } - if (corresponding_header && (!header.is_expanded)) { - corresponding_header.is_expanded = false; + if (corresponding_header && (!header.expanded)) { + corresponding_header.expanded = false; } }); var updated_headers = _.filter(new_headers, function (header) { - return (header.is_expanded !== undefined); + return (header.expanded !== undefined); }); - _.each(updated_headers, function (hdr) { - if (!hdr.is_expanded) { - hdr.children = []; + _.each(updated_headers, function (header) { + if (!header.expanded) { + header.children = []; } - hdr.root = root; + header.root = root; }); root.headers = updated_headers; - root.main = root.headers[0]; }, - //*************************************************************** - // Data loading code from db... - //*************************************************************** - get_groups: function (fields, domain, groupbys, options) { + // options: fields: _, path_prefix: [] + get_groups: function (groupbys, fields, domain, path) { + path = path || []; var self = this, - groupings = ((options || {}).first_groupby) ? [(options || {}).first_groupby].concat(groupbys) : groupbys; + groupby = (groupbys.length) ? groupbys[0] : []; - return this.query_db(fields, domain, groupings).then(function (groups) { - return _.map(groups, function (group) { - return ((options || {}).add_path) ? self.add_path(group, []) : group; - }); + 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; + } }); }, - query_db: function (fields, domain, groupbys) { - var self = this; - return this.model.query(fields) + _query_db: function (groupby, fields, domain, path) { + var self = this, + field_ids = _.without(_.pluck(fields, 'field'), '__count'); + // To do : add code to check if groupby is date/datetime + // and in that case, add the correct code to the context + return this.model.query(field_ids) .filter(domain) - .group_by(groupbys) + .group_by(groupby.field) .then(function (results) { - var non_empty_results = _.filter(results, function (group) { + var groups = _.filter(results, function (group) { return group.attributes.length > 0; }); - _.each(non_empty_results, self.sanitize_value.bind(self)); - if (groupbys.length <= 1) { - return non_empty_results; - } else { - var get_subgroups = $.when.apply(null, _.map(non_empty_results, function (result) { - var new_domain = result.model._domain; - var new_groupings = groupbys.slice(1); - return self.query_db(fields,new_domain, new_groupings).then(function (subgroups) { - result.subgroups_data = subgroups; - }); - })); - return get_subgroups.then(function () { - return non_empty_results; - }); - } + return _.map(groups, function (g) { return self.format_group(g, path); }); }); }, - sanitize_value: function (group) { - var value = group.attributes.value; + format_group: function (group, current_path) { + var value = group.attributes.value; - if (this.fields && - group.attributes.grouped_on && - this.fields[group.attributes.grouped_on].type === 'selection') { - var selection = this.fields[group.attributes.grouped_on].selection; - var value_lookup = _.find(selection, function (val) { - return val[0] === value; - }); - group.attributes.value = (value_lookup) ? value_lookup[1] : 'undefined'; - return; - } - if (value === false) { - group.attributes.value = 'undefined'; - } else if (value instanceof Array) { - group.attributes.value = value[1]; - } else { - group.attributes.value = value; - } - }, + if (group.attributes.grouped_on && this.fields[group.attributes.grouped_on].type === 'selection') { + var selection = this.fields[group.attributes.grouped_on].selection, + value_lookup = _.find(selection, function (val) { return val[0] === value; }); + group.attributes.value = value_lookup ? value_lookup[1] : 'undefined'; + } else if (value === false) { + group.attributes.value = 'undefined'; + } else if (value instanceof Array) { + group.attributes.value = value[1]; + } - add_path: function (group, current_path) { - var self = this; + group.path = value ? (current_path || []).concat(group.attributes.value) : []; + group.attributes.aggregates.__count = group.attributes.length; - group.path = current_path.concat(group.attributes.value); - var result = [group]; - _.each(group.subgroups_data, function (subgroup) { - result = result.concat(self.add_path(subgroup, group.path)); - }); - return result; + return group; }, // To obtain all the values required to draw the full table, we have to do @@ -384,13 +430,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // 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 (options) { + load_data: function () { var self = this, - cols = options.col_groupby, - rows = options.row_groupby, - visible_fields = _.without(rows.concat(cols, options.measures), '__count'); - - // if (options.measure) { visible_fields = visible_fields.concat(options.measure); } + cols = this.cols.groupby, + rows = this.rows.groupby, + visible_fields = rows.concat(cols, self.measures); var groupbys = _.map(_.range(cols.length + 1), function (i) { return cols.slice(0, i).concat(rows); @@ -398,7 +442,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM groupbys.push([]); var def_array = _.map(groupbys, function (groupby) { - return self.get_groups(visible_fields, options.domain, groupby); + return self.get_groups(groupby, visible_fields, self.domain); }); return $.when.apply(null, def_array).then(function () { @@ -407,92 +451,67 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM col_data = (cols.length !== 0) ? data[data.length - 2] : [], total = data[data.length - 1][0]; - options.total = total; return (total === undefined) ? undefined - : self.format_data(total, col_data, row_data, data, options); - }); - }, - - get_value_from_data: function (data, measures) { - var attr = data.attributes; - var result = _.map(measures, function (measure) { - return (measure === '__count') ? attr.length : attr.aggregates[measure]; + : self.format_data(total, col_data, row_data, data); }); - return result; }, - format_data: function (total, col_data, row_data, cell_data, options) { + format_data: function (total, col_data, row_data, cell_data) { var self = this, - dim_row = options.row_groupby.length, - dim_col = options.col_groupby.length, - col_headers = make_list(this.make_headers(col_data, dim_col, options)), - row_headers = make_list(this.make_headers(row_data, dim_row, options)), + 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)), cells = []; + this.cells = []; _.each(cell_data, function (data, index) { - self.make_cells(data, index, [], cells, row_headers, col_headers, options); + self.make_cells(data, index, [], row_headers, col_headers); }); // make it more functional? return {col_headers: col_headers, - row_headers: row_headers, - cells: cells}; - - function make_list (tree) { - return [].concat.apply([tree], _.map(tree.children, make_list)); - } + row_headers: row_headers}; }, - make_headers: function (data, depth, options, parent) { + make_headers: function (data, depth, parent) { var self = this, main = { id: _.uniqueId(), - path: (parent) ? parent.path.concat(data.attributes.value) : [], - parent: parent, + path: parent ? parent.path.concat(data.attributes.value) : [], children: [], - title: (parent) ? data.attributes.value : '', - domain: (parent) ? data.model._domain : options.domain, - total: this.get_value_from_data(options.total, options.measures), + title: parent ? data.attributes.value : '', + domain: parent ? data.model._domain : this.domain, }; if (main.path.length < depth) { - main.children = _.map(data.subgroups_data || data, function (data_pt) { - return self.make_headers (data_pt, depth, options, main); + 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, current_cells, rows, cols, options) { + make_cells: function (data, index, current_path, rows, cols) { var self = this; _.each(data, function (group) { var attr = group.attributes, - group_val = (attr.value instanceof Array) ? attr.value[1] : attr.value, - path = current_path, - values = _.map(options.measures, function (measure) { - return (measure === '__count') ? attr.length : attr.aggregates[measure]; + path = attr.grouped_on ? current_path.concat(attr.value) : current_path, + values = _.map(self.measures, function (measure) { + return (measure.field === '__count') ? attr.length : attr.aggregates[measure.field]; }); - group_val = (group_val === false) ? undefined : group_val; - - if (attr.grouped_on !== undefined) { - path = path.concat((attr.value === false) ? 'undefined' : group_val); - } - var row = _.find(rows, function (header) { - return _.isEqual(header.path, path.slice(index)); - }); - var col = _.find(cols, function (header) { - return _.isEqual(header.path, path.slice(0, index)); - }); - current_cells.push({x: Math.min(row.id, col.id), - y: Math.max(row.id, col.id), - values: values}); + var row = _.find(rows, function (header) { return _.isEqual(header.path, path.slice(index)); }); + var col = _.find(cols, function (header) { return _.isEqual(header.path, path.slice(0, index)); }); + self.add_cell(row.id, col.id, values); - if (attr.has_children) { - self.make_cells (group.subgroups_data, index, path, current_cells, rows, cols, options); + if (group.children) { + self.make_cells (group.children, index, path, rows, cols); } }); }, }); -})(); \ No newline at end of file +})(); + + -- cgit v1.2.3 From dbf064e817b3b37fa29c01ef362662ec134707d2 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 10 Jan 2014 13:01:49 +0100 Subject: [REF] removes useless comments (addon web_graph) bzr revid: ged@openerp.com-20140110120149-pi0h75eqlr2tl9n5 --- addons/web_graph/static/src/js/graph.js | 55 +-------------------------------- addons/web_graph/static/src/js/pivot.js | 5 +-- 2 files changed, 2 insertions(+), 58 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 84a7d147ac2..8cdc9a3eb0f 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -41,7 +41,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.widget_config = { title: arch.attrs.string }; - debugger; if (!_.has(arch.attrs, 'type')) { this.widget_config.mode = 'bar_chart'; } else { @@ -238,7 +237,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix self.add_measures_to_options(); }); - $.when(def1, def2).then(function () { + return $.when(def1, def2).then(function () { self.pivot = new openerp.web_graph.PivotTable(self.model, self.domain, self.fields, self.pivot_options); self.pivot.on('redraw_required', self, self.proxy('display_data')); self.pivot.on('groupby_changed', self, function () { self.trigger('groupby_changed'); }); @@ -329,57 +328,6 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix }); }, - // self.fields = fs; - // var temp = _.map(fs, function (field, name) { - // return {name:name, type: field.type}; - // }); - // temp = _.filter(temp, function (field) { - // return (((field.type === 'integer') || (field.type === 'float')) && (field.name !== 'id')); - // }); - // self.measure_list = _.map(temp, function (field) { - // return field.name; - // }); - - // var measure_selection = self.$('.graph_measure_selection'); - // _.each(self.measure_list, function (measure) { - // var choice = $('').attr('data-choice', measure) - // .attr('href', '#') - // .append(self.fields[measure].string); - // measure_selection.append($('
  • ').append(choice)); - // }); - // }); - // }, - - // hide ui/show, stacked/grouped - // config: function (options) { - // Possible modes: pivot, heatmap, row_heatmap, col_heatmap, - // bar_chart, pie_chart, line_chart - // if (_.has(options, 'mode')) { this.mode = mode; } - // if (_.has(options, 'visible_ui')) { - // this.visible_ui = options.visible_ui; - // } - // if (_.has(options, 'bar_ui')) { - // this.bar_ui = options.bar_ui; - // } - // if (_.has(options, 'title')) { - // this.title = options.title; - // } - // debugger; - // this.pivot.config(options); - // }, - - - // get the most important fields (of the model) by looking at the - // groupby filters defined in the search view - - // get the fields descriptions and measure list from the model - - // return $.when(deferred1, deferred2).then(function () { - // self.pivot = new openerp.web_graph.PivotTable(self.model, self.fields); - // self.activate_display(); - // }); - // }, - set_mode: function (mode) { }, @@ -797,7 +745,6 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix pie_chart: function () { var self = this, dim_x = this.pivot.rows.groupby.length; - debugger; var data = _.map(this.pivot.get_rows_leaves(), function (row) { var title = _.map(row.path, function (p) { return p || 'Undefined'; diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 49f2ff4b2d5..dcf89de1144 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -9,8 +9,7 @@ // Here is a short description of the way the data is organized: // Main fields: // cells = [cell] -// cell = {x: _, y: _, values: [value]} -// value = {type: _, value: _} +// cell = {x: _, y: _, values: [_]} // measures = [measure] // measure = {field: _, string: _, type: _} // rows, cols = {groupby: [groupby], headers: [header]} @@ -20,7 +19,6 @@ // path: _, // title: _, // expanded: _, -// parent: _, // children: _, // domain: _, // root: _, @@ -28,7 +26,6 @@ // // Pivot Table emits the events 'groupby_changed' and 'redraw_required' when necessary. // PivotTable require a 'update_data' after init to be ready -// to do: add an option to enable/disable update_data at the end of init openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { init: function (model, domain, fields, options) { -- cgit v1.2.3 From 2b3b08160cd43f47f1ee11fa0fb6f400849f2fa1 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 10 Jan 2014 15:08:37 +0100 Subject: [REF] simplification of the way Pivot configuration is done in graph view (addon web_graph) bzr revid: ged@openerp.com-20140110140837-tl3ts6za0zr46id7 --- addons/web_graph/static/src/js/graph.js | 158 +++++++++++--------------------- addons/web_graph/static/src/js/pivot.js | 75 +++++++-------- 2 files changed, 83 insertions(+), 150 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 8cdc9a3eb0f..d92d09f3a8c 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -35,37 +35,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ view_loading: function (fields_view_get) { var self = this, - arch = fields_view_get.arch, - measures = [], - stacked = false; + arch = fields_view_get.arch; - this.widget_config = { title: arch.attrs.string }; - - if (!_.has(arch.attrs, 'type')) { - this.widget_config.mode = 'bar_chart'; - } else { - switch (arch.attrs.type) { - case 'bar': - this.widget_config.mode = 'bar_chart'; - break; - case 'pie': - this.widget_config.mode = 'pie_chart'; - break; - case 'line': - this.widget_config.mode = 'line_chart'; - break; - case 'pivot': - case 'heatmap': - case 'row_heatmap': - case 'col_heatmap': - this.widget_config.mode = arch.attrs.type; - break; - } - } - - if (arch.attrs.stacked === 'True') { - this.widget_config.stacked = true; - } + this.widget_config = { + title: arch.attrs.string, + stacked : (arch.attrs.stacked === 'True'), + mode: (arch.attrs.type) ? arch.attrs.type : 'bar', + measures: [], + }; _.each(arch.children, function (field) { if (_.has(field.attrs, 'type')) { @@ -77,28 +54,22 @@ instance.web_graph.GraphView = instance.web.View.extend({ self.default_col_groupby.push(field.attrs.name); break; case 'measure': - measures.push(field.attrs.name); + self.widget_config.measures.push(field.attrs.name); break; } } else { // old style, kept for backward compatibility if ('operator' in field.attrs) { - measures.push(field.attrs.name); + self.widget_config.measures.push(field.attrs.name); } else { self.default_row_groupby.push(field.attrs.name); } } }); - if (measures.length === 0) { - measures.push('__count'); + if (self.widget_config.measures.length === 0) { + self.widget_config.measures.push('__count'); } this.widget_config.row_groupby = self.default_row_groupby; this.widget_config.col_groupby = self.default_col_groupby; - this.widget_config.measures = measures; - // measures:measures, - // update:false, - // title: title, - // bar_ui: (stacked) ? 'stack' : 'group' - // }); }, get_context: function (facet) { @@ -109,46 +80,42 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { - var col_groupby = context.col_group_by || [], - options = {domain:domain}; + // var col_groupby = context.col_group_by || [], + // options = {domain:domain}; if (!this.graph_widget) { this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); + this.ViewManager.on('switch_mode', this, function (e) { if (e === 'graph') this.graph_widget.reload(); }); } - this.search_view_groupby = group_by; + // this.search_view_groupby = group_by; - if (group_by.length && this.groupby_mode !== 'manual') { - if (_.isEqual(col_groupby, [])) { - col_groupby = this.default_col_groupby; - } - } - if (group_by.length || col_groupby.length) { - this.groupby_mode = 'manual'; - } - if (!this.graph_widget.enabled) { - options.update = false; - options.silent = true; - } - - if (this.groupby_mode === 'manual') { - options.row_groupby = group_by; - options.col_groupby = col_groupby; - } else { - options.row_groupby = _.toArray(this.default_row_groupby); - options.col_groupby = _.toArray(this.default_col_groupby); - } - this.graph_widget.set_domain(domain); - this.graph_widget.set_col_groupby(options.col_groupby); - this.graph_widget.set_row_groupby(options.row_groupby); + // if (group_by.length && this.groupby_mode !== 'manual') { + // if (_.isEqual(col_groupby, [])) { + // col_groupby = this.default_col_groupby; + // } + // } + // if (group_by.length || col_groupby.length) { + // this.groupby_mode = 'manual'; + // } + // if (!this.graph_widget.enabled) { + // options.update = false; + // options.silent = true; + // } - // this.graph_widget.pivot.config(options); + // if (this.groupby_mode === 'manual') { + // options.row_groupby = group_by; + // options.col_groupby = col_groupby; + // } else { + // options.row_groupby = _.toArray(this.default_row_groupby); + // options.col_groupby = _.toArray(this.default_col_groupby); + // } + // this.graph_widget.set(domain, options.row_groupby, options.col_groupby); + // this.graph_widget.set_domain(domain); + // this.graph_widget.set_col_groupby(options.col_groupby); + // this.graph_widget.set_row_groupby(options.row_groupby); - if (!this.graph_widget.enabled) { - this.graph_widget.activate_display(); - this.ViewManager.on('switch_mode', this, function () {this.graph_widget.pivot.update_data(); }); - } }, do_show: function () { @@ -199,7 +166,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, }); -// important_fields = [field], field = {field: _,type: _, string: _} instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMixin, { template: 'GraphWidget', @@ -212,8 +178,6 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix }, init: function(parent, model, domain, options) { - var self = this; - this._super(parent); this.model = model; this.domain = domain; @@ -231,7 +195,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix self.important_fields = f; }); - var def2 = this.get_model_fields().then(function (f) { + var def2 = this.model.call('fields_get', []).then(function (f) { self.fields = f; self.measure_list = self.get_measures(); self.add_measures_to_options(); @@ -278,12 +242,6 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix }); }, - get_model_fields: function () { - return this.model.call('fields_get', []).then(function (fs) { - return fs; - }); - }, - get_measures: function(fields) { var measures = []; _.each(this.fields, function (f, id) { @@ -294,27 +252,14 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix return measures; }, - set_domain: function (domain) { - if (this.pivot) { - this.pivot.set_domain(domain); - } else { - this.pivot_options.domain = domain; - } - }, - set_row_groupby: function (groupby) { + set: function (domain, row_groupby, col_groupby) { if (this.pivot) { - this.pivot.set_row_groupby(groupby); + this.pivot.set(domain, row_groupby, col_groupby); } else { - this.pivot_options.row_groupby = groupby; - } - }, - - set_col_groupby: function (groupby) { - if (this.pivot) { - this.pivot.set_col_groupby(groupby); - } else { - this.pivot_options.col_groupby = groupby; + this.pivot_options.domain = domain; + this.pivot_options.row_groupby = row_groupby; + this.pivot_options.col_groupby = col_groupby; } }, @@ -329,10 +274,12 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix }, set_mode: function (mode) { - + this.mode = mode; + this.display_data(); }, - activate_display: function () { + reload: function () { + this.pivot.update_data(); }, display_data: function () { @@ -364,8 +311,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix mode_selection: function (event) { event.preventDefault(); var mode = event.target.attributes['data-mode'].nodeValue; - this.mode = mode; - this.display_data(); + this.set_mode(mode); }, measure_selection: function (event) { @@ -623,7 +569,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix /****************************************************************************** * Drawing charts methods... ******************************************************************************/ - bar_chart: function () { + bar: function () { var self = this, dim_x = this.pivot.rows.groupby.length, dim_y = this.pivot.cols.groupby.length, @@ -707,7 +653,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix }, - line_chart: function () { + line: function () { var self = this, dim_x = this.pivot.rows.groupby.length, dim_y = this.pivot.cols.groupby.length; @@ -742,7 +688,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix }); }, - pie_chart: function () { + pie: function () { var self = this, dim_x = this.pivot.rows.groupby.length; var data = _.map(this.pivot.get_rows_leaves(), function (row) { diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index dcf89de1144..10a6b3f9052 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -30,8 +30,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM init: function (model, domain, fields, options) { openerp.EventDispatcherMixin.init.call(this); - this.rows = { groupby: [], headers: null }; - this.cols = { groupby: [], headers: null }; this.cells = []; this.domain = domain; this.no_data = true; @@ -40,9 +38,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.fields.__count = {type: 'integer', string:'Quantity'}; this.measures = [{field:'__count', type: this.fields.type, string:this.fields.string}]; this.active = false; + this.rows = { groupby: this.create_field_values(options.row_groupby || []), headers: null }; + this.cols = { groupby: this.create_field_values(options.col_groupby || []), headers: null }; if (options.measures) { this.set_measures(options.measures); } - if (options.col_groupby) { this.set_col_groupby(options.col_groupby); } - if (options.row_groupby) { this.set_row_groupby(options.row_groupby); } }, // ---------------------------------------------------------------------- @@ -53,11 +51,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.update_data(); }, - set_domain: function (domain) { - this.domain = domain; - if (this.active) { this.update_data(); } - }, - set_measures: function (measures) { var self = this; if (!_.isEqual(measures, this.measures)) { @@ -93,42 +86,37 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM if (this.active) { this.update_data(); } }, - set_col_groupby: function (groupbys) { - var self = this; - if (!_.isEqual(groupbys, this.cols.groupby)) { - this.cols.groupby = []; - _.each(groupbys, function (g) { self._add_groupby(self.cols.groupby, g); }); - this.cols.headers = null; - if (this.active) { - this.trigger('groupby_changed'); - this.update_data(); - } - } - }, + set: function (domain, row_groupby, col_groupby) { + var row_gbs = this.create_field_values(row_groupby), + col_gbs = this.create_field_values(col_groupby), + dom_changed = !_.isEqual(this.domain, domain), + gb_changed = !(_.isEqual(row_gbs, this.rows.groupby) && + _.isEqual(col_gbs, this.cols.groupby)); - set_row_groupby: function (groupbys) { - var self = this; - if (!_.isEqual(groupbys, this.rows.groupby)) { - this.rows.groupby = []; - _.each(groupbys, function (g) { self._add_groupby(self.rows.groupby, g); }); - this.rows.headers = null; - if (this.active) { - this.trigger('groupby_changed'); - this.update_data(); - } - } - }, + if (dom_changed) { + this.domain = domain; + } + if (gb_changed) { + this.cols.groupby = col_gbs; + this.rows.groupby = row_gbs; + if (this.active) { this.trigger('groupby_changed'); } + } + if (this.active && (gb_changed || dom_changed)) { + this.update_data(); + } + }, + + create_field_value: function (f) { + return (f.field && f.string && f.type) ? f : {field: f, string: this.fields[f].string, type: this.fields[f].type}; + }, + + create_field_values: function (field_ids) { + var self = this; + return _.map(field_ids, function (f) { return self.create_field_value(f); }); + }, _add_groupby: function(groupby_list, groupby) { - if (groupby.field && groupby.string && groupby.type) { - groupby_list.push(groupby); - } else { - groupby_list.push({ - field:groupby, - string: this.fields[groupby].string, - type: this.fields[groupby].type - }); - } + groupby_list.push(this.create_field_value(groupby)); }, // ---------------------------------------------------------------------- @@ -413,7 +401,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM group.attributes.value = 'undefined'; } else if (value instanceof Array) { group.attributes.value = value[1]; - } + } group.path = value ? (current_path || []).concat(group.attributes.value) : []; group.attributes.aggregates.__count = group.attributes.length; @@ -508,7 +496,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }, }); - })(); -- cgit v1.2.3 From bb1069ace8509959d9c1b41c2fb95f85da2d9934 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 10 Jan 2014 16:15:24 +0100 Subject: [REF] removes some code duplication when creating new headers in pivot class (addon web_graph) bzr revid: ged@openerp.com-20140110151524-i2usd1nyrfpgkody --- addons/web_graph/static/src/js/pivot.js | 38 ++++++++++++++------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 10a6b3f9052..69630d360a1 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -250,7 +250,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM return this.get_groups(groupby, fields, header.domain) .then(function (groups) { _.each(groups.reverse(), function (group) { - var child_id = self.make_header(group, 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); + // return new_header.id; // make cells _.each(self.get_ancestors_and_self(group), function (data) { var values = _.map(self.measures, function (m) { @@ -265,7 +269,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM } }); if (other) { - self.add_cell(child_id, other.id, values); + self.add_cell(child.id, other.id, values); } }); }); @@ -275,19 +279,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }, make_header: function (group, parent) { - var title = group.attributes.value, - new_header = { - id: _.uniqueId(), - path: parent.path.concat(title), - title: title, - expanded: false, - children: [], - domain: group.model._domain, - root: parent.root, - }; - parent.children.splice(0,0, new_header); - parent.root.headers.splice(parent.root.headers.indexOf(parent) + 1, 0, new_header); - return new_header.id; + var title = parent ? group.attributes.value : ''; + 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 () { @@ -460,13 +460,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM make_headers: function (data, depth, parent) { var self = this, - main = { - id: _.uniqueId(), - path: parent ? parent.path.concat(data.attributes.value) : [], - children: [], - title: parent ? data.attributes.value : '', - domain: parent ? data.model._domain : this.domain, - }; + main = this.make_header(data, parent); if (main.path.length < depth) { main.children = _.map(data.children || data, function (data_pt) { -- cgit v1.2.3 From e2bb629c3c2528c26b216ff8fe21b4c4fb7634e0 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 13 Jan 2014 14:38:00 +0100 Subject: [IMP] adds support for various intervals when grouping by date in graph view (addon web_graph) bzr revid: ged@openerp.com-20140113133800-3n1hi5ajpioktr3d --- addons/web_graph/static/src/js/graph.js | 12 ++++++++--- addons/web_graph/static/src/js/pivot.js | 35 ++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 6 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index d92d09f3a8c..abd1d41d629 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -369,7 +369,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix return; } var fields = _.map(this.important_fields, function (field) { - return {id: field, value: self.fields[field].string}; + return {id: field, value: self.fields[field].string, type:self.fields[field].type}; }); this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); $(event.target).after(this.dropdown); @@ -383,9 +383,15 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix field_selection: function (event) { var id = event.target.attributes['data-id'].nodeValue, - field_id = event.target.attributes['data-field-id'].nodeValue; + field_id = event.target.attributes['data-field-id'].nodeValue, + interval; event.preventDefault(); - this.pivot.expand(id, field_id); + if (this.fields[field_id].type === 'date' || this.fields[field_id].type === 'datetime') { + interval = event.target.attributes['data-interval'].nodeValue; + this.pivot.expand(id, {field: field_id, interval: interval}); + } else { + this.pivot.expand(id, field_id); + } }, /****************************************************************************** diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 69630d360a1..62d6e35b77c 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -107,6 +107,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }, create_field_value: function (f) { + if (f.field && f.interval) { + return {field:f.field, string: this.fields[f.field].string, type:this.fields[f.field].type, interval: f.interval}; + } return (f.field && f.string && f.type) ? f : {field: f, string: this.fields[f].string, type: this.fields[f].type}; }, @@ -376,11 +379,37 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM _query_db: function (groupby, fields, domain, path) { var self = this, - field_ids = _.without(_.pluck(fields, 'field'), '__count'); - // To do : add code to check if groupby is date/datetime - // and in that case, add the correct code to the context + field_ids = _.without(_.pluck(fields, 'field'), '__count'), + context = {}; + + if (groupby.interval) { + context.datetime_format = {}; + var display_format; + switch (groupby.interval) { + case 'day': + display_format = 'dd MMMM YYYY'; + break; + case 'week': + display_format = 'w YYYY'; + break; + case 'month': + display_format = 'MMMM YYYY'; + break; + case 'quarter': + display_format = 'QQQ YYYY'; + break; + case 'year': + display_format = 'YYYY'; + break; + } + context.datetime_format[groupby.field] = { + interval: groupby.interval, + display_format: display_format + }; + } return this.model.query(field_ids) .filter(domain) + .context(context) .group_by(groupby.field) .then(function (results) { var groups = _.filter(results, function (group) { -- cgit v1.2.3 From 4d550e963ea07da045bcb8f68ec4fad5fc7b591d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 13 Jan 2014 16:23:16 +0100 Subject: [FIX] fixes some issues with chart drawing in graph view (addon web_graph) bzr revid: ged@openerp.com-20140113152316-4i3endkgu10jmxgc --- addons/web_graph/static/src/js/graph.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index abd1d41d629..f39f0574e9b 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -184,6 +184,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix this.mode = options.mode || 'pivot'; this.title = options.title || 'Graph'; this.visible_ui = options.visible_ui || true; + this.bar_ui = options.bar_ui || 'group'; this.pivot_options = options; }, @@ -325,13 +326,13 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix switch (event.target.attributes['data-choice'].nodeValue) { case 'bar_grouped': this.bar_ui = 'group'; - if (this.mode === 'bar_chart') { + if (this.mode === 'bar') { this.display_data(); } break; case 'bar_stacked': this.bar_ui = 'stack'; - if (this.mode === 'bar_chart') { + if (this.mode === 'bar') { this.display_data(); } break; @@ -609,7 +610,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix var values = _.map(self.pivot.get_rows_with_depth(1), function (header) { return { x: header.title || 'Undefined', - y: self.pivot.get_values(header.id, colhdr.id, 0)[0] + y: self.pivot.get_values(header.id, colhdr.id)[0] || 0 }; }); return {key: colhdr.title || 'Undefined', values: values}; -- cgit v1.2.3 From de85a1cefb2d62aae5a4a29295dcf36b6c545ad6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 14 Jan 2014 10:27:24 +0100 Subject: [REF] adds comments and reorganize the functions in PivotTable class (addon web_graph) bzr revid: ged@openerp.com-20140114092724-z534vyceksc4dnr2 --- addons/web_graph/static/src/js/graph.js | 4 +- addons/web_graph/static/src/js/pivot.js | 159 +++++++++++++++++--------------- 2 files changed, 88 insertions(+), 75 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index f39f0574e9b..0259b4bcf73 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -340,9 +340,7 @@ instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMix this.pivot.swap_axis(); break; case 'expand_all': - this.pivot.rows.headers = null; - this.pivot.cols.headers = null; - this.pivot.update_data(); + this.pivot.expand_all(); break; case 'update_values': this.pivot.update_data(); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js index 62d6e35b77c..b78e8323645 100644 --- a/addons/web_graph/static/src/js/pivot.js +++ b/addons/web_graph/static/src/js/pivot.js @@ -4,28 +4,9 @@ (function () { 'use strict'; -// Pivot Table -// -// Here is a short description of the way the data is organized: -// Main fields: -// cells = [cell] -// cell = {x: _, y: _, values: [_]} -// measures = [measure] -// measure = {field: _, string: _, type: _} -// rows, cols = {groupby: [groupby], headers: [header]} -// groupby = {field: _, string: _, type: _, interval: _} (interval only if type = date/datetime) -// header = { -// id: _, -// path: _, -// title: _, -// expanded: _, -// children: _, -// domain: _, -// root: _, -// } -// // Pivot Table emits the events 'groupby_changed' and 'redraw_required' when necessary. -// PivotTable require a 'update_data' after init to be ready +// PivotTable is initialized by default 'inactive', and require a call to activate() +// after init to load initial data and start triggering events. openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { init: function (model, domain, fields, options) { @@ -46,6 +27,12 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // ---------------------------------------------------------------------- // Configuration methods // ---------------------------------------------------------------------- + // this.measures: list of measure [measure], measure = {field: _, string: _, type: _} + // this.rows.groupby, this.cols.groupby : list of groupbys used for describing rows (...), + // a groupby is also {field:_, string:_, type:_} but it also has a interval + // attribute if its type is date/datetime. + // this.active: If PivotTable is active then it triggers events and updates + // its values when necessary activate: function() { this.active = true; this.update_data(); @@ -108,9 +95,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM create_field_value: function (f) { if (f.field && f.interval) { - return {field:f.field, string: this.fields[f.field].string, type:this.fields[f.field].type, interval: f.interval}; + return { field:f.field, + string: this.fields[f.field].string, + type:this.fields[f.field].type, + interval: f.interval }; } - return (f.field && f.string && f.type) ? f : {field: f, string: this.fields[f].string, type: this.fields[f].type}; + return (f.field && f.string && f.type) ? f : { field: f, + string: this.fields[f].string, + type: this.fields[f].type }; }, create_field_values: function (field_ids) { @@ -125,17 +117,18 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // ---------------------------------------------------------------------- // Cells manipulation methods // ---------------------------------------------------------------------- + // cells are objects {x:_, y:_, values:_} where x < y and values is an array + // of values (one for each measure). The condition x < y might look + // unnecessary, but it makes the rest of the code simpler: headers + // don't krow if they are rows or cols, they just know their id, so + // it is useful that a call get_values(id1, id2) is the same as get_values(id2, id1) add_cell : function (id1, id2, values) { - var x = Math.min(id1, id2), - y = Math.max(id1, id2); - this.cells.push({x: x, y: y, values: values}); + this.cells.push({x: Math.min(id1, id2), y: Math.max(id1, id2), values: values}); }, get_values: function (id1, id2, default_values) { - var x = Math.min(id1, id2), - y = Math.max(id1, id2), - cell = _.find(this.cells, function (c) { - return ((c.x == x) && (c.y == y)); + var cell = _.find(this.cells, function (c) { + return ((c.x == Math.min(id1, id2)) && (c.y == Math.max(id1, id2))); }); return (cell !== undefined) ? cell.values : (default_values || new Array(this.measures.length)); }, @@ -143,6 +136,17 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // ---------------------------------------------------------------------- // Headers/Rows/Cols manipulation methods // ---------------------------------------------------------------------- + // this.rows.headers, this.cols.headers = [header] describe the tree structure + // of rows/cols. Headers are objects + // { + // id:_, (unique id obviously) + // path: [...], (array of all parents title, with its own title at the end) + // title:_, (name of the row/col) + // children:[_], (subrows or sub cols of this row/col) + // domain:_, (domain of data in this row/col) + // root:_ (ref to this.rows or this.cols corresponding to the header) + // expanded:_ (boolean, true if it has been expanded) + // } is_row: function (id) { return !!_.find(this.rows.headers, function (header) { return header.id === id; @@ -216,7 +220,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM main_col: function () { return this.cols.headers[0]; }, // ---------------------------------------------------------------------- - // Table manipulation methods + // Table manipulation methods : fold/expand/swap // ---------------------------------------------------------------------- fold: function (header) { var ancestors = this.get_ancestors(header), @@ -253,17 +257,16 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM 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); - // return new_header.id; // 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); @@ -302,8 +305,12 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }, // ---------------------------------------------------------------------- - // Data loading methods + // 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; @@ -354,7 +361,48 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM root.headers = updated_headers; }, - // options: fields: _, path_prefix: [] + expand_all: function () { + this.rows.headers = null; + this.cols.headers = null; + this.update_data(); + }, + + // ---------------------------------------------------------------------- + // 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); + + var groupbys = _.map(_.range(cols.length + 1), function (i) { + return cols.slice(0, i).concat(rows); + }); + groupbys.push([]); + + var def_array = _.map(groupbys, function (groupby) { + return self.get_groups(groupby, visible_fields, self.domain); + }); + + return $.when.apply(null, def_array).then(function () { + var data = Array.prototype.slice.call(arguments), + row_data = data[0], + col_data = (cols.length !== 0) ? data[data.length - 2] : [], + total = data[data.length - 1][0]; + + return (total === undefined) ? undefined + : self.format_data(total, col_data, row_data, data); + }); + }, + get_groups: function (groupbys, fields, domain, path) { path = path || []; var self = this, @@ -419,6 +467,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }); }, + // add the path to the group and sanitize the value... format_group: function (group, current_path) { var value = group.attributes.value; @@ -438,53 +487,19 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM return group; }, - // 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); - - var groupbys = _.map(_.range(cols.length + 1), function (i) { - return cols.slice(0, i).concat(rows); - }); - groupbys.push([]); - - var def_array = _.map(groupbys, function (groupby) { - return self.get_groups(groupby, visible_fields, self.domain); - }); - - return $.when.apply(null, def_array).then(function () { - var data = Array.prototype.slice.call(arguments), - row_data = data[0], - col_data = (cols.length !== 0) ? data[data.length - 2] : [], - total = data[data.length - 1][0]; - - return (total === undefined) ? undefined - : self.format_data(total, col_data, row_data, data); - }); - }, - format_data: function (total, 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)), - cells = []; + 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); - }); // make it more functional? + }); // not pretty. make it more functional? - return {col_headers: col_headers, - row_headers: row_headers}; + return {col_headers: col_headers, row_headers: row_headers}; }, make_headers: function (data, depth, parent) { -- cgit v1.2.3 From 11de0f36ed923f0222d8e1ecc603b53366eabf75 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 14 Jan 2014 13:51:42 +0100 Subject: [REF] separates graph view and graph widget into two files, and renames pivot into pivot_table.js (addon web_graph) bzr revid: ged@openerp.com-20140114125142-9qj3mvu0a1fp4sis --- addons/web_graph/static/src/js/graph.js | 737 ------------------------- addons/web_graph/static/src/js/graph_view.js | 177 ++++++ addons/web_graph/static/src/js/graph_widget.js | 567 +++++++++++++++++++ addons/web_graph/static/src/js/pivot.js | 539 ------------------ addons/web_graph/static/src/js/pivot_table.js | 539 ++++++++++++++++++ 5 files changed, 1283 insertions(+), 1276 deletions(-) delete mode 100644 addons/web_graph/static/src/js/graph.js create mode 100644 addons/web_graph/static/src/js/graph_view.js create mode 100644 addons/web_graph/static/src/js/graph_widget.js delete mode 100644 addons/web_graph/static/src/js/pivot.js create mode 100644 addons/web_graph/static/src/js/pivot_table.js (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js deleted file mode 100644 index 0259b4bcf73..00000000000 --- a/addons/web_graph/static/src/js/graph.js +++ /dev/null @@ -1,737 +0,0 @@ -/*--------------------------------------------------------- - * OpenERP web_graph - *---------------------------------------------------------*/ - -/* jshint undef: false */ - -openerp.web_graph = function (instance) { -'use strict'; - -var _lt = instance.web._lt; -var _t = instance.web._t; -var QWeb = instance.web.qweb; - -instance.web.views.add('graph', 'instance.web_graph.GraphView'); - -instance.web_graph.GraphView = instance.web.View.extend({ - display_name: _lt('Graph'), - view_type: 'graph', - - init: function(parent, dataset, view_id, options) { - this._super(parent, dataset, view_id, options); - this.dataset = dataset; - this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); - this.search_view = parent.searchview; - this.search_view_groupby = []; - this.groupby_mode = 'default'; // 'default' or 'manual' - this.default_row_groupby = []; - this.default_col_groupby = []; - this.search_field = { - get_context: this.proxy('get_context'), - get_domain: function () {}, - get_groupby: function () { }, - }; - }, - - view_loading: function (fields_view_get) { - var self = this, - arch = fields_view_get.arch; - - this.widget_config = { - title: arch.attrs.string, - stacked : (arch.attrs.stacked === 'True'), - mode: (arch.attrs.type) ? arch.attrs.type : 'bar', - measures: [], - }; - - _.each(arch.children, function (field) { - if (_.has(field.attrs, 'type')) { - switch (field.attrs.type) { - case 'row': - self.default_row_groupby.push(field.attrs.name); - break; - case 'col': - self.default_col_groupby.push(field.attrs.name); - break; - case 'measure': - self.widget_config.measures.push(field.attrs.name); - break; - } - } else { // old style, kept for backward compatibility - if ('operator' in field.attrs) { - self.widget_config.measures.push(field.attrs.name); - } else { - self.default_row_groupby.push(field.attrs.name); - } - } - }); - if (self.widget_config.measures.length === 0) { - self.widget_config.measures.push('__count'); - } - this.widget_config.row_groupby = self.default_row_groupby; - this.widget_config.col_groupby = self.default_col_groupby; - }, - - get_context: function (facet) { - var col_group_by = _.map(facet.values.models, function (model) { - return model.attributes.value.attrs.context.col_group_by; - }); - return {col_group_by : col_group_by}; - }, - - do_search: function (domain, context, group_by) { - // var col_groupby = context.col_group_by || [], - // options = {domain:domain}; - - if (!this.graph_widget) { - this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); - this.graph_widget.appendTo(this.$el); - this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); - this.ViewManager.on('switch_mode', this, function (e) { if (e === 'graph') this.graph_widget.reload(); }); - } - // this.search_view_groupby = group_by; - - // if (group_by.length && this.groupby_mode !== 'manual') { - // if (_.isEqual(col_groupby, [])) { - // col_groupby = this.default_col_groupby; - // } - // } - // if (group_by.length || col_groupby.length) { - // this.groupby_mode = 'manual'; - // } - // if (!this.graph_widget.enabled) { - // options.update = false; - // options.silent = true; - // } - - // if (this.groupby_mode === 'manual') { - // options.row_groupby = group_by; - // options.col_groupby = col_groupby; - // } else { - // options.row_groupby = _.toArray(this.default_row_groupby); - // options.col_groupby = _.toArray(this.default_col_groupby); - // } - // this.graph_widget.set(domain, options.row_groupby, options.col_groupby); - // this.graph_widget.set_domain(domain); - // this.graph_widget.set_col_groupby(options.col_groupby); - // this.graph_widget.set_row_groupby(options.row_groupby); - - }, - - do_show: function () { - this.do_push_state({}); - return this._super(); - }, - - register_groupby: function() { - // var self = this, - // query = this.search_view.query; - - // this.groupby_mode = 'manual'; - // if (_.isEqual(this.search_view_groupby, this.graph_widget.pivot.rows.groupby) || - // (!_.has(this.search_view, '_s_groupby'))) { - // return; - // } - // var rows = _.map(this.graph_widget.pivot.rows.groupby, function (group) { - // return make_facet('GroupBy', group); - // }); - // var cols = _.map(this.graph_widget.pivot.cols.groupby, function (group) { - // return make_facet('ColGroupBy', group); - // }); - - // query.reset(rows.concat(cols)); - - // function make_facet (category, fields) { - // var values, - // icon, - // backbone_field, - // cat_name; - // if (!(fields instanceof Array)) { fields = [fields]; } - // if (category === 'GroupBy') { - // cat_name = 'group_by'; - // icon = 'w'; - // backbone_field = self.search_view._s_groupby; - // } else { - // cat_name = 'col_group_by'; - // icon = 'f'; - // backbone_field = self.search_field; - // } - // values = _.map(fields, function (field) { - // var context = {}; - // context[cat_name] = field; - // return {label: self.graph_widget.fields[field].string, value: {attrs:{domain: [], context: context}}}; - // }); - // return {category:category, values: values, icon:icon, field: backbone_field}; - // } - }, -}); - -instance.web_graph.Graph = instance.web.Widget.extend(openerp.EventDispatcherMixin, { - template: 'GraphWidget', - - events: { - 'click .graph_mode_selection li' : 'mode_selection', - 'click .graph_measure_selection li' : 'measure_selection', - 'click .graph_options_selection li' : 'option_selection', - 'click .web_graph_click' : 'header_cell_clicked', - 'click a.field-selection' : 'field_selection', - }, - - init: function(parent, model, domain, options) { - this._super(parent); - this.model = model; - this.domain = domain; - this.mode = options.mode || 'pivot'; - this.title = options.title || 'Graph'; - this.visible_ui = options.visible_ui || true; - this.bar_ui = options.bar_ui || 'group'; - this.pivot_options = options; - }, - - start: function() { - var self = this; - this.table = $('
    '); - this.$('.graph_main_content').append(this.table); - var def1 = this.get_search_fields().then(function (f) { - self.important_fields = f; - }); - - var def2 = this.model.call('fields_get', []).then(function (f) { - self.fields = f; - self.measure_list = self.get_measures(); - self.add_measures_to_options(); - }); - - return $.when(def1, def2).then(function () { - self.pivot = new openerp.web_graph.PivotTable(self.model, self.domain, self.fields, self.pivot_options); - self.pivot.on('redraw_required', self, self.proxy('display_data')); - self.pivot.on('groupby_changed', self, function () { self.trigger('groupby_changed'); }); - instance.web.bus.on('click', self, function () { - if (self.dropdown) { - self.dropdown.remove(); - self.dropdown = null; - } - }); - self.pivot.activate(); - }); - }, - - get_search_fields: function () { - var self = this, - options = {model:this.model, view_type: 'search'}, - result = []; - - return instance.web.fields_view_get(options).then(function (search_view) { - var groups = _.select(search_view.arch.children, function (c) { - return (c.tag === 'group') && (c.attrs.string != 'Display'); - }); - _.each(groups, function(g) { - _.each(g.children, function (g) { - if (g.attrs.context) { - var field_id = py.eval(g.attrs.context).group_by; - if (field_id) { - if (field_id instanceof Array) { - result.concat(field_id); - } else { - result.push(field_id); - } - } - } - }); - }); - return result; - }); - }, - - get_measures: function(fields) { - var measures = []; - _.each(this.fields, function (f, id) { - if (((f.type === 'integer') || (f.type === 'float')) && (id !== 'id')) { - measures.push({field:id, type: f.type, string: f.string}); - } - }); - return measures; - }, - - - set: function (domain, row_groupby, col_groupby) { - if (this.pivot) { - this.pivot.set(domain, row_groupby, col_groupby); - } else { - this.pivot_options.domain = domain; - this.pivot_options.row_groupby = row_groupby; - this.pivot_options.col_groupby = col_groupby; - } - }, - - add_measures_to_options: function() { - var measure_selection = this.$('.graph_measure_selection'); - _.each(this.measure_list, function (measure) { - var choice = $('').attr('data-choice', measure.field) - .attr('href', '#') - .append(measure.string); - measure_selection.append($('
  • ').append(choice)); - }); - }, - - set_mode: function (mode) { - this.mode = mode; - this.display_data(); - }, - - reload: function () { - this.pivot.update_data(); - }, - - display_data: function () { - this.$('.graph_main_content svg').remove(); - this.$('.graph_main_content div').remove(); - this.table.empty(); - - if (this.visible_ui) { - this.$('.graph_header').css('display', 'block'); - } else { - this.$('.graph_header').css('display', 'none'); - } - if (this.pivot.no_data) { - this.$('.graph_main_content').append($(QWeb.render('graph_no_data'))); - } else { - var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; - if (_.contains(table_modes, this.mode)) { - this.draw_table(); - } else { - this.$('.graph_main_content').append($('
    ')); - this.svg = this.$('.graph_main_content svg')[0]; - this.width = this.$el.width(); - this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); - this[this.mode](); - } - } - }, - - mode_selection: function (event) { - event.preventDefault(); - var mode = event.target.attributes['data-mode'].nodeValue; - this.set_mode(mode); - }, - - measure_selection: function (event) { - event.preventDefault(); - var measure = event.target.attributes['data-choice'].nodeValue; - this.pivot.toggle_measure(measure); - }, - - option_selection: function (event) { - event.preventDefault(); - switch (event.target.attributes['data-choice'].nodeValue) { - case 'bar_grouped': - this.bar_ui = 'group'; - if (this.mode === 'bar') { - this.display_data(); - } - break; - case 'bar_stacked': - this.bar_ui = 'stack'; - if (this.mode === 'bar') { - this.display_data(); - } - break; - case 'swap_axis': - this.pivot.swap_axis(); - break; - case 'expand_all': - this.pivot.expand_all(); - break; - case 'update_values': - this.pivot.update_data(); - break; - case 'export_data': - // Export code... To do... - break; - } - }, - - header_cell_clicked: function (event) { - event.preventDefault(); - event.stopPropagation(); - var id = event.target.attributes['data-id'].nodeValue, - header = this.pivot.get_header(id), - self = this; - - if (header.expanded) { - this.pivot.fold(header); - } else { - if (header.path.length < header.root.groupby.length) { - this.pivot.expand(id); - } else { - if (!this.important_fields.length) { - return; - } - var fields = _.map(this.important_fields, function (field) { - return {id: field, value: self.fields[field].string, type:self.fields[field].type}; - }); - this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); - $(event.target).after(this.dropdown); - this.dropdown.css({position:'absolute', - left:event.pageX, - top:event.pageY}); - this.$('.field-selection').next('.dropdown-menu').toggle(); - } - } - }, - - field_selection: function (event) { - var id = event.target.attributes['data-id'].nodeValue, - field_id = event.target.attributes['data-field-id'].nodeValue, - interval; - event.preventDefault(); - if (this.fields[field_id].type === 'date' || this.fields[field_id].type === 'datetime') { - interval = event.target.attributes['data-interval'].nodeValue; - this.pivot.expand(id, {field: field_id, interval: interval}); - } else { - this.pivot.expand(id, field_id); - } - }, - -/****************************************************************************** - * Drawing pivot table methods... - ******************************************************************************/ - draw_table: function () { - this.pivot.main_row().title = 'Total'; - if (this.pivot.measures.length == 1) { - this.pivot.main_col().title = this.pivot.measures[0].string; - } else { - this.pivot.main_col().title = this.title; - } - this.draw_top_headers(); - _.each(this.pivot.rows.headers, this.proxy('draw_row')); - }, - - make_border_cell: function (colspan, rowspan, headercell) { - var tag = (headercell) ? $('') : $(''); - return tag.addClass('graph_border') - .attr('colspan', (colspan) ? colspan : 1) - .attr('rowspan', (rowspan) ? rowspan : 1); - }, - - make_header_title: function (header) { - return $(' ') - .addClass('web_graph_click') - .attr('href', '#') - .addClass((header.expanded) ? 'fa fa-minus-square' : 'fa fa-plus-square') - .append((header.title !== undefined) ? header.title : 'Undefined'); - }, - - draw_top_headers: function () { - var self = this, - 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); - } 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).append('Total').css('font-weight', 'bold')); - } - } - - _.each(header_cells, function (cells) { - thead.append($('').append(cells)); - }); - - if (pivot.measures.length >= 2) { - thead.append(self.make_measure_row()); - } - - self.table.append(thead); - }, - - make_measure_row: function() { - var self = this, - measures = this.pivot.measures, - cols = this.pivot.cols.headers, - measure_cells, - measure_row = $(''); - - measure_row.append($('')); - - _.each(cols, function (col) { - if (!col.children.length) { - for (var i = 0; i < measures.length; i++) { - measure_cells = $('').addClass('measure_row'); - measure_cells.append(measures[i].string); - measure_row.append(measure_cells); - } - } - }); - - if (this.pivot.get_cols_leaves().length > 1) { - for (var i = 0; i < measures.length; i++) { - measure_cells = $('').addClass('measure_row'); - measure_cells.append(measures[i].string); - measure_row.append(measure_cells); - } - } - return measure_row; - }, - - draw_row: function (row) { - var self = this, - pivot = this.pivot, - measure_types = _.pluck(this.pivot.measures, 'type'), - html_row = $(''), - 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($('', {class:'web_graph_indent'})); - } - - html_row.append(row_header); - - _.each(pivot.cols.headers, function (col) { - if (col.children.length === 0) { - 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)); - } - } - }); - - 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 color, - total, - cell = $(''); - if (value === undefined) { - return cell; - } - cell.append(instance.web.format_value(value, {type: measure_type})); - if (self.mode === 'heatmap') { - total = pivot.get_total()[index]; - color = Math.floor(90 + 165*(total - Math.abs(value))/total); - cell.css('background-color', $.Color(255, color, color)); - } - if (self.mode === 'row_heatmap') { - total = pivot.get_total(row)[index]; - color = Math.floor(90 + 165*(total - Math.abs(value))/total); - cell.css('background-color', $.Color(255, color, color)); - } - if (self.mode === 'col_heatmap') { - debugger; - total = pivot.get_total(col)[index]; - color = Math.floor(90 + 165*(total - Math.abs(value))/total); - cell.css('background-color', $.Color(255, color, color)); - } - return cell; - } - }, - -/****************************************************************************** - * Drawing charts methods... - ******************************************************************************/ - bar: function () { - var self = this, - dim_x = this.pivot.rows.groupby.length, - dim_y = this.pivot.cols.groupby.length, - data; - - // No groupby ************************************************************** - if ((dim_x === 0) && (dim_y === 0)) { - data = [{key: 'Total', values:[{ - x: 'Total', - y: this.pivot.get_total(), - }]}]; - // Only column groupbys **************************************************** - } else if ((dim_x === 0) && (dim_y >= 1)){ - data = _.map(this.pivot.get_columns_with_depth(1), function (header) { - return { - key: header.title, - values: [{x:header.root[0].title, y: self.pivot.get_total(header)[0]}] - }; - }); - // Just 1 row groupby ****************************************************** - } else if ((dim_x === 1) && (dim_y === 0)) { - data = _.map(this.pivot.main_row().children, function (pt) { - var value = self.pivot.get_total(pt), - title = (pt.title !== undefined) ? pt.title : 'Undefined'; - return {x: title, y: value}; - }); - data = [{key: self.pivot.measures[0].string, values:data}]; - // 1 row groupby and some col groupbys************************************** - } else if ((dim_x === 1) && (dim_y >= 1)) { - data = _.map(this.pivot.get_cols_with_depth(1), function (colhdr) { - var values = _.map(self.pivot.get_rows_with_depth(1), function (header) { - return { - x: header.title || 'Undefined', - y: self.pivot.get_values(header.id, colhdr.id)[0] || 0 - }; - }); - return {key: colhdr.title || 'Undefined', values: values}; - }); - // At least two row groupby************************************************* - } else { - var keys = _.uniq(_.map(this.pivot.get_rows_with_depth(2), function (hdr) { - return hdr.title || 'Undefined'; - })); - data = _.map(keys, function (key) { - var values = _.map(self.pivot.get_rows_with_depth(1), function (hdr) { - var subhdr = _.find(hdr.children, function (child) { - return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); - }); - return { - x: hdr.title || 'Undefined', - y: (subhdr) ? self.pivot.get_total(subhdr)[0] : 0 - }; - }); - return {key:key, values: values}; - }); - } - - nv.addGraph(function () { - var chart = nv.models.multiBarChart() - .width(self.width) - .height(self.height) - .reduceXTicks(false) - .stacked(self.bar_ui === 'stack') - .showControls(false); - - if (self.width / data[0].values.length < 80) { - chart.rotateLabels(-15); - chart.reduceXTicks(true); - chart.margin({bottom:40}); - } - - d3.select(self.svg) - .datum(data) - .attr('width', self.width) - .attr('height', self.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - - }, - - line: function () { - var self = this, - dim_x = this.pivot.rows.groupby.length, - dim_y = this.pivot.cols.groupby.length; - - var data = _.map(this.pivot.get_cols_leaves(), function (col) { - var values = _.map(self.pivot.get_rows_with_depth(dim_x), function (row) { - return {x: row.title, y: self.pivot.get_values(row.id,col.id, 0)}; - }); - var title = _.map(col.path, function (p) { - return p || 'Undefined'; - }).join('/'); - if (dim_y === 0) { - title = self.pivot.measures[0].string; - } - return {values: values, key: title}; - }); - - nv.addGraph(function () { - var chart = nv.models.lineChart() - .x(function (d,u) { return u; }) - .width(self.width) - .height(self.height) - .margin({top: 30, right: 20, bottom: 20, left: 60}); - - d3.select(self.svg) - .attr('width', self.width) - .attr('height', self.height) - .datum(data) - .call(chart); - - return chart; - }); - }, - - pie: function () { - var self = this, - dim_x = this.pivot.rows.groupby.length; - var data = _.map(this.pivot.get_rows_leaves(), function (row) { - var title = _.map(row.path, function (p) { - return p || 'Undefined'; - }).join('/'); - if (dim_x === 0) { - title = self.measure_label; - } - return {x: title, y: self.pivot.get_total(row)}; - }); - - nv.addGraph(function () { - var chart = nv.models.pieChart() - .color(d3.scale.category10().range()) - .width(self.width) - .height(self.height); - - d3.select(self.svg) - .datum(data) - .transition().duration(1200) - .attr('width', self.width) - .attr('height', self.height) - .call(chart); - - nv.utils.windowResize(chart.update); - return chart; - }); - }, - -}); - -}; - - - - - - - - diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js new file mode 100644 index 00000000000..1b940c1703a --- /dev/null +++ b/addons/web_graph/static/src/js/graph_view.js @@ -0,0 +1,177 @@ +/*--------------------------------------------------------- + * OpenERP web_graph + *---------------------------------------------------------*/ + +/* jshint undef: false */ + +openerp.web_graph = function (instance) { +'use strict'; + +var _lt = instance.web._lt; +var _t = instance.web._t; + +instance.web.views.add('graph', 'instance.web_graph.GraphView'); + +instance.web_graph.GraphView = instance.web.View.extend({ + display_name: _lt('Graph'), + view_type: 'graph', + + init: function(parent, dataset, view_id, options) { + this._super(parent, dataset, view_id, options); + this.dataset = dataset; + this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); + this.search_view = parent.searchview; + this.search_view_groupby = []; + this.groupby_mode = 'default'; // 'default' or 'manual' + this.default_row_groupby = []; + this.default_col_groupby = []; + this.search_field = { + get_context: this.proxy('get_context'), + get_domain: function () {}, + get_groupby: function () { }, + }; + }, + + view_loading: function (fields_view_get) { + var self = this, + arch = fields_view_get.arch; + + this.widget_config = { + title: arch.attrs.string, + stacked : (arch.attrs.stacked === 'True'), + mode: (arch.attrs.type) ? arch.attrs.type : 'bar', + measures: [], + }; + + _.each(arch.children, function (field) { + if (_.has(field.attrs, 'type')) { + switch (field.attrs.type) { + case 'row': + self.default_row_groupby.push(field.attrs.name); + break; + case 'col': + self.default_col_groupby.push(field.attrs.name); + break; + case 'measure': + self.widget_config.measures.push(field.attrs.name); + break; + } + } else { // old style, kept for backward compatibility + if ('operator' in field.attrs) { + self.widget_config.measures.push(field.attrs.name); + } else { + self.default_row_groupby.push(field.attrs.name); + } + } + }); + if (self.widget_config.measures.length === 0) { + self.widget_config.measures.push('__count'); + } + this.widget_config.row_groupby = self.default_row_groupby; + this.widget_config.col_groupby = self.default_col_groupby; + }, + + get_context: function (facet) { + var col_group_by = _.map(facet.values.models, function (model) { + return model.attributes.value.attrs.context.col_group_by; + }); + return {col_group_by : col_group_by}; + }, + + do_search: function (domain, context, group_by) { + // var col_groupby = context.col_group_by || [], + // options = {domain:domain}; + + if (!this.graph_widget) { + this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); + this.graph_widget.appendTo(this.$el); + this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); + this.ViewManager.on('switch_mode', this, function (e) { if (e === 'graph') this.graph_widget.reload(); }); + } + // this.search_view_groupby = group_by; + + // if (group_by.length && this.groupby_mode !== 'manual') { + // if (_.isEqual(col_groupby, [])) { + // col_groupby = this.default_col_groupby; + // } + // } + // if (group_by.length || col_groupby.length) { + // this.groupby_mode = 'manual'; + // } + // if (!this.graph_widget.enabled) { + // options.update = false; + // options.silent = true; + // } + + // if (this.groupby_mode === 'manual') { + // options.row_groupby = group_by; + // options.col_groupby = col_groupby; + // } else { + // options.row_groupby = _.toArray(this.default_row_groupby); + // options.col_groupby = _.toArray(this.default_col_groupby); + // } + // this.graph_widget.set(domain, options.row_groupby, options.col_groupby); + // this.graph_widget.set_domain(domain); + // this.graph_widget.set_col_groupby(options.col_groupby); + // this.graph_widget.set_row_groupby(options.row_groupby); + + }, + + do_show: function () { + this.do_push_state({}); + return this._super(); + }, + + register_groupby: function() { + // var self = this, + // query = this.search_view.query; + + // this.groupby_mode = 'manual'; + // if (_.isEqual(this.search_view_groupby, this.graph_widget.pivot.rows.groupby) || + // (!_.has(this.search_view, '_s_groupby'))) { + // return; + // } + // var rows = _.map(this.graph_widget.pivot.rows.groupby, function (group) { + // return make_facet('GroupBy', group); + // }); + // var cols = _.map(this.graph_widget.pivot.cols.groupby, function (group) { + // return make_facet('ColGroupBy', group); + // }); + + // query.reset(rows.concat(cols)); + + // function make_facet (category, fields) { + // var values, + // icon, + // backbone_field, + // cat_name; + // if (!(fields instanceof Array)) { fields = [fields]; } + // if (category === 'GroupBy') { + // cat_name = 'group_by'; + // icon = 'w'; + // backbone_field = self.search_view._s_groupby; + // } else { + // cat_name = 'col_group_by'; + // icon = 'f'; + // backbone_field = self.search_field; + // } + // values = _.map(fields, function (field) { + // var context = {}; + // context[cat_name] = field; + // return {label: self.graph_widget.fields[field].string, value: {attrs:{domain: [], context: context}}}; + // }); + // return {category:category, values: values, icon:icon, field: backbone_field}; + // } + }, +}); + + +}; + + + + + + + + diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js new file mode 100644 index 00000000000..33f3caabc07 --- /dev/null +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -0,0 +1,567 @@ + +/* jshint undef: false */ + +(function () { +'use strict'; +var QWeb = openerp.web.qweb; + +openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin, { + template: 'GraphWidget', + + events: { + 'click .graph_mode_selection li' : 'mode_selection', + 'click .graph_measure_selection li' : 'measure_selection', + 'click .graph_options_selection li' : 'option_selection', + 'click .web_graph_click' : 'header_cell_clicked', + 'click a.field-selection' : 'field_selection', + }, + + init: function(parent, model, domain, options) { + this._super(parent); + this.model = model; + this.domain = domain; + this.mode = options.mode || 'pivot'; + this.title = options.title || 'Graph'; + this.visible_ui = options.visible_ui || true; + this.bar_ui = options.bar_ui || 'group'; + this.pivot_options = options; + }, + + start: function() { + var self = this; + this.table = $('
    '); + this.$('.graph_main_content').append(this.table); + var def1 = this.get_search_fields().then(function (f) { + self.important_fields = f; + }); + + var def2 = this.model.call('fields_get', []).then(function (f) { + self.fields = f; + self.measure_list = self.get_measures(); + self.add_measures_to_options(); + }); + + return $.when(def1, def2).then(function () { + self.pivot = new openerp.web_graph.PivotTable(self.model, self.domain, self.fields, self.pivot_options); + self.pivot.on('redraw_required', self, self.proxy('display_data')); + self.pivot.on('groupby_changed', self, function () { self.trigger('groupby_changed'); }); + openerp.web.bus.on('click', self, function () { + if (self.dropdown) { + self.dropdown.remove(); + self.dropdown = null; + } + }); + self.pivot.activate(); + }); + }, + + get_search_fields: function () { + var self = this, + options = {model:this.model, view_type: 'search'}, + result = []; + + return openerp.web.fields_view_get(options).then(function (search_view) { + var groups = _.select(search_view.arch.children, function (c) { + return (c.tag === 'group') && (c.attrs.string != 'Display'); + }); + _.each(groups, function(g) { + _.each(g.children, function (g) { + if (g.attrs.context) { + var field_id = py.eval(g.attrs.context).group_by; + if (field_id) { + if (field_id instanceof Array) { + result.concat(field_id); + } else { + result.push(field_id); + } + } + } + }); + }); + return result; + }); + }, + + get_measures: function(fields) { + var measures = []; + _.each(this.fields, function (f, id) { + if (((f.type === 'integer') || (f.type === 'float')) && (id !== 'id')) { + measures.push({field:id, type: f.type, string: f.string}); + } + }); + return measures; + }, + + + set: function (domain, row_groupby, col_groupby) { + if (this.pivot) { + this.pivot.set(domain, row_groupby, col_groupby); + } else { + this.pivot_options.domain = domain; + this.pivot_options.row_groupby = row_groupby; + this.pivot_options.col_groupby = col_groupby; + } + }, + + add_measures_to_options: function() { + var measure_selection = this.$('.graph_measure_selection'); + _.each(this.measure_list, function (measure) { + var choice = $('').attr('data-choice', measure.field) + .attr('href', '#') + .append(measure.string); + measure_selection.append($('
  • ').append(choice)); + }); + }, + + set_mode: function (mode) { + this.mode = mode; + this.display_data(); + }, + + reload: function () { + this.pivot.update_data(); + }, + + display_data: function () { + this.$('.graph_main_content svg').remove(); + this.$('.graph_main_content div').remove(); + this.table.empty(); + + if (this.visible_ui) { + this.$('.graph_header').css('display', 'block'); + } else { + this.$('.graph_header').css('display', 'none'); + } + if (this.pivot.no_data) { + this.$('.graph_main_content').append($(QWeb.render('graph_no_data'))); + } else { + var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; + if (_.contains(table_modes, this.mode)) { + this.draw_table(); + } else { + this.$('.graph_main_content').append($('
    ')); + this.svg = this.$('.graph_main_content svg')[0]; + this.width = this.$el.width(); + this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); + this[this.mode](); + } + } + }, + + mode_selection: function (event) { + event.preventDefault(); + var mode = event.target.attributes['data-mode'].nodeValue; + this.set_mode(mode); + }, + + measure_selection: function (event) { + event.preventDefault(); + var measure = event.target.attributes['data-choice'].nodeValue; + this.pivot.toggle_measure(measure); + }, + + option_selection: function (event) { + event.preventDefault(); + switch (event.target.attributes['data-choice'].nodeValue) { + case 'bar_grouped': + this.bar_ui = 'group'; + if (this.mode === 'bar') { + this.display_data(); + } + break; + case 'bar_stacked': + this.bar_ui = 'stack'; + if (this.mode === 'bar') { + this.display_data(); + } + break; + case 'swap_axis': + this.pivot.swap_axis(); + break; + case 'expand_all': + this.pivot.expand_all(); + break; + case 'update_values': + this.pivot.update_data(); + break; + case 'export_data': + // Export code... To do... + break; + } + }, + + header_cell_clicked: function (event) { + event.preventDefault(); + event.stopPropagation(); + var id = event.target.attributes['data-id'].nodeValue, + header = this.pivot.get_header(id), + self = this; + + if (header.expanded) { + this.pivot.fold(header); + } else { + if (header.path.length < header.root.groupby.length) { + this.pivot.expand(id); + } else { + if (!this.important_fields.length) { + return; + } + var fields = _.map(this.important_fields, function (field) { + return {id: field, value: self.fields[field].string, type:self.fields[field].type}; + }); + this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); + $(event.target).after(this.dropdown); + this.dropdown.css({position:'absolute', + left:event.pageX, + top:event.pageY}); + this.$('.field-selection').next('.dropdown-menu').toggle(); + } + } + }, + + field_selection: function (event) { + var id = event.target.attributes['data-id'].nodeValue, + field_id = event.target.attributes['data-field-id'].nodeValue, + interval; + event.preventDefault(); + if (this.fields[field_id].type === 'date' || this.fields[field_id].type === 'datetime') { + interval = event.target.attributes['data-interval'].nodeValue; + this.pivot.expand(id, {field: field_id, interval: interval}); + } else { + this.pivot.expand(id, field_id); + } + }, + +/****************************************************************************** + * Drawing pivot table methods... + ******************************************************************************/ + draw_table: function () { + this.pivot.main_row().title = 'Total'; + if (this.pivot.measures.length == 1) { + this.pivot.main_col().title = this.pivot.measures[0].string; + } else { + this.pivot.main_col().title = this.title; + } + this.draw_top_headers(); + _.each(this.pivot.rows.headers, this.proxy('draw_row')); + }, + + make_border_cell: function (colspan, rowspan, headercell) { + var tag = (headercell) ? $('') : $(''); + return tag.addClass('graph_border') + .attr('colspan', (colspan) ? colspan : 1) + .attr('rowspan', (rowspan) ? rowspan : 1); + }, + + make_header_title: function (header) { + return $(' ') + .addClass('web_graph_click') + .attr('href', '#') + .addClass((header.expanded) ? 'fa fa-minus-square' : 'fa fa-plus-square') + .append((header.title !== undefined) ? header.title : 'Undefined'); + }, + + draw_top_headers: function () { + var self = this, + 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); + } 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).append('Total').css('font-weight', 'bold')); + } + } + + _.each(header_cells, function (cells) { + thead.append($('').append(cells)); + }); + + if (pivot.measures.length >= 2) { + thead.append(self.make_measure_row()); + } + + self.table.append(thead); + }, + + make_measure_row: function() { + var self = this, + measures = this.pivot.measures, + cols = this.pivot.cols.headers, + measure_cells, + measure_row = $(''); + + measure_row.append($('')); + + _.each(cols, function (col) { + if (!col.children.length) { + for (var i = 0; i < measures.length; i++) { + measure_cells = $('').addClass('measure_row'); + measure_cells.append(measures[i].string); + measure_row.append(measure_cells); + } + } + }); + + if (this.pivot.get_cols_leaves().length > 1) { + for (var i = 0; i < measures.length; i++) { + measure_cells = $('').addClass('measure_row'); + measure_cells.append(measures[i].string); + measure_row.append(measure_cells); + } + } + return measure_row; + }, + + draw_row: function (row) { + var self = this, + pivot = this.pivot, + measure_types = _.pluck(this.pivot.measures, 'type'), + html_row = $(''), + 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($('', {class:'web_graph_indent'})); + } + + html_row.append(row_header); + + _.each(pivot.cols.headers, function (col) { + if (col.children.length === 0) { + 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)); + } + } + }); + + 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 color, + total, + cell = $(''); + if (value === undefined) { + return cell; + } + cell.append(openerp.web.format_value(value, {type: measure_type})); + if (self.mode === 'heatmap') { + total = pivot.get_total()[index]; + color = Math.floor(90 + 165*(total - Math.abs(value))/total); + cell.css('background-color', $.Color(255, color, color)); + } + if (self.mode === 'row_heatmap') { + total = pivot.get_total(row)[index]; + color = Math.floor(90 + 165*(total - Math.abs(value))/total); + cell.css('background-color', $.Color(255, color, color)); + } + if (self.mode === 'col_heatmap') { + debugger; + total = pivot.get_total(col)[index]; + color = Math.floor(90 + 165*(total - Math.abs(value))/total); + cell.css('background-color', $.Color(255, color, color)); + } + return cell; + } + }, + +/****************************************************************************** + * Drawing charts methods... + ******************************************************************************/ + bar: function () { + var self = this, + dim_x = this.pivot.rows.groupby.length, + dim_y = this.pivot.cols.groupby.length, + data; + + // No groupby ************************************************************** + if ((dim_x === 0) && (dim_y === 0)) { + data = [{key: 'Total', values:[{ + x: 'Total', + y: this.pivot.get_total(), + }]}]; + // Only column groupbys **************************************************** + } else if ((dim_x === 0) && (dim_y >= 1)){ + data = _.map(this.pivot.get_columns_with_depth(1), function (header) { + return { + key: header.title, + values: [{x:header.root[0].title, y: self.pivot.get_total(header)[0]}] + }; + }); + // Just 1 row groupby ****************************************************** + } else if ((dim_x === 1) && (dim_y === 0)) { + data = _.map(this.pivot.main_row().children, function (pt) { + var value = self.pivot.get_total(pt), + title = (pt.title !== undefined) ? pt.title : 'Undefined'; + return {x: title, y: value}; + }); + data = [{key: self.pivot.measures[0].string, values:data}]; + // 1 row groupby and some col groupbys************************************** + } else if ((dim_x === 1) && (dim_y >= 1)) { + data = _.map(this.pivot.get_cols_with_depth(1), function (colhdr) { + var values = _.map(self.pivot.get_rows_with_depth(1), function (header) { + return { + x: header.title || 'Undefined', + y: self.pivot.get_values(header.id, colhdr.id)[0] || 0 + }; + }); + return {key: colhdr.title || 'Undefined', values: values}; + }); + // At least two row groupby************************************************* + } else { + var keys = _.uniq(_.map(this.pivot.get_rows_with_depth(2), function (hdr) { + return hdr.title || 'Undefined'; + })); + data = _.map(keys, function (key) { + var values = _.map(self.pivot.get_rows_with_depth(1), function (hdr) { + var subhdr = _.find(hdr.children, function (child) { + return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); + }); + return { + x: hdr.title || 'Undefined', + y: (subhdr) ? self.pivot.get_total(subhdr)[0] : 0 + }; + }); + return {key:key, values: values}; + }); + } + + nv.addGraph(function () { + var chart = nv.models.multiBarChart() + .width(self.width) + .height(self.height) + .reduceXTicks(false) + .stacked(self.bar_ui === 'stack') + .showControls(false); + + if (self.width / data[0].values.length < 80) { + chart.rotateLabels(-15); + chart.reduceXTicks(true); + chart.margin({bottom:40}); + } + + d3.select(self.svg) + .datum(data) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + + }, + + line: function () { + var self = this, + dim_x = this.pivot.rows.groupby.length, + dim_y = this.pivot.cols.groupby.length; + + var data = _.map(this.pivot.get_cols_leaves(), function (col) { + var values = _.map(self.pivot.get_rows_with_depth(dim_x), function (row) { + return {x: row.title, y: self.pivot.get_values(row.id,col.id, 0)}; + }); + var title = _.map(col.path, function (p) { + return p || 'Undefined'; + }).join('/'); + if (dim_y === 0) { + title = self.pivot.measures[0].string; + } + return {values: values, key: title}; + }); + + nv.addGraph(function () { + var chart = nv.models.lineChart() + .x(function (d,u) { return u; }) + .width(self.width) + .height(self.height) + .margin({top: 30, right: 20, bottom: 20, left: 60}); + + d3.select(self.svg) + .attr('width', self.width) + .attr('height', self.height) + .datum(data) + .call(chart); + + return chart; + }); + }, + + pie: function () { + var self = this, + dim_x = this.pivot.rows.groupby.length; + var data = _.map(this.pivot.get_rows_leaves(), function (row) { + var title = _.map(row.path, function (p) { + return p || 'Undefined'; + }).join('/'); + if (dim_x === 0) { + title = self.measure_label; + } + return {x: title, y: self.pivot.get_total(row)}; + }); + + nv.addGraph(function () { + var chart = nv.models.pieChart() + .color(d3.scale.category10().range()) + .width(self.width) + .height(self.height); + + d3.select(self.svg) + .datum(data) + .transition().duration(1200) + .attr('width', self.width) + .attr('height', self.height) + .call(chart); + + nv.utils.windowResize(chart.update); + return chart; + }); + }, + +}); +})(); diff --git a/addons/web_graph/static/src/js/pivot.js b/addons/web_graph/static/src/js/pivot.js deleted file mode 100644 index b78e8323645..00000000000 --- a/addons/web_graph/static/src/js/pivot.js +++ /dev/null @@ -1,539 +0,0 @@ - -/* jshint undef: false */ - -(function () { -'use strict'; - -// Pivot Table emits the events 'groupby_changed' and 'redraw_required' when necessary. -// PivotTable is initialized by default 'inactive', and require a call to activate() -// after init to load initial data and start triggering events. -openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { - - init: function (model, domain, fields, options) { - openerp.EventDispatcherMixin.init.call(this); - this.cells = []; - this.domain = domain; - this.no_data = true; - this.model = model; - this.fields = fields; - this.fields.__count = {type: 'integer', string:'Quantity'}; - this.measures = [{field:'__count', type: this.fields.type, string:this.fields.string}]; - this.active = false; - this.rows = { groupby: this.create_field_values(options.row_groupby || []), headers: null }; - this.cols = { groupby: this.create_field_values(options.col_groupby || []), headers: null }; - if (options.measures) { this.set_measures(options.measures); } - }, - - // ---------------------------------------------------------------------- - // Configuration methods - // ---------------------------------------------------------------------- - // this.measures: list of measure [measure], measure = {field: _, string: _, type: _} - // this.rows.groupby, this.cols.groupby : list of groupbys used for describing rows (...), - // a groupby is also {field:_, string:_, type:_} but it also has a interval - // attribute if its type is date/datetime. - // this.active: If PivotTable is active then it triggers events and updates - // its values when necessary - activate: function() { - this.active = true; - this.update_data(); - }, - - set_measures: function (measures) { - var self = this; - if (!_.isEqual(measures, this.measures)) { - this.measures = []; - _.each(measures, function (m) { self._add_measure(m); }); - if (this.active) { this.update_data(); } - } - }, - - _add_measure: function (measure) { - if (measure.field && measure.string && measure.type) { - this.measures.push(measure); - } else { - this.measures.push({ - field: measure, - string: this.fields[measure].string, - type: this.fields[measure].type, - }); - } - }, - - toggle_measure: function (field_id) { - var current_measure = _.findWhere(this.measures, {field:field_id}); - if (current_measure) { - this.measures = _.without(this.measures, current_measure); - } else { - this.measures.push({ - field: field_id, - type: this.fields[field_id].type, - string: this.fields[field_id].string - }); - } - if (this.active) { this.update_data(); } - }, - - set: function (domain, row_groupby, col_groupby) { - var row_gbs = this.create_field_values(row_groupby), - col_gbs = this.create_field_values(col_groupby), - dom_changed = !_.isEqual(this.domain, domain), - gb_changed = !(_.isEqual(row_gbs, this.rows.groupby) && - _.isEqual(col_gbs, this.cols.groupby)); - - if (dom_changed) { - this.domain = domain; - } - if (gb_changed) { - this.cols.groupby = col_gbs; - this.rows.groupby = row_gbs; - if (this.active) { this.trigger('groupby_changed'); } - } - if (this.active && (gb_changed || dom_changed)) { - this.update_data(); - } - }, - - create_field_value: function (f) { - if (f.field && f.interval) { - return { field:f.field, - string: this.fields[f.field].string, - type:this.fields[f.field].type, - interval: f.interval }; - } - return (f.field && f.string && f.type) ? f : { field: f, - string: this.fields[f].string, - type: this.fields[f].type }; - }, - - create_field_values: function (field_ids) { - var self = this; - return _.map(field_ids, function (f) { return self.create_field_value(f); }); - }, - - _add_groupby: function(groupby_list, groupby) { - groupby_list.push(this.create_field_value(groupby)); - }, - - // ---------------------------------------------------------------------- - // Cells manipulation methods - // ---------------------------------------------------------------------- - // cells are objects {x:_, y:_, values:_} where x < y and values is an array - // of values (one for each measure). The condition x < y might look - // unnecessary, but it makes the rest of the code simpler: headers - // don't krow if they are rows or cols, they just know their id, so - // it is useful that a call get_values(id1, id2) is the same as get_values(id2, id1) - add_cell : function (id1, id2, values) { - this.cells.push({x: Math.min(id1, id2), y: Math.max(id1, id2), values: values}); - }, - - get_values: function (id1, id2, default_values) { - var cell = _.find(this.cells, function (c) { - return ((c.x == Math.min(id1, id2)) && (c.y == Math.max(id1, id2))); - }); - return (cell !== undefined) ? cell.values : (default_values || new Array(this.measures.length)); - }, - - // ---------------------------------------------------------------------- - // Headers/Rows/Cols manipulation methods - // ---------------------------------------------------------------------- - // this.rows.headers, this.cols.headers = [header] describe the tree structure - // of rows/cols. Headers are objects - // { - // id:_, (unique id obviously) - // path: [...], (array of all parents title, with its own title at the end) - // title:_, (name of the row/col) - // children:[_], (subrows or sub cols of this row/col) - // domain:_, (domain of data in this row/col) - // root:_ (ref to this.rows or this.cols corresponding to the header) - // expanded:_ (boolean, true if it has been expanded) - // } - is_row: function (id) { - return !!_.find(this.rows.headers, function (header) { - return header.id === id; - }); - }, - - is_col: function (id) { - return !!_.find(this.cols.headers, function (header) { - return header.id === id; - }); - }, - - get_header: function (id) { - return _.find(this.rows.headers.concat(this.cols.headers), function (header) { - return header.id === id; - }); - }, - - // return all columns with a path length of 'depth' - get_cols_with_depth: function (depth) { - return _.filter(this.cols.headers, function (header) { - return header.path.length === depth; - }); - }, - - // return all rows with a path length of 'depth' - get_rows_with_depth: function (depth) { - return _.filter(this.rows.headers, function (header) { - return header.path.length === depth; - }); - }, - - // return all non expanded rows - get_rows_leaves: function () { - return _.filter(this.rows.headers, function (header) { - return !header.expanded; - }); - }, - - // return all non expanded cols - get_cols_leaves: function () { - return _.filter(this.cols.headers, function (header) { - return !header.expanded; - }); - }, - - 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); })); - }, - - 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); })); - }, - - get_total: function (header) { - if (header) { - return this.get_values(header.id, this.get_other_root(header).headers[0].id); - } - return this.get_values(this.rows.headers[0].id, this.cols.headers[0].id); - }, - - get_other_root: function (header) { - return (header.root === this.rows) ? this.cols : this.rows; - }, - - main_row: function () { return this.rows.headers[0]; }, - - main_col: function () { return this.cols.headers[0]; }, - - // ---------------------------------------------------------------------- - // Table manipulation methods : fold/expand/swap - // ---------------------------------------------------------------------- - fold: function (header) { - var ancestors = this.get_ancestors(header), - removed_ids = _.pluck(ancestors, 'id'); - - header.root.headers = _.difference(header.root.headers, ancestors); - header.children = []; - header.expanded = false; - - this.cells = _.reject(this.cells, function (cell) { - return (_.contains(removed_ids, cell.x) || _.contains(removed_ids, cell.y)); - }); - - var new_groupby_length = _.max(_.map(header.root.headers, function(g) {return g.path.length;})); - if (new_groupby_length < header.root.groupby.length) { - header.root.groupby.splice(new_groupby_length); - this.trigger('groupby_changed'); - } - this.trigger('redraw_required'); - }, - - 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); - - if (header.path.length === header.root.groupby.length) { - self._add_groupby(header.root.groupby, groupby); - this.trigger('groupby_changed'); - } - groupby = [header.root.groupby[header.path.length]].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); - } - }); - }); - header.expanded = true; - self.trigger('redraw_required'); - }); - }, - - make_header: function (group, parent) { - var title = parent ? group.attributes.value : ''; - 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; - this.cols = temp; - this.trigger('groupby_changed'); - this.trigger('redraw_required'); - }, - - // ---------------------------------------------------------------------- - // 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; - } - self.trigger('redraw_required'); - }); - }, - - 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_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; - }, - - expand_all: function () { - this.rows.headers = null; - this.cols.headers = null; - this.update_data(); - }, - - // ---------------------------------------------------------------------- - // 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); - - var groupbys = _.map(_.range(cols.length + 1), function (i) { - return cols.slice(0, i).concat(rows); - }); - groupbys.push([]); - - var def_array = _.map(groupbys, function (groupby) { - return self.get_groups(groupby, visible_fields, self.domain); - }); - - return $.when.apply(null, def_array).then(function () { - var data = Array.prototype.slice.call(arguments), - row_data = data[0], - col_data = (cols.length !== 0) ? data[data.length - 2] : [], - total = data[data.length - 1][0]; - - return (total === undefined) ? undefined - : self.format_data(total, col_data, row_data, data); - }); - }, - - get_groups: function (groupbys, fields, domain, path) { - path = path || []; - var self = this, - groupby = (groupbys.length) ? groupbys[0] : []; - - 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; - } - }); - - }, - - _query_db: function (groupby, fields, domain, path) { - var self = this, - field_ids = _.without(_.pluck(fields, 'field'), '__count'), - context = {}; - - if (groupby.interval) { - context.datetime_format = {}; - var display_format; - switch (groupby.interval) { - case 'day': - display_format = 'dd MMMM YYYY'; - break; - case 'week': - display_format = 'w YYYY'; - break; - case 'month': - display_format = 'MMMM YYYY'; - break; - case 'quarter': - display_format = 'QQQ YYYY'; - break; - case 'year': - display_format = 'YYYY'; - break; - } - context.datetime_format[groupby.field] = { - interval: groupby.interval, - display_format: display_format - }; - } - return this.model.query(field_ids) - .filter(domain) - .context(context) - .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); }); - }); - }, - - // add the path to the group and sanitize the value... - format_group: function (group, current_path) { - var value = group.attributes.value; - - if (group.attributes.grouped_on && this.fields[group.attributes.grouped_on].type === 'selection') { - var selection = this.fields[group.attributes.grouped_on].selection, - value_lookup = _.find(selection, function (val) { return val[0] === value; }); - group.attributes.value = value_lookup ? value_lookup[1] : 'undefined'; - } else if (value === false) { - group.attributes.value = 'undefined'; - } else if (value instanceof Array) { - group.attributes.value = value[1]; - } - - group.path = value ? (current_path || []).concat(group.attributes.value) : []; - group.attributes.aggregates.__count = group.attributes.length; - - return group; - }, - - format_data: function (total, 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 (measure.field === '__count') ? attr.length : attr.aggregates[measure.field]; - }); - - var row = _.find(rows, function (header) { return _.isEqual(header.path, path.slice(index)); }); - var 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); - } - }); - }, - -}); -})(); - - diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js new file mode 100644 index 00000000000..9c927150f20 --- /dev/null +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -0,0 +1,539 @@ + +/* jshint undef: false */ + +(function () { +'use strict'; + +// Pivot Table emits the events 'groupby_changed' and 'redraw_required' when necessary. +// PivotTable is initialized by default 'inactive', and require a call to activate() +// after init to load initial data and start triggering events. +openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { + + init: function (model, domain, fields, options) { + openerp.EventDispatcherMixin.init.call(this); + this.cells = []; + this.domain = domain; + this.no_data = true; + this.model = model; + this.fields = fields; + this.fields.__count = {type: 'integer', string:'Quantity'}; + this.measures = [{field:'__count', type: this.fields.type, string:this.fields.string}]; + this.active = false; + this.rows = { groupby: this.create_field_values(options.row_groupby || []), headers: null }; + this.cols = { groupby: this.create_field_values(options.col_groupby || []), headers: null }; + if (options.measures) { this.set_measures(options.measures); } + }, + + // ---------------------------------------------------------------------- + // Configuration methods + // ---------------------------------------------------------------------- + // this.measures: list of measure [measure], measure = {field: _, string: _, type: _} + // this.rows.groupby, this.cols.groupby : list of groupbys used for describing rows (...), + // a groupby is also {field:_, string:_, type:_} but it also has a interval + // attribute if its type is date/datetime. + // this.active: If PivotTable is active then it triggers events and updates + // its values when necessary + activate: function() { + this.active = true; + this.update_data(); + }, + + set_measures: function (measures) { + var self = this; + if (!_.isEqual(measures, this.measures)) { + this.measures = []; + _.each(measures, function (m) { self._add_measure(m); }); + if (this.active) { this.update_data(); } + } + }, + + _add_measure: function (measure) { + if (measure.field && measure.string && measure.type) { + this.measures.push(measure); + } else { + this.measures.push({ + field: measure, + string: this.fields[measure].string, + type: this.fields[measure].type, + }); + } + }, + + toggle_measure: function (field_id) { + var current_measure = _.findWhere(this.measures, {field:field_id}); + if (current_measure) { + this.measures = _.without(this.measures, current_measure); + } else { + this.measures.push({ + field: field_id, + type: this.fields[field_id].type, + string: this.fields[field_id].string + }); + } + if (this.active) { this.update_data(); } + }, + + set: function (domain, row_groupby, col_groupby) { + var row_gbs = this.create_field_values(row_groupby), + col_gbs = this.create_field_values(col_groupby), + dom_changed = !_.isEqual(this.domain, domain), + gb_changed = !(_.isEqual(row_gbs, this.rows.groupby) && + _.isEqual(col_gbs, this.cols.groupby)); + + if (dom_changed) { + this.domain = domain; + } + if (gb_changed) { + this.cols.groupby = col_gbs; + this.rows.groupby = row_gbs; + if (this.active) { this.trigger('groupby_changed'); } + } + if (this.active && (gb_changed || dom_changed)) { + this.update_data(); + } + }, + + create_field_value: function (f) { + if (f.field && f.interval) { + return { field:f.field, + string: this.fields[f.field].string, + type:this.fields[f.field].type, + interval: f.interval }; + } + return (f.field && f.string && f.type) ? f : { field: f, + string: this.fields[f].string, + type: this.fields[f].type }; + }, + + create_field_values: function (field_ids) { + var self = this; + return _.map(field_ids, function (f) { return self.create_field_value(f); }); + }, + + _add_groupby: function(groupby_list, groupby) { + groupby_list.push(this.create_field_value(groupby)); + }, + + // ---------------------------------------------------------------------- + // Cells manipulation methods + // ---------------------------------------------------------------------- + // cells are objects {x:_, y:_, values:_} where x < y and values is an array + // of values (one for each measure). The condition x < y might look + // unnecessary, but it makes the rest of the code simpler: headers + // don't krow if they are rows or cols, they just know their id, so + // it is useful that a call get_values(id1, id2) is the same as get_values(id2, id1) + add_cell : function (id1, id2, values) { + this.cells.push({x: Math.min(id1, id2), y: Math.max(id1, id2), values: values}); + }, + + get_values: function (id1, id2, default_values) { + var cell = _.find(this.cells, function (c) { + return ((c.x == Math.min(id1, id2)) && (c.y == Math.max(id1, id2))); + }); + return (cell !== undefined) ? cell.values : (default_values || new Array(this.measures.length)); + }, + + // ---------------------------------------------------------------------- + // Headers/Rows/Cols manipulation methods + // ---------------------------------------------------------------------- + // this.rows.headers, this.cols.headers = [header] describe the tree structure + // of rows/cols. Headers are objects + // { + // id:_, (unique id obviously) + // path: [...], (array of all parents title, with its own title at the end) + // title:_, (name of the row/col) + // children:[_], (subrows or sub cols of this row/col) + // domain:_, (domain of data in this row/col) + // root:_ (ref to this.rows or this.cols corresponding to the header) + // expanded:_ (boolean, true if it has been expanded) + // } + is_row: function (id) { + return !!_.find(this.rows.headers, function (header) { + return header.id === id; + }); + }, + + is_col: function (id) { + return !!_.find(this.cols.headers, function (header) { + return header.id === id; + }); + }, + + get_header: function (id) { + return _.find(this.rows.headers.concat(this.cols.headers), function (header) { + return header.id === id; + }); + }, + + // return all columns with a path length of 'depth' + get_cols_with_depth: function (depth) { + return _.filter(this.cols.headers, function (header) { + return header.path.length === depth; + }); + }, + + // return all rows with a path length of 'depth' + get_rows_with_depth: function (depth) { + return _.filter(this.rows.headers, function (header) { + return header.path.length === depth; + }); + }, + + // return all non expanded rows + get_rows_leaves: function () { + return _.filter(this.rows.headers, function (header) { + return !header.expanded; + }); + }, + + // return all non expanded cols + get_cols_leaves: function () { + return _.filter(this.cols.headers, function (header) { + return !header.expanded; + }); + }, + + 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); })); + }, + + 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); })); + }, + + get_total: function (header) { + if (header) { + return this.get_values(header.id, this.get_other_root(header).headers[0].id); + } + return this.get_values(this.rows.headers[0].id, this.cols.headers[0].id); + }, + + get_other_root: function (header) { + return (header.root === this.rows) ? this.cols : this.rows; + }, + + main_row: function () { return this.rows.headers[0]; }, + + main_col: function () { return this.cols.headers[0]; }, + + // ---------------------------------------------------------------------- + // Table manipulation methods : fold/expand/swap + // ---------------------------------------------------------------------- + fold: function (header) { + var ancestors = this.get_ancestors(header), + removed_ids = _.pluck(ancestors, 'id'); + + header.root.headers = _.difference(header.root.headers, ancestors); + header.children = []; + header.expanded = false; + + this.cells = _.reject(this.cells, function (cell) { + return (_.contains(removed_ids, cell.x) || _.contains(removed_ids, cell.y)); + }); + + var new_groupby_length = _.max(_.map(header.root.headers, function(g) {return g.path.length;})); + if (new_groupby_length < header.root.groupby.length) { + header.root.groupby.splice(new_groupby_length); + this.trigger('groupby_changed'); + } + this.trigger('redraw_required'); + }, + + 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); + + if (header.path.length === header.root.groupby.length) { + self._add_groupby(header.root.groupby, groupby); + this.trigger('groupby_changed'); + } + groupby = [header.root.groupby[header.path.length]].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); + } + }); + }); + header.expanded = true; + self.trigger('redraw_required'); + }); + }, + + make_header: function (group, parent) { + var title = parent ? group.attributes.value : ''; + 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; + this.cols = temp; + this.trigger('groupby_changed'); + this.trigger('redraw_required'); + }, + + // ---------------------------------------------------------------------- + // 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; + } + self.trigger('redraw_required'); + }); + }, + + 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_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; + }, + + expand_all: function () { + this.rows.headers = null; + this.cols.headers = null; + this.update_data(); + }, + + // ---------------------------------------------------------------------- + // 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); + + var groupbys = _.map(_.range(cols.length + 1), function (i) { + return cols.slice(0, i).concat(rows); + }); + groupbys.push([]); + + var def_array = _.map(groupbys, function (groupby) { + return self.get_groups(groupby, visible_fields, self.domain); + }); + + return $.when.apply(null, def_array).then(function () { + var data = Array.prototype.slice.call(arguments), + row_data = data[0], + col_data = (cols.length !== 0) ? data[data.length - 2] : [], + total = data[data.length - 1][0]; + + return (total === undefined) ? undefined + : self.format_data(total, col_data, row_data, data); + }); + }, + + get_groups: function (groupbys, fields, domain, path) { + path = path || []; + var self = this, + groupby = (groupbys.length) ? groupbys[0] : []; + + 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; + } + }); + + }, + + _query_db: function (groupby, fields, domain, path) { + var self = this, + field_ids = _.without(_.pluck(fields, 'field'), '__count'), + context = {}; + + if (groupby.interval) { + context.datetime_format = {}; + var display_format; + switch (groupby.interval) { + case 'day': + display_format = 'dd MMMM YYYY'; + break; + case 'week': + display_format = 'w YYYY'; + break; + case 'month': + display_format = 'MMMM YYYY'; + break; + case 'quarter': + display_format = 'QQQ YYYY'; + break; + case 'year': + display_format = 'YYYY'; + break; + } + context.datetime_format[groupby.field] = { + interval: groupby.interval, + display_format: display_format + }; + } + return this.model.query(field_ids) + .filter(domain) + .context(context) + .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); }); + }); + }, + + // add the path to the group and sanitize the value... + format_group: function (group, current_path) { + var value = group.attributes.value; + + if (group.attributes.grouped_on && this.fields[group.attributes.grouped_on].type === 'selection') { + var selection = this.fields[group.attributes.grouped_on].selection, + value_lookup = _.find(selection, function (val) { return val[0] === value; }); + group.attributes.value = value_lookup ? value_lookup[1] : 'undefined'; + } else if (value === false) { + group.attributes.value = 'undefined'; + } else if (value instanceof Array) { + group.attributes.value = value[1]; + } + + group.path = value ? (current_path || []).concat(group.attributes.value) : []; + group.attributes.aggregates.__count = group.attributes.length; + + return group; + }, + + format_data: function (total, 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 (measure.field === '__count') ? attr.length : attr.aggregates[measure.field]; + }); + + var row = _.find(rows, function (header) { return _.isEqual(header.path, path.slice(index)); }); + var 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 b681cff77f8232d5d67f065daf278a17c3f98107 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 14 Jan 2014 14:01:41 +0100 Subject: [IMP] sets nvd3 library in production mode instead of debug mode (addon web_graph) bzr revid: ged@openerp.com-20140114130141-b41640a72gpshw1x --- addons/web_graph/static/src/js/graph_widget.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 33f3caabc07..c34603da19a 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -4,6 +4,7 @@ (function () { 'use strict'; var QWeb = openerp.web.qweb; +nv.dev = false; // sets nvd3 library in production mode openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin, { template: 'GraphWidget', -- cgit v1.2.3 From cf81efda4309f895f6777c46c39f1fe894f109cf Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 15 Jan 2014 10:37:49 +0100 Subject: [IMP] adds search view integration in graph view (addon web_graph) bzr revid: ged@openerp.com-20140115093749-t2s0306fchm2tnir --- addons/web_graph/static/src/js/graph_view.js | 140 +++++++++---------------- addons/web_graph/static/src/js/graph_widget.js | 130 +++++++++++++---------- addons/web_graph/static/src/js/pivot_table.js | 10 +- 3 files changed, 134 insertions(+), 146 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 1b940c1703a..eb901c28423 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -16,20 +16,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ display_name: _lt('Graph'), view_type: 'graph', + // ---------------------------------------------------------------------- + // Init stuff + // ---------------------------------------------------------------------- init: function(parent, dataset, view_id, options) { this._super(parent, dataset, view_id, options); this.dataset = dataset; this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); this.search_view = parent.searchview; - this.search_view_groupby = []; - this.groupby_mode = 'default'; // 'default' or 'manual' - this.default_row_groupby = []; - this.default_col_groupby = []; - this.search_field = { - get_context: this.proxy('get_context'), - get_domain: function () {}, - get_groupby: function () { }, - }; }, view_loading: function (fields_view_get) { @@ -41,16 +35,18 @@ instance.web_graph.GraphView = instance.web.View.extend({ stacked : (arch.attrs.stacked === 'True'), mode: (arch.attrs.type) ? arch.attrs.type : 'bar', measures: [], + row_groupby: [], + col_groupby: [], }; _.each(arch.children, function (field) { if (_.has(field.attrs, 'type')) { switch (field.attrs.type) { case 'row': - self.default_row_groupby.push(field.attrs.name); + self.widget_config.row_groupby.push(field.attrs.name); break; case 'col': - self.default_col_groupby.push(field.attrs.name); + self.widget_config.col_groupby.push(field.attrs.name); break; case 'measure': self.widget_config.measures.push(field.attrs.name); @@ -60,61 +56,28 @@ instance.web_graph.GraphView = instance.web.View.extend({ if ('operator' in field.attrs) { self.widget_config.measures.push(field.attrs.name); } else { - self.default_row_groupby.push(field.attrs.name); + self.widet_config.row_groupby.push(field.attrs.name); } } }); if (self.widget_config.measures.length === 0) { self.widget_config.measures.push('__count'); } - this.widget_config.row_groupby = self.default_row_groupby; - this.widget_config.col_groupby = self.default_col_groupby; - }, - - get_context: function (facet) { - var col_group_by = _.map(facet.values.models, function (model) { - return model.attributes.value.attrs.context.col_group_by; - }); - return {col_group_by : col_group_by}; }, do_search: function (domain, context, group_by) { - // var col_groupby = context.col_group_by || [], - // options = {domain:domain}; - if (!this.graph_widget) { + if (group_by.length) { + this.widget_config.row_groupby = group_by; + } this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); this.ViewManager.on('switch_mode', this, function (e) { if (e === 'graph') this.graph_widget.reload(); }); + return; } - // this.search_view_groupby = group_by; - - // if (group_by.length && this.groupby_mode !== 'manual') { - // if (_.isEqual(col_groupby, [])) { - // col_groupby = this.default_col_groupby; - // } - // } - // if (group_by.length || col_groupby.length) { - // this.groupby_mode = 'manual'; - // } - // if (!this.graph_widget.enabled) { - // options.update = false; - // options.silent = true; - // } - - // if (this.groupby_mode === 'manual') { - // options.row_groupby = group_by; - // options.col_groupby = col_groupby; - // } else { - // options.row_groupby = _.toArray(this.default_row_groupby); - // options.col_groupby = _.toArray(this.default_col_groupby); - // } - // this.graph_widget.set(domain, options.row_groupby, options.col_groupby); - // this.graph_widget.set_domain(domain); - // this.graph_widget.set_col_groupby(options.col_groupby); - // this.graph_widget.set_row_groupby(options.row_groupby); + this.graph_widget.set(domain, group_by, this.graph_widget.get_col_groupby()); }, do_show: function () { @@ -122,47 +85,46 @@ instance.web_graph.GraphView = instance.web.View.extend({ return this._super(); }, + // ---------------------------------------------------------------------- + // Search view integration + // ---------------------------------------------------------------------- + + // add groupby to the search view register_groupby: function() { - // var self = this, - // query = this.search_view.query; - - // this.groupby_mode = 'manual'; - // if (_.isEqual(this.search_view_groupby, this.graph_widget.pivot.rows.groupby) || - // (!_.has(this.search_view, '_s_groupby'))) { - // return; - // } - // var rows = _.map(this.graph_widget.pivot.rows.groupby, function (group) { - // return make_facet('GroupBy', group); - // }); - // var cols = _.map(this.graph_widget.pivot.cols.groupby, function (group) { - // return make_facet('ColGroupBy', group); - // }); - - // query.reset(rows.concat(cols)); - - // function make_facet (category, fields) { - // var values, - // icon, - // backbone_field, - // cat_name; - // if (!(fields instanceof Array)) { fields = [fields]; } - // if (category === 'GroupBy') { - // cat_name = 'group_by'; - // icon = 'w'; - // backbone_field = self.search_view._s_groupby; - // } else { - // cat_name = 'col_group_by'; - // icon = 'f'; - // backbone_field = self.search_field; - // } - // values = _.map(fields, function (field) { - // var context = {}; - // context[cat_name] = field; - // return {label: self.graph_widget.fields[field].string, value: {attrs:{domain: [], context: context}}}; - // }); - // return {category:category, values: values, icon:icon, field: backbone_field}; - // } + var query = this.search_view.query; + + if (!_.has(this.search_view, '_s_groupby')) { return; } + + var row_groupby = this.graph_widget.get_row_groupby(); + var gb_facet = this.make_groupby_facets(row_groupby); + var search_facet = query.findWhere({category:'GroupBy'}); + + if (search_facet) { + search_facet.values.reset(gb_facet.values); + } else { + if (row_groupby.length) { + query.add(gb_facet); + } + } }, + + make_groupby_facets: function(fields) { + var self = this, + values = _.map(fields, function (field) { + return { + label: self.graph_widget.fields[field].string, + value: {attrs:{domain: [], context: {group_by: field}}} + }; + }); + return {category:'GroupBy', values: values, icon:'w', field: self.search_view._s_groupby}; + }, + + search_field: { + get_context: function() {}, + get_domain: function () {}, + get_groupby: function () { }, + }, + }); diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index c34603da19a..a2f7761514a 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -9,14 +9,9 @@ nv.dev = false; // sets nvd3 library in production mode openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin, { template: 'GraphWidget', - events: { - 'click .graph_mode_selection li' : 'mode_selection', - 'click .graph_measure_selection li' : 'measure_selection', - 'click .graph_options_selection li' : 'option_selection', - 'click .web_graph_click' : 'header_cell_clicked', - 'click a.field-selection' : 'field_selection', - }, - + // ---------------------------------------------------------------------- + // Init stuff + // ---------------------------------------------------------------------- init: function(parent, model, domain, options) { this._super(parent); this.model = model; @@ -56,6 +51,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin }); }, + // this method gets the fields that appear in the search view, under the + // 'Groupby' heading get_search_fields: function () { var self = this, options = {model:this.model, view_type: 'search'}, @@ -83,6 +80,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin }); }, + // Extracts the integer/float fields which are not 'id' get_measures: function(fields) { var measures = []; _.each(this.fields, function (f, id) { @@ -93,7 +91,19 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin return measures; }, + add_measures_to_options: function() { + var measure_selection = this.$('.graph_measure_selection'); + _.each(this.measure_list, function (measure) { + var choice = $('').attr('data-choice', measure.field) + .attr('href', '#') + .append(measure.string); + measure_selection.append($('
  • ').append(choice)); + }); + }, + // ---------------------------------------------------------------------- + // Configuration methods + // ---------------------------------------------------------------------- set: function (domain, row_groupby, col_groupby) { if (this.pivot) { this.pivot.set(domain, row_groupby, col_groupby); @@ -104,49 +114,34 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin } }, - add_measures_to_options: function() { - var measure_selection = this.$('.graph_measure_selection'); - _.each(this.measure_list, function (measure) { - var choice = $('').attr('data-choice', measure.field) - .attr('href', '#') - .append(measure.string); - measure_selection.append($('
  • ').append(choice)); - }); - }, - set_mode: function (mode) { this.mode = mode; this.display_data(); }, + // returns the row groupbys as a list of fields (not the representation used + // internally by pivot table) + get_row_groupby: function () { + return _.pluck(this.pivot.rows.groupby, 'field'); + }, + + get_col_groupby: function () { + return _.pluck(this.pivot.cols.groupby, 'field'); + }, + reload: function () { this.pivot.update_data(); }, - display_data: function () { - this.$('.graph_main_content svg').remove(); - this.$('.graph_main_content div').remove(); - this.table.empty(); - - if (this.visible_ui) { - this.$('.graph_header').css('display', 'block'); - } else { - this.$('.graph_header').css('display', 'none'); - } - if (this.pivot.no_data) { - this.$('.graph_main_content').append($(QWeb.render('graph_no_data'))); - } else { - var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; - if (_.contains(table_modes, this.mode)) { - this.draw_table(); - } else { - this.$('.graph_main_content').append($('
    ')); - this.svg = this.$('.graph_main_content svg')[0]; - this.width = this.$el.width(); - this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); - this[this.mode](); - } - } + // ---------------------------------------------------------------------- + // UI code + // ---------------------------------------------------------------------- + events: { + 'click .graph_mode_selection li' : 'mode_selection', + 'click .graph_measure_selection li' : 'measure_selection', + 'click .graph_options_selection li' : 'option_selection', + 'click .web_graph_click' : 'header_cell_clicked', + 'click a.field-selection' : 'field_selection', }, mode_selection: function (event) { @@ -233,9 +228,38 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin } }, -/****************************************************************************** - * Drawing pivot table methods... - ******************************************************************************/ + // ---------------------------------------------------------------------- + // Main display method + // ---------------------------------------------------------------------- + display_data: function () { + this.$('.graph_main_content svg').remove(); + this.$('.graph_main_content div').remove(); + this.table.empty(); + + if (this.visible_ui) { + this.$('.graph_header').css('display', 'block'); + } else { + this.$('.graph_header').css('display', 'none'); + } + if (this.pivot.no_data) { + this.$('.graph_main_content').append($(QWeb.render('graph_no_data'))); + } else { + var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; + if (_.contains(table_modes, this.mode)) { + this.draw_table(); + } else { + this.$('.graph_main_content').append($('
    ')); + this.svg = this.$('.graph_main_content svg')[0]; + this.width = this.$el.width(); + this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); + this[this.mode](); + } + } + }, + + // ---------------------------------------------------------------------- + // Drawing the table + // ---------------------------------------------------------------------- draw_table: function () { this.pivot.main_row().title = 'Total'; if (this.pivot.measures.length == 1) { @@ -411,22 +435,22 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin } }, -/****************************************************************************** - * Drawing charts methods... - ******************************************************************************/ + // ---------------------------------------------------------------------- + // Drawing charts code + // ---------------------------------------------------------------------- bar: function () { var self = this, dim_x = this.pivot.rows.groupby.length, dim_y = this.pivot.cols.groupby.length, data; - // No groupby ************************************************************** + // No groupby if ((dim_x === 0) && (dim_y === 0)) { data = [{key: 'Total', values:[{ x: 'Total', y: this.pivot.get_total(), }]}]; - // Only column groupbys **************************************************** + // Only column groupbys } else if ((dim_x === 0) && (dim_y >= 1)){ data = _.map(this.pivot.get_columns_with_depth(1), function (header) { return { @@ -434,7 +458,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin values: [{x:header.root[0].title, y: self.pivot.get_total(header)[0]}] }; }); - // Just 1 row groupby ****************************************************** + // Just 1 row groupby } else if ((dim_x === 1) && (dim_y === 0)) { data = _.map(this.pivot.main_row().children, function (pt) { var value = self.pivot.get_total(pt), @@ -442,7 +466,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin return {x: title, y: value}; }); data = [{key: self.pivot.measures[0].string, values:data}]; - // 1 row groupby and some col groupbys************************************** + // 1 row groupby and some col groupbys } else if ((dim_x === 1) && (dim_y >= 1)) { data = _.map(this.pivot.get_cols_with_depth(1), function (colhdr) { var values = _.map(self.pivot.get_rows_with_depth(1), function (header) { @@ -453,7 +477,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin }); return {key: colhdr.title || 'Undefined', values: values}; }); - // At least two row groupby************************************************* + // At least two row groupby } else { var keys = _.uniq(_.map(this.pivot.get_rows_with_depth(2), function (hdr) { return hdr.title || 'Undefined'; diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 9c927150f20..edd1fc68042 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -77,18 +77,20 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var row_gbs = this.create_field_values(row_groupby), col_gbs = this.create_field_values(col_groupby), dom_changed = !_.isEqual(this.domain, domain), - gb_changed = !(_.isEqual(row_gbs, this.rows.groupby) && - _.isEqual(col_gbs, this.cols.groupby)); + row_gb_changed = !_.isEqual(row_gbs, this.rows.groupby), + col_gb_changed = !_.isEqual(col_gbs, this.cols.groupby); if (dom_changed) { this.domain = domain; } - if (gb_changed) { + if (row_gb_changed || col_gb_changed) { this.cols.groupby = col_gbs; this.rows.groupby = row_gbs; + if (row_gb_changed) {this.rows.headers = null; } + if (col_gb_changed) {this.cols.headers = null; } if (this.active) { this.trigger('groupby_changed'); } } - if (this.active && (gb_changed || dom_changed)) { + if (this.active && (row_gb_changed || col_gb_changed || dom_changed)) { this.update_data(); } }, -- cgit v1.2.3 From 4343ca278a21cd12880857736a9bf81a4cc83524 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 15 Jan 2014 11:51:04 +0100 Subject: [FIX] correctly compares groupby in pivot_table to avoid bugs/crashes (now, it ignores the 'interval' attributes) so the table can interact with the graph view (addon web_graph) bzr revid: ged@openerp.com-20140115105104-qff3t47lo1lyp5wd --- addons/web_graph/static/src/js/pivot_table.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index edd1fc68042..79d351ce315 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -77,8 +77,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var row_gbs = this.create_field_values(row_groupby), col_gbs = this.create_field_values(col_groupby), dom_changed = !_.isEqual(this.domain, domain), - row_gb_changed = !_.isEqual(row_gbs, this.rows.groupby), - col_gb_changed = !_.isEqual(col_gbs, this.cols.groupby); + row_gb_changed = !this.equal_groupby(row_gbs, this.rows.groupby), + col_gb_changed = !this.equal_groupby(col_gbs, this.cols.groupby); if (dom_changed) { this.domain = domain; @@ -95,6 +95,22 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM } }, + // compare groupby, ignoring the 'interval' attribute of dates... + // this is necessary to avoid problems with the groupby received by the + // context which do not have the interval attribute. This is ugly + // and need to be changed at some point + equal_groupby: function (groupby1, groupby2) { + if (groupby1.length !== groupby2.length) { return false; } + for (var i = 0; i < groupby1.length; i++) { + if (!this.equal_value(groupby1[i], groupby2[i])) { return false; } + } + return true; + }, + + equal_value: function (val1, val2) { + return ((val1.field === val2.field) && (val1.string === val2.string) && (val1.type === val2.type)); + }, + create_field_value: function (f) { if (f.field && f.interval) { return { field:f.field, -- cgit v1.2.3 From 74d6e75007ea089d79190e58a2579aaa8cd46060 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 15 Jan 2014 16:51:37 +0100 Subject: [IMP] supports col groupby in search view in graph view (addon web_graph) bzr revid: ged@openerp.com-20140115155137-qwy0sr49zhizgmf6 --- addons/web_graph/static/src/js/graph_view.js | 77 ++++++++++++++++++++------ addons/web_graph/static/src/js/graph_widget.js | 4 +- 2 files changed, 61 insertions(+), 20 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index eb901c28423..c2b3979199f 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -66,10 +66,15 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { + var col_group_by = this.get_col_groupbys_from_searchview(); + if (!this.graph_widget) { if (group_by.length) { this.widget_config.row_groupby = group_by; } + if (col_group_by.length) { + this.widget_config.col_groupby = group_by; + } this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); @@ -77,7 +82,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ return; } - this.graph_widget.set(domain, group_by, this.graph_widget.get_col_groupby()); + this.graph_widget.set(domain, group_by, col_group_by); + }, + + get_col_groupbys_from_searchview: function () { + var facet = this.search_view.query.findWhere({category:'ColGroupBy'}), + groupby_list = facet ? facet.attributes.values : []; + return _.map(groupby_list, function (g) { return g.value.attrs.context.col_group_by; }); }, do_show: function () { @@ -95,39 +106,69 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (!_.has(this.search_view, '_s_groupby')) { return; } - var row_groupby = this.graph_widget.get_row_groupby(); - var gb_facet = this.make_groupby_facets(row_groupby); - var search_facet = query.findWhere({category:'GroupBy'}); + // add row groupbys + var row_groupby = this.graph_widget.get_row_groupby(), + row_facet = this.make_row_groupby_facets(row_groupby), + row_search_facet = query.findWhere({category:'GroupBy'}); - if (search_facet) { - search_facet.values.reset(gb_facet.values); + if (row_search_facet) { + row_search_facet.values.reset(row_facet.values); } else { if (row_groupby.length) { - query.add(gb_facet); + query.add(row_facet); + } + } + // add col groupbys + var col_groupby = this.graph_widget.get_col_groupby(), + col_facet = this.make_col_groupby_facets(col_groupby), + col_search_facet = query.findWhere({category:'ColGroupBy'}); + + if (col_search_facet) { + col_search_facet.values.reset(col_facet.values); + } else { + if (col_groupby.length) { + query.add(col_facet); } } }, - make_groupby_facets: function(fields) { - var self = this, - values = _.map(fields, function (field) { - return { - label: self.graph_widget.fields[field].string, - value: {attrs:{domain: [], context: {group_by: field}}} - }; - }); - return {category:'GroupBy', values: values, icon:'w', field: self.search_view._s_groupby}; + make_row_groupby_facets: function(groupbys) { + return { + category:'GroupBy', + values: this.make_groupby_values(groupbys, 'group_by'), + icon:'w', + field: this.search_view._s_groupby + }; + }, + + make_col_groupby_facets: function(groupbys) { + return { + category:'ColGroupBy', + values: this.make_groupby_values(groupbys, 'col_group_by'), + icon:'f', + field: this.search_field + }; + }, + + make_groupby_values: function (groupbys, category) { + return _.map(groupbys, function (groupby) { + var context = {}; + context[category] = groupby.field; + return { + label: groupby.string, + value: {attrs:{domain: [], context: context}} + }; + }); }, search_field: { get_context: function() {}, get_domain: function () {}, - get_groupby: function () { }, + get_groupby: function () {}, }, }); - }; diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index a2f7761514a..d84c8d794f4 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -122,11 +122,11 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin // returns the row groupbys as a list of fields (not the representation used // internally by pivot table) get_row_groupby: function () { - return _.pluck(this.pivot.rows.groupby, 'field'); + return this.pivot.rows.groupby; }, get_col_groupby: function () { - return _.pluck(this.pivot.cols.groupby, 'field'); + return this.pivot.cols.groupby; }, reload: function () { -- cgit v1.2.3 From 588e5413872c5c50ba9f48d4fd094ae1ba05e3c7 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 16 Jan 2014 10:55:49 +0100 Subject: [FIX] fixes some issues with the col_group_bys in searchbar (main problem was that do_search is called twice when the user swap axis) (addon web_graph) bzr revid: ged@openerp.com-20140116095549-3f2hbyzj32nuj147 --- addons/web_graph/static/src/js/graph_view.js | 15 +++++++++++++-- addons/web_graph/static/src/js/graph_widget.js | 1 + addons/web_graph/static/src/js/pivot_table.js | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index c2b3979199f..91fcefaf1b8 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -78,17 +78,23 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); + this.graph_widget.on('groupby_swapped', this, this.proxy('swap_groupby')); this.ViewManager.on('switch_mode', this, function (e) { if (e === 'graph') this.graph_widget.reload(); }); return; } + if (this.swapped) { + this.swapped = false; + return; + } + this.graph_widget.set(domain, group_by, col_group_by); }, get_col_groupbys_from_searchview: function () { var facet = this.search_view.query.findWhere({category:'ColGroupBy'}), - groupby_list = facet ? facet.attributes.values : []; - return _.map(groupby_list, function (g) { return g.value.attrs.context.col_group_by; }); + groupby_list = facet ? facet.values.models : []; + return _.map(groupby_list, function (g) { return g.attributes.value.attrs.context.col_group_by; }); }, do_show: function () { @@ -132,6 +138,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }, + swap_groupby: function () { + this.swap = true; + this.register_groupby(); + }, + make_row_groupby_facets: function(groupbys) { return { category:'GroupBy', diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index d84c8d794f4..e9e3b4acb12 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -41,6 +41,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin self.pivot = new openerp.web_graph.PivotTable(self.model, self.domain, self.fields, self.pivot_options); self.pivot.on('redraw_required', self, self.proxy('display_data')); self.pivot.on('groupby_changed', self, function () { self.trigger('groupby_changed'); }); + self.pivot.on('groupby_swapped', self, function () { self.trigger('groupby_swapped'); }); openerp.web.bus.on('click', self, function () { if (self.dropdown) { self.dropdown.remove(); diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 79d351ce315..d7a836d98b8 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -4,7 +4,7 @@ (function () { 'use strict'; -// Pivot Table emits the events 'groupby_changed' and 'redraw_required' when necessary. +// Pivot Table emits the events 'groupby_changed', 'groupby_swapped' and 'redraw_required' when necessary. // PivotTable is initialized by default 'inactive', and require a call to activate() // after init to load initial data and start triggering events. openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { @@ -318,7 +318,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var temp = this.rows; this.rows = this.cols; this.cols = temp; - this.trigger('groupby_changed'); + this.trigger('groupby_swapped'); this.trigger('redraw_required'); }, -- cgit v1.2.3 From 1c1a02d16630250ce981cf3411638922734d0224 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 16 Jan 2014 15:00:58 +0100 Subject: [IMP] changes the UI of the graph view: removes old dropdown buttons and adds a toolbar instead (addon web_graph) bzr revid: ged@openerp.com-20140116140058-rd6nde1mfupgnajt --- addons/web_graph/static/src/js/graph_widget.js | 63 +++++++++++++++++++++----- 1 file changed, 51 insertions(+), 12 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index e9e3b4acb12..789cc54cbe3 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -16,7 +16,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin this._super(parent); this.model = model; this.domain = domain; - this.mode = options.mode || 'pivot'; + this.mode = options.mode || 'pivot'; // pivot, bar, pie, line + this.heatmap_mode = options.heatmap_mode || 'none'; this.title = options.title || 'Graph'; this.visible_ui = options.visible_ui || true; this.bar_ui = options.bar_ui || 'group'; @@ -27,6 +28,17 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin var self = this; this.table = $('
    '); this.$('.graph_main_content').append(this.table); + + var index = 0; + if (this.mode === 'bar') { index = 1; } + if (this.mode === 'line') { index = 2; } + if (this.mode === 'chart') { index = 3; } + this.$('.graph_mode_selection label').eq(index).addClass('active'); + + if (this.mode !== 'pivot') { + this.$('.graph_heatmap label').addClass('disabled'); + } + var def1 = this.get_search_fields().then(function (f) { self.important_fields = f; }); @@ -117,6 +129,22 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin set_mode: function (mode) { this.mode = mode; + + if (mode === 'pivot') { + this.$('.graph_heatmap label').removeClass('disabled'); + } else { + this.$('.graph_heatmap label').addClass('disabled'); + } + this.display_data(); + }, + + set_heatmap_mode: function (mode) { // none, row, col, all + debugger; + this.heatmap_mode = mode; + if (mode === 'none') { + this.$('.graph_heatmap label').removeClass('disabled'); + this.$('.graph_heatmap label').removeClass('active'); + } this.display_data(); }, @@ -138,16 +166,17 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin // UI code // ---------------------------------------------------------------------- events: { - 'click .graph_mode_selection li' : 'mode_selection', + 'click .graph_mode_selection label' : 'mode_selection', 'click .graph_measure_selection li' : 'measure_selection', - 'click .graph_options_selection li' : 'option_selection', + 'click .graph_options_selection label' : 'option_selection', + 'click .graph_heatmap label' : 'heatmap_mode_selection', 'click .web_graph_click' : 'header_cell_clicked', 'click a.field-selection' : 'field_selection', }, mode_selection: function (event) { event.preventDefault(); - var mode = event.target.attributes['data-mode'].nodeValue; + var mode = event.currentTarget.attributes['data-mode'].nodeValue; this.set_mode(mode); }, @@ -159,7 +188,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin option_selection: function (event) { event.preventDefault(); - switch (event.target.attributes['data-choice'].nodeValue) { + switch (event.currentTarget.attributes['data-choice'].nodeValue) { case 'bar_grouped': this.bar_ui = 'group'; if (this.mode === 'bar') { @@ -187,6 +216,17 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin } }, + heatmap_mode_selection: function (event) { + event.preventDefault(); + var mode = event.currentTarget.attributes['data-mode'].nodeValue; + if (this.heatmap_mode === mode) { + event.stopPropagation(); + this.set_heatmap_mode('none'); + } else { + this.set_heatmap_mode(mode); + } + }, + header_cell_clicked: function (event) { event.preventDefault(); event.stopPropagation(); @@ -245,8 +285,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin if (this.pivot.no_data) { this.$('.graph_main_content').append($(QWeb.render('graph_no_data'))); } else { - var table_modes = ['pivot', 'heatmap', 'row_heatmap', 'col_heatmap']; - if (_.contains(table_modes, this.mode)) { + if (this.mode === 'pivot') { this.draw_table(); } else { this.$('.graph_main_content').append($('
    ')); @@ -416,17 +455,17 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin return cell; } cell.append(openerp.web.format_value(value, {type: measure_type})); - if (self.mode === 'heatmap') { + if (self.heatmap_mode === 'both') { total = pivot.get_total()[index]; color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); } - if (self.mode === 'row_heatmap') { + if (self.heatmap_mode === 'row') { total = pivot.get_total(row)[index]; color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); } - if (self.mode === 'col_heatmap') { + if (self.heatmap_mode === 'col') { debugger; total = pivot.get_total(col)[index]; color = Math.floor(90 + 165*(total - Math.abs(value))/total); @@ -453,10 +492,10 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin }]}]; // Only column groupbys } else if ((dim_x === 0) && (dim_y >= 1)){ - data = _.map(this.pivot.get_columns_with_depth(1), function (header) { + data = _.map(this.pivot.get_cols_with_depth(1), function (header) { return { key: header.title, - values: [{x:header.root[0].title, y: self.pivot.get_total(header)[0]}] + values: [{x:header.title, y: self.pivot.get_total(header)[0]}] }; }); // Just 1 row groupby -- cgit v1.2.3 From feff16b03e29974567edbf6dd0f656adf280ec54 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 17 Jan 2014 09:58:42 +0100 Subject: [FIX] fixes a typo 'widet_config' => 'widget_config' (it previously crashed the graph view) (addon web_graph) bzr revid: ged@openerp.com-20140117085842-vxaxes0yv3dr7t24 --- addons/web_graph/static/src/js/graph_view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 91fcefaf1b8..a192952ab5c 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -56,7 +56,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ if ('operator' in field.attrs) { self.widget_config.measures.push(field.attrs.name); } else { - self.widet_config.row_groupby.push(field.attrs.name); + self.widget_config.row_groupby.push(field.attrs.name); } } }); -- cgit v1.2.3 From 6839fcaddd60d82c66626acfeaa7467232f67471 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 17 Jan 2014 11:23:39 +0100 Subject: [IMP] makes sure that the graph view does not reload data if the user removes a measure. Also, display the 'no data' screen if there are no current measure in graph view (addon web_graph) bzr revid: ged@openerp.com-20140117102339-99kka9v6wfsgesdn --- addons/web_graph/static/src/js/pivot_table.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index d7a836d98b8..61a6587e0a2 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -61,16 +61,25 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM toggle_measure: function (field_id) { var current_measure = _.findWhere(this.measures, {field:field_id}); - if (current_measure) { + if (current_measure) { // remove current_measure + var index = this.measures.indexOf(current_measure); this.measures = _.without(this.measures, current_measure); - } else { + if (this.measures.length === 0) { + this.nodata = true; + } else { + _.each(this.cells, function (cell) { + cell.values.splice(index, 1); + }); + } + if (this.active) { this.trigger('redraw_required'); } + } else { // add a new measure this.measures.push({ field: field_id, type: this.fields[field_id].type, string: this.fields[field_id].string }); + if (this.active) { this.update_data(); } } - if (this.active) { this.update_data(); } }, set: function (domain, row_groupby, col_groupby) { @@ -401,6 +410,12 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM rows = this.rows.groupby, visible_fields = rows.concat(cols, self.measures); + if (this.measures.length === 0) { + var result = $.Deferred(); + result.resolve() + return result; + } + var groupbys = _.map(_.range(cols.length + 1), function (i) { return cols.slice(0, i).concat(rows); }); -- cgit v1.2.3 From c54746744251924691a9aa1170d32f3bc1c4d50d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 17 Jan 2014 15:43:03 +0100 Subject: [IMP] adds checkmarks next to measures when they are used in graph view (addon web_graph) bzr revid: ged@openerp.com-20140117144303-tqj7cn5xd1c0xvhm --- addons/web_graph/static/src/js/graph_widget.js | 31 ++++++++++++++++++-------- addons/web_graph/static/src/js/pivot_table.js | 8 +++---- 2 files changed, 26 insertions(+), 13 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 789cc54cbe3..85b37170a4b 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -61,14 +61,14 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin } }); self.pivot.activate(); + self.put_measure_checkmarks(); }); }, // this method gets the fields that appear in the search view, under the // 'Groupby' heading get_search_fields: function () { - var self = this, - options = {model:this.model, view_type: 'search'}, + var options = {model:this.model, view_type: 'search'}, result = []; return openerp.web.fields_view_get(options).then(function (search_view) { @@ -94,8 +94,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin }, // Extracts the integer/float fields which are not 'id' - get_measures: function(fields) { - var measures = []; + get_measures: function() { + var measures = [{field:'__count', type: 'integer', string:'Quantity'}]; _.each(this.fields, function (f, id) { if (((f.type === 'integer') || (f.type === 'float')) && (id !== 'id')) { measures.push({field:id, type: f.type, string: f.string}); @@ -134,12 +134,11 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin this.$('.graph_heatmap label').removeClass('disabled'); } else { this.$('.graph_heatmap label').addClass('disabled'); - } + } this.display_data(); }, set_heatmap_mode: function (mode) { // none, row, col, all - debugger; this.heatmap_mode = mode; if (mode === 'none') { this.$('.graph_heatmap label').removeClass('disabled'); @@ -184,6 +183,22 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin event.preventDefault(); var measure = event.target.attributes['data-choice'].nodeValue; this.pivot.toggle_measure(measure); + this.put_measure_checkmarks(); + }, + + put_measure_checkmarks: function () { + var self = this, + measures_li = this.$('.graph_measure_selection a'); + measures_li.removeClass('oe_selected'); + // measures_li.eq(0).addClass('oe_selected'); + console.log('measures_li', measures_li); + _.each(this.measure_list, function (measure, index) { + if (_.findWhere(self.pivot.measures, measure)) { + console.log('measure', measure, index); + measures_li.eq(index).addClass('oe_selected'); + } + }); + }, option_selection: function (event) { @@ -385,8 +400,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin }, make_measure_row: function() { - var self = this, - measures = this.pivot.measures, + var measures = this.pivot.measures, cols = this.pivot.cols.headers, measure_cells, measure_row = $(''); @@ -466,7 +480,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin cell.css('background-color', $.Color(255, color, color)); } if (self.heatmap_mode === 'col') { - debugger; total = pivot.get_total(col)[index]; color = Math.floor(90 + 165*(total - Math.abs(value))/total); cell.css('background-color', $.Color(255, color, color)); diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 61a6587e0a2..55719200098 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -17,7 +17,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.model = model; this.fields = fields; this.fields.__count = {type: 'integer', string:'Quantity'}; - this.measures = [{field:'__count', type: this.fields.type, string:this.fields.string}]; + this.measures = [{field:'__count', type: 'integer', string:'Quantity'}]; this.active = false; this.rows = { groupby: this.create_field_values(options.row_groupby || []), headers: null }; this.cols = { groupby: this.create_field_values(options.col_groupby || []), headers: null }; @@ -410,10 +410,10 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM rows = this.rows.groupby, visible_fields = rows.concat(cols, self.measures); - if (this.measures.length === 0) { + if (this.measures.length === 0) { var result = $.Deferred(); - result.resolve() - return result; + result.resolve(); + return result; } var groupbys = _.map(_.range(cols.length + 1), function (i) { -- cgit v1.2.3 From 9a8d3950780f3ad90549ce80b5d74fdd0db9fecf Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 17 Jan 2014 15:50:56 +0100 Subject: [IMP] display bar chart controls when the size is large enough and when it makes sense (dim x + dim y >= 2) in grap view (addon web_graph) bzr revid: ged@openerp.com-20140117145056-dby0g4sj7v056gpq --- addons/web_graph/static/src/js/graph_widget.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 85b37170a4b..66e40a00849 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -495,6 +495,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin var self = this, dim_x = this.pivot.rows.groupby.length, dim_y = this.pivot.cols.groupby.length, + show_controls = (this.width > 400 && this.height > 300 && dim_x + dim_y >=2), data; // No groupby @@ -555,7 +556,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin .height(self.height) .reduceXTicks(false) .stacked(self.bar_ui === 'stack') - .showControls(false); + .showControls(show_controls); if (self.width / data[0].values.length < 80) { chart.rotateLabels(-15); -- cgit v1.2.3 From 86a18410d19e668f27afee18bc4eaa50917ec3fc Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 17 Jan 2014 16:24:13 +0100 Subject: [IMP] keeps the dropdown open when the user selects some measures in graph view (addon web_graph) bzr revid: ged@openerp.com-20140117152413-ycktqzi51a3lhhz9 --- addons/web_graph/static/src/js/graph_widget.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 66e40a00849..c89944d712a 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -181,6 +181,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin measure_selection: function (event) { event.preventDefault(); + event.stopPropagation(); var measure = event.target.attributes['data-choice'].nodeValue; this.pivot.toggle_measure(measure); this.put_measure_checkmarks(); -- cgit v1.2.3 From 5aade330c20a1021eaa31bf932dab81dd45ec431 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 17 Jan 2014 16:33:30 +0100 Subject: [FIX] fixes a typo (nodata => no_data), which prevents a crash in graph_view, addon web_graph) bzr revid: ged@openerp.com-20140117153330-9vc6bzljmso9zu71 --- addons/web_graph/static/src/js/graph_widget.js | 3 --- addons/web_graph/static/src/js/pivot_table.js | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index c89944d712a..d774b66727e 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -191,11 +191,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin var self = this, measures_li = this.$('.graph_measure_selection a'); measures_li.removeClass('oe_selected'); - // measures_li.eq(0).addClass('oe_selected'); - console.log('measures_li', measures_li); _.each(this.measure_list, function (measure, index) { if (_.findWhere(self.pivot.measures, measure)) { - console.log('measure', measure, index); measures_li.eq(index).addClass('oe_selected'); } }); diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 55719200098..476891644d7 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -65,7 +65,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var index = this.measures.indexOf(current_measure); this.measures = _.without(this.measures, current_measure); if (this.measures.length === 0) { - this.nodata = true; + this.no_data = true; } else { _.each(this.cells, function (cell) { cell.values.splice(index, 1); -- cgit v1.2.3 From ba9999c28aa0e821924e5792a672eb429467ab6c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 17 Jan 2014 17:19:40 +0100 Subject: [FIX] fix crash happening when user goes to graph view, switch to other view, changes groupby and goes back to graph view. (addon web_graph) bzr revid: ged@openerp.com-20140117161940-3ojz17luxtsb9qfa --- addons/web_graph/static/src/js/graph_view.js | 17 +++++++++++++++-- addons/web_graph/static/src/js/graph_widget.js | 9 +++++---- addons/web_graph/static/src/js/pivot_table.js | 1 + 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index a192952ab5c..0af32c8af7d 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -66,7 +66,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { - var col_group_by = this.get_col_groupbys_from_searchview(); + var self = this, + col_group_by = this.get_col_groupbys_from_searchview(); if (!this.graph_widget) { if (group_by.length) { @@ -79,7 +80,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.graph_widget.appendTo(this.$el); this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); this.graph_widget.on('groupby_swapped', this, this.proxy('swap_groupby')); - this.ViewManager.on('switch_mode', this, function (e) { if (e === 'graph') this.graph_widget.reload(); }); + this.ViewManager.on('switch_mode', this, function (e) { + var domain = self.graph_widget.get_domain(), + col_gb = self.get_col_groupbys_from_searchview(), + row_gb = self.get_row_groupbys_from_searchview(); + + if (e === 'graph') this.graph_widget.set(domain, row_gb, col_gb); + }); return; } @@ -97,6 +104,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ return _.map(groupby_list, function (g) { return g.attributes.value.attrs.context.col_group_by; }); }, + get_row_groupbys_from_searchview: function () { + var facet = this.search_view.query.findWhere({category:'GroupBy'}), + groupby_list = facet ? facet.values.models : []; + return _.map(groupby_list, function (g) { return g.attributes.value.attrs.context.group_by; }); + }, + do_show: function () { this.do_push_state({}); return this._super(); diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index d774b66727e..1dc4510c5b6 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -62,6 +62,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin }); self.pivot.activate(); self.put_measure_checkmarks(); + self.trigger('groupby_changed'); }); }, @@ -150,15 +151,15 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin // returns the row groupbys as a list of fields (not the representation used // internally by pivot table) get_row_groupby: function () { - return this.pivot.rows.groupby; + return (this.pivot) ? this.pivot.rows.groupby : this.pivot_options.row_groupby; }, get_col_groupby: function () { - return this.pivot.cols.groupby; + return (this.pivot) ? this.pivot.cols.groupby : this.pivot_options.col_groupby; }, - reload: function () { - this.pivot.update_data(); + get_domain: function () { + return (this.pivot) ? this.pivot.domain : this.pivot_options.domain; }, // ---------------------------------------------------------------------- diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 476891644d7..26c1395dff6 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -82,6 +82,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM } }, + // return true if an update is triggered, false otherwise set: function (domain, row_groupby, col_groupby) { var row_gbs = this.create_field_values(row_groupby), col_gbs = this.create_field_values(col_groupby), -- cgit v1.2.3 From f404bf8b406ef276f4c16856172ef1ecd2f45dae Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 20 Jan 2014 10:32:54 +0100 Subject: [IMP] optimizes pivot table so that it doesn't reload data when the groupbys have been changed in such a way that it should only fold some headers (addon web_graph) bzr revid: ged@openerp.com-20140120093254-mta9v6hjmsgfpr2n --- addons/web_graph/static/src/js/pivot_table.js | 54 ++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 26c1395dff6..d54161f8ba7 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -87,12 +87,27 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var row_gbs = this.create_field_values(row_groupby), col_gbs = this.create_field_values(col_groupby), dom_changed = !_.isEqual(this.domain, domain), + row_subset = is_strict_beginning_of(row_gbs, this.rows.groupby), + col_subset = is_strict_beginning_of(col_gbs, this.cols.groupby), row_gb_changed = !this.equal_groupby(row_gbs, this.rows.groupby), col_gb_changed = !this.equal_groupby(col_gbs, this.cols.groupby); if (dom_changed) { this.domain = domain; } + + if (row_subset && !dom_changed && !col_gb_changed) { + this.fold_with_depth(this.rows, row_gbs.length); + if (this.active) { this.trigger('redraw_required'); } + return; + } + + if (col_subset && !dom_changed && !row_gb_changed) { + this.fold_with_depth(this.cols, col_gbs.length); + if (this.active) { this.trigger('redraw_required'); } + return; + } + if (row_gb_changed || col_gb_changed) { this.cols.groupby = col_gbs; this.rows.groupby = row_gbs; @@ -193,18 +208,20 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }); }, + _get_headers_with_depth: function (headers, depth) { + return _.filter(headers, function (header) { + return header.path.length === depth; + }); + }, + // return all columns with a path length of 'depth' get_cols_with_depth: function (depth) { - return _.filter(this.cols.headers, function (header) { - return header.path.length === depth; - }); + return this._get_headers_with_depth(this.cols.headers, depth); }, // return all rows with a path length of 'depth' get_rows_with_depth: function (depth) { - return _.filter(this.rows.headers, function (header) { - return header.path.length === depth; - }); + return this._get_headers_with_depth(this.rows.headers), depth; }, // return all non expanded rows @@ -250,7 +267,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // ---------------------------------------------------------------------- // Table manipulation methods : fold/expand/swap // ---------------------------------------------------------------------- - fold: function (header) { + fold: function (header, silent) { var ancestors = this.get_ancestors(header), removed_ids = _.pluck(ancestors, 'id'); @@ -265,11 +282,18 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var new_groupby_length = _.max(_.map(header.root.headers, function(g) {return g.path.length;})); if (new_groupby_length < header.root.groupby.length) { header.root.groupby.splice(new_groupby_length); - this.trigger('groupby_changed'); + if (!silent) { this.trigger('groupby_changed'); } } - this.trigger('redraw_required'); + if (!silent) { this.trigger('redraw_required'); } }, + fold_with_depth: function (root, depth) { + var self = this; + _.each(this._get_headers_with_depth(root.headers, depth), function (header) { + self.fold(header, true); + }); + }, + expand: function (header_id, groupby) { var self = this, header = this.get_header(header_id), @@ -568,6 +592,18 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }, }); + +// Utility function: returns true if the beginning of array2 is array1 and +// if array1 is not array2 +function is_strict_beginning_of (array1, array2) { + if (array1.length >= array2.length) { return false; } + var result = true; + for (var i = 0; i < array1.length; i++) { + if (!_.isEqual(array1[i], array2[i])) { return false;} + } + return result; +} + })(); -- cgit v1.2.3 From 2cafcfbde7612c1d16513ad7ddc416de7d6a6497 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 21 Jan 2014 15:30:34 +0100 Subject: [REF] large refactoring in graph view: changes the flow of the program to make it much simpler (addon web_graph) bzr revid: ged@openerp.com-20140121143034-rid4saax5y63g7i1 --- addons/web_graph/static/src/js/graph_view.js | 51 ++----- addons/web_graph/static/src/js/graph_widget.js | 203 +++++++++++++++++-------- addons/web_graph/static/src/js/pivot_table.js | 203 +++++-------------------- 3 files changed, 200 insertions(+), 257 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 0af32c8af7d..0c0e80c566f 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -30,13 +30,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ var self = this, arch = fields_view_get.arch; - this.widget_config = { + this.widget_config = { title: arch.attrs.string, stacked : (arch.attrs.stacked === 'True'), mode: (arch.attrs.type) ? arch.attrs.type : 'bar', measures: [], row_groupby: [], col_groupby: [], + graph_view: this, }; _.each(arch.children, function (field) { @@ -67,7 +68,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { var self = this, - col_group_by = this.get_col_groupbys_from_searchview(); + col_group_by = this.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); if (!this.graph_widget) { if (group_by.length) { @@ -78,36 +79,23 @@ instance.web_graph.GraphView = instance.web.View.extend({ } this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); - this.graph_widget.on('groupby_changed', this, this.proxy('register_groupby')); - this.graph_widget.on('groupby_swapped', this, this.proxy('swap_groupby')); - this.ViewManager.on('switch_mode', this, function (e) { + this.ViewManager.on('switch_mode', this, function (e) { var domain = self.graph_widget.get_domain(), - col_gb = self.get_col_groupbys_from_searchview(), - row_gb = self.get_row_groupbys_from_searchview(); + col_gb = self.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'), + row_gb = self.get_groupbys_from_searchview('GroupBy', 'group_by'); - if (e === 'graph') this.graph_widget.set(domain, row_gb, col_gb); + if (e === 'graph') this.graph_widget.set(domain, row_gb, col_gb); }); return; } - if (this.swapped) { - this.swapped = false; - return; - } - this.graph_widget.set(domain, group_by, col_group_by); }, - get_col_groupbys_from_searchview: function () { - var facet = this.search_view.query.findWhere({category:'ColGroupBy'}), + get_groupbys_from_searchview: function (cat_name, cat_field) { + var facet = this.search_view.query.findWhere({category:cat_name}), groupby_list = facet ? facet.values.models : []; - return _.map(groupby_list, function (g) { return g.attributes.value.attrs.context.col_group_by; }); - }, - - get_row_groupbys_from_searchview: function () { - var facet = this.search_view.query.findWhere({category:'GroupBy'}), - groupby_list = facet ? facet.values.models : []; - return _.map(groupby_list, function (g) { return g.attributes.value.attrs.context.group_by; }); + return _.map(groupby_list, function (g) { return g.attributes.value.attrs.context[cat_field]; }); }, do_show: function () { @@ -120,14 +108,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ // ---------------------------------------------------------------------- // add groupby to the search view - register_groupby: function() { + register_groupby: function(row_groupby, col_groupby) { var query = this.search_view.query; if (!_.has(this.search_view, '_s_groupby')) { return; } // add row groupbys - var row_groupby = this.graph_widget.get_row_groupby(), - row_facet = this.make_row_groupby_facets(row_groupby), + var row_facet = this.make_row_groupby_facets(row_groupby), row_search_facet = query.findWhere({category:'GroupBy'}); if (row_search_facet) { @@ -138,8 +125,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ } } // add col groupbys - var col_groupby = this.graph_widget.get_col_groupby(), - col_facet = this.make_col_groupby_facets(col_groupby), + var col_facet = this.make_col_groupby_facets(col_groupby), col_search_facet = query.findWhere({category:'ColGroupBy'}); if (col_search_facet) { @@ -151,11 +137,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ } }, - swap_groupby: function () { - this.swap = true; - this.register_groupby(); - }, - make_row_groupby_facets: function(groupbys) { return { category:'GroupBy', @@ -178,9 +159,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ return _.map(groupbys, function (groupby) { var context = {}; context[category] = groupby.field; + var value = (category === 'group_by') ? groupby.filter : {attrs:{domain: [], context: context}}; return { - label: groupby.string, - value: {attrs:{domain: [], context: context}} + label: groupby.string, + value: value }; }); }, @@ -192,7 +174,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, }); - }; diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 1dc4510c5b6..28a96ca7907 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -6,7 +6,7 @@ var QWeb = openerp.web.qweb; nv.dev = false; // sets nvd3 library in production mode -openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin, { +openerp.web_graph.Graph = openerp.web.Widget.extend({ template: 'GraphWidget', // ---------------------------------------------------------------------- @@ -21,7 +21,9 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin this.title = options.title || 'Graph'; this.visible_ui = options.visible_ui || true; this.bar_ui = options.bar_ui || 'group'; + this.graph_view = options.graph_view || null; this.pivot_options = options; + this.important_fields = this.get_search_fields(); }, start: function() { @@ -39,58 +41,48 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin this.$('.graph_heatmap label').addClass('disabled'); } - var def1 = this.get_search_fields().then(function (f) { - self.important_fields = f; - }); - - var def2 = this.model.call('fields_get', []).then(function (f) { + return this.model.call('fields_get', []).then(function (f) { self.fields = f; + self.fields.__count = {string: 'Quantity', type: 'integer'}; self.measure_list = self.get_measures(); self.add_measures_to_options(); - }); - - return $.when(def1, def2).then(function () { + self.pivot_options.row_groupby = self.create_field_values(self.pivot_options.row_groupby || []); + self.pivot_options.col_groupby = self.create_field_values(self.pivot_options.col_groupby || []); + self.pivot_options.measures = self.create_field_values(self.pivot_options.measures || [{field:'__count', type: 'integer', string:'Quantity'}]); self.pivot = new openerp.web_graph.PivotTable(self.model, self.domain, self.fields, self.pivot_options); - self.pivot.on('redraw_required', self, self.proxy('display_data')); - self.pivot.on('groupby_changed', self, function () { self.trigger('groupby_changed'); }); - self.pivot.on('groupby_swapped', self, function () { self.trigger('groupby_swapped'); }); + self.pivot.update_data().then(function () { + self.display_data(); + if (self.graph_view) { + self.graph_view.register_groupby(self.pivot.rows.groupby, self.pivot.cols.groupby); + } + }); openerp.web.bus.on('click', self, function () { if (self.dropdown) { self.dropdown.remove(); self.dropdown = null; } }); - self.pivot.activate(); self.put_measure_checkmarks(); - self.trigger('groupby_changed'); }); }, // this method gets the fields that appear in the search view, under the // 'Groupby' heading get_search_fields: function () { - var options = {model:this.model, view_type: 'search'}, - result = []; + var search_view = openerp.client.action_manager.inner_widget.searchview; - return openerp.web.fields_view_get(options).then(function (search_view) { - var groups = _.select(search_view.arch.children, function (c) { - return (c.tag === 'group') && (c.attrs.string != 'Display'); - }); - _.each(groups, function(g) { - _.each(g.children, function (g) { - if (g.attrs.context) { - var field_id = py.eval(g.attrs.context).group_by; - if (field_id) { - if (field_id instanceof Array) { - result.concat(field_id); - } else { - result.push(field_id); - } - } - } - }); - }); - return result; + var groupbygroups = _(search_view.inputs).select(function (g) { + return g instanceof openerp.web.search.GroupbyGroup; + }); + + var filters = [].concat.apply([], _.pluck(groupbygroups, 'filters')); + + return _.map(filters, function (filter) { + return { + field: py.eval(filter.attrs.context).group_by, + string: filter.attrs.string, + filter: filter + }; }); }, @@ -119,12 +111,33 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin // Configuration methods // ---------------------------------------------------------------------- set: function (domain, row_groupby, col_groupby) { - if (this.pivot) { - this.pivot.set(domain, row_groupby, col_groupby); - } else { + if (!this.pivot) { this.pivot_options.domain = domain; this.pivot_options.row_groupby = row_groupby; this.pivot_options.col_groupby = col_groupby; + return; + } + var row_gbs = this.create_field_values(row_groupby), + col_gbs = this.create_field_values(col_groupby), + dom_changed = !_.isEqual(this.pivot.domain, domain), + row_gb_changed = !this.equal_groupby(row_gbs, this.pivot.rows.groupby), + col_gb_changed = !this.equal_groupby(col_gbs, this.pivot.cols.groupby), + row_reduced = is_strict_beginning_of(row_gbs, this.pivot.rows.groupby), + col_reduced = is_strict_beginning_of(col_gbs, this.pivot.cols.groupby); + + if (!dom_changed && row_reduced && !col_gb_changed) { + this.pivot.fold_with_depth(this.pivot.rows, row_gbs.length); + this.display_data(); + return; + } + if (!dom_changed && col_reduced && !row_gb_changed) { + this.pivot.fold_with_depth(this.pivot.cols, col_gbs.length); + this.display_data(); + return; + } + + if (dom_changed || row_gb_changed || col_gb_changed) { + this.pivot.set(domain, row_gbs, col_gbs).then(this.proxy('display_data')); } }, @@ -148,20 +161,39 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin this.display_data(); }, - // returns the row groupbys as a list of fields (not the representation used - // internally by pivot table) - get_row_groupby: function () { - return (this.pivot) ? this.pivot.rows.groupby : this.pivot_options.row_groupby; + // compare groupby, ignoring the 'interval' attribute of dates... + // this is necessary to avoid problems with the groupby received by the + // context which does not have the interval attribute. This is ugly + // and need to be changed at some point + equal_groupby: function (groupby1, groupby2) { + if (groupby1.length !== groupby2.length) { return false; } + for (var i = 0; i < groupby1.length; i++) { + if (!this.equal_value(groupby1[i], groupby2[i])) { return false; } + } + return true; }, - get_col_groupby: function () { - return (this.pivot) ? this.pivot.cols.groupby : this.pivot_options.col_groupby; + equal_value: function (val1, val2) { + return ((val1.field === val2.field) && (val1.string === val2.string) && (val1.type === val2.type)); }, - get_domain: function () { - return (this.pivot) ? this.pivot.domain : this.pivot_options.domain; + create_field_value: function (f) { + var important_field = _.findWhere(this.important_fields, {field:f}), + string = important_field ? important_field.string : this.fields[f].string, + result = {field: f, string: string, type: this.fields[f].type }; + + if (important_field) { + result.filter = important_field.filter; + } + return result; }, + create_field_values: function (field_ids) { + var self = this; + return _.map(field_ids, function (f) { return self.create_field_value(f); }); + }, + + // ---------------------------------------------------------------------- // UI code // ---------------------------------------------------------------------- @@ -183,8 +215,14 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin measure_selection: function (event) { event.preventDefault(); event.stopPropagation(); - var measure = event.target.attributes['data-choice'].nodeValue; - this.pivot.toggle_measure(measure); + var measure_field = event.target.attributes['data-choice'].nodeValue; + var measure = { + field: measure_field, + type: this.fields[measure_field].type, + string: this.fields[measure_field].string + }; + + this.pivot.toggle_measure(measure).then(this.proxy('display_data')); this.put_measure_checkmarks(); }, @@ -216,16 +254,13 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin } break; case 'swap_axis': - this.pivot.swap_axis(); + this.swap_axis(); break; case 'expand_all': - this.pivot.expand_all(); + this.pivot.expand_all().then(this.proxy('display_data')); break; case 'update_values': - this.pivot.update_data(); - break; - case 'export_data': - // Export code... To do... + this.pivot.update_data().then(this.proxy('display_data')); break; } }, @@ -249,16 +284,16 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin self = this; if (header.expanded) { - this.pivot.fold(header); + this.fold(header); } else { if (header.path.length < header.root.groupby.length) { - this.pivot.expand(id); + this.expand(id); } else { if (!this.important_fields.length) { return; } var fields = _.map(this.important_fields, function (field) { - return {id: field, value: self.fields[field].string, type:self.fields[field].type}; + return {id: field.field, value: field.string, type:self.fields[field.field].type}; }); this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); $(event.target).after(this.dropdown); @@ -277,12 +312,46 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin event.preventDefault(); if (this.fields[field_id].type === 'date' || this.fields[field_id].type === 'datetime') { interval = event.target.attributes['data-interval'].nodeValue; - this.pivot.expand(id, {field: field_id, interval: interval}); + this.expand(id, {field: field_id, interval: interval}); } else { - this.pivot.expand(id, field_id); + this.expand(id, field_id); } }, + // ---------------------------------------------------------------------- + // Pivot Table integration + // ---------------------------------------------------------------------- + expand: function (header_id, field_id) { + var self = this, + header = this.pivot.get_header(header_id), + update_groupby = !!field_id, + groupby = (update_groupby) ? this.create_field_value(field_id) + : header.root.groupby[header.path.length]; + + this.pivot.expand(header_id, groupby).then(function () { + if (update_groupby && self.graph_view) { + self.graph_view.register_groupby(self.pivot.rows.groupby, self.pivot.cols.groupby); + } + self.display_data(); + }); + + }, + + fold: function (header) { + var update_groupby = this.pivot.fold(header); + + this.display_data(); + if (update_groupby && this.graph_view) { + this.graph_view.register_groupby(this.pivot.rows.groupby, this.pivot.cols.groupby); + } + }, + + swap_axis: function () { + this.pivot.swap_axis(); + this.display_data(); + this.graph_view.register_groupby(this.pivot.rows.groupby, this.pivot.cols.groupby); + }, + // ---------------------------------------------------------------------- // Main display method // ---------------------------------------------------------------------- @@ -290,6 +359,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin this.$('.graph_main_content svg').remove(); this.$('.graph_main_content div').remove(); this.table.empty(); + this.width = this.$el.width(); + this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); if (this.visible_ui) { this.$('.graph_header').css('display', 'block'); @@ -304,8 +375,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin } else { this.$('.graph_main_content').append($('
    ')); this.svg = this.$('.graph_main_content svg')[0]; - this.width = this.$el.width(); - this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); this[this.mode](); } } @@ -642,4 +711,16 @@ openerp.web_graph.Graph = openerp.web.Widget.extend(openerp.EventDispatcherMixin }, }); + +// Utility function: returns true if the beginning of array2 is array1 and +// if array1 is not array2 +function is_strict_beginning_of (array1, array2) { + if (array1.length >= array2.length) { return false; } + var result = true; + for (var i = 0; i < array1.length; i++) { + if (!_.isEqual(array1[i], array2[i])) { return false;} + } + return result; +} + })(); diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index d54161f8ba7..74197f3a984 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -4,10 +4,8 @@ (function () { 'use strict'; -// Pivot Table emits the events 'groupby_changed', 'groupby_swapped' and 'redraw_required' when necessary. -// PivotTable is initialized by default 'inactive', and require a call to activate() -// after init to load initial data and start triggering events. -openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherMixin, { +// PivotTable requires a call to update_data after initialization +openerp.web_graph.PivotTable = openerp.web.Class.extend({ init: function (model, domain, fields, options) { openerp.EventDispatcherMixin.init.call(this); @@ -17,11 +15,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM this.model = model; this.fields = fields; this.fields.__count = {type: 'integer', string:'Quantity'}; - this.measures = [{field:'__count', type: 'integer', string:'Quantity'}]; - this.active = false; - this.rows = { groupby: this.create_field_values(options.row_groupby || []), headers: null }; - this.cols = { groupby: this.create_field_values(options.col_groupby || []), headers: null }; - if (options.measures) { this.set_measures(options.measures); } + this.measures = options.measures || []; + this.rows = { groupby: options.row_groupby, headers: null }; + this.cols = { groupby: options.col_groupby, headers: null }; }, // ---------------------------------------------------------------------- @@ -31,36 +27,13 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // this.rows.groupby, this.cols.groupby : list of groupbys used for describing rows (...), // a groupby is also {field:_, string:_, type:_} but it also has a interval // attribute if its type is date/datetime. - // this.active: If PivotTable is active then it triggers events and updates - // its values when necessary - activate: function() { - this.active = true; - this.update_data(); - }, - set_measures: function (measures) { - var self = this; - if (!_.isEqual(measures, this.measures)) { - this.measures = []; - _.each(measures, function (m) { self._add_measure(m); }); - if (this.active) { this.update_data(); } - } - }, - - _add_measure: function (measure) { - if (measure.field && measure.string && measure.type) { - this.measures.push(measure); - } else { - this.measures.push({ - field: measure, - string: this.fields[measure].string, - type: this.fields[measure].type, - }); - } + this.measures = measures; + return this.update_data(); }, - toggle_measure: function (field_id) { - var current_measure = _.findWhere(this.measures, {field:field_id}); + toggle_measure: function (measure) { + var current_measure = _.findWhere(this.measures, measure); if (current_measure) { // remove current_measure var index = this.measures.indexOf(current_measure); this.measures = _.without(this.measures, current_measure); @@ -71,92 +44,27 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM cell.values.splice(index, 1); }); } - if (this.active) { this.trigger('redraw_required'); } + return $.Deferred().resolve(); } else { // add a new measure - this.measures.push({ - field: field_id, - type: this.fields[field_id].type, - string: this.fields[field_id].string - }); - if (this.active) { this.update_data(); } + this.measures.push(measure); + return this.update_data(); } }, - // return true if an update is triggered, false otherwise set: function (domain, row_groupby, col_groupby) { - var row_gbs = this.create_field_values(row_groupby), - col_gbs = this.create_field_values(col_groupby), - dom_changed = !_.isEqual(this.domain, domain), - row_subset = is_strict_beginning_of(row_gbs, this.rows.groupby), - col_subset = is_strict_beginning_of(col_gbs, this.cols.groupby), - row_gb_changed = !this.equal_groupby(row_gbs, this.rows.groupby), - col_gb_changed = !this.equal_groupby(col_gbs, this.cols.groupby); - - if (dom_changed) { - this.domain = domain; - } - - if (row_subset && !dom_changed && !col_gb_changed) { - this.fold_with_depth(this.rows, row_gbs.length); - if (this.active) { this.trigger('redraw_required'); } - return; - } - - if (col_subset && !dom_changed && !row_gb_changed) { - this.fold_with_depth(this.cols, col_gbs.length); - if (this.active) { this.trigger('redraw_required'); } - return; - } - - if (row_gb_changed || col_gb_changed) { - this.cols.groupby = col_gbs; - this.rows.groupby = row_gbs; - if (row_gb_changed) {this.rows.headers = null; } - if (col_gb_changed) {this.cols.headers = null; } - if (this.active) { this.trigger('groupby_changed'); } - } - if (this.active && (row_gb_changed || col_gb_changed || dom_changed)) { - this.update_data(); - } - }, - - // compare groupby, ignoring the 'interval' attribute of dates... - // this is necessary to avoid problems with the groupby received by the - // context which do not have the interval attribute. This is ugly - // and need to be changed at some point - equal_groupby: function (groupby1, groupby2) { - if (groupby1.length !== groupby2.length) { return false; } - for (var i = 0; i < groupby1.length; i++) { - if (!this.equal_value(groupby1[i], groupby2[i])) { return false; } - } - return true; - }, - - equal_value: function (val1, val2) { - return ((val1.field === val2.field) && (val1.string === val2.string) && (val1.type === val2.type)); - }, + var row_gb_changed = !_.isEqual(row_groupby, this.rows.groupby), + col_gb_changed = !_.isEqual(col_groupby, this.cols.groupby); + + this.domain = domain; + this.rows.groupby = row_groupby; + this.cols.groupby = col_groupby; - create_field_value: function (f) { - if (f.field && f.interval) { - return { field:f.field, - string: this.fields[f.field].string, - type:this.fields[f.field].type, - interval: f.interval }; - } - return (f.field && f.string && f.type) ? f : { field: f, - string: this.fields[f].string, - type: this.fields[f].type }; - }, + if (row_gb_changed) { this.rows.headers = null; } + if (col_gb_changed) { this.cols.headers = null; } - create_field_values: function (field_ids) { - var self = this; - return _.map(field_ids, function (f) { return self.create_field_value(f); }); + return this.update_data(); }, - _add_groupby: function(groupby_list, groupby) { - groupby_list.push(this.create_field_value(groupby)); - }, - // ---------------------------------------------------------------------- // Cells manipulation methods // ---------------------------------------------------------------------- @@ -191,21 +99,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // expanded:_ (boolean, true if it has been expanded) // } is_row: function (id) { - return !!_.find(this.rows.headers, function (header) { - return header.id === id; - }); - }, + return !!_.findWhere(this.rows.headers, {id:id}); + }, is_col: function (id) { - return !!_.find(this.cols.headers, function (header) { - return header.id === id; - }); + return !!_.findWhere(this.cols.headers, {id:id}); }, get_header: function (id) { - return _.find(this.rows.headers.concat(this.cols.headers), function (header) { - return header.id === id; - }); + return _.findWhere(this.rows.headers.concat(this.cols.headers), {id:id}); }, _get_headers_with_depth: function (headers, depth) { @@ -221,21 +123,17 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // return all rows with a path length of 'depth' get_rows_with_depth: function (depth) { - return this._get_headers_with_depth(this.rows.headers), depth; + return this._get_headers_with_depth(this.rows.headers, depth); }, // return all non expanded rows get_rows_leaves: function () { - return _.filter(this.rows.headers, function (header) { - return !header.expanded; - }); + return _.where(this.rows.headers, {expanded:false}); }, // return all non expanded cols get_cols_leaves: function () { - return _.filter(this.cols.headers, function (header) { - return !header.expanded; - }); + return _.where(this.cols.headers, {expanded:false}); }, get_ancestors: function (header) { @@ -267,7 +165,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM // ---------------------------------------------------------------------- // Table manipulation methods : fold/expand/swap // ---------------------------------------------------------------------- - fold: function (header, silent) { + // return true if the folding changed the groupbys, false if not + fold: function (header) { var ancestors = this.get_ancestors(header), removed_ids = _.pluck(ancestors, 'id'); @@ -279,12 +178,12 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM return (_.contains(removed_ids, cell.x) || _.contains(removed_ids, cell.y)); }); - var new_groupby_length = _.max(_.map(header.root.headers, function(g) {return g.path.length;})); + var new_groupby_length = _.max(_.pluck(_.pluck(header.root.headers, 'path'), 'length')); if (new_groupby_length < header.root.groupby.length) { header.root.groupby.splice(new_groupby_length); - if (!silent) { this.trigger('groupby_changed'); } + return true; } - if (!silent) { this.trigger('redraw_required'); } + return false; }, fold_with_depth: function (root, depth) { @@ -294,6 +193,12 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }); }, + expand_all: function () { + this.rows.headers = null; + this.cols.headers = null; + return this.update_data(); + }, + expand: function (header_id, groupby) { var self = this, header = this.get_header(header_id), @@ -301,10 +206,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM fields = otherRoot.groupby.concat(this.measures); if (header.path.length === header.root.groupby.length) { - self._add_groupby(header.root.groupby, groupby); - this.trigger('groupby_changed'); + header.root.groupby.push(groupby); } - groupby = [header.root.groupby[header.path.length]].concat(otherRoot.groupby); + groupby = [groupby].concat(otherRoot.groupby); return this.get_groups(groupby, fields, header.domain) .then(function (groups) { @@ -332,7 +236,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }); }); header.expanded = true; - self.trigger('redraw_required'); }); }, @@ -352,8 +255,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM var temp = this.rows; this.rows = this.cols; this.cols = temp; - this.trigger('groupby_swapped'); - this.trigger('redraw_required'); }, // ---------------------------------------------------------------------- @@ -374,7 +275,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM } else { self.no_data = true; } - self.trigger('redraw_required'); }); }, @@ -413,12 +313,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM root.headers = updated_headers; }, - expand_all: function () { - this.rows.headers = null; - this.cols.headers = null; - this.update_data(); - }, - // ---------------------------------------------------------------------- // Data loading methods // ---------------------------------------------------------------------- @@ -436,9 +330,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM visible_fields = rows.concat(cols, self.measures); if (this.measures.length === 0) { - var result = $.Deferred(); - result.resolve(); - return result; + return $.Deferred.resolve().promise(); } var groupbys = _.map(_.range(cols.length + 1), function (i) { @@ -593,17 +485,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend(openerp.EventDispatcherM }); -// Utility function: returns true if the beginning of array2 is array1 and -// if array1 is not array2 -function is_strict_beginning_of (array1, array2) { - if (array1.length >= array2.length) { return false; } - var result = true; - for (var i = 0; i < array1.length; i++) { - if (!_.isEqual(array1[i], array2[i])) { return false;} - } - return result; -} - })(); -- cgit v1.2.3 From d1e3504b8051a91ea85f5add314277caef6592d9 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 22 Jan 2014 08:56:52 +0100 Subject: [IMP] two small tweaks to improve the code quality in addon web_graph bzr revid: ged@openerp.com-20140122075652-wz2uk3tv31ady4ej --- addons/web_graph/static/src/js/graph_widget.js | 1 - addons/web_graph/static/src/js/pivot_table.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 28a96ca7907..0b78468b0b4 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -43,7 +43,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return this.model.call('fields_get', []).then(function (f) { self.fields = f; - self.fields.__count = {string: 'Quantity', type: 'integer'}; self.measure_list = self.get_measures(); self.add_measures_to_options(); self.pivot_options.row_groupby = self.create_field_values(self.pivot_options.row_groupby || []); diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 74197f3a984..5a2e93ecd7c 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -423,7 +423,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ if (group.attributes.grouped_on && this.fields[group.attributes.grouped_on].type === 'selection') { var selection = this.fields[group.attributes.grouped_on].selection, - value_lookup = _.find(selection, function (val) { return val[0] === value; }); + value_lookup = _.where(selection, {0:value}); group.attributes.value = value_lookup ? value_lookup[1] : 'undefined'; } else if (value === false) { group.attributes.value = 'undefined'; -- cgit v1.2.3 From a3bb723379d5b9c9302658925c076ce4a341d76c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 22 Jan 2014 14:34:52 +0100 Subject: [IMP] changes the backend code of graph view to use the new functionality of read_group (use 'field_name:interval' in readgroup instead of context (addon web_graph) bzr revid: ged@openerp.com-20140122133452-wy3hrsrokhnwc3ru --- addons/web_graph/static/src/js/graph_view.js | 13 +++-- addons/web_graph/static/src/js/graph_widget.js | 13 ++++- addons/web_graph/static/src/js/pivot_table.js | 78 +++++++++++--------------- 3 files changed, 51 insertions(+), 53 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 0c0e80c566f..a452efb78e6 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -80,8 +80,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); this.ViewManager.on('switch_mode', this, function (e) { - var domain = self.graph_widget.get_domain(), - col_gb = self.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'), + var col_gb = self.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'), row_gb = self.get_groupbys_from_searchview('GroupBy', 'group_by'); if (e === 'graph') this.graph_widget.set(domain, row_gb, col_gb); @@ -95,7 +94,13 @@ instance.web_graph.GraphView = instance.web.View.extend({ get_groupbys_from_searchview: function (cat_name, cat_field) { var facet = this.search_view.query.findWhere({category:cat_name}), groupby_list = facet ? facet.values.models : []; - return _.map(groupby_list, function (g) { return g.attributes.value.attrs.context[cat_field]; }); + return _.map(groupby_list, function (g) { + if (cat_name === 'GroupBy') { + return py.eval(g.attributes.value.attrs.context).group_by; + } else { + return g.attributes.value.attrs.context[cat_field]; + } + }); }, do_show: function () { @@ -158,7 +163,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ make_groupby_values: function (groupbys, category) { return _.map(groupbys, function (groupby) { var context = {}; - context[category] = groupby.field; + context[category] = groupby.interval ? groupby.field + ':' + groupby.interval : groupby.field; var value = (category === 'group_by') ? groupby.filter : {attrs:{domain: [], context: context}}; return { label: groupby.string, diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 0b78468b0b4..7b4d96ce304 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -177,13 +177,20 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }, create_field_value: function (f) { - var important_field = _.findWhere(this.important_fields, {field:f}), - string = important_field ? important_field.string : this.fields[f].string, - result = {field: f, string: string, type: this.fields[f].type }; + var field = f.field || ((_.contains(f, ':')) ? f.split(':')[0] : f), + important_field = _.findWhere(this.important_fields, {field:field}), + string = important_field ? important_field.string : this.fields[field].string, + result = {field: field, string: string, type: this.fields[field].type }; if (important_field) { result.filter = important_field.filter; } + if (f.interval) { + result.interval = f.interval; + } + if (_.contains(f, ':')) { + result.interval = f.split(':')[1]; + } return result; }, diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 5a2e93ecd7c..17a70d22c26 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -221,6 +221,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ // make cells _.each(self.get_ancestors_and_self(group), function (data) { var values = _.map(self.measures, function (m) { + console.log('m.field', m.field); return data.attributes.aggregates[m.field]; }); var other = _.find(otherRoot.headers, function (h) { @@ -230,6 +231,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return _.isEqual(_.rest(data.path), h.path); } }); + console.log('dbg', child.id, other.id, values); + if (_.isEqual(values, [46125])) debugger; if (other) { self.add_cell(child.id, other.id, values); } @@ -378,37 +381,14 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ _query_db: function (groupby, fields, domain, path) { var self = this, field_ids = _.without(_.pluck(fields, 'field'), '__count'), - context = {}; - - if (groupby.interval) { - context.datetime_format = {}; - var display_format; - switch (groupby.interval) { - case 'day': - display_format = 'dd MMMM YYYY'; - break; - case 'week': - display_format = 'w YYYY'; - break; - case 'month': - display_format = 'MMMM YYYY'; - break; - case 'quarter': - display_format = 'QQQ YYYY'; - break; - case 'year': - display_format = 'YYYY'; - break; - } - context.datetime_format[groupby.field] = { - interval: groupby.interval, - display_format: display_format - }; - } + formatted_groupby = (groupby.interval) ? groupby.field + ':' + groupby.interval : groupby.field; + + fields = _.map(field_ids, function (field) { + return (_.contains(field, ':')) ? field.split(':')[0] : field; + }); return this.model.query(field_ids) .filter(domain) - .context(context) - .group_by(groupby.field) + .group_by(formatted_groupby) .then(function (results) { var groups = _.filter(results, function (group) { return group.attributes.length > 0; @@ -417,25 +397,32 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); }, + // if field is a fieldname, returns field, if field is field_id:interval, retuns field_id + raw_field: function (field) { + return (_.contains(field, ':')) ? field.split(':')[0] : field; + }, + // add the path to the group and sanitize the value... - format_group: function (group, current_path) { - var value = group.attributes.value; - - if (group.attributes.grouped_on && this.fields[group.attributes.grouped_on].type === 'selection') { - var selection = this.fields[group.attributes.grouped_on].selection, - value_lookup = _.where(selection, {0:value}); - group.attributes.value = value_lookup ? value_lookup[1] : 'undefined'; - } else if (value === false) { - group.attributes.value = 'undefined'; - } else if (value instanceof Array) { - group.attributes.value = value[1]; - } - - group.path = value ? (current_path || []).concat(group.attributes.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 (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[1] : 'undefined'; + } else if (value === false) { + group.attributes.value = '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; - }, + return group; + }, format_data: function (total, col_data, row_data, cell_data) { var self = this, @@ -476,7 +463,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ var row = _.find(rows, function (header) { return _.isEqual(header.path, path.slice(index)); }); var 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 39e0f4736f447fe5e4160e670a74e0b79a5ad266 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 22 Jan 2014 17:07:07 +0100 Subject: [REF] refactoring: removes the 'interval' attributes in groupbys and improves searchbar integration (addon web_graph) bzr revid: ged@openerp.com-20140122160707-39el7frwfj4pwd4d --- addons/web_graph/static/src/js/graph_view.js | 32 +++++++++----- addons/web_graph/static/src/js/graph_widget.js | 61 +++++++++----------------- addons/web_graph/static/src/js/pivot_table.js | 15 +++---- 3 files changed, 46 insertions(+), 62 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index a452efb78e6..6d121bdc6c5 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -20,10 +20,16 @@ instance.web_graph.GraphView = instance.web.View.extend({ // Init stuff // ---------------------------------------------------------------------- init: function(parent, dataset, view_id, options) { + var self = this; this._super(parent, dataset, view_id, options); this.dataset = dataset; this.model = new instance.web.Model(dataset.model, {group_by_no_leaf: true}); this.search_view = parent.searchview; + this.col_search_field = { + get_context: function() { return { col_group_by: self.graph_widget.get_col_groupbys()};}, + get_domain: function () {}, + get_groupby: function () {}, + }; }, view_loading: function (fields_view_get) { @@ -68,7 +74,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { var self = this, - col_group_by = this.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); + col_group_by = context.col_group_by || this.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); if (!this.graph_widget) { if (group_by.length) { @@ -95,10 +101,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ var facet = this.search_view.query.findWhere({category:cat_name}), groupby_list = facet ? facet.values.models : []; return _.map(groupby_list, function (g) { - if (cat_name === 'GroupBy') { - return py.eval(g.attributes.value.attrs.context).group_by; + var context = g.attributes.value.attrs.context; + if (_.isString(context)) { + return py.eval(context).group_by; } else { - return g.attributes.value.attrs.context[cat_field]; + return context[cat_field]; } }); }, @@ -156,15 +163,21 @@ instance.web_graph.GraphView = instance.web.View.extend({ category:'ColGroupBy', values: this.make_groupby_values(groupbys, 'col_group_by'), icon:'f', - field: this.search_field + field: this.col_search_field }; }, make_groupby_values: function (groupbys, category) { return _.map(groupbys, function (groupby) { var context = {}; - context[category] = groupby.interval ? groupby.field + ':' + groupby.interval : groupby.field; - var value = (category === 'group_by') ? groupby.filter : {attrs:{domain: [], context: context}}; + context[category] = groupby.field; + var value; + if (category === 'group_by' && groupby.type !== 'date' && groupby.type !== 'datetime') { + value = groupby.filter; + } else { + value = {attrs: {domain: [], context: context}}; + } + // var value = (category === 'group_by') ? groupby.filter : {attrs:{domain: [], context: context}}; return { label: groupby.string, value: value @@ -172,11 +185,6 @@ instance.web_graph.GraphView = instance.web.View.extend({ }); }, - search_field: { - get_context: function() {}, - get_domain: function () {}, - get_groupby: function () {}, - }, }); }; diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 7b4d96ce304..346e8c3b808 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -119,8 +119,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ var row_gbs = this.create_field_values(row_groupby), col_gbs = this.create_field_values(col_groupby), dom_changed = !_.isEqual(this.pivot.domain, domain), - row_gb_changed = !this.equal_groupby(row_gbs, this.pivot.rows.groupby), - col_gb_changed = !this.equal_groupby(col_gbs, this.pivot.cols.groupby), + row_gb_changed = !_.isEqual(row_gbs, this.pivot.rows.groupby), + col_gb_changed = !_.isEqual(col_gbs, this.pivot.cols.groupby), row_reduced = is_strict_beginning_of(row_gbs, this.pivot.rows.groupby), col_reduced = is_strict_beginning_of(col_gbs, this.pivot.cols.groupby); @@ -160,46 +160,28 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.display_data(); }, - // compare groupby, ignoring the 'interval' attribute of dates... - // this is necessary to avoid problems with the groupby received by the - // context which does not have the interval attribute. This is ugly - // and need to be changed at some point - equal_groupby: function (groupby1, groupby2) { - if (groupby1.length !== groupby2.length) { return false; } - for (var i = 0; i < groupby1.length; i++) { - if (!this.equal_value(groupby1[i], groupby2[i])) { return false; } - } - return true; - }, - - equal_value: function (val1, val2) { - return ((val1.field === val2.field) && (val1.string === val2.string) && (val1.type === val2.type)); - }, - create_field_value: function (f) { - var field = f.field || ((_.contains(f, ':')) ? f.split(':')[0] : f), - important_field = _.findWhere(this.important_fields, {field:field}), - string = important_field ? important_field.string : this.fields[field].string, - result = {field: field, string: string, type: this.fields[field].type }; + var field = (_.contains(f, ':')) ? f.split(':')[0] : f, + groupby_field = _.findWhere(this.important_fields, {field:field}), + string = groupby_field ? groupby_field.string : this.fields[field].string, + result = {field: f, string: string, type: this.fields[field].type }; - if (important_field) { - result.filter = important_field.filter; - } - if (f.interval) { - result.interval = f.interval; - } - if (_.contains(f, ':')) { - result.interval = f.split(':')[1]; + if (groupby_field) { + result.filter = groupby_field.filter; } + return result; }, create_field_values: function (field_ids) { - var self = this; - return _.map(field_ids, function (f) { return self.create_field_value(f); }); + return _.map(field_ids, this.proxy('create_field_value')); }, + get_col_groupbys: function () { + return _.pluck(this.pivot.cols.groupby, 'field'); + }, + // ---------------------------------------------------------------------- // UI code // ---------------------------------------------------------------------- @@ -314,25 +296,24 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ field_selection: function (event) { var id = event.target.attributes['data-id'].nodeValue, field_id = event.target.attributes['data-field-id'].nodeValue, - interval; + interval, + groupby = this.create_field_value(field_id); event.preventDefault(); if (this.fields[field_id].type === 'date' || this.fields[field_id].type === 'datetime') { interval = event.target.attributes['data-interval'].nodeValue; - this.expand(id, {field: field_id, interval: interval}); - } else { - this.expand(id, field_id); + groupby.field = groupby.field + ':' + interval; } + this.expand(id, groupby); }, // ---------------------------------------------------------------------- // Pivot Table integration // ---------------------------------------------------------------------- - expand: function (header_id, field_id) { + expand: function (header_id, groupby) { var self = this, header = this.pivot.get_header(header_id), - update_groupby = !!field_id, - groupby = (update_groupby) ? this.create_field_value(field_id) - : header.root.groupby[header.path.length]; + update_groupby = !!groupby, + groupby = groupby || header.root.groupby[header.path.length]; this.pivot.expand(header_id, groupby).then(function () { if (update_groupby && self.graph_view) { diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 17a70d22c26..38662b01167 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -25,8 +25,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ // ---------------------------------------------------------------------- // this.measures: list of measure [measure], measure = {field: _, string: _, type: _} // this.rows.groupby, this.cols.groupby : list of groupbys used for describing rows (...), - // a groupby is also {field:_, string:_, type:_} but it also has a interval - // attribute if its type is date/datetime. + // a groupby is also {field:_, string:_, type:_} + // If its type is date/datetime, field can have the corresponding interval in its description, + // for example 'create_date:week'. set_measures: function (measures) { this.measures = measures; return this.update_data(); @@ -221,7 +222,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ // make cells _.each(self.get_ancestors_and_self(group), function (data) { var values = _.map(self.measures, function (m) { - console.log('m.field', m.field); return data.attributes.aggregates[m.field]; }); var other = _.find(otherRoot.headers, function (h) { @@ -231,8 +231,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return _.isEqual(_.rest(data.path), h.path); } }); - console.log('dbg', child.id, other.id, values); - if (_.isEqual(values, [46125])) debugger; if (other) { self.add_cell(child.id, other.id, values); } @@ -381,14 +379,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ _query_db: function (groupby, fields, domain, path) { var self = this, field_ids = _.without(_.pluck(fields, 'field'), '__count'), - formatted_groupby = (groupby.interval) ? groupby.field + ':' + groupby.interval : groupby.field; + fields = _.map(field_ids, function(f) { return self.raw_field(f); }); - fields = _.map(field_ids, function (field) { - return (_.contains(field, ':')) ? field.split(':')[0] : field; - }); return this.model.query(field_ids) .filter(domain) - .group_by(formatted_groupby) + .group_by(groupby.field) .then(function (results) { var groups = _.filter(results, function (group) { return group.attributes.length > 0; -- cgit v1.2.3 From b83cfc2c2b900f33d08ba068ab7b4d468ddb3017 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 23 Jan 2014 12:34:50 +0100 Subject: [FIX] fixes a crash happening when in dashboards, the graph view was trying to access undefined attributes (addon web_graph) bzr revid: ged@openerp.com-20140123113450-ec4fubf1urkdutw7 --- addons/web_graph/static/src/js/graph_view.js | 2 +- addons/web_graph/static/src/js/graph_widget.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 6d121bdc6c5..39634ff103a 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -173,7 +173,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ context[category] = groupby.field; var value; if (category === 'group_by' && groupby.type !== 'date' && groupby.type !== 'datetime') { - value = groupby.filter; + value = groupby.filter || {attrs: {domain: [], context: context}}; } else { value = {attrs: {domain: [], context: context}}; } diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 346e8c3b808..64b163e883d 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -43,6 +43,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return this.model.call('fields_get', []).then(function (f) { self.fields = f; + self.fields.__count = {field:'__count', type: 'integer', string:'Quantity'}; self.measure_list = self.get_measures(); self.add_measures_to_options(); self.pivot_options.row_groupby = self.create_field_values(self.pivot_options.row_groupby || []); @@ -87,7 +88,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // Extracts the integer/float fields which are not 'id' get_measures: function() { - var measures = [{field:'__count', type: 'integer', string:'Quantity'}]; + var measures = []; _.each(this.fields, function (f, id) { if (((f.type === 'integer') || (f.type === 'float')) && (id !== 'id')) { measures.push({field:id, type: f.type, string: f.string}); -- cgit v1.2.3 From 59b75a0176143da2756e8658ea853a64b23e7e84 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 23 Jan 2014 15:23:18 +0100 Subject: [FIX] fixes a problem with fields selection : the string was not correctly displayed (addon web_graph) bzr revid: ged@openerp.com-20140123142318-kbk6f2rsug3uxi0j --- addons/web_graph/static/src/js/pivot_table.js | 49 +++++++++++++-------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 38662b01167..f47fcabc92e 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -211,33 +211,32 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ } 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.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); + } }); - header.expanded = true; }); + header.expanded = true; + }); }, make_header: function (group, parent) { @@ -406,7 +405,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ 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[1] : 'undefined'; + group.attributes.value = value_lookup ? value_lookup[0][1] : 'undefined'; } else if (value === false) { group.attributes.value = 'undefined'; } else if (value instanceof Array) { -- cgit v1.2.3 From 29d08d9a6bc31b5ddaccaca78c97e9f093725069 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 24 Jan 2014 09:42:22 +0100 Subject: [IMP] graph_view now properly honors the 'interval' attribute of field names in the xml description (addon web_graph) bzr revid: ged@openerp.com-20140124084222-dq1gpg1tg8rinozx --- addons/web_graph/static/src/js/graph_view.js | 14 +++++++++----- addons/web_graph/static/src/js/graph_widget.js | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 39634ff103a..1122089f060 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -47,23 +47,27 @@ instance.web_graph.GraphView = instance.web.View.extend({ }; _.each(arch.children, function (field) { + var field_name = field.attrs.name; + if (_.has(field.attrs, 'interval')) { + field_name = field.attrs.name + ':' + field.attrs.interval; + } if (_.has(field.attrs, 'type')) { switch (field.attrs.type) { case 'row': - self.widget_config.row_groupby.push(field.attrs.name); + self.widget_config.row_groupby.push(field_name); break; case 'col': - self.widget_config.col_groupby.push(field.attrs.name); + self.widget_config.col_groupby.push(field_name); break; case 'measure': - self.widget_config.measures.push(field.attrs.name); + self.widget_config.measures.push(field_name); break; } } else { // old style, kept for backward compatibility if ('operator' in field.attrs) { - self.widget_config.measures.push(field.attrs.name); + self.widget_config.measures.push(field_name); } else { - self.widget_config.row_groupby.push(field.attrs.name); + self.widget_config.row_groupby.push(field_name); } } }); diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 64b163e883d..d9fd73924ee 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -281,6 +281,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ if (!this.important_fields.length) { return; } + var fields = _.map(this.important_fields, function (field) { return {id: field.field, value: field.string, type:self.fields[field.field].type}; }); -- cgit v1.2.3 From 524324ae4e4ec21b58d2d3a89340d1d36173b260 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 24 Jan 2014 13:59:44 +0100 Subject: [FIX] fixes two small issues concerning the groupby dates in graph view (addon web_graph) bzr revid: ged@openerp.com-20140124125944-wxl4zdya37pxdnqv --- addons/web_graph/static/src/js/graph_widget.js | 24 ++++++++++++++---------- addons/web_graph/static/src/js/pivot_table.js | 6 +++--- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index d9fd73924ee..6d8dc185243 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -23,7 +23,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.bar_ui = options.bar_ui || 'group'; this.graph_view = options.graph_view || null; this.pivot_options = options; - this.important_fields = this.get_search_fields(); }, start: function() { @@ -44,6 +43,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return this.model.call('fields_get', []).then(function (f) { self.fields = f; self.fields.__count = {field:'__count', type: 'integer', string:'Quantity'}; + self.important_fields = self.get_search_fields(); self.measure_list = self.get_measures(); self.add_measures_to_options(); self.pivot_options.row_groupby = self.create_field_values(self.pivot_options.row_groupby || []); @@ -69,6 +69,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // this method gets the fields that appear in the search view, under the // 'Groupby' heading get_search_fields: function () { + var self = this; var search_view = openerp.client.action_manager.inner_widget.searchview; var groupbygroups = _(search_view.inputs).select(function (g) { @@ -77,13 +78,15 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ var filters = [].concat.apply([], _.pluck(groupbygroups, 'filters')); - return _.map(filters, function (filter) { - return { - field: py.eval(filter.attrs.context).group_by, - string: filter.attrs.string, - filter: filter - }; - }); + return _.uniq(_.map(filters, function (filter) { + console.log(filter); + var field = py.eval(filter.attrs.context).group_by, + raw_field = field.split(':')[0], + string = (field === raw_field) ? filter.attrs.string : self.fields[raw_field].string, + filter = (field === raw_field) ? filter : undefined; + + return { field: raw_field, string: string, filter: filter }; + }), false, function (filter) {return filter.field;}); }, // Extracts the integer/float fields which are not 'id' @@ -281,10 +284,11 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ if (!this.important_fields.length) { return; } - + var fields = _.map(this.important_fields, function (field) { - return {id: field.field, value: field.string, type:self.fields[field.field].type}; + return {id: field.field, value: field.string, type:self.fields[field.field.split(':')[0]].type}; }); + debugger; this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); $(event.target).after(this.dropdown); this.dropdown.css({position:'absolute', diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index f47fcabc92e..d5c01765504 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -402,12 +402,12 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ value = attrs.value, grouped_on = attrs.grouped_on ? this.raw_field(attrs.grouped_on) : false; - if (grouped_on && this.fields[grouped_on].type === 'selection') { + if (value === false) { + group.attributes.value = '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] : 'undefined'; - } else if (value === false) { - group.attributes.value = 'undefined'; } else if (value instanceof Array) { group.attributes.value = value[1]; } -- cgit v1.2.3 From c43147628b6cfe9eb62b0da797cdff3f2c53d443 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 24 Jan 2014 16:16:35 +0100 Subject: [REF] lots of small tweaks to improve the code, and some small fixes, after xmo's code review (addon web_graph) bzr revid: ged@openerp.com-20140124151635-14l3dchnrmujo5ni --- addons/web_graph/static/src/js/graph_view.js | 5 +- addons/web_graph/static/src/js/graph_widget.js | 151 +++++++++++-------------- addons/web_graph/static/src/js/pivot_table.js | 36 +++--- 3 files changed, 83 insertions(+), 109 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 1122089f060..e1a50d4ff6d 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -39,7 +39,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.widget_config = { title: arch.attrs.string, stacked : (arch.attrs.stacked === 'True'), - mode: (arch.attrs.type) ? arch.attrs.type : 'bar', + mode: arch.attrs.type || 'bar', measures: [], row_groupby: [], col_groupby: [], @@ -181,15 +181,12 @@ instance.web_graph.GraphView = instance.web.View.extend({ } else { value = {attrs: {domain: [], context: context}}; } - // var value = (category === 'group_by') ? groupby.filter : {attrs:{domain: [], context: context}}; return { label: groupby.string, value: value }; }); }, - - }); }; diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 6d8dc185243..0ada5b1a3c2 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -27,14 +27,11 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ start: function() { var self = this; - this.table = $('
    '); + this.table = $(''); this.$('.graph_main_content').append(this.table); - var index = 0; - if (this.mode === 'bar') { index = 1; } - if (this.mode === 'line') { index = 2; } - if (this.mode === 'chart') { index = 3; } - this.$('.graph_mode_selection label').eq(index).addClass('active'); + var indexes = {'pivot': 0, 'bar': 1, 'line': 2, 'chart': 3}; + this.$('.graph_mode_selection label').eq(indexes[this.mode]).addClass('active'); if (this.mode !== 'pivot') { this.$('.graph_heatmap label').addClass('disabled'); @@ -69,21 +66,27 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // this method gets the fields that appear in the search view, under the // 'Groupby' heading get_search_fields: function () { - var self = this; - var search_view = openerp.client.action_manager.inner_widget.searchview; + var self = this, + parent = this.getParent(); + + while (!(parent instanceof openerp.web.ViewManager)) { + parent = parent.getParent(); + } + + var search_view = parent.searchview; var groupbygroups = _(search_view.inputs).select(function (g) { return g instanceof openerp.web.search.GroupbyGroup; }); - var filters = [].concat.apply([], _.pluck(groupbygroups, 'filters')); + var filters = _.flatten(_.pluck(groupbygroups, 'filters'), true); return _.uniq(_.map(filters, function (filter) { - console.log(filter); var field = py.eval(filter.attrs.context).group_by, raw_field = field.split(':')[0], - string = (field === raw_field) ? filter.attrs.string : self.fields[raw_field].string, - filter = (field === raw_field) ? filter : undefined; + string = (field === raw_field) ? filter.attrs.string : self.fields[raw_field].string; + + filter = (field === raw_field) ? filter : undefined; return { field: raw_field, string: string, filter: filter }; }), false, function (filter) {return filter.field;}); @@ -91,23 +94,20 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // Extracts the integer/float fields which are not 'id' get_measures: function() { - var measures = []; - _.each(this.fields, function (f, id) { + return _.compact(_.map(this.fields, function (f, id) { if (((f.type === 'integer') || (f.type === 'float')) && (id !== 'id')) { - measures.push({field:id, type: f.type, string: f.string}); + return {field:id, type: f.type, string: f.string}; } - }); - return measures; + })); }, add_measures_to_options: function() { - var measure_selection = this.$('.graph_measure_selection'); - _.each(this.measure_list, function (measure) { - var choice = $('').attr('data-choice', measure.field) + this.$('.graph_measure_selection').append( + _.map(this.measure_list, function (measure) { + return $('
  • ').append($('').attr('data-choice', measure.field) .attr('href', '#') - .append(measure.string); - measure_selection.append($('
  • ').append(choice)); - }); + .text(measure.string)); + })); }, // ---------------------------------------------------------------------- @@ -200,14 +200,14 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ mode_selection: function (event) { event.preventDefault(); - var mode = event.currentTarget.attributes['data-mode'].nodeValue; + var mode = event.currentTarget.getAttribute('data-mode'); this.set_mode(mode); }, measure_selection: function (event) { event.preventDefault(); event.stopPropagation(); - var measure_field = event.target.attributes['data-choice'].nodeValue; + var measure_field = event.target.getAttribute('data-choice'); var measure = { field: measure_field, type: this.fields[measure_field].type, @@ -232,7 +232,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ option_selection: function (event) { event.preventDefault(); - switch (event.currentTarget.attributes['data-choice'].nodeValue) { + switch (event.currentTarget.getAttribute('data-choice')) { case 'bar_grouped': this.bar_ui = 'group'; if (this.mode === 'bar') { @@ -259,7 +259,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ heatmap_mode_selection: function (event) { event.preventDefault(); - var mode = event.currentTarget.attributes['data-mode'].nodeValue; + var mode = event.currentTarget.getAttribute('data-mode'); if (this.heatmap_mode === mode) { event.stopPropagation(); this.set_heatmap_mode('none'); @@ -271,7 +271,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ header_cell_clicked: function (event) { event.preventDefault(); event.stopPropagation(); - var id = event.target.attributes['data-id'].nodeValue, + var id = event.target.getAttribute('data-id'), header = this.pivot.get_header(id), self = this; @@ -288,7 +288,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ var fields = _.map(this.important_fields, function (field) { return {id: field.field, value: field.string, type:self.fields[field.field.split(':')[0]].type}; }); - debugger; this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); $(event.target).after(this.dropdown); this.dropdown.css({position:'absolute', @@ -300,13 +299,13 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }, field_selection: function (event) { - var id = event.target.attributes['data-id'].nodeValue, - field_id = event.target.attributes['data-field-id'].nodeValue, + var id = event.target.getAttribute('data-id'), + field_id = event.target.getAttribute('data-field-id'), interval, groupby = this.create_field_value(field_id); event.preventDefault(); if (this.fields[field_id].type === 'date' || this.fields[field_id].type === 'datetime') { - interval = event.target.attributes['data-interval'].nodeValue; + interval = event.target.getAttributes('data-interval'); groupby.field = groupby.field + ':' + interval; } this.expand(id, groupby); @@ -318,8 +317,9 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ expand: function (header_id, groupby) { var self = this, header = this.pivot.get_header(header_id), - update_groupby = !!groupby, - groupby = groupby || header.root.groupby[header.path.length]; + update_groupby = !!groupby; + + groupby = groupby || header.root.groupby[header.path.length]; this.pivot.expand(header_id, groupby).then(function () { if (update_groupby && self.graph_view) { @@ -355,18 +355,14 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.width = this.$el.width(); this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); - if (this.visible_ui) { - this.$('.graph_header').css('display', 'block'); - } else { - this.$('.graph_header').css('display', 'none'); - } + this.$('.graph_header').toggle(this.visible_ui); if (this.pivot.no_data) { this.$('.graph_main_content').append($(QWeb.render('graph_no_data'))); } else { if (this.mode === 'pivot') { this.draw_table(); } else { - this.$('.graph_main_content').append($('
    ')); + this.$('.graph_main_content').append($('
    ')); this.svg = this.$('.graph_main_content svg')[0]; this[this.mode](); } @@ -388,23 +384,23 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }, make_border_cell: function (colspan, rowspan, headercell) { - var tag = (headercell) ? $('') : $(''); + var tag = (headercell) ? $('') : $(''); return tag.addClass('graph_border') - .attr('colspan', (colspan) ? colspan : 1) - .attr('rowspan', (rowspan) ? rowspan : 1); + .attr('colspan', colspan || 1) + .attr('rowspan', rowspan || 1); }, make_header_title: function (header) { - return $(' ') + return $(' ') .addClass('web_graph_click') .attr('href', '#') .addClass((header.expanded) ? 'fa fa-minus-square' : 'fa fa-plus-square') - .append((header.title !== undefined) ? header.title : 'Undefined'); + .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)]]; @@ -445,12 +441,12 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ } 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).append('Total').css('font-weight', 'bold')); + header_cells[0].push(self.make_border_cell(pivot.measures.length, height, true).text('Total').css('font-weight', 'bold')); } } _.each(header_cells, function (cells) { - thead.append($('').append(cells)); + thead.append($('').append(cells)); }); if (pivot.measures.length >= 2) { @@ -460,30 +456,28 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ self.table.append(thead); }, + make_measure_cells: function () { + return _.map(this.pivot.measures, function (measure) { + return $(''); + measure_row = $(''); - measure_row.append($('')); + measure_row.append($('').addClass('measure_row'); - measure_cells.append(measures[i].string); - measure_row.append(measure_cells); - } + measure_row.append(self.make_measure_cells()); } }); if (this.pivot.get_cols_leaves().length > 1) { - for (var i = 0; i < measures.length; i++) { - measure_cells = $('').addClass('measure_row'); - measure_cells.append(measures[i].string); - measure_row.append(measure_cells); - } + measure_row.append(self.make_measure_cells()); } return measure_row; }, @@ -492,19 +486,19 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ var self = this, pivot = this.pivot, measure_types = _.pluck(this.pivot.measures, 'type'), - html_row = $(''), + html_row = $(''), 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($('', {class:'web_graph_indent'})); + row_header.prepend($('', {class:'web_graph_indent'})); } html_row.append(row_header); _.each(pivot.cols.headers, function (col) { - if (col.children.length === 0) { + 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)); @@ -523,26 +517,18 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.table.append(html_row); function make_cell (value, measure_type, index, col) { - var color, - total, - cell = $(''); + var cell = $(''); measure_row.append($(''), - 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') ? $('').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($('', {class:'web_graph_indent'})); } } - - self.table.append(thead); + return cell.append(content); }, - make_measure_cells: function () { - return _.map(this.pivot.measures, function (measure) { - return $(''); + draw_headers: function (headers) { + var make_cell = this.make_header_cell, + empty_cell = $(''); - measure_row.append($(''); + _.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 = $(''), - 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($('', {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 = $('').append('').append(make_cell(row)); + _.each(row.cells, function (cell) { + var value = openerp.web.format_value(cell.value, {type: cell.type}), + html_cell = $('').append(make_cell(row)); _.each(row.cells, function (cell) { - var value = openerp.web.format_value(cell.value, {type: cell.type}), - html_cell = $('
    ').addClass('measure_row').text(measure.string); + }); + }, + make_measure_row: function() { - var measures = this.pivot.measures, + var self = this, cols = this.pivot.cols.headers, measure_cells, - measure_row = $('
    ')); _.each(cols, function (col) { if (!col.children.length) { - for (var i = 0; i < measures.length; i++) { - measure_cells = $('
    '); if (value === undefined) { return cell; } - cell.append(openerp.web.format_value(value, {type: measure_type})); - if (self.heatmap_mode === 'both') { - total = pivot.get_total()[index]; - color = Math.floor(90 + 165*(total - Math.abs(value))/total); - cell.css('background-color', $.Color(255, color, color)); - } - if (self.heatmap_mode === 'row') { - total = pivot.get_total(row)[index]; - color = Math.floor(90 + 165*(total - Math.abs(value))/total); - cell.css('background-color', $.Color(255, color, color)); - } - if (self.heatmap_mode === 'col') { - total = pivot.get_total(col)[index]; - color = Math.floor(90 + 165*(total - Math.abs(value))/total); + 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; @@ -711,9 +697,8 @@ function is_strict_beginning_of (array1, array2) { if (array1.length >= array2.length) { return false; } var result = true; for (var i = 0; i < array1.length; i++) { - if (!_.isEqual(array1[i], array2[i])) { return false;} + if (!_.isEqual(array1[i], array2[i])) { return false;} } return result; } - })(); diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index d5c01765504..a5bfba3c09a 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -8,7 +8,6 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ init: function (model, domain, fields, options) { - openerp.EventDispatcherMixin.init.call(this); this.cells = []; this.domain = domain; this.no_data = true; @@ -79,9 +78,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, get_values: function (id1, id2, default_values) { - var cell = _.find(this.cells, function (c) { - return ((c.x == Math.min(id1, id2)) && (c.y == Math.max(id1, id2))); - }); + 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)); }, @@ -149,10 +146,8 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, get_total: function (header) { - if (header) { - return this.get_values(header.id, this.get_other_root(header).headers[0].id); - } - return this.get_values(this.rows.headers[0].id, this.cols.headers[0].id); + return (header) ? this.get_values(header.id, this.get_other_root(header).headers[0].id) + : this.get_values(this.rows.headers[0].id, this.cols.headers[0].id); }, get_other_root: function (header) { @@ -190,7 +185,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ fold_with_depth: function (root, depth) { var self = this; _.each(this._get_headers_with_depth(root.headers, depth), function (header) { - self.fold(header, true); + self.fold(header); }); }, @@ -338,25 +333,24 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }); groupbys.push([]); - var def_array = _.map(groupbys, function (groupby) { + var get_data_requests = _.map(groupbys, function (groupby) { return self.get_groups(groupby, visible_fields, self.domain); }); - return $.when.apply(null, def_array).then(function () { + 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] : [], - total = data[data.length - 1][0]; + has_data = data[data.length - 1][0]; - return (total === undefined) ? undefined - : self.format_data(total, col_data, row_data, data); + return has_data && self.format_data(col_data, row_data, data); }); }, get_groups: function (groupbys, fields, domain, path) { - path = 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) { @@ -393,7 +387,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ // if field is a fieldname, returns field, if field is field_id:interval, retuns field_id raw_field: function (field) { - return (_.contains(field, ':')) ? field.split(':')[0] : field; + return field.split(':')[0]; }, // add the path to the group and sanitize the value... @@ -418,7 +412,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return group; }, - format_data: function (total, col_data, row_data, cell_data) { + format_data: function (col_data, row_data, cell_data) { var self = this, dim_row = this.rows.groupby.length, dim_col = this.cols.groupby.length, @@ -450,12 +444,10 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ _.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 (measure.field === '__count') ? attr.length : attr.aggregates[measure.field]; - }); + 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)); }); - var row = _.find(rows, function (header) { return _.isEqual(header.path, path.slice(index)); }); - var 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 7b4f2df8be1a2fbe6cbe51a2d0ee6ae9752ec60f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 24 Jan 2014 16:25:36 +0100 Subject: [FIX] fixes a crash in line chart mode when the view had more than one measure (addon web_graph) bzr revid: ged@openerp.com-20140124152536-an2aelpaa43ivzjw --- addons/web_graph/static/src/js/graph_widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 0ada5b1a3c2..c4d0e3d8518 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -630,7 +630,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ var data = _.map(this.pivot.get_cols_leaves(), function (col) { var values = _.map(self.pivot.get_rows_with_depth(dim_x), function (row) { - return {x: row.title, y: self.pivot.get_values(row.id,col.id, 0)}; + return {x: row.title, y: self.pivot.get_values(row.id,col.id)[0] || 0}; }); var title = _.map(col.path, function (p) { return p || 'Undefined'; -- cgit v1.2.3 From 4620c520a1313c63643b7ce5769f500322832714 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 24 Jan 2014 16:28:21 +0100 Subject: [FIX] fixes a typo, causing crashes when selecting date fields in groupbys (addon web_graph) bzr revid: ged@openerp.com-20140124152821-a9ts9soiwlc2niov --- addons/web_graph/static/src/js/graph_widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index c4d0e3d8518..49ddb9388a0 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -305,7 +305,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ groupby = this.create_field_value(field_id); event.preventDefault(); if (this.fields[field_id].type === 'date' || this.fields[field_id].type === 'datetime') { - interval = event.target.getAttributes('data-interval'); + interval = event.target.getAttribute('data-interval'); groupby.field = groupby.field + ':' + interval; } this.expand(id, groupby); -- cgit v1.2.3 From f38017faecc1bf6e745ca1a330c584da7ac061af Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 27 Jan 2014 16:23:24 +0100 Subject: [FIX] fixes a crash happening when the context has a groupby attributes which is an array (addon web_graph) bzr revid: ged@openerp.com-20140127152324-n1jeyfjvii9dfeoh --- addons/web_graph/static/src/js/graph_widget.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 49ddb9388a0..454af202593 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -79,10 +79,18 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return g instanceof openerp.web.search.GroupbyGroup; }); - var filters = _.flatten(_.pluck(groupbygroups, 'filters'), true); + var filters = _.flatten(_.pluck(groupbygroups, 'filters'), true), + 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 _.uniq(_.map(filters, function (filter) { - var field = py.eval(filter.attrs.context).group_by, + return _.uniq(_.map(groupbys, function (groupby) { + var field = groupby.field, + filter = groupby.filter, raw_field = field.split(':')[0], string = (field === raw_field) ? filter.attrs.string : self.fields[raw_field].string; @@ -465,7 +473,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ make_measure_row: function() { var self = this, cols = this.pivot.cols.headers, - measure_cells, measure_row = $('
    ')); -- cgit v1.2.3 From 31374c2eeffe824188b1a43768bc216a86d29b03 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 28 Jan 2014 12:10:22 +0100 Subject: [IMP] this commit translates the hardcoded strings that appears in graph view (addon web_graph) bzr revid: ged@openerp.com-20140128111022-ghoxwvlmywzr2yke --- addons/web_graph/static/src/js/graph_widget.js | 31 ++++++++++++++------------ addons/web_graph/static/src/js/pivot_table.js | 9 +++++--- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 454af202593..c17fd0bcf43 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -4,6 +4,9 @@ (function () { 'use strict'; var QWeb = openerp.web.qweb; +var _lt = openerp.web._lt; +var _t = openerp.web._t; + nv.dev = false; // sets nvd3 library in production mode openerp.web_graph.Graph = openerp.web.Widget.extend({ @@ -39,7 +42,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return this.model.call('fields_get', []).then(function (f) { self.fields = f; - self.fields.__count = {field:'__count', type: 'integer', string:'Quantity'}; + self.fields.__count = {field:'__count', type: 'integer', string:_t('Quantity')}; self.important_fields = self.get_search_fields(); self.measure_list = self.get_measures(); self.add_measures_to_options(); @@ -381,11 +384,11 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // Drawing the table // ---------------------------------------------------------------------- draw_table: function () { - this.pivot.main_row().title = 'Total'; + this.pivot.main_row().title = _t('Total'); if (this.pivot.measures.length == 1) { this.pivot.main_col().title = this.pivot.measures[0].string; } else { - this.pivot.main_col().title = this.title; + this.pivot.main_col().title = _t(this.title); } this.draw_top_headers(); _.each(this.pivot.rows.headers, this.proxy('draw_row')); @@ -449,7 +452,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ } 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('Total').css('font-weight', 'bold')); + header_cells[0].push(self.make_border_cell(pivot.measures.length, height, true).text(_t('Total')).css('font-weight', 'bold')); } } @@ -554,8 +557,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // No groupby if ((dim_x === 0) && (dim_y === 0)) { - data = [{key: 'Total', values:[{ - x: 'Total', + data = [{key: _t('Total'), values:[{ + x: _t('Total'), y: this.pivot.get_total(), }]}]; // Only column groupbys @@ -570,7 +573,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ } else if ((dim_x === 1) && (dim_y === 0)) { data = _.map(this.pivot.main_row().children, function (pt) { var value = self.pivot.get_total(pt), - title = (pt.title !== undefined) ? pt.title : 'Undefined'; + title = (pt.title !== undefined) ? pt.title : _t('Undefined'); return {x: title, y: value}; }); data = [{key: self.pivot.measures[0].string, values:data}]; @@ -579,24 +582,24 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ data = _.map(this.pivot.get_cols_with_depth(1), function (colhdr) { var values = _.map(self.pivot.get_rows_with_depth(1), function (header) { return { - x: header.title || 'Undefined', + x: header.title || _t('Undefined'), y: self.pivot.get_values(header.id, colhdr.id)[0] || 0 }; }); - return {key: colhdr.title || 'Undefined', values: values}; + return {key: colhdr.title || _t('Undefined'), values: values}; }); // At least two row groupby } else { var keys = _.uniq(_.map(this.pivot.get_rows_with_depth(2), function (hdr) { - return hdr.title || 'Undefined'; + return hdr.title || _t('Undefined'); })); data = _.map(keys, function (key) { var values = _.map(self.pivot.get_rows_with_depth(1), function (hdr) { var subhdr = _.find(hdr.children, function (child) { - return ((child.title === key) || ((child.title === undefined) && (key === 'Undefined'))); + return ((child.title === key) || ((child.title === undefined) && (key === _t('Undefined')))); }); return { - x: hdr.title || 'Undefined', + x: hdr.title || _t('Undefined'), y: (subhdr) ? self.pivot.get_total(subhdr)[0] : 0 }; }); @@ -640,7 +643,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return {x: row.title, y: self.pivot.get_values(row.id,col.id)[0] || 0}; }); var title = _.map(col.path, function (p) { - return p || 'Undefined'; + return p || _t('Undefined'); }).join('/'); if (dim_y === 0) { title = self.pivot.measures[0].string; @@ -670,7 +673,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ dim_x = this.pivot.rows.groupby.length; var data = _.map(this.pivot.get_rows_leaves(), function (row) { var title = _.map(row.path, function (p) { - return p || 'Undefined'; + return p || _t('Undefined'); }).join('/'); if (dim_x === 0) { title = self.measure_label; diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index a5bfba3c09a..89ca36f3b61 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -4,6 +4,9 @@ (function () { 'use strict'; +var _lt = openerp.web._lt; +var _t = openerp.web._t; + // PivotTable requires a call to update_data after initialization openerp.web_graph.PivotTable = openerp.web.Class.extend({ @@ -13,7 +16,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ this.no_data = true; this.model = model; this.fields = fields; - this.fields.__count = {type: 'integer', string:'Quantity'}; + this.fields.__count = {type: 'integer', string:_t('Quantity')}; this.measures = options.measures || []; this.rows = { groupby: options.row_groupby, headers: null }; this.cols = { groupby: options.col_groupby, headers: null }; @@ -397,11 +400,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ grouped_on = attrs.grouped_on ? this.raw_field(attrs.grouped_on) : false; if (value === false) { - group.attributes.value = 'undefined'; + 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] : 'undefined'; + group.attributes.value = value_lookup ? value_lookup[0][1] : _t('undefined'); } else if (value instanceof Array) { group.attributes.value = value[1]; } -- cgit v1.2.3 From ad76309fbe29f6d4d2d26393bc8d2b1c595a124f Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 28 Jan 2014 14:26:25 +0100 Subject: [IMP] makes the graph view in pivot table mode always display 'Total' instead of the current measure/title (addon web_graph) bzr revid: ged@openerp.com-20140128132625-pk21iuhuffvx6814 --- addons/web_graph/static/src/js/graph_widget.js | 7 ------- addons/web_graph/static/src/js/pivot_table.js | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index c17fd0bcf43..100ae21acce 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -21,7 +21,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.domain = domain; this.mode = options.mode || 'pivot'; // pivot, bar, pie, line this.heatmap_mode = options.heatmap_mode || 'none'; - this.title = options.title || 'Graph'; this.visible_ui = options.visible_ui || true; this.bar_ui = options.bar_ui || 'group'; this.graph_view = options.graph_view || null; @@ -384,12 +383,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // Drawing the table // ---------------------------------------------------------------------- draw_table: function () { - this.pivot.main_row().title = _t('Total'); - if (this.pivot.measures.length == 1) { - this.pivot.main_col().title = this.pivot.measures[0].string; - } else { - this.pivot.main_col().title = _t(this.title); - } this.draw_top_headers(); _.each(this.pivot.rows.headers, this.proxy('draw_row')); }, diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 89ca36f3b61..fccb1e4bffa 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -238,7 +238,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, make_header: function (group, parent) { - var title = parent ? group.attributes.value : ''; + var title = parent ? group.attributes.value : _t('Total'); return { id: _.uniqueId(), path: parent ? parent.path.concat(title) : [], -- cgit v1.2.3 From f27c1df4d2d8c1fe809b4b7c61d4ddfedc6de569 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 28 Jan 2014 16:11:13 +0100 Subject: [IMP] css changes to improve look and usability of pivot table view (addon web_graph) bzr revid: ged@openerp.com-20140128151113-g8yxl3lphpht4d89 --- addons/web_graph/static/src/js/graph_widget.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 100ae21acce..ef547e22632 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -362,6 +362,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.$('.graph_main_content svg').remove(); this.$('.graph_main_content div').remove(); this.table.empty(); + this.table.toggleClass('heatmap', this.heatmap_mode !== 'none') this.width = this.$el.width(); this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); -- cgit v1.2.3 From 9344f2f851823624793359c366fb6beeb1ab0242 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 28 Jan 2014 16:11:57 +0100 Subject: [FIX] changes the hardcoded string 'undefined' into 'Undefined' in pivot table (addon web_graph) bzr revid: ged@openerp.com-20140128151157-3opcfcockwrgr3kx --- addons/web_graph/static/src/js/pivot_table.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index fccb1e4bffa..770519e52c2 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -400,11 +400,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ grouped_on = attrs.grouped_on ? this.raw_field(attrs.grouped_on) : false; if (value === false) { - group.attributes.value = _t('undefined'); + 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'); + group.attributes.value = value_lookup ? value_lookup[0][1] : _t('Undefined'); } else if (value instanceof Array) { group.attributes.value = value[1]; } -- cgit v1.2.3 From 882fde48f087121b0a58888c0c0ae9734fe8b419 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 3 Feb 2014 12:33:32 +0100 Subject: [IMP] work in progress: adds the export functionality in graph view (addon web_graph) bzr revid: ged@openerp.com-20140203113332-fvr9cra2dhj4h0ju --- addons/web_graph/static/src/js/graph_widget.js | 94 +++++++++++++++++++++++++- addons/web_graph/static/src/js/pivot_table.js | 4 ++ 2 files changed, 97 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index ef547e22632..bd367f29ed1 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -39,6 +39,10 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.$('.graph_heatmap label').addClass('disabled'); } + openerp.session.rpc('/web_graph/check_xlwt').then(function (result) { + if (result) { self.$('.graph_options_selection label').toggle(true); } + }); + return this.model.call('fields_get', []).then(function (f) { self.fields = f; self.fields.__count = {field:'__count', type: 'integer', string:_t('Quantity')}; @@ -264,6 +268,9 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ case 'update_values': this.pivot.update_data().then(this.proxy('display_data')); break; + case 'export_data': + this.export_xls(); + break; } }, @@ -362,7 +369,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.$('.graph_main_content svg').remove(); this.$('.graph_main_content div').remove(); this.table.empty(); - this.table.toggleClass('heatmap', this.heatmap_mode !== 'none') + this.table.toggleClass('heatmap', this.heatmap_mode !== 'none'); this.width = this.$el.width(); this.height = Math.min(Math.max(document.documentElement.clientHeight - 116 - 60, 250), Math.round(0.8*this.$el.width())); @@ -693,6 +700,91 @@ 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_ancestors(col).length : 1; + var cell_height = height - col.path.length + 1; + var cell = {width: cell_width, height: cell_height, title: col.title, id: col.id}; + debugger; + if (rows[col.path.length - 1]) { + rows[col.path.length - 1].push(cell); + } else { + rows[col.path.length - 1] = [cell]; + } + }); + + 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 () { + return []; + }, + + // ---------------------------------------------------------------------- + // Controller stuff... + // ---------------------------------------------------------------------- + export_xls: function() { + var c = openerp.webclient.crashmanager; + + var table = this.build_table(); + console.log(table); + return; + openerp.web.blockUI(); + this.session.get_file({ + url: '/web_graph/export_xls', + data: {data: JSON.stringify({ + test: table + // model: this.view.dataset.model, + // id: (this.view.datarecord.id || ''), + // field: this.name, + // filename_field: (this.node.attrs.filename || ''), + // data: instance.web.form.is_bin_size(value) ? null : value, + // context: this.view.dataset.get_context() + })}, + complete: openerp.web.unblockUI, + error: c.rpc_error.bind(c) + }); + }, + + + + }); // Utility function: returns true if the beginning of array2 is array1 and diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 770519e52c2..f77d49f9a1a 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -127,6 +127,10 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return this._get_headers_with_depth(this.rows.headers, depth); }, + get_ancestor_leaves: function (header) { + return _.where(this.get_ancestors_and_self(header), {expanded:false}); + }, + // return all non expanded rows get_rows_leaves: function () { return _.where(this.rows.headers, {expanded:false}); -- cgit v1.2.3 From 6ddbb1f8c6903ccafce2afba22658626e6397383 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 3 Feb 2014 16:47:04 +0100 Subject: [IMP] work in progress: adds the export functionality in graph view (addon web_graph) bzr revid: ged@openerp.com-20140203154704-t2i3uvezupw7kn3n --- addons/web_graph/static/src/js/graph_widget.js | 56 +++++++++++++++++--------- 1 file changed, 36 insertions(+), 20 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index bd367f29ed1..b7a7a63de79 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -725,10 +725,9 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ _.each(pivot.cols.headers, function (col) { if (col.path.length === 0) { return;} - var cell_width = col.expanded ? pivot.get_ancestors(col).length : 1; - var cell_height = height - col.path.length + 1; - var cell = {width: cell_width, height: cell_height, title: col.title, id: col.id}; - debugger; + 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 { @@ -736,6 +735,12 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ } }); + 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; }, @@ -753,32 +758,43 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }, build_rows: function () { - return []; + 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() { - var c = openerp.webclient.crashmanager; - - var table = this.build_table(); - console.log(table); - return; openerp.web.blockUI(); this.session.get_file({ url: '/web_graph/export_xls', - data: {data: JSON.stringify({ - test: table - // model: this.view.dataset.model, - // id: (this.view.datarecord.id || ''), - // field: this.name, - // filename_field: (this.node.attrs.filename || ''), - // data: instance.web.form.is_bin_size(value) ? null : value, - // context: this.view.dataset.get_context() - })}, + data: {data: JSON.stringify(this.build_table())}, complete: openerp.web.unblockUI, - error: c.rpc_error.bind(c) + error: openerp.webclient.crashmanager.rpc_error.bind(c) }); }, -- cgit v1.2.3 From cfef03432129484f2c026f866145420f73444c4a Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 4 Feb 2014 12:31:35 +0100 Subject: [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 --- addons/web_graph/static/src/js/graph_widget.js | 397 ++++++++++--------------- 1 file changed, 162 insertions(+), 235 deletions(-) (limited to 'addons/web_graph/static/src/js') 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}; }); })); @@ -362,6 +362,104 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.graph_view.register_groupby(this.pivot.rows.groupby, this.pivot.cols.groupby); }, + // ---------------------------------------------------------------------- + // 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 // ---------------------------------------------------------------------- @@ -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) ? $('') : $(''); - return tag.addClass('graph_border') - .attr('colspan', colspan || 1) - .attr('rowspan', rowspan || 1); - }, - - make_header_title: function (header) { - return $(' ') - .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 = $('
    ') : $('')) + .addClass('graph_border') + .attr('rowspan', header.height) + .attr('colspan', header.width); + var content = $('').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($('
    ').addClass('measure_row').text(measure.string); - }); - }, - - make_measure_row: function() { - var self = this, - cols = this.pivot.cols.headers, - measure_row = $('
    ').attr('rowspan', headers.length), + thead = $('
    ')); - - _.each(cols, function (col) { - if (!col.children.length) { - measure_row.append(self.make_measure_cells()); - } + _.each(headers, function (row) { + var html_row = $('
    '); + _.each(measure_row, function (cell) { + var measure_cell = $('').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 = $('
    ').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 = $(''); - 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; - } }, // ---------------------------------------------------------------------- @@ -700,96 +715,11 @@ 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 -- cgit v1.2.3 From 19d6d98da83d9cb19d66741ed9377647ac34f762 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 5 Feb 2014 10:58:08 +0100 Subject: [IMP] completes the excel export functionality in graph view (addon web_graph) bzr revid: ged@openerp.com-20140205095808-8lzwv0yqcsjnvff9 --- addons/web_graph/static/src/js/graph_widget.js | 27 +++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 19b7b04e269..79d814460df 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -371,6 +371,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ headers: this.build_headers(), measure_row: this.build_measure_row(), rows: this.build_rows(), + nbr_measures: this.pivot.measures.length }; }, @@ -418,12 +419,15 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return result; }, - add_color: function (cell, row, col, index) { + make_cell: function (row, col, value, index) { + var formatted_value = openerp.web.format_value(value, {type:this.pivot.measures[index].type}), + cell = {value:formatted_value}; + 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); + var color = Math.floor(90 + 165*(total - Math.abs(value))/total); if (color < 255) { cell.color = color; } @@ -433,21 +437,22 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ build_rows: function () { var self = this, pivot = this.pivot, - m, - add_total = pivot.get_cols_leaves().length > 1; + m, cell; 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); + 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)); + cells.push(self.make_cell(row,col,values[m], m)); } }); - if (add_total) { + if (pivot.get_cols_leaves().length > 1) { 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)); + cell = self.make_cell(row, pivot.main_col(), totals[m], m); + cell.is_bold = 'true'; + cells.push(cell); } } return { @@ -549,8 +554,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ _.each(rows, function (row) { var html_row = $('
    ').text(value); + var html_cell = $('').text(cell.value); if (_.has(cell, 'color')) { html_cell.css('background-color', $.Color(255, cell.color, cell.color)); } @@ -719,12 +723,13 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // Controller stuff... // ---------------------------------------------------------------------- export_xls: function() { + var c = openerp.webclient.crashmanager; openerp.web.blockUI(); this.session.get_file({ url: '/web_graph/export_xls', data: {data: JSON.stringify(this.build_table())}, complete: openerp.web.unblockUI, - error: openerp.webclient.crashmanager.rpc_error.bind(c) + error: c.rpc_error.bind(c) }); }, -- cgit v1.2.3 From d0961eb09ecd2db3e155fd66b0c059ddbb30f992 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 5 Feb 2014 14:14:06 +0100 Subject: [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) bzr revid: ged@openerp.com-20140205131406-kdw5ht9u8gct9xbo --- addons/web_graph/static/src/js/graph_widget.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 79d814460df..51baabaff5e 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -25,6 +25,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ this.bar_ui = options.bar_ui || 'group'; this.graph_view = options.graph_view || null; this.pivot_options = options; + this.title = options.title || 'Data'; }, start: function() { @@ -40,7 +41,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ } openerp.session.rpc('/web_graph/check_xlwt').then(function (result) { - if (result) { self.$('.graph_options_selection label').toggle(true); } + self.$('.graph_options_selection label').toggle(result); }); return this.model.call('fields_get', []).then(function (f) { @@ -371,7 +372,8 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ headers: this.build_headers(), measure_row: this.build_measure_row(), rows: this.build_rows(), - nbr_measures: this.pivot.measures.length + nbr_measures: this.pivot.measures.length, + title: this.title, }; }, @@ -394,10 +396,10 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }); if (pivot.get_cols_leaves().length > 1) { - rows[0].push({width:nbr_measures, height:height, title: _t('Total'), id: pivot.cols.headers[0].id }); + rows[0].push({width: nbr_measures, height: height, title: _t('Total'), id: pivot.main_col().id }); } if (pivot.cols.headers.length === 1) { - rows = [[{width:nbr_measures, height:1, title: _t('Total'), id: pivot.cols.headers[0].id, expanded: false}]]; + rows = [[{width: nbr_measures, height: 1, title: _t('Total'), id: pivot.main_col().id, expanded: false}]]; } return rows; }, -- cgit v1.2.3 From 88b7511f6883ed42e113f818449fb2fa61c9c40b Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 7 Feb 2014 14:53:39 +0100 Subject: [FIX] correctly use the col group by instead of groupby when reading the context and initializing a graph view (addon web_graph) bzr revid: ged@openerp.com-20140207135339-ohrjh6uvu22tjavh --- addons/web_graph/static/src/js/graph_view.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index e1a50d4ff6d..b39ac105ee4 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -50,7 +50,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ var field_name = field.attrs.name; if (_.has(field.attrs, 'interval')) { field_name = field.attrs.name + ':' + field.attrs.interval; - } + } if (_.has(field.attrs, 'type')) { switch (field.attrs.type) { case 'row': @@ -78,14 +78,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { var self = this, - col_group_by = context.col_group_by || this.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); + col_group_by = this.extract_groupby('col_group_by', context) || []; if (!this.graph_widget) { if (group_by.length) { this.widget_config.row_groupby = group_by; } if (col_group_by.length) { - this.widget_config.col_groupby = group_by; + this.widget_config.col_groupby = col_group_by; } this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); @@ -101,16 +101,18 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.graph_widget.set(domain, group_by, col_group_by); }, + extract_groupby: function (cat_field, context) { + context = (_.isString(context)) ? py.eval(context) : context; + return context[cat_field]; + }, + get_groupbys_from_searchview: function (cat_name, cat_field) { - var facet = this.search_view.query.findWhere({category:cat_name}), + var self=this, + facet = this.search_view.query.findWhere({category:cat_name}), groupby_list = facet ? facet.values.models : []; return _.map(groupby_list, function (g) { var context = g.attributes.value.attrs.context; - if (_.isString(context)) { - return py.eval(context).group_by; - } else { - return context[cat_field]; - } + return self.extract_groupby(cat_field, context); }); }, -- cgit v1.2.3 From 817b9bdb7f6356c2db3a97ab9bc9c63e59ebd261 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 7 Feb 2014 15:22:23 +0100 Subject: [IMP] removes the 'expand all' buttons, it was confusing and not really useful (addon web_graph) bzr revid: ged@openerp.com-20140207142223-pc31xwv7kckt99a0 --- addons/web_graph/static/src/js/graph_widget.js | 3 --- 1 file changed, 3 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index ef547e22632..881be188595 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -258,9 +258,6 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ case 'swap_axis': this.swap_axis(); break; - case 'expand_all': - this.pivot.expand_all().then(this.proxy('display_data')); - break; case 'update_values': this.pivot.update_data().then(this.proxy('display_data')); break; -- cgit v1.2.3 From f4bbf7b5d4cda7825fc21b6175b6c11cf030ec19 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 10:17:16 +0100 Subject: [FIX] fixes an issue in graph view (addon web_graph) when the user clicked several times on a field name to expand it, the dropdown menu was displayed several times, overlapping, instead of being reset to the last click location bzr revid: ged@openerp.com-20140210091716-of9w9xhjnpmaa5td --- addons/web_graph/static/src/js/graph_widget.js | 39 +++++++++++++++----------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 881be188595..26f479790df 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -284,25 +284,30 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ if (header.expanded) { this.fold(header); - } else { - if (header.path.length < header.root.groupby.length) { - this.expand(id); - } else { - if (!this.important_fields.length) { - return; - } + return; + } + if (header.path.length < header.root.groupby.length) { + this.expand(id); + return; + } + if (!this.important_fields.length) { + return; + } - var fields = _.map(this.important_fields, function (field) { - return {id: field.field, value: field.string, type:self.fields[field.field.split(':')[0]].type}; - }); - this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); - $(event.target).after(this.dropdown); - this.dropdown.css({position:'absolute', - left:event.pageX, - top:event.pageY}); - this.$('.field-selection').next('.dropdown-menu').toggle(); - } + var fields = _.map(this.important_fields, function (field) { + return {id: field.field, value: field.string, type:self.fields[field.field.split(':')[0]].type}; + }); + if (this.dropdown) { + this.dropdown.remove(); } + this.dropdown = $(QWeb.render('field_selection', {fields:fields, header_id:id})); + $(event.target).after(this.dropdown); + this.dropdown.css({position:'absolute', + left:event.pageX, + top:event.pageY}); + this.$('.field-selection').next('.dropdown-menu').toggle(); + + }, field_selection: function (event) { -- cgit v1.2.3 From 9eda870d2b8bad1d2c480a9a54eb7264ce4df183 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 12:23:13 +0100 Subject: [FIX] fixes a bug caused by two consecutive calls to do_search, with incomplete informations in the first call. These calls then triggered useless queries and caused an incorrect (but brief) display of partial information in graph view (addon web_graph) bzr revid: ged@openerp.com-20140210112313-z9elwhmjil41jcd2 --- addons/web_graph/static/src/js/graph_view.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index b39ac105ee4..33b99b88bcf 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -77,6 +77,11 @@ instance.web_graph.GraphView = instance.web.View.extend({ }, do_search: function (domain, context, group_by) { + if (this.ignore_do_search) { + this.ignore_do_search = false; + return; + } + var self = this, col_group_by = this.extract_groupby('col_group_by', context) || []; @@ -131,6 +136,14 @@ instance.web_graph.GraphView = instance.web.View.extend({ if (!_.has(this.search_view, '_s_groupby')) { return; } + if (row_groupby.length && col_groupby.length) { + // when two changes to the search view will be done, the method do_search + // will be called twice, once with the correct groupby and incorrect col_groupby, + // and once with correct informations. This flag is necessary to prevent the + // incorrect informations to propagate and trigger useless queries + this.ignore_do_search = true; + } + // add row groupbys var row_facet = this.make_row_groupby_facets(row_groupby), row_search_facet = query.findWhere({category:'GroupBy'}); -- cgit v1.2.3 From 321a4a74027364f709a9830faeba4d5a70a814fe Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 10 Feb 2014 16:32:21 +0100 Subject: [FIX] make sure the graph view takes the col_group_by from the search view and not from the context. It was taken from the context, and had the unfortunate side effect that the user could not ungroup by removing the facet from the search view. (addon web_graph) bzr revid: ged@openerp.com-20140210153221-olkv8xee02r9voer --- addons/web_graph/static/src/js/graph_view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 33b99b88bcf..ace2f14ae20 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -83,7 +83,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ } var self = this, - col_group_by = this.extract_groupby('col_group_by', context) || []; + col_group_by = self.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); if (!this.graph_widget) { if (group_by.length) { -- cgit v1.2.3 From 956b73998c3efa711e7d0f58ea3264d71b8286e6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 25 Feb 2014 10:03:49 +0100 Subject: [FIX] fixes various problems with the search bar integration with the graph view. Now, the code correctly computes the group_bys and col_groupbys contained in the various filters in the search bar (addon web_graph) bzr revid: ged@openerp.com-20140225090349-z6udsjn0cjafu0lt --- addons/web_graph/static/src/js/graph_view.js | 41 ++++++++++++++++++---------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index e1a50d4ff6d..c29c78e7e33 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -50,7 +50,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ var field_name = field.attrs.name; if (_.has(field.attrs, 'interval')) { field_name = field.attrs.name + ':' + field.attrs.interval; - } + } if (_.has(field.attrs, 'type')) { switch (field.attrs.type) { case 'row': @@ -78,7 +78,8 @@ instance.web_graph.GraphView = instance.web.View.extend({ do_search: function (domain, context, group_by) { var self = this, - col_group_by = context.col_group_by || this.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); + groupbys = this.get_groupbys_dos(), + col_group_by = groupbys.col_group_by; if (!this.graph_widget) { if (group_by.length) { @@ -90,10 +91,10 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.graph_widget = new openerp.web_graph.Graph(this, this.model, domain, this.widget_config); this.graph_widget.appendTo(this.$el); this.ViewManager.on('switch_mode', this, function (e) { - var col_gb = self.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'), - row_gb = self.get_groupbys_from_searchview('GroupBy', 'group_by'); - - if (e === 'graph') this.graph_widget.set(domain, row_gb, col_gb); + if (e === 'graph') { + var group_bys = self.get_groupbys_from_searchview(); + this.graph_widget.set(domain, group_bys.group_by, group_bys.col_group_by); + } }); return; } @@ -101,17 +102,27 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.graph_widget.set(domain, group_by, col_group_by); }, - get_groupbys_from_searchview: function (cat_name, cat_field) { - var facet = this.search_view.query.findWhere({category:cat_name}), - groupby_list = facet ? facet.values.models : []; - return _.map(groupby_list, function (g) { - var context = g.attributes.value.attrs.context; - if (_.isString(context)) { - return py.eval(context).group_by; - } else { - return context[cat_field]; + get_groupbys_from_searchview: function () { + var result = { group_by: [], col_group_by: []}, + searchdata = this.search_view.build_search_data(); + + _.each(searchdata.groupbys, function (data) { + data = (_isString(data)) ? py.eval(data) : data; + result.group_by = result.group_by.concat(data.group_by); + if (data.col_group_by) { + result.col_group_by = result.col_group_by.concat(data.col_group_by); + } + }); + + if (result.col_group_by.length) { + return result; + } + _.each(searchdata.contexts, function (context) { + if (context.col_group_by) { + result.col_group_by = result.col_group_by.concat(context.col_group_by); } }); + return result; }, do_show: function () { -- cgit v1.2.3 From 02b70e2950c275e3bda3c172fdd72affa26d14b6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 25 Feb 2014 11:31:55 +0100 Subject: [FIX] fixes problems due to the preceding merge (resolved conflict was not properly resolved) (addon web_graph) bzr revid: ged@openerp.com-20140225103155-9cdbs8p79sa7hkwi --- addons/web_graph/static/src/js/graph_view.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_view.js b/addons/web_graph/static/src/js/graph_view.js index 4e799c82afd..fa39fc581db 100644 --- a/addons/web_graph/static/src/js/graph_view.js +++ b/addons/web_graph/static/src/js/graph_view.js @@ -81,14 +81,9 @@ instance.web_graph.GraphView = instance.web.View.extend({ this.ignore_do_search = false; return; } - var self = this, -<<<<<<< TREE - groupbys = this.get_groupbys_dos(), + groupbys = this.get_groupbys_from_searchview(), col_group_by = groupbys.col_group_by; -======= - col_group_by = self.get_groupbys_from_searchview('ColGroupBy', 'col_group_by'); ->>>>>>> MERGE-SOURCE if (!this.graph_widget) { if (group_by.length) { @@ -116,7 +111,7 @@ instance.web_graph.GraphView = instance.web.View.extend({ searchdata = this.search_view.build_search_data(); _.each(searchdata.groupbys, function (data) { - data = (_isString(data)) ? py.eval(data) : data; + data = (_.isString(data)) ? py.eval(data) : data; result.group_by = result.group_by.concat(data.group_by); if (data.col_group_by) { result.col_group_by = result.col_group_by.concat(data.col_group_by); -- cgit v1.2.3 From fed81544ada286ac90d6da38ef69214c89ab98f9 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 25 Feb 2014 11:42:33 +0100 Subject: [IMP] optimizes graph view to avoid reloading data in some cases (such as removing a filter from the search view) (addon web_graph) bzr revid: ged@openerp.com-20140225104233-zidrw03dh2hlwrng --- addons/web_graph/static/src/js/graph_widget.js | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index 9e4c81157d1..f9d508c08b6 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -154,6 +154,13 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ return; } + if (!dom_changed && col_reduced && row_reduced) { + this.pivot.fold_with_depth(this.pivot.rows, row_gbs.length); + this.pivot.fold_with_depth(this.pivot.cols, col_gbs.length); + this.display_data(); + return; + } + if (dom_changed || row_gb_changed || col_gb_changed) { this.pivot.set(domain, row_gbs, col_gbs).then(this.proxy('display_data')); } -- cgit v1.2.3 From 47340431f934c071a52ac1e908367fdc6d24882e Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 25 Feb 2014 15:16:23 +0100 Subject: [FIX] fixes the tooltip position in chart mode (graph view). The position was wrong because the parent position was not 'relative'. (addon web_graph) bzr revid: ged@openerp.com-20140225141623-cawr7yur38zhjcz4 --- addons/web_graph/static/src/js/graph_widget.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'addons/web_graph/static/src/js') diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index f9d508c08b6..b4f06aee3f1 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -171,8 +171,10 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ if (mode === 'pivot') { this.$('.graph_heatmap label').removeClass('disabled'); + this.$('.graph_main_content').css('position', 'inherit') } else { this.$('.graph_heatmap label').addClass('disabled'); + this.$('.graph_main_content').css('position', 'relative') } this.display_data(); }, -- cgit v1.2.3