From 76b1514392a4dee3fd07ec89a7aa5de3ef88ca16 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Mon, 7 May 2012 11:40:59 +0200 Subject: [PATCH] [IMP] code for graph lib bzr revid: fp@tinyerp.com-20120507094059-y0ogjwcocp71hfue --- addons/web_graph/static/src/js/graph.js | 280 ++++++++++++++---- addons/web_graph/static/src/xml/web_graph.xml | 93 +++--- 2 files changed, 272 insertions(+), 101 deletions(-) diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 27ae5ee3842..7f123e3584a 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({ this.mode="pie"; // line, bar, area, pie, radar this.orientation=true; // true: horizontal, false: vertical this.stacked=true; + this.spreadsheet=false; // Display data gris, allows copy to CSV this.forcehtml=false; this.legend_container; @@ -37,71 +38,240 @@ instance.web_graph.GraphView = instance.web.View.extend({ this._super(); }, - - on_loaded: function(fields_view_get) { - var self = this; - self.fields_view = fields_view_get; - return this.dataset.call_and_eval('fields_get', [false, {}], null, 1).pipe(function(fields_result) { - self.fields = fields_result; - return self.on_loaded_2(); - }); - }, - /** - * Returns all object fields involved in the graph view - */ - list_fields: function () { - var fs = [this.abscissa]; - fs.push.apply(fs, _(this.columns).pluck('name')); - if (this.group_field) { - fs.push(this.group_field); - } - return fs; - }, - on_loaded_2: function() { - this.chart = this.fields_view.arch.attrs.type || 'pie'; - this.orientation = this.fields_view.arch.attrs.orientation || 'vertical'; + this.$element.html(QWeb.render("GraphView", {})); - _.each(this.fields_view.arch.children, function (field) { - var attrs = field.attrs; - if (attrs.group) { - this.group_field = attrs.name; - } else if(!this.abscissa) { - this.first_field = this.abscissa = attrs.name; - } else { - this.columns.push({ - name: attrs.name, - operator: attrs.operator || '+' - }); + // Should I add this, in every $(...) call ? + container = $("#editor-render-body"); + $("#graph_bar,#graph_bar_stacked").click( + {mode: 'bar', stacked: true, legend: 'top'}, graph_render) + + $("#graph_bar_not_stacked").click( + {mode: 'bar', stacked: false, legend: 'top'}, graph_render) + + $("#graph_area,#graph_area_stacked").click( + {mode: "area", stacked: true, legend: "top"}, graph_render); + + $("#graph_area_not_stacked").click( + {mode: "area", stacked: false, legend: "top"}, graph_render); + + $("#graph_radar").click( + {orientation: 0, mode: "radar", legend: "inside"}, graph_render); + + $("#graph_pie").click( + {mode: "pie", legend: "inside"}, graph_render); + + $("#graph_legend_top").click( + {legend: "top"}, graph_render); + + $("#graph_legend_inside").click( + {legend: "inside"}, graph_render); + + $("#graph_legend_no").click( + {legend: "no"}, graph_render); + + $("#graph_line").click( + {mode: "line"}, graph_render); + + $("#graph_show_data").click( + function() { + spreadsheet = ! spreadsheet; + graph_render(); } - }, this); - this.ordinate = this.columns[0].name; - this.is_loaded.resolve(); - return $.when(); + ); + $("#graph_switch").click( + function() { + orientation = ! orientation; + graph_render(); + } + ); + + $("#graph_download").click( + function() { + var graph; + if (Flotr.isIE && Flotr.isIE < 9) { + alert( + "Your browser doesn't allow you to get a bitmap image from the plot, " + + "you can only get a VML image that you can use in Microsoft Office." + ); + } + if (legend=="top") legend="inside"; + forcehtml = true; + graph = graph_render(); + graph.download.saveImage('png'); + forcehtml = false; + } + ); + + this._super(); }, + get_format: function get_format(options) { + var result = { + show: this.legend!='no', + } + if (legend=="top") { + result.noColumns = 4; + // todo: I guess I should add something like this.renderer ? + result.container = $("div .graph_header_legend", this)[0]; + } else if (legend=="inside") { + result.position = 'nw'; + result.backgroundColor = '#D2E8FF'; + } + return $.extend({ + legend: result, + mouse: { + track: true, + relative: true + }, + spreadsheet : { + show: this.spreadsheet, + initialTab: "data" + }, + HtmlText : (options && options.labelsAngle)?false:!this.forcehtml, + }, options) + }, + + graph_get_data: function (options) { + var i, + d1 = [], + d2 = [], + d3 = []; + for (i = -3; i < 3; i++) { + if (this.orientation % 2) { + d1.push([Math.random(), i]); + d2.push([Math.random(), i]); + d3.push([Math.random(), i]); + } else { + d1.push([i, Math.random()]); + d2.push([i, Math.random()]); + d3.push([i, Math.random()]); + } + }; + return [ + $.extend({ data : d2, label : 'Serie 2'}, options), + $.extend({ data : d3, label : 'Serie 3'}, options), + $.extend({ data : d1, label : 'Serie 1'}, options), + ]; + }, + + + graph_bar: function (container, data) { + return Flotr.draw(container, data, get_format({ + bars : { + show : true, + stacked : this.stacked, + horizontal : this.orientation, + barWidth : 0.7, + lineWidth : 1 + }, + grid : { + verticalLines : this.orientation, + horizontalLines : !this.orientation, + outline : "sw", + }, + labelsAngle: 45 + }) + ) + }, + + graph_pie: function (container, data) { + return Flotr.draw(container, data, get_format({ + pie : { + show: true + }, + grid : { + verticalLines : false, + horizontalLines : false, + outline : "", + }, + xaxis : {showLabels: false}, + yaxis : {showLabels: false}, + }) + ) + } + + graph_radar: function (container, data) { + return Flotr.draw(container, data, get_format({ + radar : { + show : true, + stacked : this.stacked + }, + grid : { + circular : true, + minorHorizontalLines : true + } + }) + ) + } + + graph_line: function (container, data) { + return Flotr.draw(container, data, get_format({ + lines : { + show : true, + stacked : this.stacked + }, + grid : { + verticalLines : this.orientation, + horizontalLines : !this.orientation, + outline : "sw", + }, + labelsAngle : 45 + }) + ) + } + + // Render the graph and update menu styles + graph_render: function (options) { + var graph, data, mode_options, i; + + if (options) + for (i in options.data) + this[i] = options.data[i]; + + mode_options = (this.mode=='area')?{lines: {fill: true}}:{} + + // Render the graph + $(".graph_header_legend").children().remove() + data = this.get_data(mode_options); + graph = { + radar: graph_radar, + pie: graph_pie, + bar: graph_bar, + area: graph_line, + line: graph_line + }[this.mode](container, data) + + // Update styles of menus + + $("a[id^='graph_']").removeClass("active"); + $("a[id='graph_"+mode+"']").addClass("active"); + $("a[id='graph_"+mode+(this.stacked?"_stacked":"_not_stacked")+"']").addClass("active"); + + if (this.legend=='inside') + $("a[id='graph_legend_inside']").addClass("active"); + else if (this.legend=='top') + $("a[id='graph_legend_top']").addClass("active"); + else + $("a[id='graph_legend_no']").addClass("active"); + + if (this.spreadsheet) + $("a[id='graph_show_data']").addClass("active"); + return graph; + } + + schedule_chart: function(results) { - var self = this; - this.$element.html(QWeb.render("GraphView", { - "fields_view": this.fields_view, - "chart": this.chart, - 'element_id': this.getParent().element_id - })); - - var fields = _(this.columns).pluck('name').concat([this.abscissa]); - if (this.group_field) { fields.push(this.group_field); } - + self.graph_render(...) }, + + // render the graph using the domain, context and group_by + // calls the 'graph_data_get' python controller to process all data do_search: function(domain, context, group_by) { var self = this; return $.when(this.is_loaded).pipe(function() { - // TODO: handle non-empty group_by with read_group? - if (!_(group_by).isEmpty()) { - self.abscissa = group_by[0]; - } else { - self.abscissa = self.first_field; - } - return self.dataset.read_slice(self.list_fields()).then($.proxy(self, 'schedule_chart')); + // todo: find the right syntax to perform an Ajax call + return self.rpc.graph_get_data(self.view_id, domain, context, group_by).then($.proxy(self, 'schedule_chart')); }); }, diff --git a/addons/web_graph/static/src/xml/web_graph.xml b/addons/web_graph/static/src/xml/web_graph.xml index 710036d40d3..c11525ba353 100644 --- a/addons/web_graph/static/src/xml/web_graph.xml +++ b/addons/web_graph/static/src/xml/web_graph.xml @@ -1,49 +1,50 @@