From: Jukka Kurkela Date: Sat, 28 Nov 2020 07:45:43 +0000 (+0200) Subject: Unify signature of plugin hooks (#8102) X-Git-Tag: v3.0.0-beta.7~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=61aea761f487edb2796b0cea4bb836ccb49ef86c;p=thirdparty%2FChart.js.git Unify signature of plugin hooks (#8102) --- diff --git a/docs/docs/getting-started/v3-migration.md b/docs/docs/getting-started/v3-migration.md index 922e70efc..aaace7c45 100644 --- a/docs/docs/getting-started/v3-migration.md +++ b/docs/docs/getting-started/v3-migration.md @@ -494,6 +494,7 @@ All helpers are now exposed in a flat hierarchy, e.g., `Chart.helpers.canvas.cli #### IPlugin interface +* All plugin hooks have unified signature with 3 arguments: `chart`, `args` and `options`. This means change in signature for these hooks: `beforeInit`, `afterInit`, `reset`, `beforeLayout`, `afterLayout`, `beforeRender`, `afterRender`, `beforeDraw`, `afterDraw`, `beforeDatasetsDraw`, `afterDatasetsDraw`, `beforeEvent`, `afterEvent`, `resize`, `destroy`. * `afterDatasetsUpdate`, `afterUpdate`, `beforeDatasetsUpdate`, and `beforeUpdate` now receive `args` object as second argument. `options` argument is always the last and thus was moved from 2nd to 3rd place. -* `afterEvent` and `beforeEvent` now receive a wrapped `event` as the second argument. The native event is available via `event.native`. +* `afterEvent` and `beforeEvent` now receive a wrapped `event` as the `event` property of the second argument. The native event is available via `args.event.native`. * Initial `resize` is no longer silent. Meaning that `resize` event can fire between `beforeInit` and `afterInit` diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 3a1202067..7d2c564f9 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -33,7 +33,7 @@ function onAnimationsComplete(context) { const chart = context.chart; const animationOptions = chart.options.animation; - chart._plugins.notify(chart, 'afterRender'); + chart.notifyPlugins('afterRender'); callCallback(animationOptions && animationOptions.onComplete, [context], chart); } @@ -151,7 +151,7 @@ class Chart { const me = this; // Before init plugin notification - me._plugins.notify(me, 'beforeInit'); + me.notifyPlugins('beforeInit'); if (me.options.responsive) { me.resize(); @@ -162,7 +162,7 @@ class Chart { me.bindEvents(); // After init plugin notification - me._plugins.notify(me, 'afterInit'); + me.notifyPlugins('afterInit'); return me; } @@ -221,7 +221,7 @@ class Chart { retinaScale(me, newRatio); - me._plugins.notify(me, 'resize', [newSize]); + me.notifyPlugins('resize', {size: newSize}); callCallback(options.onResize, [newSize], me); @@ -435,7 +435,7 @@ class Chart { */ reset() { this._resetElements(); - this._plugins.notify(this, 'reset'); + this.notifyPlugins('reset'); } update(mode) { @@ -458,7 +458,7 @@ class Chart { // https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167 me._plugins.invalidate(); - if (me._plugins.notify(me, 'beforeUpdate', [args]) === false) { + if (me.notifyPlugins('beforeUpdate', args) === false) { return; } @@ -480,7 +480,7 @@ class Chart { me._updateDatasets(mode); // Do this before render so that any plugins that need final scale updates can use it - me._plugins.notify(me, 'afterUpdate', [args]); + me.notifyPlugins('afterUpdate', args); me._layers.sort(compare2Level('z', '_idx')); @@ -500,7 +500,7 @@ class Chart { _updateLayout() { const me = this; - if (me._plugins.notify(me, 'beforeLayout') === false) { + if (me.notifyPlugins('beforeLayout') === false) { return; } @@ -520,7 +520,7 @@ class Chart { item._idx = index; }); - me._plugins.notify(me, 'afterLayout'); + me.notifyPlugins('afterLayout'); } /** @@ -533,7 +533,7 @@ class Chart { const isFunction = typeof mode === 'function'; const args = {mode}; - if (me._plugins.notify(me, 'beforeDatasetsUpdate', [args]) === false) { + if (me.notifyPlugins('beforeDatasetsUpdate', args) === false) { return; } @@ -541,7 +541,7 @@ class Chart { me._updateDataset(i, isFunction ? mode({datasetIndex: i}) : mode); } - me._plugins.notify(me, 'afterDatasetsUpdate', [args]); + me.notifyPlugins('afterDatasetsUpdate', args); } /** @@ -554,18 +554,18 @@ class Chart { const meta = me.getDatasetMeta(index); const args = {meta, index, mode}; - if (me._plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) { + if (me.notifyPlugins('beforeDatasetUpdate', args) === false) { return; } meta.controller._update(mode); - me._plugins.notify(me, 'afterDatasetUpdate', [args]); + me.notifyPlugins('afterDatasetUpdate', args); } render() { const me = this; - if (me._plugins.notify(me, 'beforeRender') === false) { + if (me.notifyPlugins('beforeRender') === false) { return; } @@ -593,7 +593,7 @@ class Chart { return; } - if (me._plugins.notify(me, 'beforeDraw') === false) { + if (me.notifyPlugins('beforeDraw') === false) { return; } @@ -612,7 +612,7 @@ class Chart { layers[i].draw(me.chartArea); } - me._plugins.notify(me, 'afterDraw'); + me.notifyPlugins('afterDraw'); } /** @@ -650,7 +650,7 @@ class Chart { _drawDatasets() { const me = this; - if (me._plugins.notify(me, 'beforeDatasetsDraw') === false) { + if (me.notifyPlugins('beforeDatasetsDraw') === false) { return; } @@ -659,7 +659,7 @@ class Chart { me._drawDataset(metasets[i]); } - me._plugins.notify(me, 'afterDatasetsDraw'); + me.notifyPlugins('afterDatasetsDraw'); } /** @@ -677,7 +677,7 @@ class Chart { index: meta.index, }; - if (me._plugins.notify(me, 'beforeDatasetDraw', [args]) === false) { + if (me.notifyPlugins('beforeDatasetDraw', args) === false) { return; } @@ -692,7 +692,7 @@ class Chart { unclipArea(ctx); - me._plugins.notify(me, 'afterDatasetDraw', [args]); + me.notifyPlugins('afterDatasetDraw', args); } getElementsAtEventForMode(e, mode, options, useFinalPosition) { @@ -829,7 +829,7 @@ class Chart { me.ctx = null; } - me._plugins.notify(me, 'destroy'); + me.notifyPlugins('destroy'); delete Chart.instances[me.id]; } @@ -968,6 +968,18 @@ class Chart { } } + /** + * Calls enabled plugins on the specified hook and with the given args. + * This method immediately returns as soon as a plugin explicitly returns false. The + * returned value can be used, for instance, to interrupt the current action. + * @param {string} hook - The name of the plugin method to call (e.g. 'beforeUpdate'). + * @param {Object} [args] - Extra arguments to apply to the hook call. + * @returns {boolean} false if any of the plugins return false, else returns true. + */ + notifyPlugins(hook, args) { + return this._plugins.notify(this, hook, args); + } + /** * @private */ @@ -992,14 +1004,15 @@ class Chart { */ _eventHandler(e, replay) { const me = this; + const args = {event: e, replay}; - if (me._plugins.notify(me, 'beforeEvent', [e, replay]) === false) { + if (me.notifyPlugins('beforeEvent', args) === false) { return; } const changed = me._handleEvent(e, replay); - me._plugins.notify(me, 'afterEvent', [e, replay]); + me.notifyPlugins('afterEvent', args); if (changed) { me.render(); diff --git a/src/core/core.plugins.js b/src/core/core.plugins.js index b7839d356..5950d342f 100644 --- a/src/core/core.plugins.js +++ b/src/core/core.plugins.js @@ -15,10 +15,11 @@ export default class PluginService { * returned value can be used, for instance, to interrupt the current action. * @param {Chart} chart - The chart instance for which plugins should be called. * @param {string} hook - The name of the plugin method to call (e.g. 'beforeUpdate'). - * @param {Array} [args] - Extra arguments to apply to the hook call. + * @param {object} [args] - Extra arguments to apply to the hook call. * @returns {boolean} false if any of the plugins return false, else returns true. */ notify(chart, hook, args) { + args = args || {}; const descriptors = this._descriptors(chart); for (let i = 0; i < descriptors.length; ++i) { @@ -26,8 +27,7 @@ export default class PluginService { const plugin = descriptor.plugin; const method = plugin[hook]; if (typeof method === 'function') { - const params = [chart].concat(args || []); - params.push(descriptor.options); + const params = [chart, args, descriptor.options]; if (method.apply(plugin, params) === false) { return false; } @@ -117,12 +117,14 @@ function createDescriptors(plugins, options) { * @method IPlugin#beforeInit * @desc Called before initializing `chart`. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ /** * @method IPlugin#afterInit * @desc Called after `chart` has been initialized and before the first update. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ /** @@ -148,6 +150,7 @@ function createDescriptors(plugins, options) { * @method IPlugin#reset * @desc Called during chart reset * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @since version 3.0.0 */ @@ -200,6 +203,7 @@ function createDescriptors(plugins, options) { * @desc Called before laying out `chart`. If any plugin returns `false`, * the layout update is cancelled until another `update` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart layout. */ @@ -208,6 +212,7 @@ function createDescriptors(plugins, options) { * @desc Called after the `chart` has been laid out. Note that this hook will not * be called if the layout update has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ /** @@ -215,6 +220,7 @@ function createDescriptors(plugins, options) { * @desc Called before rendering `chart`. If any plugin returns `false`, * the rendering is cancelled until another `render` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart rendering. */ @@ -223,6 +229,7 @@ function createDescriptors(plugins, options) { * @desc Called after the `chart` has been fully rendered (and animation completed). Note * that this hook will not be called if the rendering has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ /** @@ -230,6 +237,7 @@ function createDescriptors(plugins, options) { * @desc Called before drawing `chart` at every animation frame. If any plugin returns `false`, * the frame drawing is cancelled until another `render` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart drawing. */ @@ -238,6 +246,7 @@ function createDescriptors(plugins, options) { * @desc Called after the `chart` has been drawn. Note that this hook will not be called * if the drawing has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ /** @@ -245,6 +254,7 @@ function createDescriptors(plugins, options) { * @desc Called before drawing the `chart` datasets. If any plugin returns `false`, * the datasets drawing is cancelled until another `render` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart datasets drawing. */ @@ -253,6 +263,7 @@ function createDescriptors(plugins, options) { * @desc Called after the `chart` datasets have been drawn. Note that this hook * will not be called if the datasets drawing has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ /** @@ -302,8 +313,9 @@ function createDescriptors(plugins, options) { * @desc Called before processing the specified `event`. If any plugin returns `false`, * the event will be discarded. * @param {Chart} chart - The chart instance. - * @param {ChartEvent} event - The event object. - * @param {boolean} replay - True if this event is replayed from `Chart.update` + * @param {object} args - The call arguments. + * @param {ChartEvent} args.event - The event object. + * @param {boolean} args.replay - True if this event is replayed from `Chart.update` * @param {object} options - The plugin options. */ /** @@ -311,20 +323,23 @@ function createDescriptors(plugins, options) { * @desc Called after the `event` has been consumed. Note that this hook * will not be called if the `event` has been previously discarded. * @param {Chart} chart - The chart instance. - * @param {ChartEvent} event - The event object. - * @param {boolean} replay - True if this event is replayed from `Chart.update` + * @param {object} args - The call arguments. + * @param {ChartEvent} args.event - The event object. + * @param {boolean} args.replay - True if this event is replayed from `Chart.update` * @param {object} options - The plugin options. */ /** * @method IPlugin#resize * @desc Called after the chart as been resized. * @param {Chart} chart - The chart instance. - * @param {number} size - The new canvas display size (eq. canvas.style width & height). + * @param {object} args - The call arguments. + * @param {number} args.size - The new canvas display size (eq. canvas.style width & height). * @param {object} options - The plugin options. */ /** * @method IPlugin#destroy * @desc Called after the chart as been destroyed. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index d4f151571..133df9da3 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -690,10 +690,10 @@ export default { }, - afterEvent(chart, e) { + afterEvent(chart, args) { const legend = chart.legend; if (legend) { - legend.handleEvent(e); + legend.handleEvent(args.event); } }, diff --git a/src/plugins/plugin.tooltip.js b/src/plugins/plugin.tooltip.js index d4a737384..15f40fb52 100644 --- a/src/plugins/plugin.tooltip.js +++ b/src/plugins/plugin.tooltip.js @@ -1074,7 +1074,7 @@ export default { tooltip }; - if (chart._plugins.notify(chart, 'beforeTooltipDraw', [args]) === false) { + if (chart.notifyPlugins('beforeTooltipDraw', args) === false) { return; } @@ -1082,14 +1082,14 @@ export default { tooltip.draw(chart.ctx); } - chart._plugins.notify(chart, 'afterTooltipDraw', [args]); + chart.notifyPlugins('afterTooltipDraw', args); }, - afterEvent(chart, e, replay) { + afterEvent(chart, args) { if (chart.tooltip) { // If the event is replayed from `update`, we should evaluate with the final positions. - const useFinalPosition = replay; - chart.tooltip.handleEvent(e, useFinalPosition); + const useFinalPosition = args.replay; + chart.tooltip.handleEvent(args.event, useFinalPosition); } }, diff --git a/test/specs/core.plugin.tests.js b/test/specs/core.plugin.tests.js index a84ed9bef..988d061e6 100644 --- a/test/specs/core.plugin.tests.js +++ b/test/specs/core.plugin.tests.js @@ -1,31 +1,33 @@ describe('Chart.plugins', function() { - describe('Chart.plugins.notify', function() { + describe('Chart.notifyPlugins', function() { it('should call inline plugins with arguments', function() { var plugin = {hook: function() {}}; var chart = window.acquireChart({ plugins: [plugin] }); + var args = {value: 42}; spyOn(plugin, 'hook'); - chart._plugins.notify(chart, 'hook', 42); + chart.notifyPlugins('hook', args); expect(plugin.hook.calls.count()).toBe(1); expect(plugin.hook.calls.first().args[0]).toBe(chart); - expect(plugin.hook.calls.first().args[1]).toBe(42); + expect(plugin.hook.calls.first().args[1]).toBe(args); expect(plugin.hook.calls.first().args[2]).toEqual({}); }); it('should call global plugins with arguments', function() { var plugin = {id: 'a', hook: function() {}}; var chart = window.acquireChart({}); + var args = {value: 42}; spyOn(plugin, 'hook'); Chart.register(plugin); - chart._plugins.notify(chart, 'hook', 42); + chart.notifyPlugins('hook', args); expect(plugin.hook.calls.count()).toBe(1); expect(plugin.hook.calls.first().args[0]).toBe(chart); - expect(plugin.hook.calls.first().args[1]).toBe(42); + expect(plugin.hook.calls.first().args[1]).toBe(args); expect(plugin.hook.calls.first().args[2]).toEqual({}); Chart.unregister(plugin); }); @@ -39,7 +41,7 @@ describe('Chart.plugins', function() { spyOn(plugin, 'hook'); Chart.register([plugin, plugin]); - chart._plugins.notify(chart, 'hook'); + chart.notifyPlugins('hook'); expect(plugin.hook.calls.count()).toBe(1); Chart.unregister(plugin); }); @@ -80,7 +82,7 @@ describe('Chart.plugins', function() { }]; Chart.register(plugins); - var ret = chart._plugins.notify(chart, 'hook'); + var ret = chart.notifyPlugins('hook'); expect(ret).toBeTruthy(); expect(results).toEqual([4, 5, 6, 1, 2, 3]); Chart.unregister(plugins); @@ -114,7 +116,7 @@ describe('Chart.plugins', function() { spyOn(plugin, 'hook').and.callThrough(); }); - var ret = chart._plugins.notify(chart, 'hook'); + var ret = chart.notifyPlugins('hook'); expect(ret).toBeTruthy(); plugins.forEach(function(plugin) { expect(plugin.hook).toHaveBeenCalled(); @@ -149,7 +151,7 @@ describe('Chart.plugins', function() { spyOn(plugin, 'hook').and.callThrough(); }); - var ret = chart._plugins.notify(chart, 'hook'); + var ret = chart.notifyPlugins('hook'); expect(ret).toBeFalsy(); expect(plugins[0].hook).toHaveBeenCalled(); expect(plugins[1].hook).toHaveBeenCalled(); @@ -174,14 +176,14 @@ describe('Chart.plugins', function() { spyOn(plugin, 'hook'); Chart.register(plugin); - chart._plugins.notify(chart, 'hook'); - chart._plugins.notify(chart, 'hook', ['bla']); - chart._plugins.notify(chart, 'hook', ['bla', 42]); + chart.notifyPlugins('hook'); + chart.notifyPlugins('hook', {arg1: 'bla'}); + chart.notifyPlugins('hook', {arg1: 'bla', arg2: 42}); expect(plugin.hook.calls.count()).toBe(3); - expect(plugin.hook.calls.argsFor(0)[1]).toEqual({a: '123'}); + expect(plugin.hook.calls.argsFor(0)[2]).toEqual({a: '123'}); expect(plugin.hook.calls.argsFor(1)[2]).toEqual({a: '123'}); - expect(plugin.hook.calls.argsFor(2)[3]).toEqual({a: '123'}); + expect(plugin.hook.calls.argsFor(2)[2]).toEqual({a: '123'}); Chart.unregister(plugin); }); @@ -210,14 +212,14 @@ describe('Chart.plugins', function() { spyOn(plugins.b, 'hook'); spyOn(plugins.c, 'hook'); - chart._plugins.notify(chart, 'hook'); + chart.notifyPlugins('hook'); expect(plugins.a.hook).toHaveBeenCalled(); expect(plugins.b.hook).toHaveBeenCalled(); expect(plugins.c.hook).toHaveBeenCalled(); - expect(plugins.a.hook.calls.first().args[1]).toEqual({a: '123'}); - expect(plugins.b.hook.calls.first().args[1]).toEqual({b: '456'}); - expect(plugins.c.hook.calls.first().args[1]).toEqual({c: '789'}); + expect(plugins.a.hook.calls.first().args[2]).toEqual({a: '123'}); + expect(plugins.b.hook.calls.first().args[2]).toEqual({b: '456'}); + expect(plugins.c.hook.calls.first().args[2]).toEqual({c: '789'}); Chart.unregister(plugins.a); }); @@ -245,7 +247,7 @@ describe('Chart.plugins', function() { spyOn(plugins.b, 'hook'); spyOn(plugins.c, 'hook'); - chart._plugins.notify(chart, 'hook'); + chart.notifyPlugins('hook'); expect(plugins.a.hook).not.toHaveBeenCalled(); expect(plugins.b.hook).not.toHaveBeenCalled(); @@ -269,10 +271,10 @@ describe('Chart.plugins', function() { spyOn(plugin, 'hook'); - chart._plugins.notify(chart, 'hook'); + chart.notifyPlugins('hook'); expect(plugin.hook).toHaveBeenCalled(); - expect(plugin.hook.calls.first().args[1]).toEqual({a: 42}); + expect(plugin.hook.calls.first().args[2]).toEqual({a: 42}); Chart.unregister(plugin); }); @@ -286,10 +288,10 @@ describe('Chart.plugins', function() { var chart = window.acquireChart(); - chart._plugins.notify(chart, 'hook'); + chart.notifyPlugins('hook'); expect(plugin.hook).toHaveBeenCalled(); - expect(plugin.hook.calls.first().args[1]).toEqual({a: 'foobar'}); + expect(plugin.hook.calls.first().args[2]).toEqual({a: 'foobar'}); Chart.unregister(plugin); }); @@ -310,19 +312,19 @@ describe('Chart.plugins', function() { spyOn(plugin, 'hook'); - chart._plugins.notify(chart, 'hook'); + chart.notifyPlugins('hook'); expect(plugin.hook).toHaveBeenCalled(); - expect(plugin.hook.calls.first().args[1]).toEqual({foo: 'foo'}); + expect(plugin.hook.calls.first().args[2]).toEqual({foo: 'foo'}); chart.options.plugins.a = {bar: 'bar'}; chart.update(); plugin.hook.calls.reset(); - chart._plugins.notify(chart, 'hook'); + chart.notifyPlugins('hook'); expect(plugin.hook).toHaveBeenCalled(); - expect(plugin.hook.calls.first().args[1]).toEqual({bar: 'bar'}); + expect(plugin.hook.calls.first().args[2]).toEqual({bar: 'bar'}); }); it('should disable all plugins', function() { @@ -336,7 +338,7 @@ describe('Chart.plugins', function() { spyOn(plugin, 'hook'); - chart._plugins.notify(chart, 'hook'); + chart.notifyPlugins('hook'); expect(plugin.hook).not.toHaveBeenCalled(); }); diff --git a/test/specs/platform.dom.tests.js b/test/specs/platform.dom.tests.js index a9218c895..e32100249 100644 --- a/test/specs/platform.dom.tests.js +++ b/test/specs/platform.dom.tests.js @@ -369,8 +369,8 @@ describe('Platform.dom', function() { it('should notify plugins about events', function(done) { var notifiedEvent; var plugin = { - afterEvent: function(chart, e) { - notifiedEvent = e; + afterEvent: function(chart, args) { + notifiedEvent = args.event; } }; var chart = acquireChart({ diff --git a/types/core/index.d.ts b/types/core/index.d.ts index c61c302b1..d31dbe853 100644 --- a/types/core/index.d.ts +++ b/types/core/index.d.ts @@ -227,6 +227,8 @@ export declare class Chart< unbindEvents(): void; updateHoverStyle(items: Element, mode: 'dataset', enabled: boolean): void; + notifyPlugins(hook: string, args?: AnyObject): boolean | void; + static readonly version: string; static readonly instances: { [key: string]: Chart }; static readonly registry: Registry; @@ -562,39 +564,29 @@ export const layouts: { update(chart: Chart, width: number, height: number): void; }; -export interface PluginService { - /** - * Calls enabled plugins for `chart` on the specified hook and with the given args. - * This method immediately returns as soon as a plugin explicitly returns false. The - * returned value can be used, for instance, to interrupt the current action. - * @param {Chart} chart - The chart instance for which plugins should be called. - * @param {string} hook - The name of the plugin method to call (e.g. 'beforeUpdate'). - * @param {Array} [args] - Extra arguments to apply to the hook call. - * @returns {boolean} false if any of the plugins return false, else returns true. - */ - notify(chart: Chart, hook: string, args: any[]): boolean; - invalidate(): void; -} - export interface Plugin { id: string; /** * @desc Called before initializing `chart`. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ - beforeInit?(chart: Chart, options: O): void; + beforeInit?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called after `chart` has been initialized and before the first update. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ - afterInit?(chart: Chart, options: O): void; + afterInit?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called before updating `chart`. If any plugin returns `false`, the update * is cancelled (and thus subsequent render(s)) until another `update` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. + * @param {UpdateMode} args.mode - The update mode * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart update. */ @@ -603,16 +595,19 @@ export interface Plugin { * @desc Called after `chart` has been updated and before rendering. Note that this * hook will not be called if the chart update has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. + * @param {UpdateMode} args.mode - The update mode * @param {object} options - The plugin options. */ - afterUpdate?(chart: Chart, args: { mode: UpdateMode }, options: O): void; + afterUpdate?(chart: Chart, args: { mode: UpdateMode }, options: O): boolean | void; /** * @desc Called during chart reset * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @since version 3.0.0 */ - reset?(chart: Chart, options: O): void; + reset?(chart: Chart, args: {}, options: O): void; /** * @desc Called before updating the `chart` datasets. If any plugin returns `false`, * the datasets update is cancelled until another `update` is triggered. @@ -633,7 +628,7 @@ export interface Plugin { * @param {object} options - The plugin options. * @since version 2.1.5 */ - afterDatasetsUpdate?(chart: Chart, args: { mode: UpdateMode }, options: O): void; + afterDatasetsUpdate?(chart: Chart, args: { mode: UpdateMode }, options: O): boolean | void; /** * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin * returns `false`, the datasets update is cancelled until another `update` is triggered. @@ -656,67 +651,75 @@ export interface Plugin { * @param {UpdateMode} args.mode - The update mode. * @param {object} options - The plugin options. */ - afterDatasetUpdate?(chart: Chart, args: { index: number; meta: ChartMeta, mode: UpdateMode }, options: O): void; + afterDatasetUpdate?(chart: Chart, args: { index: number; meta: ChartMeta, mode: UpdateMode }, options: O): boolean | void; /** * @desc Called before laying out `chart`. If any plugin returns `false`, * the layout update is cancelled until another `update` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart layout. */ - beforeLayout?(chart: Chart, options: O): boolean | void; + beforeLayout?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called after the `chart` has been laid out. Note that this hook will not * be called if the layout update has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ - afterLayout?(chart: Chart, options: O): void; + afterLayout?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called before rendering `chart`. If any plugin returns `false`, * the rendering is cancelled until another `render` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart rendering. */ - beforeRender?(chart: Chart, options: O): boolean | void; + beforeRender?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called after the `chart` has been fully rendered (and animation completed). Note * that this hook will not be called if the rendering has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ - afterRender?(chart: Chart, options: O): void; + afterRender?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called before drawing `chart` at every animation frame. If any plugin returns `false`, * the frame drawing is cancelled untilanother `render` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart drawing. */ - beforeDraw?(chart: Chart, options: O): boolean | void; + beforeDraw?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called after the `chart` has been drawn. Note that this hook will not be called * if the drawing has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ - afterDraw?(chart: Chart, options: O): void; + afterDraw?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called before drawing the `chart` datasets. If any plugin returns `false`, * the datasets drawing is cancelled until another `render` is triggered. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. * @returns {boolean} `false` to cancel the chart datasets drawing. */ - beforeDatasetsDraw?(chart: Chart, options: O): boolean | void; + beforeDatasetsDraw?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called after the `chart` datasets have been drawn. Note that this hook * will not be called if the datasets drawing has been previously cancelled. * @param {Chart} chart - The chart instance. + * @param {object} args - The call arguments. * @param {object} options - The plugin options. */ - afterDatasetsDraw?(chart: Chart, options: O): void; + afterDatasetsDraw?(chart: Chart, args: {}, options: O): boolean | void; /** * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing @@ -739,38 +742,41 @@ export interface Plugin { * @param {object} args.meta - The dataset metadata. * @param {object} options - The plugin options. */ - afterDatasetDraw?(chart: Chart, args: { index: number; meta: ChartMeta }, options: O): void; + afterDatasetDraw?(chart: Chart, args: { index: number; meta: ChartMeta }, options: O): boolean | void; /** * @desc Called before processing the specified `event`. If any plugin returns `false`, * the event will be discarded. * @param {Chart} chart - The chart instance. - * @param {ChartEvent} event - The event object. - * @param {object} options - The plugin options. + * @param {object} args - The call arguments. + * @param {ChartEvent} args.event - The event object. * @param {boolean} replay - True if this event is replayed from `Chart.update` + * @param {object} options - The plugin options. */ - beforeEvent?(chart: Chart, event: ChartEvent, options: O, replay: boolean): void; + beforeEvent?(chart: Chart, args: { event: ChartEvent, replay: boolean }, options: O): boolean | void; /** * @desc Called after the `event` has been consumed. Note that this hook * will not be called if the `event` has been previously discarded. * @param {Chart} chart - The chart instance. - * @param {ChartEvent} event - The event object. - * @param {object} options - The plugin options. + * @param {object} args - The call arguments. + * @param {ChartEvent} args.event - The event object. * @param {boolean} replay - True if this event is replayed from `Chart.update` + * @param {object} options - The plugin options. */ - afterEvent?(chart: Chart, event: ChartEvent, options: O, replay: boolean): void; + afterEvent?(chart: Chart, args: { event: ChartEvent, replay: boolean }, options: O): boolean | void; /** * @desc Called after the chart as been resized. * @param {Chart} chart - The chart instance. - * @param {number} size - The new canvas display size (eq. canvas.style width & height). + * @param {object} args - The call arguments. + * @param {number} args.size - The new canvas display size (eq. canvas.style width & height). * @param {object} options - The plugin options. */ - resize?(chart: Chart, size: number, options: O): void; + resize?(chart: Chart, args: { size: { width: number, height: number } }, options: O): boolean | void; /** * Called after the chart as been destroyed. * @param {Chart} chart - The chart instance. * @param {object} options - The plugin options. */ - destroy?(chart: Chart, options: O): void; + destroy?(chart: Chart, options: O): boolean | void; } export declare type ChartComponentLike = ChartComponent | ChartComponent[] | { [key: string]: ChartComponent };