diff options
| author | Géry Debongnie <ged@odoo.com> | 2017-03-05 10:05:56 +0100 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2017-04-11 19:44:38 +0200 |
| commit | 905e01921f3c3ef43ace6fc537d1d8c0d280002c (patch) | |
| tree | 265c43ab21c5401a5d9f0f3d64d86f1ac417451c /addons/web/static/src/js/views/graph_widget.js | |
| parent | 54d4c73af4ad05c7640d28c1892247c9538b8017 (diff) | |
[REF] web, *: redesign all JS views
This commit introduce a full redesign of all JS views. We started
basically from scratch. The goal was to unify all the various views
under a common framework, to make them testable, to make then usable in
different conditions (in studio, or in the frontend), and to make our
lives easier.
Some important points are:
- we introduced new coding guidelines (camelCase, 80 chars width, ...)
- we have a brand new testing framework (still QUnit based)
- kanban view moved to the web addon
- calendar view (formerly web_calender) moved to web as well
- the tree view was removed
- all new code should be documented
We hope that this code is the start of a new era for the Odoo web
client, we want to have a high quality codebase, well documented, well
tested, well designed.
Work done by the framework team: mostly aab, ged, chm, dmo, qsm
Diffstat (limited to 'addons/web/static/src/js/views/graph_widget.js')
| -rw-r--r-- | addons/web/static/src/js/views/graph_widget.js | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/addons/web/static/src/js/views/graph_widget.js b/addons/web/static/src/js/views/graph_widget.js deleted file mode 100644 index f778c7201ec..00000000000 --- a/addons/web/static/src/js/views/graph_widget.js +++ /dev/null @@ -1,340 +0,0 @@ -odoo.define('web.GraphWidget', function (require) { -"use strict"; - -var config = require('web.config'); -var core = require('web.core'); -var Model = require('web.DataModel'); -var formats = require('web.formats'); -var Widget = require('web.Widget'); - -var _t = core._t; -var QWeb = core.qweb; - -// hide top legend when too many item for device size -var MAX_LEGEND_LENGTH = 25 * (1 + config.device.size_class); - -return Widget.extend({ - className: "o_graph_svg_container", - init: function (parent, model, options) { - this._super(parent); - this.context = options.context; - this.fields = options.fields; - this.fields.__count__ = {string: _t("Count"), type: "integer"}; - this.model = new Model(model, {group_by_no_leaf: true}); - - this.domain = options.domain || []; - this.groupbys = options.groupbys || []; - this.mode = options.mode || "bar"; - this.measure = options.measure || "__count__"; - this.stacked = options.stacked; - }, - start: function () { - return this.load_data().then(this.proxy('display_graph')); - }, - update_data: function (domain, groupbys) { - this.domain = domain; - this.groupbys = groupbys; - return this.load_data().then(this.proxy('display_graph')); - }, - set_mode: function (mode) { - this.mode = mode; - this.display_graph(); - }, - set_measure: function (measure) { - this.measure = measure; - return this.load_data().then(this.proxy('display_graph')); - }, - load_data: function () { - var fields = this.groupbys.slice(0); - if (this.measure !== '__count__'.slice(0)) - fields = fields.concat(this.measure); - return this.model - .query(fields) - .filter(this.domain) - .context(this.context) - .lazy(false) - .group_by(this.groupbys.slice(0,2)) - .then(this.proxy('prepare_data')); - }, - prepare_data: function () { - var raw_data = arguments[0], - is_count = this.measure === '__count__'; - var data_pt, j, values, value; - - this.data = []; - for (var i = 0; i < raw_data.length; i++) { - data_pt = raw_data[i].attributes; - values = []; - if (this.groupbys.length === 1) data_pt.value = [data_pt.value]; - for (j = 0; j < data_pt.value.length; j++) { - values[j] = this.sanitize_value(data_pt.value[j], data_pt.grouped_on[j]); - } - value = is_count ? data_pt.length : data_pt.aggregates[this.measure]; - this.data.push({ - labels: values, - value: value - }); - } - }, - sanitize_value: function (value, field) { - if (value === false) return _t("Undefined"); - if (value instanceof Array) return value[1]; - if (field && this.fields[field] && (this.fields[field].type === 'selection')) { - var selected = _.where(this.fields[field].selection, {0: value})[0]; - return selected ? selected[1] : value; - } - return value; - }, - display_graph: function () { - if (this.to_remove) { - nv.utils.offWindowResize(this.to_remove); - } - this.$el.empty(); - if (!this.data.length) { - this.$el.append(QWeb.render('GraphView.error', { - title: _t("No data to display"), - description: _t("No data available for this chart. " + - "Try to add some records, or make sure that " + - "there is no active filter in the search bar."), - })); - } else { - var chart = this['display_' + this.mode](); - if (chart) { - chart.tooltip.chartContainer(this.$el[0]); - } - } - }, - display_bar: function () { - // prepare data for bar chart - var data, values, - measure = this.fields[this.measure].string, - self = this; - - // zero groupbys - if (this.groupbys.length === 0) { - data = [{ - values: [{ - x: measure, - y: this.data[0].value}], - key: measure - }]; - } - // one groupby - if (this.groupbys.length === 1) { - values = this.data.map(function (datapt) { - return {x: datapt.labels, y: datapt.value}; - }); - data = [ - { - values: values, - key: measure, - } - ]; - } - if (this.groupbys.length > 1) { - var xlabels = [], - series = [], - label, serie, value; - values = {}; - for (var i = 0; i < this.data.length; i++) { - label = this.data[i].labels[0]; - serie = this.data[i].labels[1]; - value = this.data[i].value; - if ((!xlabels.length) || (xlabels[xlabels.length-1] !== label)) { - xlabels.push(label); - } - series.push(this.data[i].labels[1]); - if (!(serie in values)) {values[serie] = {};} - values[serie][label] = this.data[i].value; - } - series = _.uniq(series); - data = []; - var current_serie, j; - for (i = 0; i < series.length; i++) { - current_serie = {values: [], key: series[i]}; - for (j = 0; j < xlabels.length; j++) { - current_serie.values.push({ - x: xlabels[j], - y: values[series[i]][xlabels[j]] || 0, - }); - } - data.push(current_serie); - } - } - var svg = d3.select(this.$el[0]).append('svg'); - svg.datum(data); - - svg.transition().duration(0); - - var chart = nv.models.multiBarChart(); - chart.options({ - margin: {left: 120, bottom: 60}, - delay: 250, - transition: 10, - showLegend: _.size(data) <= MAX_LEGEND_LENGTH, - showXAxis: true, - showYAxis: true, - rightAlignYAxis: false, - stacked: this.stacked, - reduceXTicks: false, - rotateLabels: -20, - showControls: (this.groupbys.length > 1) - }); - chart.yAxis.tickFormat(function(d) { - return formats.format_value(d, { - type : 'float', - digits : self.fields[self.measure] && self.fields[self.measure].digits || [69, 2], - }); - }); - - chart(svg); - this.to_remove = chart.update; - nv.utils.onWindowResize(chart.update); - - return chart; - }, - display_pie: function () { - var data = [], - all_negative = true, - some_negative = false, - all_zero = true; - - this.data.forEach(function (datapt) { - all_negative = all_negative && (datapt.value < 0); - some_negative = some_negative || (datapt.value < 0); - all_zero = all_zero && (datapt.value === 0); - }); - if (some_negative && !all_negative) { - this.$el.append(QWeb.render('GraphView.error', { - title: _t("Invalid data"), - description: _t("Pie chart cannot mix positive and negative numbers. " + - "Try to change your domain to only display positive results"), - })); - return; - } - if (all_zero) { - this.$el.append(QWeb.render('GraphView.error', { - title: _t("Invalid data"), - description: _t("Pie chart cannot display all zero numbers.. " + - "Try to change your domain to display positive results"), - })); - return; - } - if (this.groupbys.length) { - data = this.data.map(function (datapt) { - return {x:datapt.labels.join("/"), y: datapt.value}; - }); - } - var svg = d3.select(this.$el[0]).append('svg'); - svg.datum(data); - - svg.transition().duration(100); - - var legend_right = config.device.size_class > config.device.SIZES.XS; - - var chart = nv.models.pieChart().labelType('percent'); - chart.options({ - delay: 250, - showLegend: legend_right || _.size(data) <= MAX_LEGEND_LENGTH, - legendPosition: legend_right ? 'right' : 'top', - transition: 100, - color: d3.scale.category10().range(), - }); - - chart(svg); - this.to_remove = chart.update; - nv.utils.onWindowResize(chart.update); - - return chart; - }, - display_line: function () { - if (this.data.length < 2) { - this.$el.append(QWeb.render('GraphView.error', { - title: _t("Not enough data points"), - description: "You need at least two data points to display a line chart." - })); - return; - } - var self = this, - data = [], - tickValues, - tickFormat, - measure = this.fields[this.measure].string; - if (this.groupbys.length === 1) { - var values = this.data.map(function (datapt, index) { - return {x: index, y: datapt.value}; - }); - data = [ - { - values: values, - key: measure, - } - ]; - tickValues = this.data.map(function (d, i) { return i;}); - tickFormat = function (d) {return self.data[d].labels;}; - } - if (this.groupbys.length > 1) { - data = []; - var data_dict = {}, - tick = 0, - tickLabels = [], - serie, tickLabel, - identity = function (p) {return p;}; - tickValues = []; - for (var i = 0; i < this.data.length; i++) { - if (this.data[i].labels[0] !== tickLabel) { - tickLabel = this.data[i].labels[0]; - tickValues.push(tick); - tickLabels.push(tickLabel); - tick++; - } - serie = this.data[i].labels[1]; - if (!data_dict[serie]) { - data_dict[serie] = { - values: [], - key: serie, - }; - } - data_dict[serie].values.push({ - x: tick, y: this.data[i].value, - }); - data = _.map(data_dict, identity); - } - tickFormat = function (d) {return tickLabels[d];}; - } - - var svg = d3.select(this.$el[0]).append('svg'); - svg.datum(data); - - svg.transition().duration(0); - - var chart = nv.models.lineChart(); - chart.options({ - margin: {left: 120, bottom: 60}, - useInteractiveGuideline: true, - showLegend: _.size(data) <= MAX_LEGEND_LENGTH, - showXAxis: true, - showYAxis: true, - }); - chart.xAxis.tickValues(tickValues) - .tickFormat(tickFormat); - chart.yAxis.tickFormat(function(d) { - return formats.format_value(d, { - type : 'float', - digits : self.fields[self.measure] && self.fields[self.measure].digits || [69, 2], - }); - }); - - chart(svg); - this.to_remove = chart.update; - nv.utils.onWindowResize(chart.update); - - return chart; - }, - destroy: function () { - nv.utils.offWindowResize(this.to_remove); - return this._super(); - } -}); - -}); |
