Photo by Luke Chesser on Unsplash

How to use D3js with WebComponents

Make powerful graphs with D3js and Stencil

Ruben Triviño
Towards Data Science
6 min readMay 19, 2020

--

D3 is a fantastic open source library for data visualization developed originally by Mike Bostock. The great variety of tools it offers allow to make rare graphs from scratch or using pre-built templates. The possibilities offered by D3 are unlimited, you only need to have a look at their gallery.

If you have already worked with D3 you will know that apart from getting astonishing graphs you also end up with a bunch of scripts for formatting data, iterating over SVG elements, services to communicate with the server, models, etc.. All of these, probably, in the very middle of a project poorly related with the graphs itself, a real mess!

Luckily, the world of Web Components it is more accessible than ever and it is the perfect tool for creating your own graphic hub well encapsulated and reusable. On Custom Elements Everywhere you may check if Web Components are compatible with your preferred development framework.

StencilJS

Stencil is a Web Components, or more specifically Custom Elements, a compiler that uses the main features of the most known web development frameworks.

This tool has been developed by the IonicFramework to make it easy to make compatible components with multiple web development frameworks, towards an agnostic framework idea.

Thus, using D3 in a project based on the Web Components (Custom Components) standards using StencilJS is an elegant and easy to accomplish solution if you want to have a single reusable graphing project.

First Step: Creating a Stencil Project

Firstly, install the latest version of StencilJS using npm for instance and initialize the base project:

npm install @stencil/core@latest --save-exact
npm init stencil

Choose component option with the arrow keys and set the project name. The CLI of Stencil will create a project folder where you would find src folder which contains the first component generated by default: my-component . The .tsx file of the component folder is the one containing the main logic of it.

Scaffolding of generated Component

Now check that everything is working properly by typing the start command from the root project folder on your console.

npm run start

A new browser window should open showing the HelloWorld! of Stencil, a bit dull to be honest.

Step 2: Import D3 and Create a Graph

Once you have launched the project, any update in the code will be rendered on the browser. Now, we only have to import D3 into the code of the component. First, we need to install it using npm :

npm install d3 --save

Usually, when we work with D3 in a Javascript code we import all reference at once on a d3 alias like this: import * from ‘d3.js' . However, since the last version and using Typescript we will have to import different modules individually. This is a bit tedious but it would help us to make the app light-weighted. In this case, we are using a pie chart so we will import the following modules:

import { select } from 'd3-selection'
import { pie, arc } from 'd3-shape';import { scaleOrdinal } from 'd3-scale';
import { quantize } from 'd3-interpolate';
import { interpolateCool } from 'd3-scale-chromatic';
  • select operator allows getting reference of the html elements which we want to use or modify.
  • pie operator is responsible for generating the data structure and arc is the tool that allows us to generate the angles values and radio, needed to draw the chart.
  • scaleOrdinal, quantize andinterpolateCool operators help us to generate multiple colors depending on the value of each portion of the chart.

With this, we got all set and we only need to know where to place the D3 code. The basic structure of the component would be something like this:

Stencil API offers a bunch of decorators and methods that allow us to interact with the component and his lifecycle.

Prop()

This decorator allows getting inputs from the outer world of the component. In our case, those will be the graph data. These inputs are provided when using our component in html.

In fact, if we look a the project files, src/index.html contains the components generated (only one in this case) and we may see that the instantiation of the component is done like this:

<my-component data='myData'></my-component>

Where myData is the data structure provided to our component so it can iterate over it and draw the chart.

render()

This function is called just after the component is instantiated or modified and is responsible for generating the html tags that eventually will be rendered by the browser. Here we generate the html schema of our component and we will include the SVG element that we will use to generate all the pie chart elements.

componentDidLoad()

This method is called once the elements are fully loaded preventing us from getting null references of the html elements of the component.

Logic associated with D3, which is for regenerating data structures and graphical elements, must be set inside this method so we can guarantee that we may reference the final html.

Element()

This decorator allows us access to the main component and thus iterate over its children html elements. In particular, this is the reference that we would use to use select function of D3 and obtain the SVG where we will inflate our chart. Due to the encapsulation of Stencil we will have to access through shadowRoot :

select(this.element.shadowRoot.querySelectorAll(".chart")[0]);
Component Encapsulation for context isolation

Once we get the reference of the SVG element we may forget all about Stencil and start to think about D3 exclusively. So we add the script to generate the pie chart (or other) and this is it, we would get our webcomponent ready:

With the previous code we would get a chart like this:

Pie Chart

You may find a full code example in this GitHub link.

Finally: Export and reuse everywhere

Once we get our chart ready to publish we just have to build it and use it in any other project that we may have. Fortunately, this process is so simple as checking package.json file for setting project name, version number, license, description, etc.. and launch build command:

npm run build

This will generate the WebComponent ready to distribute in the www/build folder. To use it in any other project you will only have to publish it into your account of npm and enjoy all its features:

npm login
npm publish

Conclusion

Stencil allows creating a modular working environment, exportable and accessible for the main web development frameworks. This is a great opportunity to unify al graphical elements of multiple projects into one and standardize their use, code recycling, html, css, etc..

If you work in a development team that is in continuous contact with the UX/UI department Stencil is the perfect place to develop a sustainable Design System once for all and to make it easy for everyone.

--

--