mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-13 03:36:50 +01:00
Merge pull request #2283 from nnnick/feature/plug-in-support
Adds support for plugins
This commit is contained in:
@@ -366,6 +366,32 @@ The built in controller types are:
|
||||
#### Bar Controller
|
||||
The bar controller has a special property that you should be aware of. To correctly calculate the width of a bar, the controller must determine the number of datasets that map to bars. To do this, the bar controller attaches a property `bar` to the dataset during initialization. If you are creating a replacement or updated bar controller, you should do the same. This will ensure that charts with regular bars and your new derived bars will work seamlessly.
|
||||
|
||||
### Creating Plugins
|
||||
|
||||
Starting with v2.1.0, you can create plugins for chart.js. To register your plugin, simply call `Chart.pluginService.register` and pass your plugin in.
|
||||
Plugins will be called at the following times
|
||||
* Start of initialization
|
||||
* End of initialization
|
||||
* Start of update
|
||||
* End of update
|
||||
* Start of draw
|
||||
* End of draw
|
||||
|
||||
Plugins should derive from Chart.PluginBase and implement the following interface
|
||||
```javascript
|
||||
{
|
||||
beforeInit: function(chartInstance) { },
|
||||
afterInit: function(chartInstance) { },
|
||||
|
||||
beforeUpdate: function(chartInstance) { },
|
||||
afterUpdate: function(chartInstance) { },
|
||||
|
||||
// Easing is for animation
|
||||
beforeDraw: function(chartInstance, easing) { },
|
||||
afterDraw: function(chartInstance, easing) { }
|
||||
}
|
||||
```
|
||||
|
||||
### Building Chart.js
|
||||
|
||||
Chart.js uses <a href="http://gulpjs.com/" target="_blank">gulp</a> to build the library into a single JavaScript file.
|
||||
|
||||
@@ -18,6 +18,7 @@ require('./core/core.controller')(Chart);
|
||||
require('./core/core.datasetController')(Chart);
|
||||
require('./core/core.layoutService')(Chart);
|
||||
require('./core/core.legend')(Chart);
|
||||
require('./core/core.plugin.js')(Chart);
|
||||
require('./core/core.scale')(Chart);
|
||||
require('./core/core.scaleService')(Chart);
|
||||
require('./core/core.title')(Chart);
|
||||
|
||||
@@ -43,9 +43,8 @@ module.exports = function(Chart) {
|
||||
helpers.extend(Chart.Controller.prototype, {
|
||||
|
||||
initialize: function initialize() {
|
||||
|
||||
// TODO
|
||||
// If BeforeInit(this) doesn't return false, proceed
|
||||
// Before init plugin notification
|
||||
Chart.pluginService.notifyPlugins('beforeInit', [this]);
|
||||
|
||||
this.bindEvents();
|
||||
|
||||
@@ -60,8 +59,8 @@ module.exports = function(Chart) {
|
||||
this.initToolTip();
|
||||
this.update();
|
||||
|
||||
// TODO
|
||||
// If AfterInit(this) doesn't return false, proceed
|
||||
// After init plugin notification
|
||||
Chart.pluginService.notifyPlugins('afterInit', [this]);
|
||||
|
||||
return this;
|
||||
},
|
||||
@@ -243,6 +242,8 @@ module.exports = function(Chart) {
|
||||
},
|
||||
|
||||
update: function update(animationDuration, lazy) {
|
||||
Chart.pluginService.notifyPlugins('beforeUpdate', [this]);
|
||||
|
||||
// In case the entire data object changed
|
||||
this.tooltip._data = this.data;
|
||||
|
||||
@@ -266,6 +267,8 @@ module.exports = function(Chart) {
|
||||
dataset.controller.update();
|
||||
});
|
||||
this.render(animationDuration, lazy);
|
||||
|
||||
Chart.pluginService.notifyPlugins('afterUpdate', [this]);
|
||||
},
|
||||
|
||||
render: function render(duration, lazy) {
|
||||
@@ -302,6 +305,8 @@ module.exports = function(Chart) {
|
||||
var easingDecimal = ease || 1;
|
||||
this.clear();
|
||||
|
||||
Chart.pluginService.notifyPlugins('beforeDraw', [this, easingDecimal]);
|
||||
|
||||
// Draw all the scales
|
||||
helpers.each(this.boxes, function(box) {
|
||||
box.draw(this.chartArea);
|
||||
@@ -328,6 +333,8 @@ module.exports = function(Chart) {
|
||||
|
||||
// Finally draw the tooltip
|
||||
this.tooltip.transition(easingDecimal).draw();
|
||||
|
||||
Chart.pluginService.notifyPlugins('afterDraw', [this, easingDecimal]);
|
||||
},
|
||||
|
||||
// Get the single element that was clicked on
|
||||
|
||||
55
src/core/core.plugin.js
Normal file
55
src/core/core.plugin.js
Normal file
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function(Chart) {
|
||||
var helpers = Chart.helpers;
|
||||
|
||||
// Plugins are stored here
|
||||
Chart.plugins = [];
|
||||
Chart.pluginService = {
|
||||
// Register a new plugin
|
||||
register: function(plugin) {
|
||||
if (Chart.plugins.indexOf(plugin) === -1) {
|
||||
Chart.plugins.push(plugin);
|
||||
}
|
||||
},
|
||||
|
||||
// Remove a registered plugin
|
||||
remove: function(plugin) {
|
||||
var idx = Chart.plugins.indexOf(plugin);
|
||||
if (idx !== -1) {
|
||||
Chart.plugins.splice(idx, 1);
|
||||
}
|
||||
},
|
||||
|
||||
// Iterate over all plugins
|
||||
notifyPlugins: function(method, args, scope) {
|
||||
helpers.each(Chart.plugins, function(plugin) {
|
||||
if (plugin[method] && typeof plugin[method] === 'function') {
|
||||
plugin[method].apply(scope, args);
|
||||
}
|
||||
}, scope);
|
||||
}
|
||||
};
|
||||
|
||||
Chart.PluginBase = Chart.Element.extend({
|
||||
// Plugin methods. All functions are passed the chart instance
|
||||
|
||||
// Called at start of chart init
|
||||
beforeInit: helpers.noop,
|
||||
|
||||
// Called at end of chart init
|
||||
afterInit: helpers.noop,
|
||||
|
||||
// Called at start of update
|
||||
beforeUpdate: helpers.noop,
|
||||
|
||||
// Called at end of update
|
||||
afterUpdate: helpers.noop,
|
||||
|
||||
// Called at start of draw
|
||||
beforeDraw: helpers.noop,
|
||||
|
||||
// Called at end of draw
|
||||
afterDraw: helpers.noop,
|
||||
});
|
||||
};
|
||||
43
test/core.plugin.tests.js
Normal file
43
test/core.plugin.tests.js
Normal file
@@ -0,0 +1,43 @@
|
||||
// Plugin tests
|
||||
describe('Test the plugin system', function() {
|
||||
beforeEach(function() {
|
||||
Chart.plugins = [];
|
||||
});
|
||||
|
||||
it ('Should register plugins', function() {
|
||||
var myplugin = {};
|
||||
Chart.pluginService.register(myplugin);
|
||||
expect(Chart.plugins.length).toBe(1);
|
||||
|
||||
// Should only add plugin once
|
||||
Chart.pluginService.register(myplugin);
|
||||
expect(Chart.plugins.length).toBe(1);
|
||||
});
|
||||
|
||||
it ('Should allow unregistering plugins', function() {
|
||||
var myplugin = {};
|
||||
Chart.pluginService.register(myplugin);
|
||||
expect(Chart.plugins.length).toBe(1);
|
||||
|
||||
// Should only add plugin once
|
||||
Chart.pluginService.remove(myplugin);
|
||||
expect(Chart.plugins.length).toBe(0);
|
||||
|
||||
// Removing a plugin that doesn't exist should not error
|
||||
Chart.pluginService.remove(myplugin);
|
||||
});
|
||||
|
||||
it ('Should allow notifying plugins', function() {
|
||||
var myplugin = {
|
||||
count: 0,
|
||||
trigger: function(chart) {
|
||||
myplugin.count = chart.count;
|
||||
}
|
||||
};
|
||||
Chart.pluginService.register(myplugin);
|
||||
|
||||
Chart.pluginService.notifyPlugins('trigger', [{ count: 10 }]);
|
||||
|
||||
expect(myplugin.count).toBe(10);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user