How-to save Google Charts visualizations to an image file in a user-friendly way

Personally I love Google Charts API. It offer so much potential for visualizing information. And all that, for free.

I use Google Charts professionally to visualize online marketing statistics on Marketingfacts, the largest online marketingblog in the Netherlands.

Despite all it’s great features, Google Charts also has some limitations. One of those is the ability to save charts to images, preferably in it’s current state. Kind of frustrating to see that Google does use it themselves on http://www.thinkwithgoogle.com/mobileplanet/en/, but it’s not featured in the API.

So, why don’t you use Google Image Charts?

Image Charts was a great way to accomplish this, but unfortunately Google deprecated this as of April 20, 2012. Although it should stay continue to work, I couldn’t get it to work with my Google Charts data anymore.

Turn an interactive chart into an image

After a few searches around the web, and browsing through several tickets in Google Code (12), I eventually stumbled onto this great article by Riccardo Govoni.

As Riccardo entails, the main trick to make ‘image serialization’ work is to first convert the SVG chart into a canvas element and extract its contents as base64 encoded image using canvas.toDataURL.

Summarizing Riccardo’s solution:

  • Extract the svg code for the chart you want to serialize
  • Using the canvg svg-to-canvas converter, you transform the svg instructions into a canvas rendering
  • Extract the image data (as a base64 encoded string) and send it to the browser so it can be downloaded

This all seems very technical but if you look at the sample page it all becomes clear.

Great!

The only problem is that the download which it generated doesn’t have a user-friendly name and extensions, which make them unusable for normal users. Fortunately I found this blogpost by Jonathan Greene in which he explains his solution to offer the download in a user-friendly way, rather than this:

I’ve converted Jonathan’s .js file to the following script:

function saveAsImg(chartContainer, pngfilename) {
var chartArea = chartContainer.getElementsByTagName(‘svg’)[0].parentNode;
var svg = chartArea.innerHTML;
var doc = chartContainer.ownerDocument;
var canvas = doc.createElement(‘canvas’);
canvas.setAttribute(‘width’, chartArea.offsetWidth);
canvas.setAttribute(‘height’, chartArea.offsetHeight);
canvas.setAttribute(
‘style’,
‘position: absolute; ‘ +
‘top: ‘ + (-chartArea.offsetHeight * 2) + ‘px;’ +
‘left: ‘ + (-chartArea.offsetWidth * 2) + ‘px;’);
doc.body.appendChild(canvas);
canvg(canvas, svg);
var data = canvas.toDataURL(“image/png”);
canvas.parentNode.removeChild(canvas);
data = data.substr(data.indexOf(‘,’) + 1).toString();

var dataInput = document.createElement(“input”) ;
dataInput.setAttribute(“name”, ‘imgdata’) ;
dataInput.setAttribute(“value”, data);

var nameInput = document.createElement(“input”) ;
nameInput.setAttribute(“name”, ‘name’) ;
nameInput.setAttribute(“value”, pngfilename + ‘.png’);

var myForm = document.createElement(“form”);
myForm.method = ‘post’;
myForm.action = ‘HERE PUT THE URL TO YOU SAVEME FILE’;
myForm.appendChild(dataInput);
myForm.appendChild(nameInput);

document.body.appendChild(myForm) ;
myForm.submit() ;
document.body.removeChild(myForm) ;

}

For the actual action you need to send the right container to the javascript. You can do this as follows:

<a href=”#” onClick=”saveAsImg(document.getElementById(‘THE CHART CONTAINER’), ‘NAME OF THE FILE WHICH IS OFFERED FOR DOWNLOAD’);”>

That should do the trick! Don’t forget to setup a saveme file as Jonathan explains in his blog.

You can view some live examples here:

http://www.marketingfacts.nl/statistieken/detail/online-consumentenbestedingen

http://www.marketingfacts.nl/statistieken/detail/populariteit-sociale-media

This entry was posted in Coding
  • Stefan Coetzee

    One other problem is also that the radar (aka spider) charts are not available in Google Charts (as far as I can see), but they were part of the Image Charts.

  • bvaldebenitom .

    Do you still run this blog? If so, do you have a current working example? The original solution is not working (I don’t want to adapt it to my webpage if it’s doesn’t seem to work). I would be really thankful if you can get back to me

  • I had the same frustration but after i read this article i found a new Google functionality to print the charts to PNG format: https://developers.google.com/chart/interactive/docs/printing

  • shhasan

    Hello Danny. Thank you for this amazing article. Unfortunately Jonathan’s converted script that you’ve posted isn’t working for me. The file being downloaded isn’t the image but the saveme.php file. I’ve also tested using CanvasSaver HitHub package and I get the same issue there as well. How do I solve this issue ? All help is greatly appreciated.

    • shhasan

      I was able to find an alternative. HTML download attribute. I’m using something like this: link.download = ‘filename.png’;