I'm using react-chartjs-2 but I need to get chart only as image, without rendering it. I can't render it because I need to print the image inside a PDF document (react-pdf); if I put the chart component inside Document component (from react-pdf) I receive errors.
I tried to create inside a constant but seems not to work (neither log inside onComplete callback is printed).
const options = {
...
animation: {
onComplete: function(data) {
console.log("complete")
}
}
...
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const chart = new Chart(ctx, {
type: 'radar',
options: options,
data: data
});
console.log(chart.toBase64Image());
I search in Github repo and official website for a specific hook or something else but with no success. Is there a way to get chart image with no render?
You don't get an image for the chart because the canvas has no width or height (check canvas.offsetWidth
,
canvas.offsetHeight
), nor can it have one until you insert it into the DOM.
To get an image without inserting the chart into the DOM, you may use an OffscreenCanvas.
With that, set animation: false
for the chart, and get the data url using the OffscreenCanvas
procedure,
not chart.toBase64Image
.
Demo snippet (image inserted into the DOM for verification)
const canvas = new OffscreenCanvas(300, 300);
const chart = new Chart(canvas.getContext('2d'), {
type: 'radar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June'],
datasets: [{
label: 'Dataset 1',
data: Array.from({length: 6}, () => Math.random() * 10 + 5),
backgroundColor: 'rgba(221,84,112,0.4)',
borderColor: 'rgb(221,84,112)',
}, {
label: 'Dataset 2',
data: Array.from({length: 6}, () => Math.random() * 10 + 5),
backgroundColor: 'rgba(84,112,221,0.4)',
borderColor: 'rgb(84,112,221)',
}]
},
options: {
responsive: false,
animation: false
}
});
(async () => {
const blob = await canvas.convertToBlob();
const dataURL = await new Promise(resolve => {
const fr = new FileReader();
fr.onload = function(e){resolve(e.target.result);}
fr.readAsDataURL(blob);
});
console.log(dataURL);
// for verification
const img = new Image();
img.src = dataURL;
document.body.appendChild(img)
})();
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>