Dinero
Dinero

Reputation: 1160

Take image of a chart.js from canvas and display it as an image

Display a base64 image of a chart.

I have a simple chart that I create. After it is created i want to take the base64 image of it and display it in html but I am not able to do that.

Here is my FIDDLE

HTML

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

JS CODE

var options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [
        {
          label: '# of Votes',
          data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1,
        backgroundColor: 'rgba(255, 0, 15, 0.54)'
        },  
            {
                label: '# of Points',
                data: [7, 11, 5, 8, 3, 7],
                borderWidth: 1
            }
        ]
  },
  options: {
  label: {
      fontSize: 50
    },
    scales: {
        yAxes: [{
        ticks: {
                    reverse: false
        }
      }]
    }
  }
}


var ctx = document.getElementById('chartJSContainer').getContext('2d');
var lineChart = new Chart(ctx, options);
document.getElementById('coolImage').setAttribute('src', lineChart.toBase64Image());

I am not even sure if i am logic is correct because there could be a easier way to do this. I essentially want to display the image of the graph rather than the interactive line graph itself.

Upvotes: 3

Views: 7410

Answers (3)

Shoejep
Shoejep

Reputation: 4839

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());
  }
}

Upvotes: 4

timclutton
timclutton

Reputation: 13004

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.
    

Upvotes: 2

Kokodoko
Kokodoko

Reputation: 28128

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:

HTML

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

JAVASCRIPT

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();
    console.log(dataURL);
    document.getElementById('coolImage').src = dataURL;
})

JSFIDDLE

Upvotes: 2

Related Questions