I am using Chart.js. I am trying to convert the chart to an image by getting a base 64 string. The tutorial (http://www.chartjs.org/docs/) devotes an entire 1 line on the topic:
The canvas element also allows for saving the contents as a base 64 string, allowing saving the chart as an image.
A canvas
element has the method of toDataURL
, which returns a base64 string of the image. However, when I do that, the image it renders is just a transparent rectangle with the dimensions of the chart, and it does not include the chart contents.
Here is a fiddle: http://jsfiddle.net/KSgV7/
The "images" in the fiddle are styled with a black border, so you can see where they are supposed to be, since they seem to just be a big transparent block.
Has anyone successfully converted a Chart.js chart to an image?
This question is related to
javascript
html
canvas
chart.js
You should use the Chartjs API function toBase64Image()
instead and call it after the animation is complete. Therefore:
var pieChart, URI;
var options = {
animation : {
onComplete : function(){
URI = pieChart.toBase64Image();
}
}
};
var content = {
type: 'pie', //whatever, not relevant for this example
data: {
datasets: dataset //whatever, not relevant for this example
},
options: options
};
pieChart = new Chart(pieChart, content);
You can check this example and run it
var chart = new Chart(ctx, {_x000D_
type: 'bar',_x000D_
data: {_x000D_
labels: ['Standing costs', 'Running costs'], // responsible for how many bars are gonna show on the chart_x000D_
// create 12 datasets, since we have 12 items_x000D_
// data[0] = labels[0] (data for first bar - 'Standing costs') | data[1] = labels[1] (data for second bar - 'Running costs')_x000D_
// put 0, if there is no data for the particular bar_x000D_
datasets: [{_x000D_
label: 'Washing and cleaning',_x000D_
data: [0, 8],_x000D_
backgroundColor: '#22aa99'_x000D_
}, {_x000D_
label: 'Traffic tickets',_x000D_
data: [0, 2],_x000D_
backgroundColor: '#994499'_x000D_
}, {_x000D_
label: 'Tolls',_x000D_
data: [0, 1],_x000D_
backgroundColor: '#316395'_x000D_
}, {_x000D_
label: 'Parking',_x000D_
data: [5, 2],_x000D_
backgroundColor: '#b82e2e'_x000D_
}, {_x000D_
label: 'Car tax',_x000D_
data: [0, 1],_x000D_
backgroundColor: '#66aa00'_x000D_
}, {_x000D_
label: 'Repairs and improvements',_x000D_
data: [0, 2],_x000D_
backgroundColor: '#dd4477'_x000D_
}, {_x000D_
label: 'Maintenance',_x000D_
data: [6, 1],_x000D_
backgroundColor: '#0099c6'_x000D_
}, {_x000D_
label: 'Inspection',_x000D_
data: [0, 2],_x000D_
backgroundColor: '#990099'_x000D_
}, {_x000D_
label: 'Loan interest',_x000D_
data: [0, 3],_x000D_
backgroundColor: '#109618'_x000D_
}, {_x000D_
label: 'Depreciation of the vehicle',_x000D_
data: [0, 2],_x000D_
backgroundColor: '#109618'_x000D_
}, {_x000D_
label: 'Fuel',_x000D_
data: [0, 1],_x000D_
backgroundColor: '#dc3912'_x000D_
}, {_x000D_
label: 'Insurance and Breakdown cover',_x000D_
data: [4, 0],_x000D_
backgroundColor: '#3366cc'_x000D_
}]_x000D_
},_x000D_
options: {_x000D_
responsive: false,_x000D_
legend: {_x000D_
position: 'right' // place legend on the right side of chart_x000D_
},_x000D_
scales: {_x000D_
xAxes: [{_x000D_
stacked: true // this should be set to make the bars stacked_x000D_
}],_x000D_
yAxes: [{_x000D_
stacked: true // this also.._x000D_
}]_x000D_
},_x000D_
animation : {_x000D_
onComplete : done_x000D_
} _x000D_
}_x000D_
});_x000D_
_x000D_
function done(){_x000D_
alert(chart.toBase64Image());_x000D_
}
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>_x000D_
<canvas id="ctx" width="700"></canvas>
_x000D_
First convert your Chart.js canvas to base64 string.
var url_base64 = document.getElementById('myChart').toDataURL('image/png');
Set it as a href attribute for anchor tag.
link.href = url_base64;
<a id='link' download='filename.png'>Save as Image</a>
You can also use the toBase64Image() method setting animation: false
var options = {
bezierCurve : false,
animation: false
};
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
}
);
You can access afterRender
hook by using plugins
.
And here are all the plugin api available.
In html file:
<html>
<canvas id="myChart"></canvas>
<div id="imgWrap"></div>
</html>
In js file:
var chart = new Chart(ctx, {
...,
plugins: [{
afterRender: function () {
// Do anything you want
renderIntoImage()
},
}],
...,
});
const renderIntoImage = () => {
const canvas = document.getElementById('myChart')
const imgWrap = document.getElementById('imgWrap')
var img = new Image();
img.src = canvas.toDataURL()
imgWrap.appendChild(img)
canvas.style.display = 'none'
}
@EH_warch You need to use the Complete callback to generate your base64:
onAnimationComplete: function(){
console.log(this.toBase64Image())
}
If you see a white image, it means you called the toBase64Image before it finished rendering.
Source: Stackoverflow.com