Skip to content

Commit a341079

Browse files
authored
Add support for Chart.js v4 (#145)
1 parent 8b0fb9a commit a341079

4 files changed

Lines changed: 31 additions & 22 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ The chart configuration object is based on the popular Chart.js API. Check out
4242

4343
QuickChart includes many Chart.js plugins that allow you to add chart annotations, data labels, and more: `chartjs-plugin-datalabels`, `chartjs-plugin-annotation`, `chartjs-plugin-piechart-outlabels`, `chartjs-chart-radial-gauge`, `chartjs-chart-box-and-violin-plot `, `chartjs-plugin-doughnutlabel`, and `chartjs-plugin-colorschemes`.
4444

45-
### Chart.js v3
45+
### Chart.js versions
4646

47-
Chart.js v3 is supported via the `version` parameter ([documentation](https://quickchart.io/documentation/) to read more about parameters). Custom chart plugins such as annotations and outlabels are disabled for >= 3.0.0 due to lack of support.
47+
Chart.js v3 and v4 are supported via the `version` parameter ([documentation](https://quickchart.io/documentation/) to read more about parameters). Custom chart plugins such as annotations and outlabels currently not available for >= 3.0.0.
4848

4949
Each QuickChart instance should use 1 specific version of the Chart.js library. Mixing and matching versions (e.g., rendering a v2 chart followed by a v3 chart) is not well supported.
5050

lib/charts.js

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,17 @@ const MAX_WIDTH = process.env.CHART_MAX_WIDTH || 3000;
2727

2828
const rendererCache = {};
2929

30-
function getRenderer(width, height, version, format) {
30+
async function getChartJsForVersion(version) {
31+
if (version && version.startsWith('4')) {
32+
return (await import('chart.js-v4/auto')).Chart;
33+
}
34+
if (version && version.startsWith('3')) {
35+
return require('chart.js-v3');
36+
}
37+
return require('chart.js');
38+
}
39+
40+
async function getRenderer(width, height, version, format) {
3141
if (width > MAX_WIDTH) {
3242
throw `Requested width exceeds maximum of ${MAX_WIDTH}`;
3343
}
@@ -37,9 +47,8 @@ function getRenderer(width, height, version, format) {
3747

3848
const key = `${width}__${height}__${version}__${format}`;
3949
if (!rendererCache[key]) {
40-
rendererCache[key] = new CanvasRenderService(width, height, undefined, format, () => {
41-
return version.startsWith('3') ? require('chart.js-v3') : require('chart.js');
42-
});
50+
const Chart = await getChartJsForVersion(version);
51+
rendererCache[key] = new CanvasRenderService(width, height, undefined, format, () => Chart);
4352
}
4453
return rendererCache[key];
4554
}
@@ -111,7 +120,7 @@ function patternDraw(shapeType, backgroundColor, patternColor, requestedSize) {
111120
return pattern.draw(shapeType, backgroundColor, patternColor, size);
112121
}
113122

114-
function renderChartJs(
123+
async function renderChartJs(
115124
width,
116125
height,
117126
backgroundColor,
@@ -135,7 +144,7 @@ function renderChartJs(
135144
pattern: {
136145
draw: patternDraw,
137146
},
138-
Chart: version.startsWith('3') ? require('chart.js-v3') : require('chart.js'),
147+
Chart: getChartJsForVersion(version),
139148
},
140149
});
141150
chart = vm.run(`module.exports = ${untrustedChart}`);
@@ -368,11 +377,11 @@ function renderChartJs(
368377
}
369378
logger.debug('Chart:', JSON.stringify(chart));
370379

371-
if (version.startsWith('3')) {
380+
if (version.startsWith('3') || version.startsWith('4')) {
372381
require('chartjs-adapter-moment');
373382
}
374383
if (!chart.plugins) {
375-
if (version.startsWith('3')) {
384+
if (version.startsWith('3') || version.startsWith('4')) {
376385
chart.plugins = [];
377386
} else {
378387
const chartAnnotations = require('chartjs-plugin-annotation');
@@ -415,19 +424,13 @@ function renderChartJs(
415424
});
416425
}
417426

418-
const canvasRenderService = getRenderer(width, height, version, format);
427+
const canvasRenderService = await getRenderer(width, height, version, format);
419428

420-
try {
421-
if (format === 'svg') {
422-
// SVG rendering doesn't work asychronously.
423-
return Promise.resolve(canvasRenderService.renderToBufferSync(chart, 'image/svg+xml'));
424-
}
425-
return canvasRenderService.renderToBuffer(chart);
426-
} catch (err) {
427-
// canvasRenderService doesn't seem to be throwing errors correctly for
428-
// certain chart errors.
429-
return Promise.reject(err.message || err);
429+
if (format === 'svg') {
430+
// SVG rendering doesn't work asychronously.
431+
return canvasRenderService.renderToBufferSync(chart, 'image/svg+xml');
430432
}
433+
return canvasRenderService.renderToBuffer(chart);
431434
}
432435

433436
module.exports = {

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "quickchart",
3-
"version": "1.7.1",
3+
"version": "1.8.0",
44
"main": "index.js",
55
"license": "AGPL-3.0",
66
"homepage": "https://quickchart.io/",
@@ -26,6 +26,7 @@
2626
"canvas-5-polyfill": "^0.1.5",
2727
"chart.js": "^2.9.4",
2828
"chart.js-v3": "npm:chart.js@3.9.1",
29+
"chart.js-v4": "npm:chart.js@4.0.1",
2930
"chartjs-adapter-moment": "https://github.com/typpo/chartjs-adapter-moment.git#e9bc92ab6e0e500c91c4a9871db7b14d15b5c2e7",
3031
"chartjs-chart-box-and-violin-plot": "^2.4.0",
3132
"chartjs-chart-radial-gauge": "^1.0.3",

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,11 @@ charenc@0.0.2:
993993
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.9.1.tgz#3abf2c775169c4c71217a107163ac708515924b8"
994994
integrity sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w==
995995

996+
"chart.js-v4@npm:chart.js@4.0.1":
997+
version "4.0.1"
998+
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.0.1.tgz#93d5d50ac222a5b3b6ac7488e82e1553ac031592"
999+
integrity sha512-5/8/9eBivwBZK81mKvmIwTb2Pmw4D/5h1RK9fBWZLLZ8mCJ+kfYNmV9rMrGoa5Hgy2/wVDBMLSUDudul2/9ihA==
1000+
9961001
chart.js@^2.4.0, chart.js@^2.8.0, chart.js@^2.9.4:
9971002
version "2.9.4"
9981003
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.4.tgz#0827f9563faffb2dc5c06562f8eb10337d5b9684"

0 commit comments

Comments
 (0)