Closed dbauszus-glx closed 2 years ago
@dbauszus-glx having a look to the codepen, I have seen errors on chart configuration (responsive
and tooltip
options were in wrong position).
In the annotation plugin, you are suing enabled
option which has been remove in version 2.0.0 (see migration guide), where display
option is used.
I have created a codepen using you code (removing async load of JS, and usinf chart,js 3.9.1 and annotation 2.0.0): https://codepen.io/stockinail/pen/PoRyMpv It seems working.
The issue seems to be related to async import and registration of plugin.
Interesting. Thanks for pointing out the differences in the migration guide.
I can see that async import from https://cdn.skypack.dev/chartjs-plugin-annotation@2.0.0 fails because the options argument is a proxy with callout.display undefined.
function resolveLabelElementProperties(chart, properties, options) {
options.callout.display = false;
Is the use of a proxy new in version 2 or can you think of any other changes which may cause the registration to fail from a dynamic import?
@dbauszus-glx the problem is not related to the undefined callout
because otherwise it wouldn't work with importing javascript by <script>
tag. And the issue is a missing registrations of annotation elements and their defaults (for this reason is undefined).
Anyway, I think I found the issue.
There is something weird when we are importing chart.js 3.9.1 from cdn.skypack.dev
.
This is the imported file from skypack:
*
* Skypack CDN - chart.js@3.9.1
*
* Learn more:
* 📙 Package Documentation: https://www.skypack.dev/view/chart.js
* 📘 Skypack Documentation: https://www.skypack.dev/docs
*
* Pinned URL: (Optimized for Production)
* ▶️ Normal: https://cdn.skypack.dev/pin/chart.js@v3.9.1-PE3H4IRdC3uTYyKwatR2/mode=imports/optimized/chartjs.js
* ⏩ Minified: https://cdn.skypack.dev/pin/chart.js@v3.9.1-PE3H4IRdC3uTYyKwatR2/mode=imports,min/optimized/chartjs.js
*
*/
// Browser-Optimized Imports (Don't directly import the URLs below in your application!)
export * from '/-/chart.js@v3.9.1-PE3H4IRdC3uTYyKwatR2/dist=es2019,mode=imports/optimized/chartjs.js';
export {default} from '/-/chart.js@v3.9.1-PE3H4IRdC3uTYyKwatR2/dist=es2019,mode=imports/optimized/chartjs.js';
But in the browser FF there is 1 file tagged as 3.9.0.
It seems an issue in skypack for version 3.9.1, because using 3.9.0 it works, perfectly, without any issue.
Code:
const mod = await import("https://cdn.skypack.dev/chart.js@3.9.0");
mod.Chart.register(...mod.registerables);
const pluginAnnotation = await import(
"https://cdn.skypack.dev/chartjs-plugin-annotation@2.0.0"
);
mod.Chart.register(pluginAnnotation.default);
See codepen: https://codepen.io/stockinail/pen/eYMbaee
Let me know if it works for you as well.
Amazing. Thanks so much for looking into this. chartjs 3.9.0 works perfect with chartjs-plugin-annotation 2.0.0.
I found another oddity unrelated to the dynamic import which is working with the correct versions.
In the forked codepen. If the data is not provided in the chart construction but set after the chart has been created like so:
myChart.data = data;
myChart.update();
Then the labels do not print. The lines are drawn correctly but just the labels are missing. There is no error message.
Would you like me to open a new ticket for this issue?
Would you like me to open a new ticket for this issue?
Maybe it's better new issue! ;) If you can send also the link to forked codepen to have a look it could be helpful.
EDIT
let's stay on this issue!
anyway I'm having a look.
The issue should be solved by PR https://github.com/chartjs/chartjs-plugin-annotation/pull/790 and release with version 2.0,1. using 2.0.1 from skypack, There is the issue outlined above. It seems that skypack will dowload also chart.js 3.9.1 because used for plugin annotation to be built. It's really weird. Let me take time to have a look more in deep.
In the meanwhile, let me propose you a workaround, adding a custom plugin to enable the labels, if the lines are visible (the solution will be to go version 2.0.1):
plugins: [{
id:'my',
afterUpdate(chart){
const elements = pluginAnnotation.default._getState(chart).elements;
for (el of elements) {
if (el.options.display) {
el.label.options.display = true;
}
}
}
}],
See codepen: https://codepen.io/stockinail/pen/eYMbaee
It's weird because when you are importing the plugin. Ihave tested importing ONLY the plugin
const { default:pluginAnnotation } = await import(
"https://cdn.skypack.dev/chartjs-plugin-annotation@2.0.1"
);
it seems that skypack is importing also Chart.js at a specific version related to the plugin.
I'm not an expert about how skypack is working but it doesn't seem correct (but maybe I'm wrong).
@dbauszus-glx Found the solution:
Pass to chart.js 3.9.1 and annotation 2.0.1
const mod = await import("https://cdn.skypack.dev/chart.js@3.9.1");
mod.Chart.register(...mod.registerables);
const pluginAnnotation = await import(
"https://cdn.skypack.dev/chartjs-plugin-annotation@2.0.1"
);
mod.Chart.register(pluginAnnotation.default);
Codepen changed accordingly: https://codepen.io/stockinail/pen/eYMbaee
I think, every time new version of plugin will be delivered, you should check which version of chartjs is related to the plugin in skypack and use that. It doesn't seem so flexible.
Let me know if it works.
Sorry for the late reply as I was on holidays. I just checked this now and chart 3.9.1 with plugin annotation 2.0.1 works as expected if imported through skypack. Thanks for looking into this.
I still get this error on 2.0.1
package.json:
"chart.js": "^3.9.1",
"chartjs-plugin-annotation": "^2.0.1",
"chartjs-plugin-datalabels": "^2.1.0",
config
const annotation1 = {
type: 'line',
borderColor: 'black',
borderWidth: 1,
scaleID: 'x',
value: '10',
}
const barChartOptions = {
indexAxis: 'y',
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
grid: {
drawBorder: false,
drawOnChartArea: false,
drawTicks: false,
},
},
y: {
grid: {
drawBorder: false,
drawOnChartArea: false,
drawTicks: false,
},
},
},
animation: {
onComplete: () => {
delayed = true
},
delay: (context) => {
let delay = 0
if (context.type === 'data' && context.mode === 'default' && !delayed) {
delay = context.dataIndex * 50 + context.datasetIndex * 100
}
return delay
},
},
plugins: {
annotation: {
common: {
drawTime: 'beforeDraw',
},
annotations: {
annotation1,
// annotation2,
// annotation3,
},
},
datalabels: {
color: '#ffffff',
anchor: 'end',
align: 'left',
labels: {
title: {
font: {
weight: 'bold',
family: 'Outfit',
size: 14,
},
},
},
formatter: function (value, context) {
switch (context.dataIndex) {
case 0:
return value + ' kg'
case 1:
return value + ' kg'
case 2:
return value + ' %'
}
},
},
legend: {
display: true,
},
tooltip: {
// enabled: false,
display: true,
},
},
}
const barChart = ref({
labels: ['Peso', 'Músculo', 'Gordura'],
datasets: [
{
borderColor: '#3B323D',
backgroundColor: '#1E1020',
borderWidth: 2,
borderRadius: 8,
data: [65, 59, 80],
},
],
})
@CavalcanteLeo it seems that the line annotation element is not registered. Can you provide a codesandbox in order to reproduce the issue?
@CavalcanteLeo I forked my codepen for you to check. https://codepen.io/dbauszus-glx/pen/rNvpdVO
I added the datalabels and annotation plugin configuration which you provided and this seems to work.
just had the same issue. Somehow some graphs did draw fine with annotations, but others (just with different datapoints) failed with this error. What solved it is registering DataLabelsPlugin
with Chart.register
just had the same issue. Somehow some graphs did draw fine with annotations, but others (just with different datapoints) failed with this error. What solved it is registering
DataLabelsPlugin
with Chart.register
I'm curious to understand better why you have an issue on annotation plugin, solved registering the datalabels plugin. Do you have a codepen/codesandbox to go more in deep?
hey @stockiNail, I've just tried to reproduce this in a sandbox, but it does work there.
In my setup, I'm generating the charts on the backend with nodejs (using ChartJSNodeCanvas). Probably that's something on their side then..
I'm trying to use this plugin in an Ember (4.x) app, and I've run across this issue as well. From what I can tell, the issue for me stems from the fact that:
d('chart.js/auto', [], function() { return require('chart.js/auto'); });
d('chartjs-plugin-annotation', [], function() { return require('chartjs-plugin-annotation'); });
chart.js/auto
(version 4.1.x) to chart.js/auto/auto.cjs
(the CommonJS module), which then imports chart.js/dist/chart.cjs
, whilechartjs-plugin-annotation
(version 2.1.1) gets mapped to chartjs-plugin-annotation/dist/chartjs-plugin-annotation.esm.js
(the ESM module), which then imports chart.js/dist/chart.js
.main.js:1564 Uncaught TypeError: Cannot read properties of undefined (reading 'borderWidth')
at resolveLabelElementProperties (main.js:1564:31)
at LineAnnotation.resolveElementProperties (main.js:1380:29)
at updateElements (main.js:2082:32)
at Object.afterUpdate (main.js:2249:5)
at Object.callback (main.js:14474:19)
at PluginService._notify (main.js:8082:33)
at PluginService.notify (main.js:8065:29)
at Chart.notifyPlugins (main.js:9320:30)
at Chart.update (main.js:8881:14)
at Chart.<anonymous> (main.js:8623:64)
I am able to reproduce the issue in a minimal project with:
{
"dependencies": {
"chart.js": "^4.1.2",
"chartjs-plugin-annotation": "^2.1.1"
},
"devDependencies": {
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
}
}
using the command line:
npx webpack --mode development --devtool source-map ./index.js
and the following index.js
file modeled off the basic line sample:
const Chart = require('chart.js/auto');
const annotationPlugin = require('chartjs-plugin-annotation');
Chart.register(annotationPlugin.default);
// From https://www.chartjs.org/chartjs-plugin-annotation/latest/samples/line/basic.html
const DATA_COUNT = 8;
const labels = [];
for (let i = 0; i < DATA_COUNT; ++i) {
labels.push('' + i);
}
const data = {
labels: labels,
datasets: [{
data: [ 57.726, 91.99, 45.051, 64.686, 45.34, 88.123, 30.814, 27.856 ] // Utils.numbers(numberCfg)
}]
};
const annotation = {
type: 'line',
borderColor: 'black',
borderWidth: 3,
scaleID: 'y',
value: 50
};
const config = {
type: 'line',
data,
options: {
scales: {
y: {
stacked: true
}
},
plugins: {
annotation: {
annotations: {
annotation
}
}
}
}
};
new Chart(document.getElementById('canvas'), config);
And the following index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Reproduce chartjs-plugin-annotation#786</title>
</head>
<body>
<canvas id="canvas" width="400"></canvas>
<script src="dist/main.js"></script>
</body>
</html>
Obviously the issue is that Webpack is choosing inconsistent module types for chart.js vs this plugin.
If I replace the first lines with:
import Chart from 'chart.js/auto';
import annotationPlugin from 'chartjs-plugin-annotation';
Chart.register(annotationPlugin);
Then the issue goes away, because Webpack uses the ESM versions of each.
It's clear to me why Webpack is choosing the CJS when using require('chart.js/auto')
but it was less clear to me why it was using ESM for require('chartjs-plugin-annotation')
. Probably because it prefers module
to main
by default?
Fortunately I just noticed that #832 was merged recently, and if I apply that change to my local node_modules/chartjs-plugin-annotation/package.json
, then this issue is resolved because Webpack correctly chooses chartjs-plugin-annotation/dist/chartjs-plugin-annotation.min.js
, which then uses require("chart.js")
, which Webpack maps to chart.js/dist/chart.cjs
, thereby eliminating the inconsistent versions.
So I think this issue (at least for me) should be resolved with the next version of this plugin that includes #832.
As a workaround (for now or in perpetuity), I can introduce an intermediate ESM module that uses import
for all Chart.js plugins, so that Webpack properly and consistently chooses the ESM version of each.
We seem to be stuck with plugin-annotation v1.3.0 and chartjs v3.7.0 where following example for a line chart with multiple datasets works with multiple annotations.
https://codepen.io/dbauszus-glx/pen/MWOjGzw
Upgrading plugin-annotation to v2.0.0 causes following TypeError:
Cannot set properties of undefined (setting 'display') at resolveLabelElementProperties
.Upgrading chartjs to v3.9.1 causes a different TypeError:
Cannot read properties of undefined (reading 'lastIndexOf')
The same error persists with chartjs on v3.9.1 and plugin-aanotation on v2.0.0