HOWTO: Create a chart using PhantomJS
- Introduction
- Get hold of PhantomJS
- The HTML file that creates the chart
- The JavaScript file that makes the request for the webpage
- Making the request
- Creating the chart automatically
Introduction
A common request is to be able to use charts in PDF files (or similar) or
to be able to download the chart as an image. Some browsers (such as Mozilla
Firefox) allow you to right-click a canvas
and save it as an image - but this is
a far cry from having it done automatically (eg from a scheduled task).
Get hold of PhantomJS
The PhantomJS project appears to be stalled and not actively developed so I've added the download archives to the RGraph website and there are links below to the files.
Downloadable pre-compiled binary packages
- Windows (phantomjs-2.1.1-windows.zip)
- Linux 32bit (phantomjs-2.1.1-linux-i686.tar.bz2)
- Linux 64bit (phantomjs-2.1.1-linux-x86_64.tar.bz2)
- Mac OS (phantomjs-2.1.1-macosx.zip)
FreeBSD
Binary packages are available via pkg
:
$ sudo pkg install phantomjs
Source code
You can get hold of the source code using the GitHub PhantomJS repository.
The HTML file that creates the chart
This is the webpage that you're fetching with PhantomJS. It's a regular web
page and just produces the chart - be it a canvas
chart or svg
chart.
PhantomJS will create both. Here's the html
code for the whole page:
SVG version:
<!DOCTYPE html> <html> <head> <!-- These paths should be relative to wherever you put this page on your website --> <script src="/libraries/RGraph.svg.common.core.js" ></script> <script src="/libraries/RGraph.svg.line.js" ></script> <!-- PhantomJS renders the page with a black/transparent background so set it to white and get rid of margins/padding --> <style> body { background-color: white; margin: 0 0 0 0; padding: 0 0 0 0; } </style> <!-- Don't want this page indexed by search engines --> <meta name="robots" content="noindex, nofollow" /> </head> <body> <!-- This is the div tag where the chart will appear --> <div id="cc" style="width: 950; height: 300px"></div> <!-- This is the script that generates the chart. Like any other page on your server, this could integrate with anything else on your server - for example, MySQL --> <script> new RGraph.SVG.Line({ id: 'cc', data: [8,4,6,3,5,8,9,8,4,6,3,5,2,4,8,6], options: { xaxisLabels: ['Barry','Charles','Olga','Lou','Fred','Hoolio','Gary','Mia','Rich','Kev','John','David','Paul','Fred','Lewis','John'], linewidth: 5, spline: true, backgroundGridVlines: false, backgroundGridBorder: false, yaxis: false } }).draw(); </script> </body> </html>
Canvas version:
<html> <head> <!-- These paths should be relative to wherever you put this page on your website --> <script src="/libraries/RGraph.common.core.js" ></script> <script src="/libraries/RGraph.line.js" ></script> <!-- PhantomJS renders the page with a black/transparent background so set it to white and get rid of margins/padding --> <style> body { background-color: white; background-color: white; margin: 0 0 0 0; padding: 0 0 0 0; } </style> <!-- Don't want this page indexed by search engines --> <meta name="robots" content="noindex" /> </head> <body> <!-- This is the canvas tag where the chart will appear --> <canvas id="cvs" width="850" height="300">[No canvas support]</canvas> <!-- This is the script that generates the chart. Like any other page on your server, this could integrate with anything else on your server - for example, MySQL --> <script> new RGraph.Line({ id: 'cvs', data: [8,4,6,3,5,8,9,8,4,6,3,5,2,4,8,6], options: { xaxisLabels: ['Barry','Charles','Olga','Lou','Fred','Hoolio','Gary','Mia','Rich','Kev','John','David','Paul','Fred','Lewis','John'], linewidth: 5, spline: true, backgroundGridVlines: false, backgroundGridBorder: false, yaxis: false, shadow: true } }).draw(); </script> </body> </html>
The JavaScript file that makes the request for the webpage
This is a little javascript
snippet (it can get larger!) that is run by
PhantomJS which creates the "headless" browser instance and then requests
the page that you tell it to (in this case it's the page shown just above).
PhantomJS renders the page and the chart that we've put on it (regardless of
whether it's a canvas
or svg
chart) and saves an image of it locally. The
configuration that's used here saves the top left corner of the page -
which in this case is just the chart.
SVG version:
// This creates an instance of a page. The require() function is provided by PhantomJS page = require('webpage').create(); // Open our test webpage (this is a real page that you can view in your browser) page.open('https://www.rgraph.net/phantomjs-test.html', function() { // This sets the area of the virtual browser to be saved. The chart is positioned // in the top right corner so that's the bit we want page.viewportSize = { width: 850, height: 300 }; // Render the page to this file page.render('rgraph-svg.png'); // Exit PhantomJS cleanly phantom.exit(0); });
Canvas version:
// This creates an instance of a page. The require() function is provided by PhantomJS page = require('webpage').create(); // Open our test webpage page.open('https://www.rgraph.net/phantomjs-test.html', function() { // This sets the area of the virtual browser to be saved. The chart is positioned // in the top right corner so that's the bit we want page.viewportSize = { width: 850, height: 300 }; // Render the page to this file page.render('rgraph-canvas.png'); // Exit PhantomJS cleanly phantom.exit(0); });
Making the request
Making the request is just a case of running the PhantomJS binary and
giving it the filename of the javascript
file that we created (which
is shown just above).
The javascript
file then makes a request for the page that shows the chart
(which is also shown above). The image of the page is saved locally using
the filename that's specified in the javascript
file.
The commands that were used to run PhantomJS from the Windows command line was this (I'll assume that the Mac/Linux versions are quite similar)):
c:\PhantomJS\> .\bin\phantomjs.exe .\rgraph-svg.js c:\PhantomJS\> .\bin\phantomjs.exe .\rgraph-canvas.js
Creating the chart automatically
By adding the script to Windows Task Scheduler (or on Mac/Linux you can use a scheduled task) you can make the generation of the chart automatic - so it happens at whatever interval that you specify.
This would make things much easier and essentially remove the need to initiate the command yourself. It could be a daily task or you could have it produce the chart every minute so that it's always up-to-date.