Export Chart Images on the Server Without Rendering in a Browser

IndexYou may have often wanted to export charts as images from the backend and email them to users, especially to senior management, who love getting insightful charts & dashboards delivered straight to their inbox. Or maybe you’ve wanted to automate these reports for convenience. While we have your back covered with our server-side Export Handlers for various technologies, we realize that these still require client-side rendering using a browser, which can sometimes be a hassle. Also, recently we’ve been getting requests for a way to export charts without having to render them at client-side. This got us thinking about how to do this in a way that is simple, and yet, works across all server-side scripting languages.

We remembered blogging about something similar last year – the free PHP plugin, FCImg – which allows you to generate images of charts on the server, without rendering the chart in a browser. Picking up from here, we figured the best way to get this to work on any server-side platform would be to use command line execution. Below, we give you two options with step-by-step instructions for each.

A. Using wkhtmltoimage

wkhtmltoimage is a simple shell utility to convert HTML to images.

I. Setup wkhtmltoimage:

1. Download and install the wkhtmltoimage library for Mac, Windows, or linux (1368, amd64).

Note: Be careful not confuse wkhtmltoimage with wkhtmltopdf, which generates PDF files instead. The Windows installation comes with both.

2. It is better to add the path of the executable file to the PATH so that you do not need to type the whole path when calling it. The Windows installer asks whether to set the PATH. Do select that option while installing.

II. Export Charts as Images from Server-side:

1. Create a dynamic or static web page, and generate a chart in it using our JavaScript chart library. To take a snapshot of only the chart, we recommend loading nothing but the chart in the web page, as shown in this example.

2. Set the page’s default margin and padding to 0 using CSS.

3. Now, use command-line or server-side shell execution command to :

  • Call wkhtmltoimage
  • Pass the URL of your webpage to it
  • Pass the path and name of the image file (with extension) where the image will be saved
  • Pass additional options to set a small delay to allow the JavaScript and chart inside your page to fully load before rendering. Normally 500 ms should do, but it can be extended upto 15000 ms based on how the wkhtmltoimage engine performs in your system.

III. Sample Script Using PHP:

Here is an example of how to execute the script in command line for PHP, although you can do the same for ROR, ASP.NET, Java, ColdFusion, and pretty much any server-side scripting platform.

IV. Cropping & Other Advanced Options:
If you need to crop a part of the image that is saved through this process, it can be easily done by setting the –crop-w or –crop-h options in this wkhtmltoimage manual.

B. Using PhantomJS

The popular PhantomJS JavaScript library allows for more programming flexibility than wkhtmltoimage, but, you may find the previous one easier to implement. Here’s how to set this up:

I. Download PhantomJS:

Binary source of PhantomJS

II. Sample Script in PhantomJS:

Let’s name it as render.js

III. To Execute:

In shell, from the path where the PhantomJS executable is present:

phantomjs render.js

We hope this will ease your workflow by a bit, and allow you to share more delightful charts with your end users.

Are there any other scenarios where you face difficulty exporting charts?

  • Andrea April 22, 2013, 10:08 pm

    I to the url that generates the graph I need to pass a lot of parameters, it’s possible pass them on post and not to get? how?
    Thanks

  • Rahul April 23, 2013, 12:53 pm

    Hi Andra,
    In wkhtmltoimage: 
    You can use:
    wkhtmltoimage.exe –post name value http://www.xyz.com xyz.jpg
    –post <name> <value>           Add an additional post field (repeatable)
    In PhantomJS:
    A sample can be found at https://github.com/ariya/phantomjs/blob/master/examples/post.js
     

  • Andrea April 23, 2013, 1:04 pm

    Hi, Rahul, thanks for your reply, but this method works also if the value is a array?
    I would pass one array to labels and value for generate a dynamical chart!

  • Rahul April 23, 2013, 1:59 pm

    Hi Andrea, 
    Yes,
    wkhtmltoimage:
    wkhtmltoimage.exe –post values 1 –post values 2 –post values 3 http://xyz.com/Default.aspx test.jpg
    PhantomJS:
    var page = require(‘webpage’).create(),
        server = ‘http://xyz.com/Default.aspx’,
        data = ‘values=1&values=2&values=3‘;
     
    page.open(server, ‘post’, data, function (status) {
        if (status !== ‘success’) {
            console.log(‘Unable to post!’);
        } else {
            console.log(page.content);
        }
        phantom.exit();
    });
     
     

Leave a Comment