The chart seem to be async so you will probably need to provide a callback when the animation has finished or else the canvas will be empty.
var options = {
bezierCurve : false,
onAnimationComplete: done /// calls function done() {} at end
};
Answer from user1693593 on Stack Overflow
» npm install chartjs-to-image
Videos
The chart seem to be async so you will probably need to provide a callback when the animation has finished or else the canvas will be empty.
var options = {
bezierCurve : false,
onAnimationComplete: done /// calls function done() {} at end
};
Chart.JS API has changed since this was posted and older examples did not seem to be working for me. here is an updated fiddle that works on the newer versions
HTML:
<body>
<canvas id="canvas" height="450" width="600"></canvas>
<img id="url" />
</body>
JS:
function done(){
alert("haha");
var url=myLine.toBase64Image();
document.getElementById("url").src=url;
}
var options = {
bezierCurve : false,
animation: {
onComplete: done
}
};
var myLine = new
Chart(document.getElementById("canvas").getContext("2d"),
{
data:lineChartData,
type:"line",
options:options
}
);
http://jsfiddle.net/KSgV7/585/
its not possible to render without attaching canvas to dom, but you can hide it and it will work as expected.
const chartEl = document.createElement("canvas");
chartEl.setAttribute("width", "400");
chartEl.setAttribute("height", "400");
chartEl.style.display = "none";
document.body.append(chartEl);
let chart = new Chart(chartEl, {
type: "bar",
data: {
datasets: [
{
barPercentage: 0.5,
barThickness: 6,
maxBarThickness: 8,
minBarLength: 2,
data: [10, 20, 30, 40, 50, 60, 70]
}
]
},
options: {
scales: {},
animation: false
}
});
chart.render();
console.log(chart.toBase64Image());
chartEl.remove();
The only way to render a chart without you specifically adding it to the dom is by making use of the offscreen-canvas as explained here in the documentation of chart.js: https://www.chartjs.org/docs/3.7.1/general/performance.html#parallel-rendering-with-web-workers-chromium-only
Downside is that the offscreen canvas API is only available in chromium based browsers.
Other approach you can take is by adding the canvas to the dom, let chart.js render to it, get the base64 representation and then remove the canvas directly after that like so:
let ctx = document.createElement("canvas")
document.documentElement.appendChild(ctx)
ctx.setAttribute("width", "400")
ctx.setAttribute("height", "400")
let chart = new Chart(ctx, {
type: "bar",
data: {
labels: ['a', 'b', 'c', 'd', 'e', 'f', ' g'],
datasets: [{
barPercentage: 0.5,
barThickness: 6,
maxBarThickness: 8,
minBarLength: 2,
data: [10, 20, 30, 40, 50, 60, 70]
}]
},
options: {
scales: {}
}
})
const base64 = chart.toBase64Image();
ctx.remove();
console.log(base64)
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>
Chart.js is built on the HTML5 canvas element.
To use it on node.js you need to mimic this element in node.
There is a package that try to handle all the needed libraries for this purpose, you can find it here chartjs-node
I had this problem and wound up building a web service that renders Chart.js charts as PNG images. I open sourced my work on this
The service is called QuickChart. For example, if your chart config is:
{
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May'],
datasets: [{
label: 'Dogs',
data: [ 50, 60, 70, 180, 190 ]
}, {
label: 'Cats',
data: [ 100, 200, 300, 400, 500 ]
}]
}
}
You can embed the Chart.js config in the URL like so:
https://quickchart.io/chart?c={ type: 'bar', data: { labels: ['January', 'February', 'March', 'April', 'May'], datasets: [{ label: 'Dogs', data: [ 50, 60, 70, 180, 190 ] }, { label: 'Cats', data: [ 100, 200, 300, 400, 500 ] }] }}
...and it renders your chart as an image!
Note that for more complex charts, you'd want to URL encode the chart options.
There's an interactive editor on the QuickChart website which you can use to generate a URL for a given chart config. You may also view/fork the source code here (it's built on top of node-canvas and chartjs-node-canvas).