summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/fields/basic_fields.js
diff options
context:
space:
mode:
authorGéry Debongnie <ged@odoo.com>2019-03-28 10:02:26 +0000
committerMathieu Duckerts-Antoine <dam@odoo.com>2019-04-01 14:40:51 +0000
commit769806ad136c681acfe5a9d7a42d0cd93fde8798 (patch)
tree2919da315d01617ca174bcfa7c999b460cf2cd2f /addons/web/static/src/js/fields/basic_fields.js
parent2af74a5f535a993cc5d78aa9ba248b717cc8f4c5 (diff)
[REF] reimplement journal dashboard widget with Chart.js
This commit is one part of the task 'removing nvd3'. We use now Chart.js to draw charts. Task ID: 1946138
Diffstat (limited to 'addons/web/static/src/js/fields/basic_fields.js')
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js211
1 files changed, 94 insertions, 117 deletions
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index 7439c36037f..4940839e612 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -2483,35 +2483,16 @@ var FieldToggleBoolean = AbstractField.extend({
var JournalDashboardGraph = AbstractField.extend({
className: "o_dashboard_graph",
- cssLibs: [
- '/web/static/lib/nvd3/nv.d3.css'
- ],
jsLibs: [
- '/web/static/lib/nvd3/d3.v3.js',
- '/web/static/lib/nvd3/nv.d3.js',
- '/web/static/src/js/libs/nvd3.js'
+ '/web/static/lib/Chart/Chart.js',
],
init: function () {
this._super.apply(this, arguments);
this.graph_type = this.attrs.graph_type;
this.data = JSON.parse(this.value);
},
- start: function () {
- this._onResize = this._onResize.bind(this);
- nv.utils.windowResize(this._onResize);
- return this._super.apply(this, arguments);
- },
- destroy: function () {
- if ('nv' in window && nv.utils && nv.utils.offWindowResize) {
- // if the widget is destroyed before the lazy loaded libs (nv) are
- // actually loaded (i.e. after the widget has actually started),
- // nv is undefined, but the handler isn't bound yet anyway
- nv.utils.offWindowResize(this._onResize);
- }
- this._super.apply(this, arguments);
- },
/**
- * The widget view uses the nv(d3) lib to render the graph. This lib
+ * The widget view uses the ChartJS lib to render the graph. This lib
* requires that the rendering is done directly into the DOM (so that it can
* correctly compute positions). However, the views are always rendered in
* fragments, and appended to the DOM once ready (to prevent them from
@@ -2535,23 +2516,7 @@ var JournalDashboardGraph = AbstractField.extend({
//--------------------------------------------------------------------------
/**
- * @private
- */
- _customizeChart: function () {
- if (this.graph_type === 'bar') {
- // Add classes related to time on each bar of the bar chart
- var bar_classes = _.map(this.data[0].values, function (v) {return v.type; });
-
- _.each(this.$('.nv-bar'), function (v, k){
- // classList doesn't work with phantomJS & addClass doesn't work with a SVG element
- $(v).attr('class', $(v).attr('class') + ' ' + bar_classes[k]);
- });
- }
- },
- /**
- * Render the widget only when it is in the DOM. This is because nvd3
- * renders graph only when it is in DOM, apparently to compute available
- * height and width for instance.
+ * Render the widget only when it is in the DOM.
*
* @override
* @private
@@ -2568,89 +2533,101 @@ var JournalDashboardGraph = AbstractField.extend({
* @private
*/
_renderInDOM: function () {
- // note: the rendering of this widget is aynchronous as nvd3 does a
- // setTimeout(0) before executing the callback given to addGraph
- var self = this;
this.$el.empty();
- this.chart = null;
- nv.addGraph(function () {
- self.$svg = self.$el.append('<svg>');
- switch (self.graph_type) {
- case "line":
- self.$svg.addClass('o_graph_linechart');
-
- self.chart = nv.models.lineChart();
- self.chart.forceY([0]);
- self.chart.options({
- x: function (d, u) { return u; },
- margin: {'left': 0, 'right': 0, 'top': 5, 'bottom': 0},
- showYAxis: false,
- showLegend: false,
- });
- self.chart.xAxis.tickFormat(function (d) {
- var label = '';
- _.each(self.data, function (v){
- if (v.values[d] && v.values[d].x){
- label = v.values[d].x;
- }
- });
- return label;
- });
- self.chart.yAxis.tickFormat(d3.format(',.2f'));
-
- self.chart.tooltip.contentGenerator(function (key) {
- return qweb.render('GraphCustomTooltip', {
- 'color': key.point.color,
- 'key': self.data[0].key,
- 'value': d3.format(',.2f')(key.point.y)
- });
- });
- break;
-
- case "bar":
- self.$svg.addClass('o_graph_barchart');
-
- self.chart = nv.models.discreteBarChart()
- .x(function (d) { return d.label; })
- .y(function (d) { return d.value; })
- .showValues(false)
- .showYAxis(false)
- .color(['#875A7B', '#526774', '#FA8072'])
- .margin({'left': 0, 'right': 0, 'top': 20, 'bottom': 20});
-
- self.chart.xAxis.axisLabel(self.data[0].title);
- self.chart.yAxis.tickFormat(d3.format(',.2f'));
-
- self.chart.tooltip.contentGenerator(function (key) {
- return qweb.render('GraphCustomTooltip', {
- 'color': key.color,
- 'key': self.data[0].key,
- 'value': d3.format(',.2f')(key.data.value)
- });
- });
- break;
- }
- d3.select(self.$('svg')[0])
- .datum(self.data)
- .transition().duration(600)
- .call(self.chart);
-
- self._customizeChart();
+ var config, cssClass;
+ if (this.graph_type === 'line') {
+ config = this._getLineChartConfig();
+ cssClass = 'o_graph_linechart';
+ } else if (this.graph_type === 'bar') {
+ config = this._getBarChartConfig();
+ cssClass = 'o_graph_barchart';
+ }
+ this.$canvas = $('<canvas/>');
+ this.$el.addClass(cssClass);
+ this.$el.empty();
+ this.$el.append(this.$canvas);
+ var context = this.$canvas[0].getContext('2d');
+ this.chart = new Chart(context, config);
+ },
+ _getLineChartConfig: function () {
+ var labels = this.data[0].values.map(function (pt) {
+ return pt.x;
});
+ var borderColor = this.data[0].is_sample_data ? '#dddddd' : '#875a7b';
+ var backgroundColor = this.data[0].is_sample_data ? '#ebebeb' : '#dcd0d9';
+ return {
+ type: 'line',
+ data: {
+ labels: labels,
+ datasets: [{
+ data: this.data[0].values,
+ fill: 'start',
+ label: this.data[0].key,
+ backgroundColor: backgroundColor,
+ borderColor: borderColor,
+ borderWidth: 2,
+ }]
+ },
+ options: {
+ legend: {display: false},
+ scales: {
+ yAxes: [{display: false}],
+ xAxes: [{display: false}]
+ },
+ maintainAspectRatio: false,
+ elements: {
+ line: {
+ tension: 0.000001
+ }
+ },
+ tooltips: {
+ intersect: false,
+ position: 'nearest',
+ caretSize: 0,
+ },
+ },
+ };
},
+ _getBarChartConfig: function () {
+ var data = [];
+ var labels = [];
+ var backgroundColor = [];
- //--------------------------------------------------------------------------
- // Handlers
- //--------------------------------------------------------------------------
-
- /**
- * @private
- */
- _onResize: function () {
- if (this.chart) {
- this.chart.update();
- this._customizeChart();
- }
+ this.data[0].values.forEach(function (pt) {
+ data.push(pt.value);
+ labels.push(pt.label);
+ var color = pt.type === 'past' ? '#ccbdc8' : (pt.type === 'future' ? '#a5d8d7' : '#ebebeb');
+ backgroundColor.push(color);
+ });
+ return {
+ type: 'bar',
+ data: {
+ labels: labels,
+ datasets: [{
+ data: data,
+ fill: 'start',
+ label: this.data[0].key,
+ backgroundColor: backgroundColor,
+ }]
+ },
+ options: {
+ legend: {display: false},
+ scales: {
+ yAxes: [{display: false}],
+ },
+ maintainAspectRatio: false,
+ tooltips: {
+ intersect: false,
+ position: 'nearest',
+ caretSize: 0,
+ },
+ elements: {
+ line: {
+ tension: 0.000001
+ }
+ },
+ },
+ };
},
});