'using react-chartjs-2 , How can I save my chart as png using a download button
I'm trying to download my chart.js charts as png using a button Onclick, but I have no idea how I'm going to achieve this , I've went through this answer React-chartjs-2 Doughnut chart export to png but it wasn't quite clear enough for me as I'm quite new in chart.js don't know how I'm going to connect those variables with my button.
import React from 'react';
import { Component, useRef } from 'react';
import { Bar } from 'react-chartjs-2';
import 'chartjs-plugin-datalabels';
const data = {
labels: ['Finance & Business', 'Mining', 'Community Services', 'Electricity', 'Agriculture', 'Construction', 'Manufacture', "Trade & Tourism", "Transport & Logistics"],
datasets: [
{
label: 'My First dataset',
backgroundColor: ["#3283FC", "", "", "#00C0C8", "#C0BD00", "#3A46B1", "#00A150", "#FEB200", "#9302a1"],
borderWidth: 1,
hoverBackgroundColor: 'rgba(255,99,132,0.4)',
hoverBorderColor: 'rgba(255,99,132,1)',
data: [0.6, 0.0, 0.0, -0.1, -0.1, -0.3, -0.3, -0.6, -1.0],
}
]
};
class StackedBar extends Component {
render() {
return (
<div>
<h2>Bar Example (custom size)</h2>
<Bar
data={data}
options={{
plugins: {
datalabels: {
display: true,
color: '#fff'
}
},
title: {
display: true,
text: 'Contribution Percentage',
position: 'left'
},
maintainAspectRatio: true,
scales: {
xAxes: [{
stacked: true,
gridLines: {
borderDash: [2, 6],
color: "black"
},
scales: {
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
steps: 0.5,
stepSize: 0.5,
max: 1.5,
min: -1.0
},
}]
},
}}
/>
</div>
);
}
}
export default StackedBar;
Solution 1:[1]
So I installed a plugin called FileSave.js //
- npm install
npm i file-saver - import the plugin
import { saveAs } from 'file-saver'; - than just write this blob function
class StackedBar extends Component {
saveCanvas() {
//save to png
const canvasSave = document.getElementById('stackD');
canvasSave.toBlob(function (blob) {
saveAs(blob, "testing.png")
})
}
render() {
return (
<div>
<a onClick={this.saveCanvas}>Download as PNG</a>
<Bar id="stackD" data={data} options={options} />
</div>
);
}
}
export default StackedBar;
Solution 2:[2]
another option is to use the chart ref, and then use the chart.js toBase64Image function. save this out as base64, convert to blob and save as a file using the file-saver package.
import { saveAs } from 'file-saver';
/**
* @param b64Data
* @param contentType
* @param sliceSize
* @returns {Blob}
* @link https://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
*/
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
// eslint-disable-next-line no-plusplus
for (let i = 0; i < slice.length; i += 1) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, { type: contentType });
};
... in component
const chartRef = useRef(null);
... in jsx...
<Button
onClick={() => {
const b64 = chartRef.current.toBase64Image().replace('data:image/png;base64,', '');
const content = b64toBlob(b64);
const file = new File([content], 'Revenue_chart.png', { type: 'image/png' });
saveAs(file);
}}
>
img
</Button>
<Line data={data} options={options} ref={chartRef} />
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Phakamani Xulu |
| Solution 2 | pgee70 |
