From ae58021255274d3733e58ee8b020ca275aaa430d Mon Sep 17 00:00:00 2001 From: Mathieu Duckerts-Antoine Date: Mon, 10 Aug 2020 14:27:58 +0000 Subject: [PATCH] [IMP] web: sample data in graph view A previous commit has paved the way for displaying sample data in the reporting views. The present commit brings the required changes to have sample data in graph views. Task ID: 2282196 Co-authored-by: Aaron Bohy Co-authored-by: Mathieu Duckerts-Antoine --- .../static/src/js/views/graph/graph_model.js | 9 +- .../src/js/views/graph/graph_renderer.js | 79 ++++++---- addons/web/static/src/xml/base.xml | 12 +- addons/web/static/tests/views/graph_tests.js | 145 ++++++++++++++---- odoo/addons/base/rng/graph_view.rng | 1 + 5 files changed, 169 insertions(+), 77 deletions(-) diff --git a/addons/web/static/src/js/views/graph/graph_model.js b/addons/web/static/src/js/views/graph/graph_model.js index 8679fafe4ff..b1bcddb47c2 100644 --- a/addons/web/static/src/js/views/graph/graph_model.js +++ b/addons/web/static/src/js/views/graph/graph_model.js @@ -35,7 +35,7 @@ return AbstractModel.extend({ * @returns {Object} */ __get: function () { - return _.extend({}, this.chart); + return Object.assign({ isSample: this.isSampleModel }, this.chart); }, /** * Initial loading. @@ -165,7 +165,12 @@ return AbstractModel.extend({ this.chart.comparisonFieldIndex = -1; } }, - + /** + * @override + */ + _isEmpty() { + return this.chart.dataPoints.length === 0; + }, /** * Fetch and process graph data. It is basically a(some) read_group(s) * with correct fields for each domain. We have to do some light processing diff --git a/addons/web/static/src/js/views/graph/graph_renderer.js b/addons/web/static/src/js/views/graph/graph_renderer.js index 52608e7b9cd..5cbe3f75324 100644 --- a/addons/web/static/src/js/views/graph/graph_renderer.js +++ b/addons/web/static/src/js/views/graph/graph_renderer.js @@ -54,6 +54,7 @@ var MAX_LEGEND_LENGTH = 4 * (Math.max(1, config.device.size_class)); return AbstractRenderer.extend({ className: "o_graph_renderer", + sampleDataTargets: ['.o_graph_canvas_container'], /** * @override * @param {Widget} parent @@ -762,9 +763,30 @@ return AbstractRenderer.extend({ } var dataPoints = this._filterDataPoints(); dataPoints = this._sortDataPoints(dataPoints); - if (!dataPoints.length && this.state.mode !== 'pie') { - this.$el.append(qweb.render('View.NoContentHelper')); - } else if (this.isInDOM) { + if (this.isInDOM) { + this._renderTitle(); + + // detect if some pathologies are still present after the filtering + if (this.state.mode === 'pie') { + const someNegative = dataPoints.some(dataPt => dataPt.value < 0); + const somePositive = dataPoints.some(dataPt => dataPt.value > 0); + if (someNegative && somePositive) { + const context = { + title: _t("Invalid data"), + description: [ + _t("Pie chart cannot mix positive and negative numbers. "), + _t("Try to change your domain to only display positive results") + ].join("") + }; + this._renderNoContentHelper(context); + return; + } + } + + if (this.state.isSample && !this.isEmbedded) { + this._renderNoContentHelper(); + } + // only render the graph if the widget is already in the DOM (this // happens typically after an update), otherwise, it will be // rendered when the widget will be attached to the DOM (see @@ -785,8 +807,6 @@ return AbstractRenderer.extend({ } else if (this.state.mode === 'pie') { this._renderPieChart(dataPoints); } - - this._renderTitle(); } }, /** @@ -875,6 +895,25 @@ return AbstractRenderer.extend({ options: options, }); }, + /** + * @private + */ + _renderNoContentHelper: function (context) { + let templateName; + if (!context && this.noContentHelp) { + templateName = "web.ActionHelper"; + context = { noContentHelp: this.noContentHelp }; + } else { + templateName = "web.NoContentHelper"; + } + const template = document.createElement('template'); + // FIXME: retrieve owl qweb instance via the env set on Component s.t. + // it also works in the tests (importing 'web.env' wouldn't). This won't + // be necessary as soon as this rendering will be written in owl. + const OwlQweb = owl.Component.env.qweb; + template.innerHTML = OwlQweb.renderToString(templateName, context); + this.el.append(template.content.firstChild); + }, /** * create pie chart * @@ -883,38 +922,10 @@ return AbstractRenderer.extend({ */ _renderPieChart: function (dataPoints) { var self = this; - - // try to see if some pathologies are still present after the filtering - var allNegative = true; - var someNegative = false; - var allZero = true; - dataPoints.forEach(function (datapt) { - allNegative = allNegative && (datapt.value < 0); - someNegative = someNegative || (datapt.value < 0); - allZero = allZero && (datapt.value === 0); - }); - if (someNegative && !allNegative) { - this.$el.empty(); - this.$el.append(qweb.render('View.NoContentHelper', { - 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 (allZero && !this.isEmbedded && this.state.origins.length === 1) { - this.$el.empty(); - this.$el.append(qweb.render('View.NoContentHelper', { - title: _t("Invalid data"), - description: _t("Pie chart cannot display all zero numbers.. " + - "Try to change your domain to display positive results"), - })); - return; - } - // prepare data var data = {}; var colors = []; + const allZero = dataPoints.every(dataPt => dataPt.value === 0); if (allZero) { // add fake data to display a pie chart with a grey zone associated // with every origin diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 12eff26e6ac..27cc0fdc4f9 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -803,17 +803,9 @@ -