user7932844
user7932844

Reputation: 351

How to save Chart JS charts as image without black background using blobs and filesaver?

$("#NoBidsChart").get(0).toBlob(function(value) {
    saveAs(value, "Summary.jpg");
});

Here i am using Chart JS(v2.5.0) for rendering charts. When i try to export the charts using Canvas to Blob converter and filesaver.js, i get the black background. So how do i get the image with customized background color(preferably white)?

Upvotes: 11

Views: 21045

Answers (3)

Anne Gunn
Anne Gunn

Reputation: 2447

As I stated in my comment to the accepted answer, it bothered me that the beforeDraw event causes the fillRect code to get called multiple times. (Once per data point as far as I can see.)

But I couldn't get that approach to work when called on any other event. However, I just took the coding approach described in this answer and plugged it into code registered to run on the afterRender event and it does just what I want: run once and leave the background white.

Chart.plugins.register({
    afterRender: function(c) {
        console.log("afterRender called");
        var ctx = c.chart.ctx;
        ctx.save();
        // This line is apparently essential to getting the
        // fill to go behind the drawn graph, not on top of it.
        // Technique is taken from:
        // https://stackoverflow.com/a/50126796/165164
        ctx.globalCompositeOperation = 'destination-over';
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, c.chart.width, c.chart.height);
        ctx.restore();
    }
});

Please visit (and up vote) the linked answer to the other posted question.

Upvotes: 16

Dev_Ose
Dev_Ose

Reputation: 61

In React, with react-chartjs-2, i was able to set background color of chart like so:

const plugin = {
    beforeDraw: (chartCtx) => {
      const ctx = chartCtx.canvas.getContext('2d');
      ctx.save();
      ctx.globalCompositeOperation = 'destination-over';
      ctx.fillStyle = 'white';
      ctx.fillRect(0, 0, chartCtx.width, chartCtx.height);
      ctx.restore();
    }
};

And then add the plugin to the chart:

<Line ref={chartRef} data={chartData} options={options} plugins={[plugin]} />

Reference to the Docs

To save the chart as an image:

I created a function that uses the toBase64Image function to extract the image. I attached this function to a button to help me download chart image on click of button.

function downloadImage(){
    const link = document.createElement("a");
    link.download = `${chart.name || 'chart'}.jpg`
    link.href = chartRef.current.toBase64Image('image/jpeg', 1);
    link.click();
  }

Upvotes: 1

ɢʀᴜɴᴛ
ɢʀᴜɴᴛ

Reputation: 32879

If you want a customized background color then, you'd have to draw a background with your preferred color, and you can do so, like this ...

var backgroundColor = 'white';
Chart.plugins.register({
    beforeDraw: function(c) {
        var ctx = c.chart.ctx;
        ctx.fillStyle = backgroundColor;
        ctx.fillRect(0, 0, c.chart.width, c.chart.height);
    }
});

DEMO

// draw background
var backgroundColor = 'white';
Chart.plugins.register({
    beforeDraw: function(c) {
        var ctx = c.chart.ctx;
        ctx.fillStyle = backgroundColor;
        ctx.fillRect(0, 0, c.chart.width, c.chart.height);
    }
});

// chart
var canvas = $('#NoBidsChart').get(0);
var myChart = new Chart(canvas, {
    type: 'line',
    data: {
        labels: [1, 2, 3, 4, 5],
        datasets: [{
            label: 'Line Chart',
            data: [1, 2, 3, 4, 5],
            backgroundColor: 'rgba(255, 0, 0, 0.2)',
            borderColor: 'rgba(255, 0, 0, 0.5)',
            pointBackgroundColor: 'black'
        }]
    }
});

// save as image
$('#save').click(function() {
    canvas.toBlob(function(blob) {
        saveAs(blob, "pretty image.png");
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<button id="save">Save</button>
<canvas id="NoBidsChart"></canvas>

Upvotes: 21

Related Questions