Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

A guest post by Roland Dunn, a partner at Refined Practice, currently working on D3-based visualization tools, among other things. You can find him on Twitter at @roland_dunn, and at

One of the key things that came from me writing this post, is that by writing the code as if it were reusable, I ended up writing pretty modular code. I find my code is cleaner, my thinking is more clear, my code responsibilities (e.g managing data, rendering SVG elements) are more distinct, and the resulting code has moved towards a model-view-controller/thing type structure. Follow along in this post as I walk you through the creation of a D3.js application, using a reusable and modular approach.

A few months ago, I came across Mike Bostock’s Point-Along-Path Interpolation example (figure below), which I was quite intrigued by. It uses a path element to describe the route a circle should follow, and uses a transition.attrTween to actually move the circle along that route. The attrTween code calls the path element’s getPointAtLength function to find out what the position of the circle should be at any particular point in time, before actually rendering the circle. For more on using the path element in D3, read The Created Brush in Developing a D3.js Edge.

I thought that writing about how to re-work the Point-Along-Path Interpolation example using a reusable D3.js approach might make an interesting blog post, or at least a good way to illustrate what I learned about modular & reusable D3.js. Back in July we published this content in two parts, but we have received requests to have it in one piece to read, so we are republishing it as one post.


I ended up writing the Using AttrTween, Transitions and MV* in Reusable D3 Demo Gist example (figure above), which demonstrates a number of different aspects of using D3.js, not just code reusability:

  • Waiting for enter, update and exit functions (that use transitions) to complete, and using d3.dispatch and events to move the code onto its next state (once the transitions are complete)
  • Waiting for a number of other transitions to finish, transitions that use attrTween. Code again uses d3.dispatch to move onto next code state
  • Customizing a transition’s easing function
  • How to incorporate all of the above in “reusable” or modular D3

The code referenced in this article is up on Github as a Gist, and viewable at To learn more about Github’s version control system – Git – read the McCullough and Berglund on Mastering Git video.

So now, for me, if I’m writing something other than a really really simple D3 example, I find myself wanting to take this modular approach, particularly an MV* approach – even if the code has no hope of producing something reusable – as the resulting code is cleaner and easier to understand.

Reusable D3 Approach & Terminology

I’m not going into great detail explaining the approach used to writing reusable D3 code. I’ll leave that to other sources, such as:

Before we continue, I do need to include a tiny bit of terminology. We will call a component a reusable piece of code generating graphics, which doesn’t represent a complete chart, but a part meant to be composed with other elements.
And, a module is a reusable piece of code that doesn’t generate graphics, such as a module managing JSON, or controlling a JavaScript timer.

What Does the Demo Actually Do?


The code creates two-to-three “patterns”, where each “pattern” consists of a path that is either a circle, a spiral or a sine wave, and where a circle (accompanied by some text) navigates round the patterns path (whatever the path is). Once all the circles currently on display have completed their trips (each takes different lengths of time to complete), the code randomly decides a number of things regarding the next set of patterns to render:

  • Whether to show two or three patterns, and if only two, which two
  • The colors of the paths, the circles, and the text
  • Which transition ease setting to use for each pattern
  • The duration of each transition – each pattern has its own duration
  • What the path of each pattern will be: sine, circle or spiral
  • Which direction the circle should travel around the path

SVG Elements Making Up a Pattern


Each of the visual ‘patterns’ is structured (in terms of SVG elements) as in the above screengrab. A ‘g’ element is the primary container, holding a path element, and another ‘g’ element (this time class ‘inner’). The ‘inner’ ‘g’ class contains a circle (the circle that moves), and a text element (the text that accompanies the circle).

The screengrab below provides another view of a ‘patterns’ SVG elements (taken from Chrome’s Developer Tools):


Code Structure

But how was the code actually structured to render these SVG elements? I ended up with the following structure:


Lets look at the data and the model.


The data associated with each ‘pattern’ is held in its own instance of a “d3.cloudshapes.patternData” module. Below is a little snippet of the ‘patternData’ module:

Each d3.cloudshapes.patternData instance holds almost all the data necessary to render each pattern, including the path, the circle and text, but not all of the data. Each instance does not hold the points necessary to pass to a d3.svg.line generator to generate path data for the path element. Instead, each instance holds the data necessary to generate those points to pass to a d3.svg.line generator (otherwise the d3.cloudshapes.patternData instances would have used up large chunks of memory).

The ‘pattern’ variable contains the type of the path, e.g. circle / sine / spiral. The ‘patternData’ variable is a (I think of a as similar to a Dictionary in Python), and is used to hold onto the data used to generate the points:

Some spiral data being assigned to the patternData variable:

The “exports.createCircle” (see below), “exports.createSpiral” and “exports.createSineWave” functions can then call exports.get_pattern_points (see below), which can use the ‘pattern’ variable to simply look up the data in the ‘patternData’ variable, execute a switch on the ‘pattern’ and call the appropriate function to actually generate the necessary points.

The “exports.createCircle” (see below), “exports.createSpiral” and “exports.createSineWave” functions are all called by an instance of the “d3.cloudshapes.patternManager” component to generate the points (and then throw the points away once the path is defined) :

Let’s have a look at how the main body of the code uses the d3.cloudshapes.patternData module:

The main body of the JavaScript creates two arrays, cached_data and live_data. cached_data contains three instances of the d3.cloudshapes.patternData module and acts as our backup repository. live_data contains references to the instances held in cached_data, and periodically has references added or deleted. live_data is the array that’s actually passed to and used by the d3.cloudshapes.patternManager component (which then actually renders the patterns).

In essence then, the “model” is represented by the three instances of the d3.cloudshapes.patternData module referenced by the two arrays.


The next thing to look at is the d3.cloudshapes.patternManager component (where we really start using D3):


The main body of the JavaScript code (which here really acts as the controller) only creates one instance of the d3.cloudshapes.patternManager:

Here, the code calls once per iteration of the central transitions (which moves the circle and text):

You might wonder why there’s only one instance of a component created (d3.cloudshapes.patternManager), but three instances of a module (d3.cloudshapes.patternData). I could have created a d3.cloudshapes.pattern visual component and three separate instances (one for each pattern), but then each d3.cloudshapes.pattern instance would really have only called on the main g class, and not d3.selectAll. This would really miss out on the power of D3.

If you think about it, a barchart component is really a rectangle manager, and a linechart component is a line manager. So in the context of this example, it makes sense to create a pattern manager component:

The component consists of a set of private variables, and an internal function (exports) that provides access to those private variables and provides public functions to act on those private variables. This use of closures is pretty dense, and one of the most surreal pieces of code I’ve ever come across, so I’m not going to go into more about that right now. You can find more information, however, in Mike Bostock’s article on reusable D3 and also more in Developing a D3.js Edge. If you really want to understand closures, check this out: .

The constructor of the exports function contains the enter(), update() and exit() code. In this snippet below (showing the enter() code for the path elements), you can see the get_pattern_points function I referred to earlier being used to create a path SVG element:

And it’s in this part of the code, the constructor of the exports function, that we can see the code that waits for the enter/update/exit functions to complete (below is the code that waits for the update to complete):

In the above update code, at the end of the update transition, the code calls exports.enter_update_exit_transactionComplete() (see below):

This function counts the number of calls that it has has received. If it is equal to the number of elements in the data that is passed to the d3.cloudshapes.patternManager (in this case the data is live_data, so the count will be either two or three), the code dispatches the all_enter_update_exit_TransitionsComplete event. The main code deals with such an event by then calling exports.transition() of the d3.cloudshapes.patternManager instance (see below), and thereby kicking off the central transitions (where the circle & text follow the path):

You can see that at the end of the exports.transition, when the central transition (which uses the attrTween functionality) is complete, the code dispatches the transitionComplete event – which the main JavaScript code (the controller in this case) processes, and which I discuss again below.

The use of attrTween in exports.transition is pretty similar to the use in Mike Bostock’s Point-Along-Path Interpolation, so I won’t cover that in any more detail here.

Controller and Process

The diagram below gives an overview of the flow of the code, including the flow of the events:


At the heart of the code process (all code in this article is up on Github as a Gist, and viewable at is the following loop:

  • patternManager dispatches the allTransitionsComplete event once the central transitions (which move the circle and text) of all the g.pattern.g.inner elements are complete
  • The main body of the code traps the allTransitionsComplete event, and subsequently dispatches patternManagerTransitionComplete to itself (just to make completely sure we’re not amending anything to do with the patternManager from within any calls to the patternManager)
  • On receiving the patternManagerTransitionComplete event, the code fiddles with live_data. It makes sure it contains a full copy of cached data and decides whether to delete an element from live_data and if so, which element. For all of the remaining instances of patternData left referenced by live_data, the code randomly changes various elements, e.g. transition ease, transition duration, colors of path, text and circle, and more
  • Code calls the patternManager instance with the update live_data
  • The patternManager instance runs through the enter/update/exit code. On completion of all enter/update/exit transitions, the patternManager dispatches the snappily titled all_enter_update_exit_TransitionsComplete event
  • The main body of code traps the all_enter_update_exit_TransitionsComplete event, and calls patternManager.transition()
  • On completion of the central transitions, the patternManager instance dispatches the allTransitionsComplete event and the loop kicks off again


We have covered a lot in this post, and you should have an understanding of how to create reusable code in D3, but if you want to go further you should look at how to vary the transition ease. I’d be happy to provide more information on this and anything else if required. Just contact me via See below for D3.js resources that can be found in Safari Books Online.

Safari Books Online has the content you need

Developing a D3.js Edge is aimed at intermediate developers, so to get the most from this book you need to know some JavaScript, and you should have experience creating graphics using D3. Many examples created in the real world with D3, can best be described as “spaghetti code.” So, if you are interested in using D3 in a reusable and modular way, which is of course in line with modern development practices, then this book is for you!
Getting Started with D3 teaches you how to create beautiful, interactive, browser-based data visualizations with the D3 JavaScript library. This hands-on book shows you how to use a combination of JavaScript and SVG to build everything from simple bar charts to complex infographics. You’ll learn how to use basic D3 tools by building visualizations based on real data from the New York Metropolitan Transit Authority.
Visual Storytelling with D3: An Introduction to Data Visualization in JavaScript provides readers with a strong framework of principles for making well-conceived and well-crafted infographics, as well as detailed and practical instructions for how to really wield D3, the best tool for making web infographics available. An extended example is used in the book to explain how to put theory to practical use.

About the author Roland is a partner at Refined Practice, currently working on their D3
based visualization tool, among other things. You can find him on Twitter at @roland_dunn, and at, where he does daft visualizations such as A #D3.js Visualization of Senior UK Government Cabinet Ministers and Reusable D3 With The Queen, Prince Charles, a Corgi and Pie Charts.

Tags: D3, D3.js, Github, MV*, Reusable D3,

Comments are closed.