});
```
-Same example in classic style
-
-```javascript
-function Custom() {
- Chart.BubbleController.apply(this, arguments);
- // constructor stuff
-}
-Custom.prototype = Object.create(Chart.BubbleController.prototype);
-Custom.prototype.constructor = Custom;
-
-Custom.prototype.draw = function(ctx) {
- Chart.BubbleController.prototype.draw.apply(this, arguments);
-
- var meta = this.getMeta();
- var pt0 = meta.data[0];
- var radius = pt0.radius;
-
- var ctx = this.chart.chart.ctx;
- ctx.save();
- ctx.strokeStyle = 'red';
- ctx.lineWidth = 1;
- ctx.strokeRect(pt0.x - radius, pt0.y - radius, 2 * radius, 2 * radius);
- ctx.restore();}
-}
-
-Custom.id = 'derivedBubble';
-Custom.defaults = Chart.defaults.bubble;
-
-Chart.register(Custom);
-
-// Now we can create and use our new chart type
-new Chart(ctx, {
- type: 'derivedBubble',
- data: data,
- options: options
-});
-```
-
## TypeScript Typings
If you want your new chart type to be statically typed, you must provide a `.d.ts` TypeScript declaration file. Chart.js provides a way to augment built-in types with user-defined ones, by using the concept of "declaration merging".
describe('Chart.registry', function() {
- it('should handle a classic controller extension', function() {
- function CustomController() {
- Chart.controllers.line.apply(this, arguments);
- }
- CustomController.prototype = Object.create(Chart.controllers.line.prototype);
- CustomController.prototype.constructor = CustomController;
- CustomController.id = 'myline';
- CustomController.defaults = Chart.defaults.controllers.line;
-
- Chart.register(CustomController);
-
- expect(Chart.registry.getController('myline')).toEqual(CustomController);
- expect(Chart.defaults.controllers.myline).toEqual(CustomController.defaults);
-
- Chart.unregister(CustomController);
- });
-
- it('should handle a classic scale extension', function() {
- function CustomScale() {
- Chart.Scale.apply(this, arguments);
- }
- CustomScale.prototype = Object.create(Chart.Scale.prototype);
- CustomScale.prototype.constructor = CustomScale;
- CustomScale.id = 'myScale';
- CustomScale.defaults = {
- foo: 'bar'
- };
-
- Chart.register(CustomScale);
-
- expect(Chart.registry.getScale('myScale')).toEqual(CustomScale);
- expect(Chart.defaults.scales.myScale).toEqual(CustomScale.defaults);
-
- Chart.unregister(CustomScale);
-
- expect(function() {
- Chart.registry.getScale('myScale');
- }).toThrow(new Error('"myScale" is not a registered scale.'));
- expect(Chart.defaults.scales.myScale).not.toBeDefined();
- });
-
- it('should handle a classic element extension', function() {
- function CustomElement() {
- Chart.Element.apply(this, arguments);
- }
- CustomElement.prototype = Object.create(Chart.Element.prototype);
- CustomElement.prototype.constructor = CustomElement;
- CustomElement.id = 'myElement';
- CustomElement.defaults = {
- foo: 'baz'
- };
-
- Chart.register(CustomElement);
-
- expect(Chart.registry.getElement('myElement')).toEqual(CustomElement);
- expect(Chart.defaults.elements.myElement).toEqual(CustomElement.defaults);
-
- Chart.unregister(CustomElement);
-
- expect(function() {
- Chart.registry.getElement('myElement');
- }).toThrow(new Error('"myElement" is not a registered element.'));
- expect(Chart.defaults.elements.myElement).not.toBeDefined();
- });
-
- it('should handle a classic plugin', function() {
- const CustomPlugin = {
- id: 'customPlugin',
- defaults: {
- custom: 'plugin'
- }
- };
-
- Chart.register(CustomPlugin);
-
- expect(Chart.registry.getPlugin('customPlugin')).toEqual(CustomPlugin);
- expect(Chart.defaults.plugins.customPlugin).toEqual(CustomPlugin.defaults);
-
- Chart.unregister(CustomPlugin);
-
- expect(function() {
- Chart.registry.getPlugin('customPlugin');
- }).toThrow(new Error('"customPlugin" is not a registered plugin.'));
- expect(Chart.defaults.plugins.customPlugin).not.toBeDefined();
- });
-
it('should handle an ES6 controller extension', function() {
class CustomController extends Chart.DatasetController {}
CustomController.id = 'custom';