From 7024aad38fdf5962d0f5802ff522f19e46eef10a Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Sun, 12 Jul 2020 01:08:45 +0300 Subject: [PATCH] PluginService using registry (#7590) PluginService using registry --- docs/docs/configuration/title.md | 2 +- docs/docs/configuration/tooltip.md | 4 +- docs/docs/developers/axes.md | 24 ++- docs/docs/developers/charts.md | 38 ++++ docs/docs/getting-started/integration.md | 7 +- docs/docs/getting-started/v3-migration.md | 30 ++- docs/docs/index.md | 1 + package.json | 2 +- samples/tooltips/custom-pie.html | 2 +- src/core/core.controller.js | 61 +++--- src/core/core.datasetController.js | 4 +- src/core/core.defaults.js | 2 +- src/core/core.plugins.js | 185 ++++++------------ src/core/core.registry.js | 33 ++-- src/helpers/helpers.collection.js | 4 +- src/helpers/helpers.core.js | 7 + src/index.js | 21 +- src/plugins/index.js | 8 +- src/plugins/plugin.title.js | 28 +-- src/plugins/plugin.tooltip.js | 225 +++++++++++----------- test/specs/core.plugin.tests.js | 141 +++++--------- test/specs/global.namespace.tests.js | 1 - test/specs/plugin.title.tests.js | 16 +- test/specs/plugin.tooltip.tests.js | 6 +- 24 files changed, 419 insertions(+), 433 deletions(-) diff --git a/docs/docs/configuration/title.md b/docs/docs/configuration/title.md index efb75289d..d1d5d6123 100644 --- a/docs/docs/configuration/title.md +++ b/docs/docs/configuration/title.md @@ -6,7 +6,7 @@ The chart title defines text to draw at the top of the chart. ## Title Configuration -The title configuration is passed into the `options.title` namespace. The global options for the chart title is defined in `Chart.defaults.title`. +The title configuration is passed into the `options.title` namespace. The global options for the chart title is defined in `Chart.defaults.plugins.title`. | Name | Type | Default | Description | ---- | ---- | ------- | ----------- diff --git a/docs/docs/configuration/tooltip.md b/docs/docs/configuration/tooltip.md index 85dc19a8a..2cb65f11b 100644 --- a/docs/docs/configuration/tooltip.md +++ b/docs/docs/configuration/tooltip.md @@ -4,7 +4,7 @@ title: Tooltip ## Tooltip Configuration -The tooltip configuration is passed into the `options.tooltips` namespace. The global options for the chart tooltips is defined in `Chart.defaults.tooltips`. +The tooltip configuration is passed into the `options.tooltips` namespace. The global options for the chart tooltips is defined in `Chart.defaults.plugins.tooltip`. | Name | Type | Default | Description | ---- | ---- | ------- | ----------- @@ -63,7 +63,7 @@ Example: * @param eventPosition {Point} the position of the event in canvas coordinates * @returns {Point} the tooltip position */ -const tooltipPlugin = Chart.plugins.getAll().find(p => p.id === 'tooltip'); +const tooltipPlugin = Chart.registry.getPlugin('tooltip'); tooltipPlugin.positioners.custom = function(elements, eventPosition) { /** @type {Tooltip} */ var tooltip = this; diff --git a/docs/docs/developers/axes.md b/docs/docs/developers/axes.md index e4cd873c1..9af289ad3 100644 --- a/docs/docs/developers/axes.md +++ b/docs/docs/developers/axes.md @@ -5,12 +5,27 @@ title: New Axes Axes in Chart.js can be individually extended. Axes should always derive from `Chart.Scale` but this is not a mandatory requirement. ```javascript -class MyScale extends Chart.Scale{ +class MyScale extends Chart.Scale { /* extensions ... */ } MyScale.id = 'myScale'; MyScale.defaults = defaultConfigObject; +// Or in classic style +/* +function MyScale() { + Chart.Scale.call(this, arguments); + // constructor stuff +} + +MyScale.prototype.draw = function(ctx) { + Chart.Scale.prototype.draw.call(this, arguments); + // ... +} +MyScale.id = 'myScale'; +MyScale.defaults = defaultConfigObject; +*/ + // MyScale is now derived from Chart.Scale ``` @@ -18,6 +33,11 @@ Once you have created your scale class, you need to register it with the global ```javascript Chart.register(MyScale); + +// If the scale is created in classical way, the prototype can not be used to detect what +// you are trying to register - so you need to be explicit: + +// Chart.registry.addScales(MyScale); ``` To use the new scale, simply pass in the string key to the config when creating a chart. @@ -66,6 +86,7 @@ Scale instances are given the following properties during the fitting process. ``` ## Scale Interface + To work with Chart.js, custom scale types must implement the following interface. ```javascript @@ -120,6 +141,7 @@ Optionally, the following methods may also be overwritten, but an implementation ``` The Core.Scale base class also has some utility functions that you may find useful. + ```javascript { // Returns true if the scale instance is horizontal diff --git a/docs/docs/developers/charts.md b/docs/docs/developers/charts.md index 14c0cf1c8..dd98fd57a 100644 --- a/docs/docs/developers/charts.md +++ b/docs/docs/developers/charts.md @@ -111,3 +111,41 @@ new Chart(ctx, { options: options }); ``` + +Same example in classic style + +```javascript +function Custom() { + Chart.controllers.bubble.call(this, arguments); + // constructor stuff +} + +Custom.prototype.draw = function(ctx) { + Chart.controllers.bubble.prototype.draw.call(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; + +// Prototype chain can not be used to detect we are trying to register a controller, so we need +// to be explicit +Chart.registry.addControllers(Custom); + +// Now we can create and use our new chart type +new Chart(ctx, { + type: 'derivedBubble', + data: data, + options: options +}); +``` diff --git a/docs/docs/getting-started/integration.md b/docs/docs/getting-started/integration.md index 687b00474..0cd9bf456 100644 --- a/docs/docs/getting-started/integration.md +++ b/docs/docs/getting-started/integration.md @@ -22,8 +22,13 @@ var myChart = new Chart(ctx, {...}); ## Bundlers (Webpack, Rollup, etc.) +Chart.js 3 is tree-shakeable, so it is necessary to import and register the controllers, elements, scales and plugins you are going to use. + ```javascript -import Chart from 'chart.js'; +import Chart, LineController, Line, Point, LinearScale, CategoryScale, Title, Tooltip, Filler, Legend from 'chart.js'; + +Chart.register(LineController, Line, Point, LinearScale, CategoryScale, Title, Tooltip, Filler, Legend); + var myChart = new Chart(ctx, {...}); ``` diff --git a/docs/docs/getting-started/v3-migration.md b/docs/docs/getting-started/v3-migration.md index c264a1d62..d6de6a1f2 100644 --- a/docs/docs/getting-started/v3-migration.md +++ b/docs/docs/getting-started/v3-migration.md @@ -12,6 +12,7 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released * API documentation generated and verified by TypeDoc * No more CSS injection * Tons of bug fixes +* Tree shaking ## End user migration @@ -200,6 +201,32 @@ Some of the biggest things that have changed: * `Element._model` and `Element._view` are no longer used and properties are now set directly on the elements. You will have to use the method `getProps` to access these properties inside most methods such as `inXRange`/`inYRange` and `getCenterPoint`. Please take a look at [the Chart.js-provided elements](https://github.com/chartjs/Chart.js/tree/master/src/elements) for examples. * When building the elements in a controller, it's now suggested to call `updateElement` to provide the element properties. There are also methods such as `getSharedOptions` and `includeOptions` that have been added to skip redundant computation. Please take a look at [the Chart.js-provided controllers](https://github.com/chartjs/Chart.js/tree/master/src/controllers) for examples. * Scales introduced a new parsing API. This API takes user data and converts it into a more standard format. E.g. it allows users to provide numeric data as a `string` and converts it to a `number` where necessary. Previously this was done on the fly as charts were rendered. Now it's done up front with the ability to skip it for better performance if users provide data in the correct format. If you're using standard data format like `x`/`y` you may not need to do anything. If you're using a custom data format you will have to override some of the parse methods in `core.datasetController.js`. An example can be found in [chartjs-chart-financial](https://github.com/chartjs/chartjs-chart-financial), which uses an `{o, h, l, c}` data format. +* Chart.js 3 is tree-shakeable. So when you use it as a module in a project, you need to import and register the controllers, elements, scales and plugins you want to use: + +```javascript +import Chart, LineController, Line, Point, LinearScale, Title from `chart.js` + +Chart.register(LineController, Line, Point, LinearScale, Title); + +const chart = new Chart(ctx, { + type: 'line', + // data: ... + options: { + title: { + display: true, + text: 'Chart Title' + }, + scales: { + x: { + type: 'linear' + }, + y: { + type: 'linear' + } + } + } +}) +``` A few changes were made to controllers that are more straight-forward, but will affect all controllers: @@ -231,12 +258,14 @@ The following properties and methods were removed: * `Chart.offsetX` * `Chart.offsetY` * `Chart.outerRadius` now lives on doughnut, pie, and polarArea controllers +* `Chart.plugins` was replaced with `Chart.registry`. Plugin defaults are now in `Chart.defaults.plugins[id]`. * `Chart.PolarArea`. New charts are created via `new Chart` and providing the appropriate `type` parameter * `Chart.prototype.generateLegend` * `Chart.platform`. It only contained `disableCSSInjection`. CSS is never injected in v3. * `Chart.PluginBase` * `Chart.Radar`. New charts are created via `new Chart` and providing the appropriate `type` parameter * `Chart.radiusLength` +* `Chart.scaleService` was replaced with `Chart.registry`. Scale defaults are now in `Chart.defaults.scales[type]`. * `Chart.Scatter`. New charts are created via `new Chart` and providing the appropriate `type` parameter * `Chart.types` * `Chart.Title` was moved to `Chart.plugins.title._element` and made private @@ -405,7 +434,6 @@ The APIs listed in this section have changed in signature or behaviour from vers * `Scale.getLabelForIndex` was replaced by `scale.getLabelForValue` * `Scale.getPixelForValue` now has only one parameter. For the `TimeScale` that parameter must be millis since the epoch -* `ScaleService.registerScaleType` was renamed to `ScaleService.registerScale` and now takes a scale constructors which is expected to have `id` and `defaults` properties. ##### Ticks diff --git a/docs/docs/index.md b/docs/docs/index.md index 0731b1e1c..e43ea4a2d 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -13,6 +13,7 @@ You can download the latest version of Chart.js from the [GitHub releases](https It's easy to get started with Chart.js. All that's required is the script included in your page along with a single `` node to render the chart. In this example, we create a bar chart for a single dataset and render that in our page. You can see all the ways to use Chart.js in the [usage documentation](./getting-started/usage.md). + ```html