summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/web/static/src/js/views/graph/graph_renderer.js57
1 files changed, 45 insertions, 12 deletions
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 8ce6ec14aba..bc11bb675df 100644
--- a/addons/web/static/src/js/views/graph/graph_renderer.js
+++ b/addons/web/static/src/js/views/graph/graph_renderer.js
@@ -42,6 +42,30 @@ return AbstractRenderer.extend({
nv.utils.offWindowResize(this.to_remove);
this._super();
},
+ /**
+ * The graph view uses the nv(d3) 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 flickering). We
+ * here use the on_attach_callback hook, called when the widget is attached
+ * to the DOM, to perform the rendering. This ensures that the rendering is
+ * always done in the DOM.
+ *
+ * @override
+ */
+ on_attach_callback: function () {
+ this._super.apply(this, arguments);
+ this.isInDOM = true;
+ this._renderGraph();
+ },
+ /**
+ * @override
+ */
+ on_detach_callback: function () {
+ this._super.apply(this, arguments);
+ this.isInDOM = false;
+ },
+
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
@@ -76,21 +100,15 @@ return AbstractRenderer.extend({
description: _t("Try to add some records, or make sure that " +
"there is no active filter in the search bar."),
}));
- } else {
- var self = this;
- setTimeout(function () {
- self.$el.empty();
- var chart = self['_render' + _.str.capitalize(self.state.mode) + 'Chart']();
- if (chart && chart.tooltip.chartContainer) {
- self.to_remove = chart.update;
- nv.utils.onWindowResize(chart.update);
- chart.tooltip.chartContainer(self.el);
- }
- }, 0);
+ } else if (this.isInDOM) {
+ // 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
+ // 'on_attach_callback')
+ this._renderGraph();
}
return this._super.apply(this, arguments);
},
-
/**
* Helper function to set up data properly for the multiBarChart model in
* nvd3.
@@ -327,6 +345,21 @@ return AbstractRenderer.extend({
chart(svg);
return chart;
},
+ /**
+ * Renders the graph according to its type. This function must be called
+ * when the renderer is in the DOM (for nvd3 to render the graph correctly).
+ *
+ * @private
+ */
+ _renderGraph: function () {
+ this.$el.empty();
+ var chart = this['_render' + _.str.capitalize(this.state.mode) + 'Chart']();
+ if (chart && chart.tooltip.chartContainer) {
+ this.to_remove = chart.update;
+ nv.utils.onWindowResize(chart.update);
+ chart.tooltip.chartContainer(this.el);
+ }
+ },
});
});