NOV

2nd

Save Google Charts as images

A topics that pops up frequently in the Google Charts forums is about serializing the contents of an interactive chart - which is normally rendered as an svg object - as a plain old image. The current Google Charts API do not offer this feature (at the time of this writing) but a solution working on all modern browsers can be quickly written. This article demonstrates how.

You can try the code discussed above at this sample page, and access the example source code at this GitHub gist.

Note that this article discusses how to serialize charts to images in a completely client-side fashion. If you are willing to do server-side image generation, there are plenty of alternatives (such as getting screenshots of headless webkit processes).

Also note that there are domains in which Google Charts can be converted to images, for example when you are printing Google spreadsheets containing charts, exporting charts contained in Google spreadsheets (they offer a ‘Publish as image’ option) or generating charts using Google Apps Script Chart services. Depending on your case, you might not need the solution described here, but you may have to resort to it if you are using Google Charts directly via their public APIs.

The main trick to make image serialization work is to first convert the SVG chart into a canvas element, extract its contents as base64 encoded image using canvas.toDataURL, then use this payload as the src attribute for an img tag generated on the fly.

Caveats

There are various downsides that make this technique suboptimal (but hey, better than having nothing, right?):

  • It works only for SVG charts. You won’t be able to save an AnnotatedTimeline, or other flash-based charts, to image.
  • It requires the browser to support svg, canvas and data URLs. This cuts out Internet Explorer 8 and lower. For these cases, there are not that many alternatives, aside from installing Chrome frame or relying on ActiveX or Silverlight embeds to take screenshots of the relevant portion of the page (whose discussion is out of scope here).
  • Some browsers impose limitations on data urls sizes (for example, Opera 11) which may limit the size/complexity of the chart you can serialize
  • Serializing complex charts (for example, Geocharts) takes a noticeable amount of time (depending on the browser and speed of the machine you are using) and may freeze the browser for a few seconds. Most of the basic charts are serialized almost instantaneously though.

So this solution will work on Chrome, Safari, Firefox (tested on 3.6+), Internet Explorer 9+ and, partially, in Opera.

How it works

The serialization code works as follows. First, you extract the svg code for the chart you want to serialize (assuming chartContainer points to the html element containing the chart):

 var chartArea = chartContainer.getElementsByTagName('iframe')[0].
     contentDocument.getElementById('chartArea');
 var svg = chartArea.innerHTML;

Then you create a canvas element and position it offscreen for the user not to see it:

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

Using the canvg svg-to-canvas converter, you transform the svg instructions into a canvas rendering. You then extract the image data (as a base64 encoded string) and assign it to a local variable:

 canvg(canvas, svg);
var imgData = canvas.toDataURL("image/png");

You can then use the image data to populate an img tag elsewhere in the page, or redirect the user to download the generated image:

 // Populate img tag
var img = document.createElement('img');
img.src = imgData;
document.getElementById('imageContainer').appendChild(img);
// Download image
window.location = imgData.replace("image/png", "image/octet-stream");

Note how we force a different mime-type on the image data for the download case, to force the browser to trigger a download rather than displaying the image in the browser window.

Forcing the image download does not work in all browsers and it doesn’t behave that well: the downloaded image doesn’t have an assigned filename and every browser will use its own defaults in assigning it, often resulting in a confusing name for the user. For example, Chrome saves the image with the filename of download, with no extension, making it difficult for the user to understand that the file is indeed a PNG image.

It’s probably better to present the image in a separate window or page location, and ask the user to save it from there.

Example code

You can try the code discussed above at this sample page, and access the example source code at this GitHub gist.

Additional resources

Have fun.

Riccardo Govoni, last modified on Nov 2, 2011 - 17:03


56 Comments to this page

fred-mcclurg at uiowa dot edu over 2 years ago, Fred McClurg said:

Dear Riccardo:

I love your solution. Thanks for the well written article and examples. Is there any *easy* way to change the the filename from "file.part" to "file.png"?

duckwilliamson at mailinator dot com over 2 years ago, Duck said:

Thanks for the example, it was exactly what I needed!

To Fred: all I did was take the base64 png data, throw it into a hidden form, submit the form to my backend script (so I could post a massive string), then output that decoded png data with the "Content-Disposition: attachment;" header. No page reload necessary and you still get the "download" prompt with a clean labelled png file.

For PHP backend:
echo base64_decode(substr($_POST['data'], 22)); // data from canvas.toDataURL("image/png");
header('Content-Type: image/png');
header('Content-Disposition: attachment;filename="chart.png"');
header('Cache-Control: max-age=0');
exit;

bundapeter at yahoo dot com over 2 years ago, Bunda Péter said:

There is a bug:
If on the chart there are numbers on axis and the is a space separate tausands, it will throw an an error (and in firefox the converson stop). So the correct getImageData function is:
function getImgData(chartContainer) {
var chartArea = chartContainer.getElementsByTagName('iframe')[0].
contentDocument.getElementById('chartArea');
//************ADD this line:**************
var svg = chartArea.innerHTML.replace(/ /g," ");
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 imgData = canvas.toDataURL("image/png");
canvas.parentNode.removeChild(canvas);
return imgData;
}

sales at wearmeme dot com over 2 years ago, stevo said:

I just came here to say "battle horse, hoooooooooooo!"

muhd dot murtaza at live.com over 2 years ago, Muhammad said:

This doesn't work on Google Chrome!

ravikiran_bukka at yaho dot com about 2 years ago, Ravi said:

This does not work on IE too.

bren1818 at gmail dot com about 2 years ago, Brendon said:

This solution is perfect to tie in with the Google Charts. I really appreciate you taking the time to post this info and the tutorial. Thanks!

gymson dot viente at gmail.com about 2 years ago, gymson said:

This solution works perfectly on my project right now, since i'm doing a print functionality for google charts together with ABC PDF.

The issue here is that this doesn't work in IE8 but works in IE9, any possible workaround on this? The issue seems to be at HTML5's canvas.

I've tried reading about its counterpart for previous version which is excanvas, But haven't had any luck yet on how it is to be implemented.

Anyone?

duckwilliamson at gmail dot com about 2 years ago, Duck said:

gymson, this solution is built around the idea of svg -> canvas, so no it's impossible to work in IE8. In my application I just prompt users (when the canvas fails to create) to upgrade to IE9 or install a modern browser like Firefox or Chrome.

jon dot balut at gmail.com about 2 years ago, Jon said:

Hey hey!

I used the Github source code and prettty nice move. It works smoothly on Chrome, Firefox and Opera. However with our dear IE (even IE9) it's not possible to directly save the file.

Thx for your article, cheers.

VivekBatham86 at gmail dot com about 2 years ago, Vivek said:

Hi,

I tried it in Visualforce Page(Salesforce.com) and it is not working for Chrome, IE. It works in for Firefox. Any Idea on how do I solve it?

rub3n_lh at yahoo dot es almost 2 years ago, rub3n said:

Hi everyone... just thanks to Ricardo, is a pretty good solution...for me is working in Fx, Cr,IE9..

this is my solution back end for java, with struts2 action...
Just for to send it, first i take off the "data:image/png;base64" from the string, and handle it like a base64 string..

<code>
public String uploadImageBase64() throws IOException {


BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(imageBase64);
System.out.println("Decoded upload data : " + decodedBytes.length);

String uploadFile = "diagrama.jpg";
File file = new File(uploadFile);
if (file.exists()) {
file.delete();
}
System.out.println("outF.canWrite() = " + file.canWrite());
System.out.println("File save path : " + uploadFile);

FileOutputStream fOut = new FileOutputStream(getUserUploadDir()+"/"+file);
fOut.write(decodedBytes);
fOut.close();

jsonResponse.setSuccess(true);

return "json";
}


</code>


thanks for your tips :) ...

dggupta25 at gmail dot com almost 2 years ago, DG said:

HI Riccardo
This is a great solution....but i wanna ask you i have two chart on same page
so i am not abto download both the chart together on single click...but i can do that with individual buttons...

so can give me any solution for this...

thanks for your help..

davidnjohnson at gmail dot com almost 2 years ago, David said:

Thanks for this - it seems to work well with line charts, and it's much easier to tell users "Please use Google Chrome" than it is to teach them how to take screenshots.

I was even able to make MVC.NET echo back the image as a downloadable file. (Yes, it's very silly to have the client render the image, post it back to the server, and then serve it as a downloadable file, but it works.)

In case anyone else needs to do this, instead of adding an <img> element to the page, submit the imgData object and a filename to a controller. The controller itself is actually very simple:

public ActionResult RedownloadImage(string data, string filename)
{
return File(Convert.FromBase64String(data.Substring(data.IndexOf(",")+1)), "image/png", filename);
}

The drawback, of course, is the time spent uploading and then downloading the image. But it works, and it works far more simply than trying to get the same report to display with the same features in SSRS.

trevorf at waterrescueservicesc dot com almost 2 years ago, TJ said:

Google charts was updated today and it is now rendered without iframes. Any ideas on how to adapt the code?

ano at ano dot com almost 2 years ago, Thomas said:

Fix that google charts changes (no iFrame anymore)

var svg = $(chartContainer).find('svg').parent().html();
var doc = chartContainer.ownerDocument;
var canvas = doc.createElement('canvas');


canvas.setAttribute('style', 'position: absolute; ' + '');
doc.body.appendChild(canvas);
canvg(canvas, svg);
var imgData = canvas.toDataURL("image/png");
canvas.parentNode.removeChild(canvas);
return imgData;

igedmedia at gmail dot com almost 2 years ago, jerome said:

hello
I am French, sorry for my english
Congratulations and thank you for your contribution
http://www.battlehorse.net/attach/topics/charts/google_charts_to_image.html
I used it and it worked very well for converting graphic images.
But now it works more on my side but also on your link.
With firebug we found a problem:
erreur function getImgData :
TypeError: chartContainer.getElementsByTagName("iframe")[0] is undefined
var chartArea = chartContainer.getElementsByTagName('iframe')[0].
Do you have a hypothesis? I am looking for my side if you have an
idea, do not hesitate.
thank you,
cordially

webmaster at linux-live-cd dot org almost 2 years ago, nicolas said:

Thanks Thomas, works fine now!

igedmedia at gmail dot com almost 2 years ago, jerome said:

Thanks Thomas, works fine now!

jimenamunoz at gmail dot com almost 2 years ago, jimena said:

Change the code but did not work ...

appears "chartContainer.find" is undefined.

any ideas?

Thanks.

VivekBatham86 at gmail dot com almost 2 years ago, vivek said:

Hi ALL,
I am getting this exception.
$ is not defined
Can anyone let me know where I am going wrong?

Thanks.

syzer3 at gmail dot com almost 2 years ago, syzer said:

@vivek $ is alias for jQuery , Did you remember to include jQuery on your HTML ??

dirk at marqeting dot nl almost 2 years ago, Dirk said:

Hi there,

I got the following error:
Uncaught TypeError: Cannot read property 'contentDocument' of undefined
(line 7)

This is in all browsers. Anyone an idea about this?

Thanks
Dirk

jimenamunoz at gmail dot com almost 2 years ago, jimena said:

Thanks Syzer, works fine now!

VivekBatham86 at gmail dot com almost 2 years ago, vivek said:

Thanks Syzer,

I was referencing different jquery file. Now its working.

Thanks a Lot!

info at spicts dot nl almost 2 years ago, Sytse said:

Since the release of version 1.32 of Google Visualization API (24 sept 2012) they don't use the iframe anymore and the function getImgData(chartContainer) doesn't work anymore (https://gist.github.com/1333906).
To make the function work again I replaced the first 2 lines of the function with:
---
var chartArea = chartContainer.children[0];
var svg = chartArea.innerHTML.substring(chartArea.innerHTML.indexOf("<svg"), chartArea.innerHTML.indexOf("</svg>") + 6);
---
And it works again. :)

info at spicts dot nl almost 2 years ago, Sytse said:

Since the release of version 1.32 of Google Visualization API (24 sept 2012) they don't use the iframe anymore and the function getImgData(chartContainer) doesn't work anymore (https://gist.github.com/1333906).
To make the function work again I replaced the first 2 lines of the function with:
---
var chartArea = chartContainer.children[0];
var svg = chartArea.innerHTML.substring(chartArea.innerHTML.indexOf("<svg"), chartArea.innerHTML.indexOf("</svg>") + 6);
---
And it works again. :)

VivekBatham86 at gmail dot com almost 2 years ago, Vivek said:

A quick Question :

When I am using Firefox to save the Image. It's giving me the file with extension as .part. Is there any way to save it as .png or any other?

Thanks!

Vivek

thein dot than at ondicomdigital.com almost 2 years ago, Jonas said:

Hi Riccado,

This script just stopped working today. I think Google changed their code to generate the chart?

Javascript is showing error at the following line.

var chartArea = chartContainer.getElementsByTagName('iframe')[0].contentDocument.getElementById('chartArea');

thein dot than at ondicomdigital.com almost 2 years ago, Jonas said:

Hey Riccado,

Sytse's solution fixed this issue. You both are awesome.

ck at cypresscreative dot com almost 2 years ago, Christian K said:

Sytse, thanks so much! Saved my behind with your solution.

bhuman dot soni at gmail.com almost 2 years ago, cptdanko said:

good on you mate, great solution both the original and the one for dealing with a lack of IE.

er dot tomthomas at gmail.com almost 2 years ago, Tom said:

Demo is not working.
TypeError: chartContainer.getElementsByTagName("iframe")[0] is undefined

what is the solution for this error???

aaa at bvb dot com almost 2 years ago, miki said:

Since the last API update this is not working anymore as it does not use iFrames.

feverish30 at hotmail dot com almost 2 years ago, Michael Fever said:

What do you guys think of saving the image into a MySQL database. I've seen this done before in the past, people saving images into databases. This would allow for quick and easy recall if you are planning to include the images into a PDF through a PDF library like TCPDF.

kevin at tucj dot com over 1 year ago, Kevin said:

Great bit of code!

To fix for the new charts implementation, just do this:

var chartArea = chartContainer.getElementsByTagName('div')[1];

on line 7

aaaa at aaaa dot com over 1 year ago, aaaa said:

var chartArea = chartContainer.getElementsByTagName('div')[1];

fix line 7 but not work IE 8, IE 9

AAAAAAAAAAAAAAAAAAA......

name at domain dot com over 1 year ago, Tim said:

Very interesting!

I´m currently searching for a way users can possibly share google charts from my wordpress site.

Another approach *COULD* be to let users make a snapshot and then move ahead with that image.. don`t know whats easier to accomplish.

In case of wordpress.. i guess one could find a snapshot plugin (or modify one) for having the chart area preselected (means can only make pic of that area.. not whole webpage)and maybe integrate a share button or whatever the intention is.

daveh at sscal dot com over 1 year ago, dave said:

Fantastic tool. Though I got it working in Chrome and Firefox, IE 9 just isn't cooperating. Any ideas on why IE 9 isn't supported?

spider_dev at yahoo dot com over 1 year ago, John said:

Hi to all!

Recently i discovered an alternative solution for save google charts as image ,due to a project that i developed for my job.

I tested without problem a javascript library that it's free of charge and help me a lot to save the google charts as image.It's supports all the browsers except IE <9, but also there is an another version that supports all the browsers including IE<9.
If you interested in look at http://www.chartstoimage.eu.

vishalkacha at gmail dot com over 1 year ago, Jeny said:

Hi
i implement this code but i got the JavaScript error like
Type error s is null on js file line no

if (typeof(s.documentElement) != 'undefined') {
any one help me to fix this error.

thanks

spider_dev at yahoo dot com over 1 year ago, John said:

Hi Jeny,

If you prefer you can use the free grChartImg javascript library that it's an easy and an reliable way to do a lot of things supported by all browsers.
Just check the documentation at www.chartstoimage.eu

distantstate at gmail dot com over 1 year ago, nverba said:

I used

var chartArea = chartContainer.getElementsByTagName('svg')[0].parentNode;

to fix the no-iframes issue. But, I have issues rendering line and area graphs, the vAxis covers the left hand side of the rendered data. Can't really use this in a product till I can figure out how to avoid this.

jake at hipiti dot com over 1 year ago, Jake said:

nverba, I'm running into the exact same issue. My charts render just fine in the browser, but when I convert them to .png's (I'm using the same trick you are to handle lack of iframes) the y- and x-axis labels are shifted horizontally. So the y-axis labels are on the graph itself and the x-axis labels are off-center. I haven't found a fix yet, and in all my searching you're the only person I've seen having the same issue.

distantstate at gmail dot com over 1 year ago, nverba said:

It seems there was a bug after some refactoring of the text. This has been reported in the issues tracker https://code.google.com/p/canvg/issues/detail?id=202&q=text-anchor

For now it seems the advice is to use the older revision https://code.google.com/p/canvg/source/detail?r=152

I'm happy to say it's all working fine for me now. :)

roka at bundiland dot hu over 1 year ago, rokakoma said:

MANY MANY thanks nverba! I had a working solution on saving these charts and it just got messed up, the same as you wrote, from one day to another. I was checking for the error for hours now, luckily I found your comment. Many thanks, working perfectly with including:

https://canvg.googlecode.com/svn-history/r152/trunk/canvg.js

name at domain dot com over 1 year ago, pt said:

You can find a complete working example for this tutorial, updated to include the fixes from the comments above in this answer on StackOverflow: http://stackoverflow.com/a/16137983/571733

1) Set the chartArea variable to work with Google Visualization API version 1.32 (Sept 24, 2012) and later
2) Use canvg.js r157 as a workaround for a regression identified by @nverba

daveh at sscal dot com over 1 year ago, Dave H said:

This is a fantastic tool utility. It works in Firefox and Chrome, but not IE (any versions). Here's the error:

SCRIPT438: Object doesn't support property or method 'getContext'

daveh at sscal dot com over 1 year ago, Dave H said:

This is a fantastic tool utility. It works in Firefox and Chrome, but not IE (any versions). Here's the error:

SCRIPT438: Object doesn't support property or method 'getContext'

mreddy at myzealit dot com over 1 year ago, MReddy said:

Thanks for The great example. Basically I am a salesforce developer.
Coming to my requirement I have a page with two Google visualization API column charts and one table i want to save it as image all in one click instead of giving separate buttons for each chart is it possible to this . If possible can you please help me.

a at b dot com about 1 year ago, Joval said:

Does not work with Chrome ...

zerufiga at gmail dot com about 1 year ago, ZeruFiga said:

it's work, first you need to import these scripts

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://www.phpied.com/files/rgbcolor/rgbcolor.js"></script>
<script type="text/javascript" src="https://canvg.googlecode.com/svn-history/r152/trunk/canvg.js"></script>

and code...

var chartArea = chartContainer.children[0];
var svg = chartArea.innerHTML.substring(chartArea.innerHTML.indexOf("<svg"), chartArea.innerHTML.indexOf("</svg>") + 6);
//svg = svg.replace(/&nbsp;/g," ");
var canvas = document.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;');
document.body.appendChild(canvas);
canvg(canvas, svg);
var imgData = canvas.toDataURL("image/png");
// Populate img tag
var img = document.createElement('img');
img.src = imgData;
document.body.appendChild(img);

vigneshreddi at gmail dot com 12 months ago, vignesh said:

Here is perfectly working code: (works in IE,Firefox,chrome &safari)

with few edits ;) and google serach ;)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
<script>
function getImgData(chartContainer) {
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 imgData = canvas.toDataURL("image/png");
canvas.parentNode.removeChild(canvas);
return imgData;
}

function saveAsImg(chartContainer) {
var imgData = getImgData(chartContainer);
window.location.href = imgData.replace("image/png", "image/octet-stream");
}

function toImg(chartContainer, imgContainer) {
var doc = chartContainer.ownerDocument;
var img = doc.createElement('img');
img.src = getImgData(chartContainer);
while (imgContainer.firstChild) {
imgContainer.removeChild(imgContainer.firstChild);
}
imgContainer.appendChild(img);
}
</script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart", "treemap", "geochart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
// Pie chart
var data = new google.visualization.DataTable();
data.addColumn('string', 'Task');
data.addColumn('number', 'Hours per Day');
data.addRows(5);
data.setValue(0, 0, 'Work');
data.setValue(0, 1, 11);
data.setValue(1, 0, 'Eat');
data.setValue(1, 1, 2);
data.setValue(2, 0, 'Commute');
data.setValue(2, 1, 2);
data.setValue(3, 0, 'Watch TV');
data.setValue(3, 1, 2);
data.setValue(4, 0, 'Sleep');
data.setValue(4, 1, 7);

var chart = new google.visualization.PieChart(document.getElementById('pie_div'));
chart.draw(data, {width: 450, height: 300, title: 'My Daily Activities'});
// Line chart
data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Sales');
data.addColumn('number', 'Expenses');
data.addRows(4);
data.setValue(0, 0, '2004');
data.setValue(0, 1, 1000);
data.setValue(0, 2, 400);
data.setValue(1, 0, '2005');
data.setValue(1, 1, 1170);
data.setValue(1, 2, 460);
data.setValue(2, 0, '2006');
data.setValue(2, 1, 860);
data.setValue(2, 2, 580);
data.setValue(3, 0, '2007');
data.setValue(3, 1, 1030);
data.setValue(3, 2, 540);

var chart = new google.visualization.LineChart(document.getElementById('line_div'));
chart.draw(data, {width: 450, height: 300, title: 'Company Performance'});
// Treemap
data = new google.visualization.DataTable();
data.addColumn('string', 'Region');
data.addColumn('string', 'Parent');
data.addColumn('number', 'Market trade volume (size)');
data.addColumn('number', 'Market increase/decrease (color)');
data.addRows([
["Global",null,0,0],
["America","Global",0,0],
["Europe","Global",0,0],
["Asia","Global",0,0],
["Australia","Global",0,0],
["Africa","Global",0,0],
["Brazil","America",11,10],
["USA","America",52,31],
["Mexico","America",24,12],
["Canada","America",16,-23],
["France","Europe",42,-11],
["Germany","Europe",31,-2],
["Sweden","Europe",22,-13],
["Italy","Europe",17,4],
["UK","Europe",21,-5],
["China","Asia",36,4],
["Japan","Asia",20,-12],
["India","Asia",40,63],
["Laos","Asia",4,34],
["Mongolia","Asia",1,-5],
["Israel","Asia",12,24],
["Iran","Asia",18,13],
["Pakistan","Asia",11,-52],
["Egypt","Africa",21,0],
["S. Africa","Africa",30,43],
["Sudan","Africa",12,2],
["Congo","Africa",10,12],
["Zair","Africa",8,10]
]);

var tree = new google.visualization.TreeMap(document.getElementById('treemap_div'));
tree.draw(data, {
minColor: '#f00',
midColor: '#ddd',
maxColor: '#0d0',
headerHeight: 15,
fontColor: 'black',
showScale: true});
data = new google.visualization.DataTable();
data.addRows(6);
data.addColumn('string', 'Country');
data.addColumn('number', 'Popularity');
data.setValue(0, 0, 'Germany');
data.setValue(0, 1, 200);
data.setValue(1, 0, 'United States');
data.setValue(1, 1, 300);
data.setValue(2, 0, 'Brazil');
data.setValue(2, 1, 400);
data.setValue(3, 0, 'Canada');
data.setValue(3, 1, 500);
data.setValue(4, 0, 'France');
data.setValue(4, 1, 600);
data.setValue(5, 0, 'RU');
data.setValue(5, 1, 700);

var options = {};
var container = document.getElementById('map_div');
var geochart = new google.visualization.GeoChart(container);
geochart.draw(data, options);
data = new google.visualization.DataTable();
data.addColumn('number', 'Age');
data.addColumn('number', 'Weight');
data.addRows(6);
data.setValue(0, 0, 8);
data.setValue(0, 1, 12);
data.setValue(1, 0, 4);
data.setValue(1, 1, 5.5);
data.setValue(2, 0, 11);
data.setValue(2, 1, 14);
data.setValue(3, 0, 4);
data.setValue(3, 1, 4.5);
data.setValue(4, 0, 3);
data.setValue(4, 1, 3.5);
data.setValue(5, 0, 6.5);
data.setValue(5, 1, 7);

var chart = new google.visualization.ScatterChart(document.getElementById('scatter_div'));
chart.draw(data, {width: 400, height: 240,
title: 'Age vs. Weight comparison',
hAxis: {title: 'Age', minValue: 0, maxValue: 15},
vAxis: {title: 'Weight', minValue: 0, maxValue: 15},
legend: 'none'
});
}
</script>
</head>
<body>
<div id="img_div" style="position: fixed; top: 0; right: 0; z-index: 10; border: 1px solid #b9b9b9">
Image will be placed here
</div>

<button onclick="saveAsImg(document.getElementById('pie_div'));">Save as PNG Image</button>
<button onclick="toImg(document.getElementById('pie_div'), document.getElementById('img_div'));">Convert to image</button>
<div id="pie_div"></div>

<button onclick="saveAsImg(document.getElementById('line_div'));">Save as PNG Image</button>
<button onclick="toImg(document.getElementById('line_div'), document.getElementById('img_div'));">Convert to image</button>
<div id="line_div"></div>
<button onclick="saveAsImg(document.getElementById('treemap_div'));">Save as PNG Image</button>
<button onclick="toImg(document.getElementById('treemap_div'), document.getElementById('img_div'));">Convert to image</button>
<div id="treemap_div" style="width: 450px; height: 300px;"></div>

<button onclick="saveAsImg(document.getElementById('map_div'));">Save as PNG Image</button>
<button onclick="toImg(document.getElementById('map_div'), document.getElementById('img_div'));">Convert to image</button>
<div id="map_div" style="width: 500px; height: 300px"></div>
<button onclick="saveAsImg(document.getElementById('scatter_div'));">Save as PNG Image</button>
<button onclick="toImg(document.getElementById('scatter_div'), document.getElementById('img_div'));">Convert to image</button>
<div id="scatter_div"></div>
</body>
</html>

sathishmca1988 at gmail dot com 10 months ago, sathish said:


Thanks for your article, It helped me a lot.

As per this I am converting google charts to SVG images. Here getting SVG image path using canvas.toDataURL(), By using this path I can show image in html but not in PD4ML pdf as it is throwing an error
'ERROR STDERR - Bad Base64 input character at 6644: 59(decimal)'.

Sathish

deepak at webinfomart dot com 9 months ago, Deepak Manwal said:

Your sample page having javascript error in console then how wan i use your code???????????

FARIDATUL_AKMAL at YMAIL dot COM 5 months ago, arie said:

how to change the name file, because when i click save the file will become some random alphabet . part ... this will become unreadable file..

Tags

This page is tagged as: google charts