PDF Export
Contents
Introduction
KeyLines supports exporting charts to PDF format in vector quality.
Exporting to PDF with chart.export() offers great customisability from a simple PDF document to a tailor-made report. See more in our Export Chart and PDF Reports demos.
The chart.export() function also supports exporting charts to PNG, JPEG and SVG. See the Chart Export documentation and the Export Chart demo.
- We have tested PDF export for a number of common in-browser viewers (Chrome, Edge, Safari, Firefox), macOS Preview and Adobe Acrobat Reader. While we may not be able to resolve all 3rd party rendering issues, we will report any unresolved issues to the relevant providers.
- PDF export when integrating with Leaflet may exclude items from some custom Leaflet layers, including markers and shadows. Some options (fitTo and extents) also behave differently.
Adding dependencies
To enable PDF export, KeyLines uses the following external dependencies and their versions:
- PDFKit v0.14.0 - required
- SVG-to-PDFKit v0.1.8 - only required when embedding SVGs into PDF
If you don't include the required dependencies into your application, an error will be generated in the console and the export will fail. If you don't include the SVG-to-PDFKit dependency before exporting PDF with SVG images, KeyLines will render any SVG images as PNG images and populate warnings in the result object.
There are multiple ways to add these dependencies in your app:
Using Webpack:
If you're using a module bundler such as
Webpack,
you can instruct the bundler to provide the dependencies as global variables.
For example, with Webpack you can add the
ProvidePlugin
to your list of plugins.
You might also need to prevent Webpack from parsing these dependencies with noParse
:
module.exports = function (webpackEnv) {
return {
plugins: [
new webpack.ProvidePlugin({
PDFDocument: 'path/to/pdfkit.standalone.js',
SVGtoPDF: 'path/to/svg-to-pdfkit/source.js',
}),
],
module: {
noParse: [path-to-your-plugins-directory]
}
};
};
Using manual import:
If you are unable to provide global variables, you can instead import the files and attach them to the window object manually:
import PDFDocument from 'path/to/pdfkit.standalone.js';
import SVGtoPDF from 'path/to/svg-to-pdfkit/source.js';
window.PDFDocument = PDFDocument;
window.SVGtoPDF = SVGtoPDF;
Using a script tag:
If you've used a script tag to include KeyLines in your application, you can do the same to load the dependencies as global variables:
<head>
<script type="text/javascript" src="path/to/pdfkit.standalone.js"></script>
<script type="text/javascript" src="path/to/svg-to-pdfkit/source.js"></script>
</head>
Running PDF export
Once you've added all the required dependencies, you can start generating charts as PDF:
chart.export({
type: 'pdf',
extents: 'chart',
fitTo: 'page',
heading: 'PDF Report',
doc: {
size: 'letter',
layout: 'landscape',
margins: { top: 72, right: 36, bottom: 72, left: 36 } // 1 inch and 0.5 inch margins
},
fonts: {
'Font Awesome 5 Free Regular': { src: 'path/to/fonts/fa-regular-400.woff' },
Muli: { src: 'path/to/fonts/Muli-ExtraLight.ttf' },
Raleway: { src: 'path/to/fonts/Raleway-Regular.ttf', weight: 'regular' },
},
}).then((exportResult) => {
// do more after export
});
The extents option is available to specify whether the exported content only contains the current on-screen view or the whole chart.
The fitTo option can be used to change the size and aspect ratio of the image:
- If only one of
width
orheight
is specified, the exported image is scaled to match this dimension while keeping its aspect ratio determined byextents
. - If both dimensions are specified, the image is resized to match the dimensions while fitting into available page space.
If either of the dimensions exceed the available space, the image is scaled down accordingly while keeping the aspect ratio
set by
width
andheight
. - If set to 'page', the aspect ratio and dimensions of the exported image are scaled to fit and fill the available page space.
- If not set, the size and aspect ratio are determined by
extents
.
The scaling of the image is limited by the available page space which can be reduced by items such as margins or other content.
Note that when integrating with Leaflet, extents
and fitTo
behave slightly differently:
- The
extents
option is ignored and KeyLines always generates the on-screen view of the chart. - The
fitTo
option is ignored and the output size always corresponds to the size of the on-screen view. - If the on-screen view is larger than the size of the generated PDF document, it is scaled down to fit the size of the generated PDF document.
Passing a custom PDFDocument
As well as accepting any options available for PDFDocument
from PDFKit,
the doc option can also be passed
a custom PDFDocument
created by
PDFKit:
const doc = new PDFDocument();
const data = [];
doc.on('data', data.push.bind(data));
doc.on('end', () => {
const pdfBlobUrl = URL.createObjectURL(new Blob(data, { type: 'application/pdf' }));
// Do something with blob URL of the completed PDF document
});
await chart.export({
type: 'pdf',
doc,
});
doc.end();
You can see an example of this in our PDF Reports demo.
SVG icons and images in PDF
To enable exporting SVG icons or images in charts in vector quality, you need to add SVG-to-PDFKit as a dependency into your application. If SVG-to-PDFKit is not added or if it fails to render an SVG, KeyLines will render the image as a PNG and populate warnings in the result object.
In addition, you might need to embed your own font files if your SVGs contain custom fonts or font icons.
Note: While SVG-to-PDFKit supports most common SVG features, there are some exceptions:
- Text ordering - RTL or bidirectional text are not supported.
- Clip paths - Clip paths are ignored.
For more details about supported SVG features see the official SVG-to-PDFKit documentation.
Text in PDF
By default, PDFKit supports 128 ASCII characters and offers a limited font support. If you are using any non-ASCII characters, custom fonts or font icons, you need to embed your own font files using the fonts option.
The fonts
option takes a dictionary of font files to embed in the output indexed by font name.
The entry for each font is an object or an array of objects
specifying the font file or files for that font.
The object specifying a font file has the following keys:
- src - The value of
src
specifies the URL or base64 encoding of .woff or .ttf font file. - weight - An optional parameter for PDF export to specify style variation within a single font family. As this option corresponds to the two possible values of the fb option in KeyLines, the only possible values are 'regular' or 'bold'.
chart.export({
type: 'pdf',
fonts: {
'Font Awesome 5 Free Regular': { src: 'path/to/fonts/fa-regular-400.woff' },
'Muli-ExtraLight': { src: 'path/to/fonts/Muli-ExtraLight.ttf' }, // a single object is enough to specify a font when the fb property is not used in KeyLines
Raleway: [
{ src: 'path/to/fonts/Raleway-Regular.ttf', weight: 'regular' },
{ src: 'path/to/fonts/Raleway-Bold.ttf', weight: 'bold' },
],
},
}).then((exportResult) => {
// do more after export
});
Missing font files will populate warnings in the result object. KeyLines will replace unavailable fonts with ‘sans-serif’ and embed unavailable font icons as PNG images.
You can set your own default font by passing the relevant font file under 'sans-serif'.
Right-to-left text in PDF
KeyLines supports right-to-left and bidirectional text and will render it correctly in the output PDF.
You should note, however, that PDFKit does not support right-to-left or bidirectional text. As text in SVG images and icons within the chart is drawn using PDFKit via SVG-to-PDFKit, right-to-left and bidirectional text within SVG images and icons will not render correctly in the KeyLines export.