1

I'm drawing timeseries graphs with Chart.js which uses <canvas> to draw. Our users would like to be able to download the images of these graphs to put in their reports. The site background is dark, so the graphs themselves are using light grey colours. This means that when the users right click (in Chrome) and select "save image as..." they get a transparent image with grey / white lines (obviously not terribly visible).

I have been trying to override canvas.toDataURL in order to draw a rect first as in this post, but overriding doesn't work (I assume it's not writable). Is there another way of doing this?

GTF
  • 8,031
  • 5
  • 36
  • 59

1 Answers1

1

This should do the trick:

function getCanvasImage(_ctx, _bgColor){
    var tmpCtx = document.createElement("canvas").getContext("2d");
        tmpCtx.canvas.width  = _ctx.canvas.width;
        tmpCtx.canvas.height = _ctx.canvas.height;
        tmpCtx.fillStyle = _bgColor;
        tmpCtx.fillRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);
        tmpCtx.drawImage(_ctx.canvas, 0, 0);

    return tmpCtx.canvas;
  }

// ...
// just call the function passing your canvas context and the background color
var graphImage = getCanvasImage(ctx, "#222"); 
Sabaz
  • 4,794
  • 2
  • 18
  • 26
  • But this doesn't quite solve my problem which is that my users are right-clicking and selecting "save image as..." which is Chrome's built-in functionality. I am assuming that this calls `toDataURL()` (but I could be wrong). I want them to download an image with a background colour in it (instead of transparency), but have been unable to set the background colour - which is why I tried to override `toDataURL()`. – GTF Feb 11 '16 at 14:30
  • the graph background must be transparent? I mean can't you just draw the canvas with a background from the beginning? – Sabaz Feb 11 '16 at 14:35
  • I'm not drawing on the canvas directly (chart.js is) but I suppose I could draw a background before the chart is initialised? I don't want to draw over the chart, and Chart.js resizes the canvas element. – GTF Feb 11 '16 at 14:43
  • I tried drawing on the canvas before Chart.js is initialised, but the image I download is still transparent. – GTF Feb 11 '16 at 14:51
  • Try to edit the canvas after that Charts.js finished to draw the graph, still using the function above: `ctx.drawImage(getCanvasImage(ctx, "#222"), 0, 0); ` (I made an edited) – Sabaz Feb 11 '16 at 15:01
  • This definitely works for generating downloadable images, but I'm going to have to take a slightly different approach by just spewing the dataURI into a link which they can download with. – GTF Feb 11 '16 at 15:04
  • (performance of this data encoding isn't great with graphs so don't want to do it on every animation frame) – GTF Feb 11 '16 at 15:04
  • I removed the `toDataURL`, returning directly the new canvas element for the `drawImage` . (I don't remember it was that slow) – Sabaz Feb 11 '16 at 15:12