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_widget.js | 567 +++++++++++++++++++++++++ 1 file changed, 567 insertions(+) create mode 100644 addons/web_graph/static/src/js/graph_widget.js (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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; + }); + }, + +}); +})(); -- 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/graph_widget.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_widget.js | 130 +++++++++++++++---------- 1 file changed, 77 insertions(+), 53 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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'; -- 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_widget.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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_widget.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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(); -- 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/graph_widget.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 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 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.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)); -- 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/graph_widget.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/graph_widget.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 --- 1 file changed, 3 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.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'); } }); -- 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_widget.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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; }, // ---------------------------------------------------------------------- -- 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_widget.js | 203 +++++++++++++++++-------- 1 file changed, 142 insertions(+), 61 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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; +} + })(); -- 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 - 1 file changed, 1 deletion(-) (limited to 'addons/web_graph/static/src/js/graph_widget.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 || []); -- 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_widget.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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; }, -- 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_widget.js | 61 +++++++++----------------- 1 file changed, 21 insertions(+), 40 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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) { -- 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_widget.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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 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_widget.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.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', -- 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_widget.js | 151 +++++++++++-------------- 1 file changed, 68 insertions(+), 83 deletions(-) (limited to 'addons/web_graph/static/src/js/graph_widget.js') 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($('
    ').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; } - })(); -- 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/graph_widget.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/graph_widget.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/graph_widget.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