How to: Render Chart.js Charts Serverside

Wow! Its been quite a while since I’ve blogged. Since the last time I’ve posted I’ve left Microsoft. If you’re curious what I’m up to, checkout VMPower.

What is Chart.js

Chart.js is an amazing open source library to produce beautiful data visualization through charts. Its completely free and open source via the MIT license. Recently I was working on a feature in VMPower to email data visualizations usually only visible on our web app. The problem is the data is rendered on an HTML canvas and this is generally only available in the browser.

In comes JSDOM & Canvas for Node.js

So Chart.js uses the browser’s canvas API to draw its graphics. What if you could ‘fake’ the browser’s DOM and the canvas API?

Using JSDOM to simulate the browser DOM (adding things like window and document to your node.js application) and node-canvas you can do precisely that! Using these modules you can trick Chart.js into thinking its running in a real browser and capture those beautiful charts as images.

Why is this amazing? At VMPower, now we can email our data visualization directly to customers — without having to visit our website directly. We also don’t need the full power of a headless browser such as phantomjs

Example

Let’s take the Chart.js example from Chartjs.org:

Chart.js Vanilla Example

There are a couple options that are important to include, that aren’t included on the Chart.js website example. These options are animation: false and responsive: false. It doesn’t make much sense that these features be enabled since we are producing static graphics — unlike the dynamic Chart.js experience in the browser.

Integrating with jsdom is relatively straight-forward. Enter the HTML which contains a canvas element and provide the link to the Chart.js library. In the callback you’ll get the window object and the window.document object you may be familiar with in the browser.

Its important to npm install canvas --save as it is a peer dependency of jsdom (since we are using the <canvas> browser tag). Even though the module isn’t directly used in the sample, jsdom will look for it.

On the machine you are running you’ll have to install Cairo which went smoothly for me under OSX. On the VMPower server-side, I include the Ubuntu packages in my docker image.

Finally to export the generated chart to a file so you can store it for later use, call the toBlob and jsdom.blobToBuffer functions:

Here is the link to the jsfiddle which displays the chart in the browser.

And here is the statically generated Chart.js chart:

Statically generated chart

And that’s it. Your chart is exported as a PNG and you can include it in transactional emails or even other things like Slack.

Chartjs Module

I’ve created an npm module, chartjs-node which implements the above making it that much easier. Checkout the post here.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>