generate server-side google charts as images generate server-side google charts as images php php

generate server-side google charts as images


Use Watir to load the web page and save the images. Watir is a Ruby-based test platform aimed at testing web pages. I would do the following.

  1. Create a web page that renders the charts. It would not be forpublic use, only for generating the chart images.
  2. Add Javascript that calls getImageURI() for each chart to get thePNG data.
  3. Use Ajax to call a PHP script on the server. Pass in the PNG dataand save it to a file.
  4. Write a script in Watir that simply opens a browser and loads yourweb page.
  5. Schedule the Watir script to run as often as you desire.

The Watir script can run on any local computer (PC or Mac) or even on a server.

Here's Javascript to send the PNG data to a PHP script via Ajax. It is just the snippet that gets the image data and sends it, not a complete solution.

// Instantiate and draw our chart, passing in some options.var chart = new google.visualization.PieChart(chartDiv);// Wait for the chart to finish drawing before calling the getImageURI() method.google.visualization.events.addListener(chart, 'ready', function () {    pieDone=1;    piePNG=chart.getImageURI();    saveChartPNGs(piePNG); });chart.draw(data, options);function saveChartPNGs(png){  var jsonSavePNG = $.ajax({    type: "POST",    url: pngSaveUrl,    dataType:"json",    data: 'png=' + png  }).done();}

This PHP code processes the Ajax call and saves the file.

if (isset($_REQUEST['png'])){    // Remove header string    $data=str_replace('data:image/png;base64,','',$_REQUEST['png']);    // Restore data to original format; convert space to '+'    $data=str_replace(' ','+',$data);    // Save PNG file    $outFile=DOC_ROOT.'/atest.png';    // Decode base 64 before saving    $fres=file_put_contents($outFile, base64_decode($data));}

On your local computer, the Watir script (actually written in Ruby) is simple.

# Load watirrequire 'watir-webdriver'require "watir-webdriver/extensions/alerts"# Launch the browser; common choices: chrome, firefox, ie.# Headless browsers are available.browser = Watir::Browser.new :chrome # chrome browser window# Load the web pagebrowser.goto 'http://domain.net/page/'

To fully automate the Watir side I would write the chart rendering web page to load a new page when it has finished saving the files. You can have Watir check for that page in the browser and then exit until it executes again.

If you can arrange to install Ruby, Watir and a browser on your server, then you can automate this entire scenario with a cron job.


I've just released a relevant open-source project Google Charts Node that renders chart images in Puppeteer, a headless Chromium browser.

It can be used either as an NPM library or as a web service. Here's an example of using the NPM library:

const GoogleChartsNode = require('google-charts-node');function drawChart() {  // Set up your chart here, just like in the browser  // ...  const chart = new google.visualization.BarChart(container);  chart.draw(data, options);}// Render the chart to imageconst image = await GoogleChartsNode.render(drawChart);

Your question was tagged PHP, so I will note that it's also available as a hosted web service that can be used in any language. You can read more here.

For example:

// Generate the image$url = 'https://quickchart.io/google-charts/render';$data = array(  'width' => 600,  'height' => 300,  'packages' => array('gannt'),  'code' => 'function drawChart() {...}');$postdata = json_encode($data);$ch = curl_init($url);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));$result = curl_exec($ch);curl_close($ch);// Write it to file$fp = fopen('/tmp/image.png','x');fwrite($fp, $raw);fclose($fp);

Now you can save this image buffer as a file or return it as an HTTP response, etc.

The main caveats are:

  1. Not all charts support getImageURI, so the library makes puppeteer take a screenshot when this happens.
  2. It's slow! But if you must use Google Charts as a requirement, you don't really have an alternative. If you're able to switch chart libraries, I recommend an open format like Chart.js via QuickChart.

You can view the full source for generating server-side Google Charts at the Github project.