From 53eb7667dd25f53fbf0d65e28370b32d90ab9448 Mon Sep 17 00:00:00 2001 From: Simon Brunel Date: Sat, 11 Jun 2016 00:14:27 +0200 Subject: [PATCH] New datasets update plugin extensions Add `beforeDatasetsUpdate` and `afterDatasetsUpdate` plugin notifications during the chart update. Plugins are able to cancel the datasets update by explicitly returning false to `beforeDatasetsUpdate`. For consistency, rename `(before|after)DatasetDraw` to `(before|after)DatasetsDraw`. --- docs/09-Advanced.md | 10 +++++-- src/core/core.controller.js | 57 +++++++++++++++++++++++++++++++------ src/core/core.plugin.js | 7 +++-- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/docs/09-Advanced.md b/docs/09-Advanced.md index 952ec88f5..58dd50da9 100644 --- a/docs/09-Advanced.md +++ b/docs/09-Advanced.md @@ -378,6 +378,8 @@ Plugins will be called at the following times * End of initialization * Start of update * After the chart scales have calculated +* Start of datasets update +* End of datasets update * End of update (before render occurs) * Start of draw * End of draw @@ -396,9 +398,11 @@ Plugins should derive from Chart.PluginBase and implement the following interfac beforeUpdate: function(chartInstance) { }, afterScaleUpdate: function(chartInstance) { } + beforeDatasetsUpdate: function(chartInstance) { } + afterDatasetsUpdate: function(chartInstance) { } afterUpdate: function(chartInstance) { }, - // This is called at the start of a render. It is only called once, even if the animation will run for a number of frames. Use beforeDraw or afterDraw + // This is called at the start of a render. It is only called once, even if the animation will run for a number of frames. Use beforeDraw or afterDraw // to do something on each animation frame beforeRender: function(chartInstance) { }, @@ -406,8 +410,8 @@ Plugins should derive from Chart.PluginBase and implement the following interfac beforeDraw: function(chartInstance, easing) { }, afterDraw: function(chartInstance, easing) { }, // Before the datasets are drawn but after scales are drawn - beforeDatasetDraw: function(chartInstance, easing) { }, - afterDatasetDraw: function(chartInstance, easing) { }, + beforeDatasetsDraw: function(chartInstance, easing) { }, + afterDatasetsDraw: function(chartInstance, easing) { }, destroy: function(chartInstance) { } } diff --git a/src/core/core.controller.js b/src/core/core.controller.js index eb472d63c..2d0148b77 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -13,7 +13,10 @@ module.exports = function(Chart) { // Controllers available for dataset visualization eg. bar, line, slice, etc. Chart.controllers = {}; - // The main controller of a chart + /** + * @class Chart.Controller + * The main controller of a chart. + */ Chart.Controller = function(instance) { this.chart = instance; @@ -40,7 +43,7 @@ module.exports = function(Chart) { return this; }; - helpers.extend(Chart.Controller.prototype, { + helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ { initialize: function initialize() { var me = this; @@ -248,10 +251,7 @@ module.exports = function(Chart) { controller.reset(); }); - // This will loop through any data and do the appropriate element update for the type - helpers.each(me.data.datasets, function(dataset, datasetIndex) { - me.getDatasetMeta(datasetIndex).controller.update(); - }, me); + me.updateDatasets(); // Do this before render so that any plugins that need final scale updates can use it Chart.plugins.notify('afterUpdate', [me]); @@ -259,6 +259,47 @@ module.exports = function(Chart) { me.render(animationDuration, lazy); }, + /** + * @method beforeDatasetsUpdate + * @description Called before all datasets are updated. If a plugin returns false, + * the datasets update will be cancelled until another chart update is triggered. + * @param {Object} instance the chart instance being updated. + * @returns {Boolean} false to cancel the datasets update. + * @memberof Chart.PluginBase + * @since version 2.1.5 + * @instance + */ + + /** + * @method afterDatasetsUpdate + * @description Called after all datasets have been updated. Note that this + * extension will not be called if the datasets update has been cancelled. + * @param {Object} instance the chart instance being updated. + * @memberof Chart.PluginBase + * @since version 2.1.5 + * @instance + */ + + /** + * Updates all datasets unless a plugin returns false to the beforeDatasetsUpdate + * extension, in which case no datasets will be updated and the afterDatasetsUpdate + * notification will be skipped. + * @protected + * @instance + */ + updateDatasets: function() { + var me = this; + var i, ilen; + + if (Chart.plugins.notify('beforeDatasetsUpdate', [ me ])) { + for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) { + me.getDatasetMeta(i).controller.update(); + } + + Chart.plugins.notify('afterDatasetsUpdate', [ me ]); + } + }, + render: function render(duration, lazy) { var me = this; Chart.plugins.notify('beforeRender', [me]); @@ -307,7 +348,7 @@ module.exports = function(Chart) { me.scale.draw(); } - Chart.plugins.notify('beforeDatasetDraw', [me, easingDecimal]); + Chart.plugins.notify('beforeDatasetsDraw', [me, easingDecimal]); // Draw each dataset via its respective controller (reversed to support proper line stacking) helpers.each(me.data.datasets, function(dataset, datasetIndex) { @@ -316,7 +357,7 @@ module.exports = function(Chart) { } }, me, true); - Chart.plugins.notify('afterDatasetDraw', [me, easingDecimal]); + Chart.plugins.notify('afterDatasetsDraw', [me, easingDecimal]); // Finally draw the tooltip me.tooltip.transition(easingDecimal).draw(); diff --git a/src/core/core.plugin.js b/src/core/core.plugin.js index 5fce40077..d6f95c4d1 100644 --- a/src/core/core.plugin.js +++ b/src/core/core.plugin.js @@ -91,9 +91,12 @@ module.exports = function(Chart) { } }; + /** + * Plugin extension methods. + * @interface Chart.PluginBase + * @since 2.1.0 + */ Chart.PluginBase = Chart.Element.extend({ - // Plugin extensions. All functions are passed the chart instance - // Called at start of chart init beforeInit: noop, -- 2.47.2