Composing D3 Visualizations With Vue.js

By Tyrone Tudehope

Originally appeared on https://tyronetudehope.com.

D3 is a powerful data visualization library combining visualization components and DOM manipulation. On the other hand, Vue.js is a reactive front-end framework which allows you to declaritvely render data to the DOM and abstract out complex logic. Both frameworks try to do similar things, however, when combined it can become difficult to keep logic consistent. This post will attempt to address this conflict by demonstrating how we can use Vue to manipulate the DOM while embracing reactivity to update D3 components.

A demo can be found here, and the sample code here.

Before we begin, lets create a Vue component which renders a simple line chart using regular D3 DOM manipulation:

This will render the following:

The code is simple and easy to understand, but this is just a basic example. Because we aren’t making use of a template, more complex visualizations which would require a lot more manipulation and calculations, would obscure design and logic of a component. Another caveat of the above approach is that we cannot make use of the scoped property for our CSS since D3 is dynamically adding elements to the DOM.

We can recreate this example in a more vuu-esque fashion:

Quite cool, even though it doesn’t expose any properties and the data is hard-coded, it nicely separates the view from the logic and makes use of Vue hooks, methods and the data object.

We are making use of D3s components to generate the data we require to populate the document with, but we’re using Vue to manage the DOM and the state of the component.

Here is component which generates a stacked area chart, adds user interaction, responds to resize events on its parent container and reacts to changes to its dataset by animating the chart to its new state:

We have now built a reusable component which requires only an array of arbitrary numbers to be passed down to it.

This component registers a listener on the resize event which calculates the container dimensions; Updates are triggered by changes to width and data; And, a mouseover handler snaps the data “selector” to a value in the chart and emits an event back to the parent component.

An example rendering of pseudo-random numbers within a range defined by the user:

Live example

There are plenty of responsive HTML charting libraries available, and most of them can be quite easily wrapped inside Vue components. However, the extensibility of D3 and the amount of features it offers makes it a good fit for anybody wanting advanced data visualisation. Coupled with Vue.js, creating D3 components is not only easy, but also quite fun!