6

So after hours of websearching, googling and overflowing i can't find the solution to my problem.

I got a linechart from Google charts. I want to convert it to PNG, save it on the server en insert it into a MySQL database.

Sounds simple, but i cant get it to work. The script from this website isnt working anymore (atleast not here) http://www.battlehorse.net/page/topics/charts/save_google_charts_as_image.html -> Not working.

Second option is the old option:

$imageData =     file_get_contents('http://chart.apis.google.com/chart... etc');

I cant use that because its not supported anymore and cant get some decent quality out of it.

Is there anybody here that can give a good tutorial or help for my problem?

EDIT:

I used the code from Battlehorse combined with the code from EriC.

So now i got this working to show the chart as an image in a DIV i want to save this image on the server and update the mysql to use it in the future to use it in PDF files.

Kenny
  • 144
  • 1
  • 2
  • 9
  • Why can't you get it to work? Is providing something like a JSFiddle possible (or the actual site)? – EricG Dec 11 '12 at 16:22
  • Well its a private backend, so i can't give the website. But the demo from Battlehorse the sample doesnt work. I still tried to use it but without success. – Kenny Dec 11 '12 at 16:28
  • what about http://www.nihilogic.dk/labs/canvas2image/ ? Something like `contentDocument` doesnt exist in the Charts thing :/ Odd that they use that. – EricG Dec 11 '12 at 16:33

4 Answers4

8

When you visit the site, paste this in the console (overwriting the malfunctioning function).

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

In JS it was searching for an iframe bla bla to get the svg.


To automatically save the image, you can just let the method being invoked programmatically.

document.body.addEventListener("load", function() {

        saveAsImg( document.getElementById("pie_div")); // or your ID

    }, false );


For saving images serverside, this post could be helpful save a PNG image server-side

Update
Posting images to PHP (index.js)

function saveToPHP( imgdata ) {

    var script = document.createElement("SCRIPT");

    script.setAttribute( 'type', 'text/javascript' );
    script.setAttribute( 'src', 'save.php?data=' + imgdata );

    document.head.appendChild( script );
}

function save() {

    var canvas = document.getElementById("canvas"), // Get your canvas
        imgdata = canvas.toDataURL();

    saveToPHP( imgdata );
}

function drawOnCanvas() {

    var canvas = document.getElementById("canvas"), // Get your canvas
        ctx = canvas.getContext("2d");

    ctx.strokeStyle = "#000000";
    ctx.fillStyle = "#FFFF00";
    ctx.beginPath();
    ctx.arc(100,99,50,0,Math.PI*2,true);
    ctx.closePath();
    ctx.stroke();
    ctx.fill();
}

drawOnCanvas(); // Test
save();

save.php

<?php
    // Get the request
    $data = $_GET['data'];

    // Save to your DB.
?>
Community
  • 1
  • 1
EricG
  • 3,788
  • 1
  • 23
  • 34
  • I'm gonna try this asap! Ill let you know, thanks for helping. – Kenny Dec 11 '12 at 17:10
  • Okay, so i got this working now, when i press the button everything works fine. Now i want that when the page is loaded the image is being put in the database. – Kenny Dec 12 '12 at 11:07
  • That is ofcourse a different question, and the title of your post wouldnt correspond to the content of this topic. If you update your post, I'll update my answer, too ;) So that this post could be helpful for others. – EricG Dec 12 '12 at 11:12
  • I updated my post, i think a lot of people are searching for this question and answer from you. – Kenny Dec 12 '12 at 11:23
  • Oh my original post says this: "I got a linechart from Google charts. I want to convert it to PNG, save it on the server en insert it into a MySQL database." So i got the first step now, now i need to save it, if i can save it thats all i need to know. – Kenny Dec 12 '12 at 11:34
  • Is the addition in the post not satisfactory..? – EricG Dec 12 '12 at 12:04
  • How do you mean? I told you im very happy with the progress, i got the image now, now i need to send it with jQuery to get it in PHP, right? – Kenny Dec 12 '12 at 12:14
  • Hmm I think that saving images to the server is a whole different subject. I'm not sure if you should put that in this very post as well. Have a look at this post http://stackoverflow.com/questions/11511511/how-to-save-a-png-image-server-side-from-a-base64-data-string – EricG Dec 12 '12 at 12:28
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/21003/discussion-between-ericg-and-kenny) – EricG Dec 12 '12 at 12:29
  • @EricG - Have you got an email address so that I could ask you about the saving function as I have hit a dead end. tweet me: mgpwr, if you don't mind that is. – MarkP Oct 23 '13 at 10:42
  • @MarkP my email is in Profile. Please put a proper title so that I know its not spam, refering to SO or sth. – EricG Oct 29 '13 at 16:25
  • Hey, @EricG, what does `chartContainer` refers to? My chart goes like this
    , should I point `chartContainer` to #graph or what?
    – LasagnaAndroid Jan 31 '14 at 19:21
  • Hi @AdriánSalgado, yes, `chartContainer` is a semantic name, you can add the DOM element `#graph` as an argument. Note that it is simply fixing the malfunctioning, it is your responsibility to rewrite it properly. – EricG Feb 03 '14 at 16:05
  • Yeah, got it working now. Was trying to select the #graph element with jQuery and didn't work, changed back to vanilla js and works perfectly. :) – LasagnaAndroid Feb 04 '14 at 18:30
  • The code was to use at the referred site, I'm not responsible for that site's contents and this post might be outdated (its been 3 years). To post images in php please use the "update" part of my post :) – EricG Aug 25 '15 at 10:27
3

You can use the grChartImg library. It's a cross browser solution and supports even old versions of IE (8 and earlier).It has many features such as download image,upload to the server, show the image in a dialog etc.

For more info look at http://www.chartstoimage.eu.

i hope help you.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
john
  • 41
  • 1
0

This is not really an answer but might be one in the future and it is nescesary if you just want the feature back. The following URL shows all the current issues and feature requests for the visualization API.

https://code.google.com/p/google-visualization-api-issues/issues/list?can=2&q=&sort=-stars+id&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary%20Stars

The more stars/votes this feature request gets, the higher the chance they will take a look at it.

MmynameStackflow
  • 1,251
  • 3
  • 19
  • 39
0

I have the same issue - Save Google charts as image on server. None of answers here works for me. Finally I get solution but with some bugs(working only in Chrome browser). As base I used script from here https://gist.github.com/mpetherb/7085315 I made some changes for my project. I use jquery for importing generated graph image to to my server. This is a graph that I want to convert to image and save google graph example id="ex0"

Script for converting to image and importing to server

<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 toImg(chartContainer, imgContainer) {
var doc = chartContainer.ownerDocument;
var img = doc.createElement('img');
var myimg=img.src = getImgData(chartContainer);
//Here I am using jquery for importing decoded image to hidden.php on my server 
$.ajax({
    method: "POST",
    url: "hidden.php",
    data: { name: myimg } });
while (imgContainer.firstChild) {
imgContainer.removeChild(imgContainer.firstChild);
}
imgContainer.appendChild(img);
}
</script>

<button onclick="toImg(document.getElementById('ex0'), document.getElementById('ex0'));" 
type="button" <Convert to image and upload on server></button>
// ex0 - div id of this type of google graph. If you using another type of google graph - you should change it
Don't forget include jquery to your code.

and php hidden script for receiving data from jquery method POST and saving it on server

hidden.php file

<?php
 if(isset($_POST['name']))
  {   
    $data = $_POST['name'];

    list($type, $data) = explode(';', $data);
 list(, $data)      = explode(',', $data);
 file_put_contents('graph_temp.png', base64_decode($data));

I will notice again - works only in Chrome browser. Firefox also create image file on server but without any content (looks like firefox not support base64 encoded data)

Yuriy Chih
  • 1
  • 1
  • 3