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`.
This commit is contained in:
Simon Brunel 2016-06-11 00:14:27 +02:00
parent dfdbd4465c
commit 53eb7667dd
3 changed files with 61 additions and 13 deletions

View File

@ -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) { }
}

View File

@ -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();

View File

@ -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,