-
Notifications
You must be signed in to change notification settings - Fork 12k
Description
Expected behavior
Described behavior
According to the documentation docs/developers/charts.md the chart static defaults = { ... } allow dataElementType to be null or false with the following comment:
defaults: { // If set to `false` or `null`, no dataset level element is created. // If set to a string, this is the type of element to create for the dataset. // For example, a line create needs to create a line element so this is the string 'line' datasetElementType: string | null | false, // If set to `false` or `null`, no elements are created for each data value. // If set to a string, this is the type of element to create for each data value. // For example, a line create needs to create a point element so this is the string 'point' dataElementType: string | null | false, }
and the type hints in src/types/index.d.ts allow the dataElementType to be even undefined unspecified:
export interface DatasetControllerChartComponent extends ChartComponent { defaults: { datasetElementType?: string | null | false; dataElementType?: string | null | false; }; }
although this might be wrong since DatasetControllerChartComponent is never used again in the whole codebase and just stays as an exported type.
If I do not specify dataElementType or set it to null | false | undefined the code should not crash unexpectedly (and should not allocate any arrays, create new objects, ... - unless parsing I guess?).
Current behavior
class MyController extends DatasetController {
static id = 'my';
static defaults = {
dataElementType: null,
}
parse() { }
draw() { }
}results in
core.registry.js:178 Uncaught Error: "null" is not a registered element.
at Registry._get (core.registry.js:178:13)
at Registry.getElement (core.registry.js:74:17)
at Chart.buildOrUpdateControllers (core.controller.js:445:37)
at Chart.update (core.controller.js:495:33)
at new Chart (core.controller.js:193:12)
at (index):31:1
The same behavior as with null can be observed with dataElementType set to false (allowed by docs) and eve with dataElementType not being defined at all (kinda allowed by the unused type, disallowed by docs).
This happens in
src/core/core.datasetController.js::DatasetController::_insertElements which does not check the value of dataElementType in any way. This function also allocates the meta.data array even though it should not be needed in this case (especially when parsing disabled - probably?).
I found also something similar in
src/core/core.datasetController.js::DatasetController::constructor but this somehow never gets called, at least in my experiments.
Reproducible sample
https://jsfiddle.net/cb37sr54/2/
Optional extra steps/info to reproduce
Gist GitHub: https://gist.github.com/antoninkriz/2ced01a7e90db8ac2dd417064e6a08a7
JSFiddle: https://jsfiddle.net/cb37sr54/2/
This code will raise the described error.
<canvas id="myChart"></canvas>
<script type="importmap">
{
"imports": {
"@kurkle/color": "https://cdn.jsdelivr.net/npm/@kurkle/color@0.4.0/+esm",
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.0/chunks/helpers.dataset.js": "https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chunks/helpers.dataset.js"
}
}
</script>
<script type="module">
import { Chart } from 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.0/chart.js'
import { DatasetController } from 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.0/chart.js'
import { BarController, BarElement, CategoryScale, LinearScale } from 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.0/chart.js'
class MyController extends DatasetController {
static id = 'my';
static defaults = {
dataElementType: false,
}
parse() { }
draw() { }
}
Chart.register(MyController)
Chart.register(BarController, BarElement, CategoryScale, LinearScale);
new Chart(document.getElementById('myChart'), {
data: {
labels: ['a', 'b', 'c', 'd'],
datasets: [{
type: 'my',
data: [1, 2, 3, 4],
}],
},
});
</script>Possible solution
Here I define an element to keep the code from crying and successfully render a completely empty chart.
Anyway since I do not define inRange and events: [] is not set in the config I get error on mouse moves over the chart.
core.interaction.js:174 Uncaught TypeError: element.inRange is not a function
at evaluationFunc (core.interaction.js:174:29)
at evaluateInteractionItems (core.interaction.js:83:9)
at getNearestCartesianItems (core.interaction.js:195:3)
at getNearestItems (core.interaction.js:216:7)
at nearest (core.interaction.js:356:14)
at Chart.getElementsAtEventForMode (core.controller.js:823:14)
at Chart._getActiveElements (core.controller.js:1260:17)
at Chart._handleEvent (core.controller.js:1213:25)
at Chart._eventHandler (core.controller.js:1176:26)
at listener (core.controller.js:988:12)
<canvas id="myChart"></canvas>
<script type="importmap">
{
"imports": {
"@kurkle/color": "https://cdn.jsdelivr.net/npm/@kurkle/color@0.4.0/+esm",
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.0/chunks/helpers.dataset.js": "https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chunks/helpers.dataset.js"
}
}
</script>
<script type="module">
import { Chart } from 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.0/chart.js'
import { DatasetController, Element } from 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.0/chart.js'
import { BarController, BarElement, CategoryScale, LinearScale } from 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.5.0/chart.js'
class NoopElement extends Element {
static id = 'noop'
}
class MyController extends DatasetController {
static id = 'my';
static defaults = {
dataElementType: 'noop',
}
parse() { }
draw() { }
}
Chart.register(NoopElement, MyController)
Chart.register(BarController, BarElement, CategoryScale, LinearScale);
new Chart(document.getElementById('myChart'), {
data: {
labels: ['a', 'b', 'c', 'd'],
datasets: [{
type: 'my',
data: [1, 2, 3, 4],
}],
},
});
</script>Context
No response
chart.js version
4.5.0
Browser name and version
Chrome 143, macOS 26, Apple ARM
Link to your project
No response