5 simple rules to data visualization with Vue.js and D3.js
D3.js is a visualization library providing all necessary functions and methods needed to create charts and diagrams. Vue.js is a MVC framework for creating single page applications (SPA).
The real challenge comes where both D3 and Vue.js are able to manipulate DOM elements. In this guide, we focus on only using D3 for calculating all rendering parts required, but we let Vue.js create and modify the DOM.
This is also a walkthrough how I first implemented a graph component in Vue.JS using D3 library and how I improved it afterwards.
😖 The wrong way
This is actually the first implementation I did inspired by most examples found on the internet:
This can work quite well in the beginning, but:
- graph is not responsive
- data is static
- it renders the graph once
- styling is hardcoded
In this end, this component is actually not reusable.
🧙♂️ 5 simple rules
Rule 1:📜 Prefer viewBox against width & height
We want to make our SVG images responsive. Width and height limit our implementation to the dimensions defined. By setting viewBox instead, we are able to scale the SVG image to fill a container.
Rule 2: 📜 Write SVG template in template
Most D3js examples on the internet prefer to use append
function and attach DOM elements to already existing ones. Since we use Vue.js now it is better now to use only template
section instead.
Rule 3:📜 Write stylings in styling section
As SVG supports adding classes and styling elements in CSS and it is better to write styling in style
section than having hardcoded values on the Javascript code.
In this rule there is an exception, if you want to introduce a styling as property to the component.
Rule 4: 📜 Use props to provide data
Of course we want our component to be reusable and dynamically assign data into our graph! As most examples with Vue.js and SVG found on the internet, we set some properties to the component in order to make it dynamic.
Like this example:
Now that we set a parameter in props
area we can also do the following:
<SvgDemo title="John Snow"></SvgDemo>
And we are all set!
Rule 5: 📜 Use computed to provide D3 calculations
The biggest challenge here is to render the graphs everytime props
changes.
I first tried to use the append
and attr
methods from D3 library to render during mounted
. In order to render after each change I had to introduce watchers
, remove all elements and re-render again. This solution was already confusing enough for developers and does not work well together with Vue.js. In the end, tt is better to perform only the calculations in D3js and bind them with Vue.js instead.
All calculation can be bound directly to DOM using the computed
functions. This way the calculation will be invoked every time data information changes.
No worries. Vue.js is smart enough to invoke functions only when needed 😉.
😇 The right way
After applying all rules above the result to the previous example should look like this:
Check all these functions in computed
area! They can be directly used in template
now. The most important one is line
, which actually draws the chart thanks to D3.js. Every time we change data
, other functions will be reinvoked and a new value for line
will be returned. The chart will be rerendered with the new graph!
Now, in this example:
- graph is responsive (like every SVG must be!)
- a property data can be used to dynamically load data into graph
- graph will render any changes into the data automatically
- CSS classes can be used to override styling (not suggested but possible)