Most recently, I was tasked to convert a page containing multiple graphs to a single PDF without using server-side technologies. The graphs were rendered using Highcharts and the final PDF needed to have really good quality.
If you want to skip to the code, there’s a fiddle at the end of the post. Knock yourself out.
Default Export
By default, Highcharts has exporting functionality built in to the hamburger menu available on the top right of every graph. Of course, you need the exporting module to be included for that to show up.
While it works pretty well out of the box, the problem is that you can only download one graph at a time. What if you need to add multiple graphs (like a dashboard) to a PDF?
Setup
You’ll need the following libraries:
- Highcharts - Core
- Highcharts - Exporting Plugin
- Highcharts - Offline Exporting Plugin
- jsPDF
Note: If you want offline exporting and don’t want to send graph data to Highsoft’s servers (for privacy reasons), yo need to add the following option to the Highcharts graph options:
Adding graphs to PDF
The way this works is that we need to export the Highcharts graph as an image and then slap it on the PDF. After a lot of testing, I’ve come to a conclusion that exporting a chart as SVG on the PDF gives best results and quality.
In this example, we’ll be using two charts - one scatter and one pie chart. Let’s assume that their respective Highchart objects are chart1
and chart2
We will also need an instance of jsPDF:
If you look at the Highcharts API, it has a method called exportChartLocal
that allows you to export a chart in a specific format (JPEG, PNG, SVG and PDF). The problem is that calling the method triggers a download popup in the browser. We don’t really want that - instead we want the dataURL
(a base64 encoded string) of the image that we can put on the PDF using addImage
.
To stop the download popup and get the dataURL
, we need to hook into the downloadURL
method on the base Highcharts object that will give us the dataURL
and the filename
of the image.
Yet another problem here is that there is no callback to the exportChartLocal
method so we’ll have to use a counter and an array to store the dataURLs in an array.
To check if all the dataURLs are added to the array, we need to poll continuously. Once the array is prepared, we loop over it and add the image URLs to the PDF:
And it’s done! Here’s a demo of the entire process. Switch to the Result tab and click on the Export button to download the PDF. The code contains comments so it’s easy to follow.