I’ve been using Highcharts for a year now - in my day job. We have all sorts of compliance to worry about - what we show on screen also needs to be reflected in the pdfs that get emailed/printed out.
I’ve been looking into ways of rendering the charts server-side. The preferred process (by Highcharts themselves) being using PhantomJS and the “Highcharts-convert.js” file - detailed here.
That’s great and it works, but for me - running a headless browser on a server just to render a chart seems a bit excessive. As detailed on their site (they’ve implemented in Java), the server would ideally be a pool of PhantomJS resources which aids concurrency. This method requires sending the Highcharts (JSON) configuration object to the server - in order to reconstruct the chart.
I’m a fan of keeping things light - why render the charts again (on the server) - if the client’s browser has already done it?……they aren’t going to change.
So, lets get to it…
Firstly, we’re going to need the exporting module which can be found on this page - this provides us with a function to get the SVG representation of the chart. You can do this “manually” via jQuery or plain old JS - but I’m using the exporting module as it does some funky regex to ensure compatibility with various old browsers (I’m looking at you IE).
When you have the chart built that you wish to capture, call
chart.getSVGForExport() which will return the SVG. You could use
chart.exportChart(options) and pass in options pointing to a url you own - Highcharts will send your SVG off as form-data - but I’m not going to use this, I want more control.
We’ll use the simple bit of script below to post the SVG to our server (to be saved and rendered at a later date).
Now on to the server…
I’m not going to detail the saving/loading of the SVG string you uploaded earlier. How you may use this differ greatly and at what time you wish to actually do the rendering (now or later).
But… here is a simple console application that shows you the basic principle - it’s really easy.
After setting up your preferred solution/project/service. Go to nuget and install this package Svg
The following code, receives the SVG as a string (could even be a Stream), passes it to SVG, to render it, returns it as a bitmap. Then saves it to disk (again, could be a Stream).
A small downside to this approach
The benefit the PhantomJS approach has over this way is it more easily allows you to modify the JSON (using Json.Net for example). You could change things in to the Highcharts options to alter the chart. Another benefit is that you can change the data and then send it to PhantomJS to render a new chart - without ever having to show the client.
The SVG way
Obviously editing the chart using SVG would be reckless and you’d have to be very confident in your abilities. However, for situations where you may be generating a report for a client who has just seen the screen (and you don’t need to change the chart in anyway) - why would you want to render the chart server side? when the client has already done the work.
Oh and another thing, when tested locally (150 times each way) PhantomJS averaged at 100ms per chart, whereas the SVG took around 60ms per chart.
This is expected due to the extra work PhantomJS has to do - as it is actually rendering the chart.
Shout me on twitter if you’re doing it another way not mentioned above - I’d love to see more ways of tackling this problem :)comments powered by Disqus