Along with the modularisation of code, D3 version 4 also brings new support for canvas drawing, thanks to the d3-path package introduced in version 4.
There are performance advantages to using canvas over svg for drawing complex charts (however canvas is not necessarily always better). You can read more about d3-path and svg vs canvasin this blog post.
In this blog post I will be showing off an example d3fc component, which can render on an svg and canvas elements. This is a first step to creating canvas compatible chart components which we may eventually incorporate into d3fc.
First, the candlestick component. We need 2 separate internal functions to handle either svg or canvas rendering. The series generator function then calls either the svg or canvas render function depending on what type of DOM element was passed to it in the selection.
First, the candlestick generator, which uses the d3fc-shape candlestick to generate the ‘path’ for both canvas or svg. The default is svg, but you can set the context to a canvas context for drawing on canvas, which you will see in action in a minute.
To render to canvas -
and the SVG render -
Then the series creation function simply sets up the zoom behaviour, splits the data into up and down arrays (to colour the up and down candlesticks differently), then draws the chart using the appropriate render function.
Then in our main code we need to just generate the x and y scales, initialise the series, then call the series with the data with our d3 selection. In a simple case the code would look something likes this -
Performance
As you can see above, to compare performance I added some zoom functionality to the series.
I created this small application to demonstrate both charts side by side, so you can try out and feel the performance difference for yourself.
Also you can check out the full code here.
They perform equally with a low number of candlesticks, but as you increase this number, the svg becomes very laggy and unresponsive on zoom, because it is having to mutate a huge DOM path element, whilst the canvas keeps its smoothness for much longer, performing well even up to 20,000 candlesticks on my PC.
Try it yourself
The future
At some point in the future, we may create some canvas series, or adapt the current series in a similar way to this component, to allow it to render to svg or canvas. But until then, if you want to start rendering your charts on canvas, the code in this post should give you an idea of how to implement your own canvas components.
d3-path is an abstraction over SVG path creation which uses the canvas element's Context2D interface. Previously creating path generation code involved a lot of concatenating SVG path commands like M0,0 or L2,2, and the somewhat more cryptic C70 20,120 20,120 10. Even with ES6 string interpolation such code can be incredibly hard to read (and write!).
This blog post introduces the WebGL components which we recently added to D3FC, this suite of components make it easy to render charts with very large numbers of datapoints using D3. Throughout this post I'll describe the creation of the following visualisation, which displays 1 million books from the Hathi Trust library
If you enjoyed this blog post, why not subscribe to our mailing list
to receive Scott Logic content, news and insights straight to your inbox?
Sign up here.