diff --git a/docs/docs/charts/bar.mdx b/docs/docs/charts/bar.mdx index 22ea1936187..cce21feb2f1 100644 --- a/docs/docs/charts/bar.mdx +++ b/docs/docs/charts/bar.mdx @@ -235,7 +235,7 @@ If true, the bars for a particular data point fall between the grid lines. The g ## Default Options -It is common to want to apply a configuration setting to all created bar charts. The global bar chart settings are stored in `Chart.defaults.controllers.bar`. Changing the global options only affects charts created after the change. Existing charts are not changed. +It is common to want to apply a configuration setting to all created bar charts. The global bar chart settings are stored in `Chart.overrides.bar`. Changing the global options only affects charts created after the change. Existing charts are not changed. ## barPercentage vs categoryPercentage diff --git a/docs/docs/charts/bubble.mdx b/docs/docs/charts/bubble.mdx index 9c42ab33a2c..fff1413b721 100644 --- a/docs/docs/charts/bubble.mdx +++ b/docs/docs/charts/bubble.mdx @@ -106,7 +106,7 @@ All these values, if `undefined`, fallback to the associated [`elements.point.*` ## Default Options -We can also change the default values for the Bubble chart type. Doing so will give all bubble charts created after this point the new defaults. The default configuration for the bubble chart can be accessed at `Chart.defaults.controllers.bubble`. +We can also change the default values for the Bubble chart type. Doing so will give all bubble charts created after this point the new defaults. The default configuration for the bubble chart can be accessed at `Chart.overrides.bubble`. ## Data Structure diff --git a/docs/docs/charts/doughnut.mdx b/docs/docs/charts/doughnut.mdx index 02838865dd0..6dc8948ef1c 100644 --- a/docs/docs/charts/doughnut.mdx +++ b/docs/docs/charts/doughnut.mdx @@ -172,7 +172,7 @@ These are the customisation options specific to Pie & Doughnut charts. These opt ## Default Options -We can also change these default values for each Doughnut type that is created, this object is available at `Chart.defaults.controllers.doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.defaults.controllers.pie`, with the only difference being `cutout` being set to 0. +We can also change these default values for each Doughnut type that is created, this object is available at `Chart.overrides.doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.overrides.pie`, with the only difference being `cutout` being set to 0. ## Data Structure diff --git a/docs/docs/charts/line.mdx b/docs/docs/charts/line.mdx index 2a265c0a321..7a403052288 100644 --- a/docs/docs/charts/line.mdx +++ b/docs/docs/charts/line.mdx @@ -188,12 +188,12 @@ The line chart defines the following configuration options. These options are lo ## Default Options -It is common to want to apply a configuration setting to all created line charts. The global line chart settings are stored in `Chart.defaults.controllers.line`. Changing the global options only affects charts created after the change. Existing charts are not changed. +It is common to want to apply a configuration setting to all created line charts. The global line chart settings are stored in `Chart.overrides.line`. Changing the global options only affects charts created after the change. Existing charts are not changed. For example, to configure all line charts with `spanGaps = true` you would do: ```javascript -Chart.defaults.controllers.line.spanGaps = true; +Chart.overrides.line.spanGaps = true; ``` ## Data Structure diff --git a/docs/docs/charts/polar.mdx b/docs/docs/charts/polar.mdx index 17c5d4fa32a..e1644fbd8e3 100644 --- a/docs/docs/charts/polar.mdx +++ b/docs/docs/charts/polar.mdx @@ -120,12 +120,12 @@ The polar area chart uses the [radialLinear](../axes/radial/linear.mdx) scale. A ## Default Options -We can also change these default values for each PolarArea type that is created, this object is available at `Chart.defaults.controllers.polarArea`. Changing the global options only affects charts created after the change. Existing charts are not changed. +We can also change these default values for each PolarArea type that is created, this object is available at `Chart.overrides.polarArea`. Changing the global options only affects charts created after the change. Existing charts are not changed. For example, to configure all new polar area charts with `animateScale = false` you would do: ```javascript -Chart.defaults.controllers.polarArea.animation.animateScale = false; +Chart.overrides.polarArea.animation.animateScale = false; ``` ## Data Structure diff --git a/docs/docs/charts/radar.mdx b/docs/docs/charts/radar.mdx index 23ee58d7aac..316eadb1430 100644 --- a/docs/docs/charts/radar.mdx +++ b/docs/docs/charts/radar.mdx @@ -193,7 +193,7 @@ options = { ## Default Options -It is common to want to apply a configuration setting to all created radar charts. The global radar chart settings are stored in `Chart.defaults.controllers.radar`. Changing the global options only affects charts created after the change. Existing charts are not changed. +It is common to want to apply a configuration setting to all created radar charts. The global radar chart settings are stored in `Chart.overrides.radar`. Changing the global options only affects charts created after the change. Existing charts are not changed. ## Data Structure diff --git a/docs/docs/configuration/animations.mdx b/docs/docs/configuration/animations.mdx index 65ea5f67f1e..16826616bb1 100644 --- a/docs/docs/configuration/animations.mdx +++ b/docs/docs/configuration/animations.mdx @@ -86,7 +86,7 @@ function example() { y: { from: 0 } - } + } }, hide: { animations: { @@ -124,9 +124,8 @@ Animation configuration consists of 3 keys. These keys can be configured in following paths: * `` - chart options -* `controllers[type]` - controller type options -* `controllers[type].datasets` - dataset type options * `datasets[type]` - dataset type options +* `overrides[type]` - chart type options These paths are valid under `defaults` for global confuguration and `options` for instance configuration. diff --git a/docs/docs/configuration/index.md b/docs/docs/configuration/index.md index ce8074f5c37..6c429ed951d 100644 --- a/docs/docs/configuration/index.md +++ b/docs/docs/configuration/index.md @@ -42,7 +42,7 @@ The following example would set the `showLine` option to 'false' for all line da ```javascript // Do not show lines for all datasets by default -Chart.defaults.controllers.line.showLine = false; +Chart.defaults.datasets.line.showLine = false; // This chart would show a line only for the third dataset var chart = new Chart(ctx, { diff --git a/docs/docs/general/options.md b/docs/docs/general/options.md index e5906a2fede..092d8c8351d 100644 --- a/docs/docs/general/options.md +++ b/docs/docs/general/options.md @@ -9,7 +9,7 @@ Options are resolved from top to bottom, using a context dependent route. ### Chart level options * options -* defaults.controllers[`config.type`] +* overrides[`config.type`] * defaults ### Dataset level options @@ -18,18 +18,18 @@ Options are resolved from top to bottom, using a context dependent route. * dataset * options.datasets[`dataset.type`] -* options.controllers[`dataset.type`].datasets * options +* overrides[`config.type`].datasets[`dataset.type`] * defaults.datasets[`dataset.type`] -* defaults.controllers[`dataset.type`].datasets * defaults ### Dataset animation options * dataset.animation -* options.controllers[`dataset.type`].datasets.animation +* options.datasets[`dataset.type`].animation * options.animation -* defaults.controllers[`dataset.type`].datasets.animation +* overrides[`config.type`].datasets[`dataset.type`].animation +* defaults.datasets[`dataset.type`].animation * defaults.animation ### Dataset element level options @@ -38,31 +38,30 @@ Each scope is looked up with `elementType` prefix in the option name first, then * dataset * options.datasets[`dataset.type`] -* options.controllers[`dataset.type`].datasets -* options.controllers[`dataset.type`].elements[`elementType`] +* options.datasets[`dataset.type`].elements[`elementType`] * options.elements[`elementType`] * options +* overrides[`config.type`].datasets[`dataset.type`] +* overrides[`config.type`].datasets[`dataset.type`].elements[`elementType`] * defaults.datasets[`dataset.type`] -* defaults.controllers[`dataset.type`].datasets -* defaults.controllers[`dataset.type`].elements[`elementType`] +* defaults.datasets[`dataset.type`].elements[`elementType`] * defaults.elements[`elementType`] * defaults ### Scale options * options.scales -* defaults.controllers[`config.type`].scales -* defaults.controllers[`dataset.type`].scales +* overrides[`config.type`].scales * defaults.scales +* defaults.scale ### Plugin options A plugin can provide `additionalOptionScopes` array of paths to additionally look for its options in. For root scope, use empty string: `''`. Most core plugins also take options from root scope. * options.plugins[`plugin.id`] -* options.controllers[`config.type`].plugins[`plugin.id`] * (options.[`...plugin.additionalOptionScopes`]) -* defaults.controllers[`config.type`].plugins[`plugin.id`] +* overrides[`config.type`].plugins[`plugin.id`] * defaults.plugins[`plugin.id`] * (defaults.[`...plugin.additionalOptionScopes`]) diff --git a/docs/docs/getting-started/v3-migration.md b/docs/docs/getting-started/v3-migration.md index fc03f38645f..1aa12040f6d 100644 --- a/docs/docs/getting-started/v3-migration.md +++ b/docs/docs/getting-started/v3-migration.md @@ -111,7 +111,7 @@ A number of changes were made to the configuration options passed to the `Chart` #### Defaults * `global` namespace was removed from `defaults`. So `Chart.defaults.global` is now `Chart.defaults` -* Dataset controller defaults were relocate to `controllers`. For example `Chart.defaults.line` is now `Chart.defaults.controllers.line` +* Dataset controller defaults were relocate to `overrides`. For example `Chart.defaults.line` is now `Chart.overrides.line` * `default` prefix was removed from defaults. For example `Chart.defaults.global.defaultColor` is now `Chart.defaults.color` * `defaultColor` was split to `color`, `borderColor` and `backgroundColor` * `defaultFontColor` was renamed to `color` diff --git a/samples/advanced/derived-chart-type.html b/samples/advanced/derived-chart-type.html index 3bb7a1dbb2f..9f6cb205b23 100644 --- a/samples/advanced/derived-chart-type.html +++ b/samples/advanced/derived-chart-type.html @@ -24,7 +24,7 @@ // Call bubble controller method to draw all the points super.draw(arguments); - // Now we can do some custom drawing for this dataset. Here we'll draw a red box around the first point in each dataset + // Now we can do some custom drawing for this dataset. Here we'll draw a box around the first point in each dataset, using `boxStrokeStyle` dataset option for color var meta = this.getMeta(); var pt0 = meta.data[0]; @@ -33,14 +33,19 @@ var ctx = this.chart.ctx; ctx.save(); - ctx.strokeStyle = 'red'; + ctx.strokeStyle = this.options.boxStrokeStyle; ctx.lineWidth = 1; ctx.strokeRect(x - radius, y - radius, 2 * radius, 2 * radius); ctx.restore(); } } Custom.id = 'derivedBubble'; - Custom.defaults = Chart.controllers.bubble.defaults; + Custom.defaults = { + // Custom defaults. Bubble defaults are inherited. + boxStrokeStyle: 'red' + }; + // Overrides are only inherited, but not merged if defined + // Custom.overrides = Chart.overrides.bubble; // Stores the controller so that the chart initialization routine can look it up Chart.register(Custom); diff --git a/samples/charts/multi-series-pie.html b/samples/charts/multi-series-pie.html index c4952b11278..13adb98f18f 100644 --- a/samples/charts/multi-series-pie.html +++ b/samples/charts/multi-series-pie.html @@ -48,7 +48,7 @@ labels: { generateLabels: function(chart) { // Get the default label list - var original = Chart.defaults.controllers.pie.plugins.legend.labels.generateLabels; + var original = Chart.overrides.pie.plugins.legend.labels.generateLabels; var labels = original.call(this, chart); // Build an array of colors used in the datasets of the chart diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 94d7a5313ee..9bf5ef32e4c 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -511,23 +511,27 @@ BarController.defaults = { datasetElementType: false, dataElementType: 'bar', + categoryPercentage: 0.8, + barPercentage: 0.9, + + animations: { + numbers: { + type: 'number', + properties: ['x', 'y', 'base', 'width', 'height'] + } + } +}; + +/** + * @type {any} + */ +BarController.overrides = { interaction: { mode: 'index' }, hover: {}, - datasets: { - categoryPercentage: 0.8, - barPercentage: 0.9, - animations: { - numbers: { - type: 'number', - properties: ['x', 'y', 'base', 'width', 'height'] - } - } - }, - scales: { _index_: { type: 'category', diff --git a/src/controllers/controller.bubble.js b/src/controllers/controller.bubble.js index 348ea8866d7..08632e72bb1 100644 --- a/src/controllers/controller.bubble.js +++ b/src/controllers/controller.bubble.js @@ -133,12 +133,19 @@ BubbleController.id = 'bubble'; BubbleController.defaults = { datasetElementType: false, dataElementType: 'point', + animations: { numbers: { type: 'number', properties: ['x', 'y', 'borderWidth', 'radius'] } - }, + } +}; + +/** + * @type {any} + */ +BubbleController.overrides = { scales: { x: { type: 'linear' diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index ef38f02250e..a8a3fbcbdf1 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -328,23 +328,26 @@ DoughnutController.defaults = { properties: ['circumference', 'endAngle', 'innerRadius', 'outerRadius', 'startAngle', 'x', 'y', 'offset', 'borderWidth'] }, }, - aspectRatio: 1, - - datasets: { - // The percentage of the chart that we cut out of the middle. - cutout: '50%', + // The percentage of the chart that we cut out of the middle. + cutout: '50%', - // The rotation of the chart, where the first data arc begins. - rotation: 0, + // The rotation of the chart, where the first data arc begins. + rotation: 0, - // The total circumference of the chart. - circumference: 360, + // The total circumference of the chart. + circumference: 360, - // The outr radius of the chart - radius: '100%' - }, + // The outr radius of the chart + radius: '100%', indexAxis: 'r', +}; + +/** + * @type {any} + */ +DoughnutController.overrides = { + aspectRatio: 1, // Need to override these to give a nice default plugins: { diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index e6245295cd6..ca56046e802 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -111,11 +111,14 @@ LineController.defaults = { datasetElementType: 'line', dataElementType: 'point', - datasets: { - showLine: true, - spanGaps: false, - }, + showLine: true, + spanGaps: false, +}; +/** + * @type {any} + */ +LineController.overrides = { interaction: { mode: 'index' }, diff --git a/src/controllers/controller.pie.js b/src/controllers/controller.pie.js index a53b8d5f9ed..f0ba83e15a1 100644 --- a/src/controllers/controller.pie.js +++ b/src/controllers/controller.pie.js @@ -11,17 +11,15 @@ PieController.id = 'pie'; * @type {any} */ PieController.defaults = { - datasets: { - // The percentage of the chart that we cut out of the middle. - cutout: 0, + // The percentage of the chart that we cut out of the middle. + cutout: 0, - // The rotation of the chart, where the first data arc begins. - rotation: 0, + // The rotation of the chart, where the first data arc begins. + rotation: 0, - // The total circumference of the chart. - circumference: 360, + // The total circumference of the chart. + circumference: 360, - // The outr radius of the chart - radius: '100%' - } + // The outr radius of the chart + radius: '100%' }; diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index 49ac298987c..ec09716a830 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -131,25 +131,16 @@ PolarAreaController.defaults = { properties: ['x', 'y', 'startAngle', 'endAngle', 'innerRadius', 'outerRadius'] }, }, - aspectRatio: 1, indexAxis: 'r', - scales: { - r: { - type: 'radialLinear', - angleLines: { - display: false - }, - beginAtZero: true, - gridLines: { - circular: true - }, - pointLabels: { - display: false - } - } - }, - startAngle: 0, +}; + +/** + * @type {any} + */ +PolarAreaController.overrides = { + aspectRatio: 1, + plugins: { legend: { labels: { @@ -193,6 +184,21 @@ PolarAreaController.defaults = { } } } - } + }, + scales: { + r: { + type: 'radialLinear', + angleLines: { + display: false + }, + beginAtZero: true, + gridLines: { + circular: true + }, + pointLabels: { + display: false + } + } + } }; diff --git a/src/controllers/controller.radar.js b/src/controllers/controller.radar.js index 36473f60079..e38c0778376 100644 --- a/src/controllers/controller.radar.js +++ b/src/controllers/controller.radar.js @@ -80,16 +80,21 @@ RadarController.id = 'radar'; RadarController.defaults = { datasetElementType: 'line', dataElementType: 'point', - aspectRatio: 1, - datasets: { - showLine: true, - }, + indexAxis: 'r', + showLine: true, elements: { line: { fill: 'start' } }, - indexAxis: 'r', +}; + +/** + * @type {any} + */ +RadarController.overrides = { + aspectRatio: 1, + scales: { r: { type: 'radialLinear', diff --git a/src/controllers/controller.scatter.js b/src/controllers/controller.scatter.js index cc9823f4585..1d1ccb73e5a 100644 --- a/src/controllers/controller.scatter.js +++ b/src/controllers/controller.scatter.js @@ -10,19 +10,14 @@ ScatterController.id = 'scatter'; * @type {any} */ ScatterController.defaults = { - scales: { - x: { - type: 'linear' - }, - y: { - type: 'linear' - } - }, + showLine: false, + fill: false +}; - datasets: { - showLine: false, - fill: false - }, +/** + * @type {any} + */ +ScatterController.overrides = { interaction: { mode: 'point' @@ -39,5 +34,14 @@ ScatterController.defaults = { } } } + }, + + scales: { + x: { + type: 'linear' + }, + y: { + type: 'linear' + } } }; diff --git a/src/core/core.config.js b/src/core/core.config.js index d41240c685a..a9e937ce9c7 100644 --- a/src/core/core.config.js +++ b/src/core/core.config.js @@ -1,13 +1,11 @@ -import defaults from './core.defaults'; +import defaults, {overrides, descriptors} from './core.defaults'; import {mergeIf, resolveObjectKey, isArray, isFunction, valueOrDefault, isObject} from '../helpers/helpers.core'; import {_attachContext, _createResolver, _descriptors} from '../helpers/helpers.config'; export function getIndexAxis(type, options) { - const typeDefaults = defaults.controllers[type] || {}; - const datasetDefaults = typeDefaults.datasets || {}; - const datasetOptions = options.datasets || {}; - const typeOptions = datasetOptions[type] || {}; - return typeOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || 'x'; + const datasetDefaults = defaults.datasets[type] || {}; + const datasetOptions = (options.datasets || {})[type] || {}; + return datasetOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || 'x'; } function getAxisFromDefaultScaleID(id, indexAxis) { @@ -41,7 +39,7 @@ export function determineAxis(id, scaleOptions) { } function mergeScaleConfig(config, options) { - const chartDefaults = defaults.controllers[config.type] || {scales: {}}; + const chartDefaults = overrides[config.type] || {scales: {}}; const configScales = options.scales || {}; const chartIndexAxis = getIndexAxis(config.type, options); const firstIDs = Object.create(null); @@ -61,7 +59,7 @@ function mergeScaleConfig(config, options) { config.data.datasets.forEach(dataset => { const type = dataset.type || config.type; const indexAxis = dataset.indexAxis || getIndexAxis(type, options); - const datasetDefaults = defaults.controllers[type] || {}; + const datasetDefaults = overrides[type] || {}; const defaultScaleOptions = datasetDefaults.scales || {}; Object.keys(defaultScaleOptions).forEach(defaultID => { const axis = getAxisFromDefaultScaleID(defaultID, indexAxis); @@ -175,8 +173,6 @@ export default class Config { return cachedKeys(datasetType, () => [ `datasets.${datasetType}`, - `controllers.${datasetType}`, - `controllers.${datasetType}.datasets`, '' ]); } @@ -192,12 +188,9 @@ export default class Config { return cachedKeys(`${datasetType}.transition.${transition}`, () => [ `datasets.${datasetType}.transitions.${transition}`, - `controllers.${datasetType}.transitions.${transition}`, - `controllers.${datasetType}.datasets.transitions.${transition}`, `transitions.${transition}`, + // The following are used for looking up the `animations` and `animation` keys `datasets.${datasetType}`, - `controllers.${datasetType}`, - `controllers.${datasetType}.datasets`, '' ]); } @@ -213,9 +206,8 @@ export default class Config { datasetElementScopeKeys(datasetType, elementType) { return cachedKeys(`${datasetType}-${elementType}`, () => [ + `datasets.${datasetType}.elements.${elementType}`, `datasets.${datasetType}`, - `controllers.${datasetType}.datasets`, - `controllers.${datasetType}.elements.${elementType}`, `elements.${elementType}`, '' ]); @@ -231,7 +223,6 @@ export default class Config { const type = this.type; return cachedKeys(`${type}-plugin-${id}`, () => [ - `controllers.${type}.plugins.${id}`, `plugins.${id}`, ...plugin.additionalOptionScopes || [], ]); @@ -244,10 +235,11 @@ export default class Config { * @param {boolean} [resetCache] - reset the cache for this mainScope */ getOptionScopes(mainScope, scopeKeys, resetCache) { - let cache = this._scopeCache.get(mainScope); + const {_scopeCache, options, type} = this; + let cache = _scopeCache.get(mainScope); if (!cache || resetCache) { cache = new Map(); - this._scopeCache.set(mainScope, cache); + _scopeCache.set(mainScope, cache); } const cached = cache.get(scopeKeys); if (cached) { @@ -260,9 +252,10 @@ export default class Config { scopes.add(mainScope); scopeKeys.forEach(key => addIfFound(scopes, mainScope, key)); } - scopeKeys.forEach(key => addIfFound(scopes, this.options, key)); + scopeKeys.forEach(key => addIfFound(scopes, options, key)); + scopeKeys.forEach(key => addIfFound(scopes, overrides[type] || {}, key)); scopeKeys.forEach(key => addIfFound(scopes, defaults, key)); - scopeKeys.forEach(key => addIfFound(scopes, defaults.descriptors, key)); + scopeKeys.forEach(key => addIfFound(scopes, descriptors, key)); const array = [...scopes]; if (keysCached.has(scopeKeys)) { @@ -276,14 +269,15 @@ export default class Config { * @return {object[]} */ chartOptionScopes() { - const controllerDefaults = defaults.controllers[this.type] || {}; + const {options, type} = this; + return [ - this.options, - controllerDefaults, - controllerDefaults.datasets || {}, - {type: this.type}, + options, + overrides[type] || {}, + defaults.datasets[type] || {}, // https://github.com/chartjs/Chart.js/issues/8531 + {type}, defaults, - defaults.descriptors + descriptors ]; } diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 6d196d03243..cf2c195b791 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -1,5 +1,5 @@ import animator from './core.animator'; -import defaults from './core.defaults'; +import defaults, {overrides} from './core.defaults'; import Interaction from './core.interaction'; import layouts from './core.layouts'; import {BasicPlatform, DomPlatform} from '../platform'; @@ -410,11 +410,11 @@ class Chart { meta.controller.updateIndex(i); meta.controller.linkScales(); } else { - const controllerDefaults = defaults.controllers[type]; const ControllerClass = registry.getController(type); + const {datasetElementType, dataElementType} = defaults.datasets[type]; Object.assign(ControllerClass.prototype, { - dataElementType: registry.getElement(controllerDefaults.dataElementType), - datasetElementType: controllerDefaults.datasetElementType && registry.getElement(controllerDefaults.datasetElementType) + dataElementType: registry.getElement(dataElementType), + datasetElementType: datasetElementType && registry.getElement(datasetElementType) }); meta.controller = new ControllerClass(me, i); newControllers.push(meta.controller); @@ -1117,6 +1117,10 @@ Object.defineProperties(Chart, { enumerable, value: instances }, + overrides: { + enumerable, + value: overrides + }, registry: { enumerable, value: registry diff --git a/src/core/core.defaults.js b/src/core/core.defaults.js index c99ab78f039..4d94bbfd2c1 100644 --- a/src/core/core.defaults.js +++ b/src/core/core.defaults.js @@ -1,7 +1,8 @@ import {getHoverColor} from '../helpers/helpers.color'; import {isObject, merge, valueOrDefault} from '../helpers/helpers.core'; -const privateSymbol = Symbol('private'); +export const overrides = Object.create(null); +export const descriptors = Object.create(null); /** * @param {object} node @@ -20,17 +21,24 @@ function getScope(node, key) { return node; } +function set(root, scope, values) { + if (typeof scope === 'string') { + return merge(getScope(root, scope), values); + } + return merge(getScope(root, ''), scope); +} + /** * Please use the module's default export which provides a singleton instance * Note: class is exported for typedoc */ export class Defaults { - constructor(descriptors) { + constructor(_descriptors) { this.animation = undefined; this.backgroundColor = 'rgba(0,0,0,0.1)'; this.borderColor = 'rgba(0,0,0,0.1)'; this.color = '#666'; - this.controllers = {}; + this.datasets = {}; this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio(); this.elements = {}; this.events = [ @@ -68,12 +76,7 @@ export class Defaults { this.scales = {}; this.showLine = true; - Object.defineProperty(this, privateSymbol, { - value: Object.create(null), - writable: false - }); - - this.describe(descriptors); + this.describe(_descriptors); } /** @@ -81,10 +84,7 @@ export class Defaults { * @param {object} [values] */ set(scope, values) { - if (typeof scope === 'string') { - return merge(getScope(this, scope), values); - } - return merge(getScope(this, ''), scope); + return set(this, scope, values); } /** @@ -99,15 +99,11 @@ export class Defaults { * @param {object} [values] */ describe(scope, values) { - const root = this[privateSymbol]; - if (typeof scope === 'string') { - return merge(getScope(root, scope), values); - } - return merge(getScope(root, ''), scope); + return set(descriptors, scope, values); } - get descriptors() { - return this[privateSymbol]; + override(scope, values) { + return set(overrides, scope, values); } /** diff --git a/src/core/core.registry.js b/src/core/core.registry.js index e46d2dc2fdd..6547da2dfb7 100644 --- a/src/core/core.registry.js +++ b/src/core/core.registry.js @@ -10,7 +10,7 @@ import {each, callback as call, _capitalize} from '../helpers/helpers.core'; */ export class Registry { constructor() { - this.controllers = new TypedRegistry(DatasetController, 'controllers'); + this.controllers = new TypedRegistry(DatasetController, 'datasets', true); this.elements = new TypedRegistry(Element, 'elements'); this.plugins = new TypedRegistry(Object, 'plugins'); this.scales = new TypedRegistry(Scale, 'scales'); diff --git a/src/core/core.typedRegistry.js b/src/core/core.typedRegistry.js index 76306cbe0e7..0439faf2d7f 100644 --- a/src/core/core.typedRegistry.js +++ b/src/core/core.typedRegistry.js @@ -1,13 +1,15 @@ -import defaults from './core.defaults'; +import {merge} from '../helpers'; +import defaults, {overrides} from './core.defaults'; /** - * @typedef {{id: string, defaults: any, defaultRoutes: any}} IChartComponent + * @typedef {{id: string, defaults: any, overrides?: any, defaultRoutes: any}} IChartComponent */ export default class TypedRegistry { - constructor(type, scope) { + constructor(type, scope, override) { this.type = type; this.scope = scope; + this.override = override; this.items = Object.create(null); } @@ -20,18 +22,18 @@ export default class TypedRegistry { * @returns {string} The scope where items defaults were registered to. */ register(item) { + const me = this; const proto = Object.getPrototypeOf(item); let parentScope; if (isIChartComponent(proto)) { // Make sure the parent is registered and note the scope where its defaults are. - parentScope = this.register(proto); + parentScope = me.register(proto); } - const items = this.items; + const items = me.items; const id = item.id; - const baseScope = this.scope; - const scope = baseScope ? baseScope + '.' + id : id; + const scope = me.scope + '.' + id; if (!id) { throw new Error('class does not have id: ' + item); @@ -44,6 +46,9 @@ export default class TypedRegistry { items[id] = item; registerDefaults(item, scope, parentScope); + if (me.override) { + defaults.override(item.id, item.overrides); + } return scope; } @@ -70,18 +75,20 @@ export default class TypedRegistry { if (scope && id in defaults[scope]) { delete defaults[scope][id]; + if (this.override) { + delete overrides[id]; + } } } } function registerDefaults(item, scope, parentScope) { // Inherit the parent's defaults and keep existing defaults - const itemDefaults = Object.assign( - Object.create(null), - parentScope && defaults.get(parentScope), - item.defaults, - defaults.get(scope) - ); + const itemDefaults = merge(Object.create(null), [ + parentScope ? defaults.get(parentScope) : {}, + defaults.get(scope), + item.defaults + ]); defaults.set(scope, itemDefaults); diff --git a/test/specs/controller.bar.tests.js b/test/specs/controller.bar.tests.js index b69a5819b94..883a9ed58e1 100644 --- a/test/specs/controller.bar.tests.js +++ b/test/specs/controller.bar.tests.js @@ -1306,7 +1306,7 @@ describe('Chart.controllers.bar', function() { var chart = window.acquireChart(this.config); var meta = chart.getDatasetMeta(0); var xScale = chart.scales[meta.xAxisID]; - var options = Chart.defaults.controllers.bar.datasets; + var options = Chart.defaults.datasets.bar; var categoryPercentage = options.categoryPercentage; var barPercentage = options.barPercentage; @@ -1482,7 +1482,7 @@ describe('Chart.controllers.bar', function() { expected = barThickness; } else { var scale = chart.scales.x; - var options = Chart.defaults.controllers.bar.datasets; + var options = Chart.defaults.datasets.bar; var categoryPercentage = options.categoryPercentage; var barPercentage = options.barPercentage; var tickInterval = scale.getPixelForTick(1) - scale.getPixelForTick(0); diff --git a/test/specs/controller.line.tests.js b/test/specs/controller.line.tests.js index 187d4d1d654..9878eca185e 100644 --- a/test/specs/controller.line.tests.js +++ b/test/specs/controller.line.tests.js @@ -511,18 +511,16 @@ describe('Chart.controllers.line', function() { describe('dataset global defaults', function() { beforeEach(function() { - this._defaults = Chart.helpers.clone(Chart.defaults.controllers.line.datasets); + this._defaults = Chart.helpers.clone(Chart.defaults.datasets.line); }); afterEach(function() { - Chart.defaults.controllers.line.datasets = this._defaults; + Chart.defaults.datasets.line = this._defaults; delete this._defaults; }); it('should utilize the dataset global default options', function() { - Chart.defaults.controllers.line.datasets = Chart.defaults.controllers.line.datasets || {}; - - Chart.helpers.merge(Chart.defaults.controllers.line.datasets, { + Chart.helpers.merge(Chart.defaults.datasets.line, { spanGaps: true, tension: 0.231, backgroundColor: '#add', @@ -563,9 +561,7 @@ describe('Chart.controllers.line', function() { }); it('should be overriden by user-supplied values', function() { - Chart.defaults.controllers.line.datasets = Chart.defaults.controllers.line.datasets || {}; - - Chart.helpers.merge(Chart.defaults.controllers.line.datasets, { + Chart.helpers.merge(Chart.defaults.datasets.line, { spanGaps: true, tension: 0.231 }); diff --git a/test/specs/core.controller.tests.js b/test/specs/core.controller.tests.js index fc379d9ef52..8d95f90ac2b 100644 --- a/test/specs/core.controller.tests.js +++ b/test/specs/core.controller.tests.js @@ -1,5 +1,7 @@ describe('Chart', function() { + const overrides = Chart.overrides; + // https://github.com/chartjs/Chart.js/issues/2481 // See global.deprecations.tests.js for backward compatibility it('should be defined and prototype of chart instances', function() { @@ -92,11 +94,10 @@ describe('Chart', function() { it('should initialize config with default interaction options', function() { var callback = function() {}; var defaults = Chart.defaults; - var defaultMode = defaults.controllers.line.interaction.mode; + var defaultMode = overrides.line.interaction.mode; defaults.hover.onHover = callback; - defaults.controllers.line.spanGaps = true; - defaults.controllers.line.interaction.mode = 'test'; + overrides.line.interaction.mode = 'test'; var chart = acquireChart({ type: 'line' @@ -104,14 +105,11 @@ describe('Chart', function() { var options = chart.options; expect(options.font.size).toBe(defaults.font.size); - expect(options.showLine).toBe(defaults.controllers.line.datasets.showLine); - expect(options.spanGaps).toBe(true); expect(options.hover.onHover).toBe(callback); expect(options.hover.mode).toBe('test'); defaults.hover.onHover = null; - defaults.controllers.line.spanGaps = false; - defaults.controllers.line.interaction.mode = defaultMode; + overrides.line.interaction.mode = defaultMode; }); it('should initialize config with default hover options', function() { @@ -119,8 +117,7 @@ describe('Chart', function() { var defaults = Chart.defaults; defaults.hover.onHover = callback; - defaults.controllers.line.spanGaps = true; - defaults.controllers.line.hover.mode = 'test'; + overrides.line.hover.mode = 'test'; var chart = acquireChart({ type: 'line' @@ -128,23 +125,21 @@ describe('Chart', function() { var options = chart.options; expect(options.font.size).toBe(defaults.font.size); - expect(options.showLine).toBe(defaults.controllers.line.datasets.showLine); - expect(options.spanGaps).toBe(true); expect(options.hover.onHover).toBe(callback); expect(options.hover.mode).toBe('test'); defaults.hover.onHover = null; - defaults.controllers.line.spanGaps = false; - delete defaults.controllers.line.hover.mode; + delete overrides.line.hover.mode; }); it('should override default options', function() { var callback = function() {}; var defaults = Chart.defaults; + var defaultSpanGaps = defaults.datasets.line.spanGaps; defaults.hover.onHover = callback; - defaults.controllers.line.hover.mode = 'x-axis'; - defaults.controllers.line.spanGaps = true; + overrides.line.hover.mode = 'x-axis'; + defaults.datasets.line.spanGaps = true; var chart = acquireChart({ type: 'line', @@ -167,12 +162,12 @@ describe('Chart', function() { expect(options.plugins.title.position).toBe('bottom'); defaults.hover.onHover = null; - delete defaults.controllers.line.hover.mode; - defaults.controllers.line.spanGaps = false; + delete overrides.line.hover.mode; + defaults.datasets.line.spanGaps = defaultSpanGaps; }); it('should initialize config with default dataset options', function() { - var defaults = Chart.defaults.controllers.pie.datasets; + var defaults = Chart.defaults.datasets.pie; var chart = acquireChart({ type: 'pie' @@ -431,7 +426,7 @@ describe('Chart', function() { expect(chart.scales.x.options._jasmineCheck).toBeDefined(); expect(chart.scales.y.options._jasmineCheck).toBeDefined(); - expect(Chart.defaults.controllers.line._jasmineCheck).not.toBeDefined(); + expect(Chart.overrides.line._jasmineCheck).not.toBeDefined(); expect(Chart.defaults._jasmineCheck).not.toBeDefined(); expect(Chart.defaults.scales.linear._jasmineCheck).not.toBeDefined(); expect(Chart.defaults.scales.category._jasmineCheck).not.toBeDefined(); diff --git a/test/specs/core.registry.tests.js b/test/specs/core.registry.tests.js index ade0ffdb33a..2d94105f14b 100644 --- a/test/specs/core.registry.tests.js +++ b/test/specs/core.registry.tests.js @@ -5,17 +5,22 @@ describe('Chart.registry', function() { CustomController.defaults = { foo: 'bar' }; + CustomController.overrides = { + bar: 'foo' + }; Chart.register(CustomController); expect(Chart.registry.getController('custom')).toEqual(CustomController); - expect(Chart.defaults.controllers.custom).toEqual(CustomController.defaults); + expect(Chart.defaults.datasets.custom).toEqual(CustomController.defaults); + expect(Chart.overrides.custom).toEqual(CustomController.overrides); Chart.unregister(CustomController); expect(function() { Chart.registry.getController('custom'); }).toThrow(new Error('"custom" is not a registered controller.')); - expect(Chart.defaults.controllers.custom).not.toBeDefined(); + expect(Chart.overrides.custom).not.toBeDefined(); + expect(Chart.defaults.datasets.custom).not.toBeDefined(); }); it('should handle an ES6 scale extension', function() { @@ -34,7 +39,7 @@ describe('Chart.registry', function() { expect(function() { Chart.registry.getScale('es6Scale'); }).toThrow(new Error('"es6Scale" is not a registered scale.')); - expect(Chart.defaults.controllers.custom).not.toBeDefined(); + expect(Chart.defaults.scales.es6Scale).not.toBeDefined(); }); it('should handle an ES6 element extension', function() { @@ -104,14 +109,14 @@ describe('Chart.registry', function() { Chart.registry.addControllers(customExtension); expect(Chart.registry.getController('custom')).toEqual(customExtension); - expect(Chart.defaults.controllers.custom).toEqual(customExtension.defaults); + expect(Chart.defaults.datasets.custom).toEqual(customExtension.defaults); Chart.registry.removeControllers(customExtension); expect(function() { Chart.registry.getController('custom'); }).toThrow(new Error('"custom" is not a registered controller.')); - expect(Chart.defaults.controllers.custom).not.toBeDefined(); + expect(Chart.defaults.datasets.custom).not.toBeDefined(); }); it('as scale', function() { @@ -199,17 +204,21 @@ describe('Chart.registry', function() { }); it('should preserve existing defaults', function() { - Chart.defaults.controllers.test = {test1: true}; + Chart.defaults.datasets.test = {test1: true, test3: false}; + Chart.overrides.test = {testA: true, testC: false}; class testController extends Chart.DatasetController {} testController.id = 'test'; testController.defaults = {test1: false, test2: true}; + testController.overrides = {testA: false, testB: true}; Chart.register(testController); - expect(Chart.defaults.controllers.test).toEqual({test1: true, test2: true}); + expect(Chart.defaults.datasets.test).toEqual({test1: false, test2: true, test3: false}); + expect(Chart.overrides.test).toEqual({testA: false, testB: true, testC: false}); Chart.unregister(testController); - expect(Chart.defaults.controllers.test).not.toBeDefined(); + expect(Chart.defaults.datasets.test).not.toBeDefined(); + expect(Chart.overrides.test).not.toBeDefined(); }); describe('should handle multiple items', function() { diff --git a/test/specs/global.defaults.tests.js b/test/specs/global.defaults.tests.js index a1fcf4996d1..ddf21e78755 100644 --- a/test/specs/global.defaults.tests.js +++ b/test/specs/global.defaults.tests.js @@ -1,7 +1,6 @@ describe('Default Configs', function() { describe('Bubble Chart', function() { it('should return correct tooltip strings', function() { - var config = Chart.defaults.controllers.bubble; var chart = window.acquireChart({ type: 'bubble', data: { @@ -14,7 +13,6 @@ describe('Default Configs', function() { }] }] }, - options: config }); // fake out the tooltip hover and force the tooltip to update @@ -33,7 +31,6 @@ describe('Default Configs', function() { describe('Doughnut Chart', function() { it('should return correct tooltip strings', function() { - var config = Chart.defaults.controllers.doughnut; var chart = window.acquireChart({ type: 'doughnut', data: { @@ -42,7 +39,6 @@ describe('Default Configs', function() { data: [10, 20, 30], }] }, - options: config }); // fake out the tooltip hover and force the tooltip to update @@ -59,7 +55,6 @@ describe('Default Configs', function() { }); it('should return correct tooltip string for a multiline label', function() { - var config = Chart.defaults.controllers.doughnut; var chart = window.acquireChart({ type: 'doughnut', data: { @@ -68,7 +63,6 @@ describe('Default Configs', function() { data: [10, 20, 30], }] }, - options: config }); // fake out the tooltip hover and force the tooltip to update @@ -89,7 +83,6 @@ describe('Default Configs', function() { }); it('should return correct legend label objects', function() { - var config = Chart.defaults.controllers.doughnut; var chart = window.acquireChart({ type: 'doughnut', data: { @@ -101,7 +94,6 @@ describe('Default Configs', function() { borderColor: '#000' }] }, - options: config }); var expected = [{ @@ -130,7 +122,7 @@ describe('Default Configs', function() { }); it('should hide the correct arc when a legend item is clicked', function() { - var config = Chart.defaults.controllers.doughnut; + var config = Chart.overrides.doughnut; var chart = window.acquireChart({ type: 'doughnut', data: { @@ -142,7 +134,6 @@ describe('Default Configs', function() { borderColor: '#000' }] }, - options: config }); spyOn(chart, 'update').and.callThrough(); @@ -159,7 +150,6 @@ describe('Default Configs', function() { describe('Polar Area Chart', function() { it('should return correct tooltip strings', function() { - var config = Chart.defaults.controllers.polarArea; var chart = window.acquireChart({ type: 'polarArea', data: { @@ -168,7 +158,6 @@ describe('Default Configs', function() { data: [10, 20, 30], }] }, - options: config }); // fake out the tooltip hover and force the tooltip to update @@ -185,7 +174,6 @@ describe('Default Configs', function() { }); it('should return correct legend label objects', function() { - var config = Chart.defaults.controllers.polarArea; var chart = window.acquireChart({ type: 'polarArea', data: { @@ -197,7 +185,6 @@ describe('Default Configs', function() { borderColor: '#000' }] }, - options: config }); var expected = [{ @@ -226,7 +213,7 @@ describe('Default Configs', function() { }); it('should hide the correct arc when a legend item is clicked', function() { - var config = Chart.defaults.controllers.polarArea; + var config = Chart.overrides.polarArea; var chart = window.acquireChart({ type: 'polarArea', data: { @@ -238,7 +225,6 @@ describe('Default Configs', function() { borderColor: '#000' }] }, - options: config }); spyOn(chart, 'update').and.callThrough(); diff --git a/test/specs/platform.dom.tests.js b/test/specs/platform.dom.tests.js index 683f3712fe5..7e6ab03e54f 100644 --- a/test/specs/platform.dom.tests.js +++ b/test/specs/platform.dom.tests.js @@ -119,8 +119,8 @@ describe('Platform.dom', function() { }); it('should use default "chart" aspect ratio for render and display sizes', function() { - var ratio = Chart.defaults.controllers.doughnut.aspectRatio; - Chart.defaults.controllers.doughnut.aspectRatio = 1; + var ratio = Chart.overrides.doughnut.aspectRatio; + Chart.overrides.doughnut.aspectRatio = 1; var chart = acquireChart({ type: 'doughnut', @@ -133,7 +133,7 @@ describe('Platform.dom', function() { } }); - Chart.defaults.controllers.doughnut.aspectRatio = ratio; + Chart.overrides.doughnut.aspectRatio = ratio; expect(chart).toBeChartOfSize({ dw: 425, dh: 425, diff --git a/types/index.esm.d.ts b/types/index.esm.d.ts index 9ae5fc70a66..4052e0d1f43 100644 --- a/types/index.esm.d.ts +++ b/types/index.esm.d.ts @@ -93,7 +93,8 @@ export interface ControllerDatasetOptions extends ParsingOptions { export interface BarControllerDatasetOptions extends ControllerDatasetOptions, ScriptableAndArrayOptions>, - ScriptableAndArrayOptions> { + ScriptableAndArrayOptions>, + AnimationOptions<'bar'> { /** * The ID of the x axis to plot this dataset on. */ @@ -182,7 +183,8 @@ export interface LineControllerDatasetOptions ScriptableAndArrayOptions>, ScriptableAndArrayOptions>, ScriptableOptions>, - ScriptableOptions> { + ScriptableOptions>, + AnimationOptions<'line'> { /** * The ID of the x axis to plot this dataset on. */ @@ -238,7 +240,8 @@ export const ScatterController: ChartComponent & { export interface DoughnutControllerDatasetOptions extends ControllerDatasetOptions, ScriptableAndArrayOptions>, - ScriptableAndArrayOptions> { + ScriptableAndArrayOptions>, + AnimationOptions<'doughnut'> { /** * Sweep to allow arcs to cover. @@ -364,8 +367,9 @@ export interface RadarControllerDatasetOptions ScriptableOptions>, ScriptableOptions>, ScriptableOptions>, - ScriptableOptions> { - /** + ScriptableOptions>, + AnimationOptions<'radar'> { + /** * The ID of the x axis to plot this dataset on. */ xAxisID: string; @@ -496,6 +500,7 @@ export declare class Chart< notifyPlugins(hook: string, args?: AnyObject): boolean | void; static readonly defaults: Defaults; + static readonly overrides: Overrides; static readonly version: string; static readonly instances: { [key: string]: Chart }; static readonly registry: Registry; @@ -608,16 +613,6 @@ export interface DatasetControllerChartComponent extends ChartComponent { } export interface Defaults extends CoreChartOptions, ElementChartOptions, PluginChartOptions { - controllers: { - [key in ChartType]: DeepPartial< - CoreChartOptions & - ElementChartOptions & - PluginChartOptions & - DatasetChartOptions[key] & - ScaleChartOptions & - ChartTypeRegistry[key]['chartOptions'] - >; - }; scale: ScaleOptionsByType; scales: { @@ -648,6 +643,17 @@ export interface Defaults extends CoreChartOptions, ElementChartOptio route(scope: string, name: string, targetScope: string, targetName: string): void; } +export type Overrides = { + [key in ChartType]: DeepPartial< + CoreChartOptions & + ElementChartOptions & + PluginChartOptions & + DatasetChartOptions & + ScaleChartOptions & + ChartTypeRegistry[key]['chartOptions'] + >; +} + export const defaults: Defaults; export interface InteractionOptions { axis?: string; @@ -1349,7 +1355,9 @@ export interface HoverInteractionOptions extends CoreInteractionOptions { export interface CoreChartOptions extends ParsingOptions, AnimationOptions { - datasets: AnimationOptions; + datasets: { + [key in ChartType]: ChartTypeRegistry[key]['datasetOptions'] + } /** * The base axis of the chart. 'x' for vertical charts and 'y' for horizontal charts. @@ -1474,30 +1482,24 @@ export type AnimationSpec = { * The number of milliseconds an animation takes. * @default 1000 */ - duration: Scriptable>; + duration?: Scriptable>; /** * Easing function to use * @default 'easeOutQuart' */ - easing: Scriptable>; - - /** - * Running animation count + FPS display in upper left corner of the chart. - * @default false - */ - debug: Scriptable>; + easing?: Scriptable>; /** * Delay before starting the animations. * @default 0 */ - delay: Scriptable>; + delay?: Scriptable>; /** * If set to true, the animations loop endlessly. * @default false */ - loop: Scriptable>; + loop?: Scriptable>; } export type AnimationsSpec = { @@ -1536,11 +1538,11 @@ export type AnimationOptions = { /** * Callback called on each step of an animation. */ - onProgress: (this: Chart, event: AnimationEvent) => void; + onProgress?: (this: Chart, event: AnimationEvent) => void; /** * Callback called when all animations are completed. */ - onComplete: (this: Chart, event: AnimationEvent) => void; + onComplete?: (this: Chart, event: AnimationEvent) => void; }; animations: AnimationsSpec; transitions: TransitionsSpec; diff --git a/types/tests/defaults.ts b/types/tests/defaults.ts new file mode 100644 index 00000000000..d6dba5ad6dd --- /dev/null +++ b/types/tests/defaults.ts @@ -0,0 +1,9 @@ +import { Chart } from '../index.esm'; + +Chart.defaults.scales.time.time.minUnit = 'day'; + +Chart.defaults.plugins.title.display = false; + +Chart.defaults.datasets.bar.backgroundColor = 'red'; + +Chart.defaults.animation = { duration: 500 }; diff --git a/types/tests/options.ts b/types/tests/options.ts new file mode 100644 index 00000000000..d771a88da46 --- /dev/null +++ b/types/tests/options.ts @@ -0,0 +1,33 @@ +import { Chart } from '../index.esm'; + +export const chart = new Chart('test', { + type: 'bar', + data: { + labels: ['a'], + datasets: [{ + data: [1], + }, { + type: 'line', + data: [{ x: 1, y: 1 }] + }] + }, + options: { + animation: { + duration: 500 + }, + backgroundColor: 'red', + datasets: { + line: { + animation: { + duration: 600 + }, + backgroundColor: 'blue', + } + }, + elements: { + point: { + backgroundColor: 'red' + } + } + } +}); diff --git a/types/tests/overrides.ts b/types/tests/overrides.ts new file mode 100644 index 00000000000..8c2e02d6cc9 --- /dev/null +++ b/types/tests/overrides.ts @@ -0,0 +1,10 @@ +import { Chart } from '../index.esm'; + +Chart.overrides.bar.scales.x.type = 'time'; + +Chart.overrides.bar.plugins.title.display = false; + +Chart.overrides.line.datasets.bar.backgroundColor = 'red'; + +Chart.overrides.line.animation = false; +Chart.overrides.line.datasets.bar.animation = { duration: 100 }; diff --git a/types/tests/plugins/plugin.tooltip/tooltip_parsed_data_chart_defaults.ts b/types/tests/plugins/plugin.tooltip/tooltip_parsed_data_chart_defaults.ts index 119301c44cf..694943e6094 100644 --- a/types/tests/plugins/plugin.tooltip/tooltip_parsed_data_chart_defaults.ts +++ b/types/tests/plugins/plugin.tooltip/tooltip_parsed_data_chart_defaults.ts @@ -1,6 +1,6 @@ import { Chart } from '../../../index.esm'; -Chart.defaults.controllers.bubble.plugins.tooltip.callbacks.label = (item) => { +Chart.overrides.bubble.plugins.tooltip.callbacks.label = (item) => { const { x, y, _custom: r } = item.parsed; return `${item.label}: (${x}, ${y}, ${r})`; };