Accepted answer

You just need to wait until the chart has loaded before you get the image.

The only callback I could find with a quick search was the animation onComplete.

Here's a fiddle showing it working.

animation: {
  onComplete: function() {
    document.getElementById('coolImage').setAttribute('src', lineChart.toBase64Image());


You can get the base64 from a canvas with toDataURL(). But in your case, the graphic probably hasn't been drawn completely before you try to read the canvas.

It works if I put the drawing code in a button:


    <canvas id="chartJSContainer" width="100" height="100"></canvas>
    <img src="" id="coolImage" class="img-fluid" alt="Responsive image">
    <button id="create">Create image</button>


var canvas = document.getElementById('chartJSContainer');
var ctx = canvas.getContext('2d');
var lineChart = new Chart(ctx, options);
var button = document.getElementById("create")

button.addEventListener("click", function() {
    var dataURL = canvas.toDataURL();
    document.getElementById('coolImage').src = dataURL;



Your code is working, but Kokodoko is correct that "the graphic probably hasn't been drawn completely before you try to read the canvas", so the image is simply of a blank canvas.

However, here are two ways I can immediately think of to set the image instead of manually pressing a button:

  1. Turn off animation:

    options: {
      animation: {
        duration: 0 // general animation time
  2. Delay reading the canvas:

    setTimeout(() => {
      document.getElementById('coolImage').setAttribute('src', lineChart.toBase64Image());
    }, 1000); // execute after 1 second.

Related Query

More Query from same tag