Menu iconMenu

D3 is a great library for displaying visual data on a webpage. Getting it integrated with your favourite framework, in my experience at least, takes a bit of time and thought. This post looks at a few of the things I’ve learnt building D3 charts within the EmberJS framework. We’ll start with the basics of installing and then look at a couple of ways to integrate D3 with your Ember components.

At the time of writing Ember is v3.10 and D3 is v5.9 however the patterns should translate well to most other versions.

Installing D3 and Integrating with Ember

Firstly we’re going to want D3:

By default, you’ll have the entire library loaded in at this point and you can start using it like:

But to reduce your build size, I’d recommend whitelisting only those parts of the library that you’re using. Add the following to your environment.js file:

 

After changing that array make sure you completely stop and restart Ember. Relying on Ember serve rebuilding didn’t work for me, and the changes were picked up only after a full restart.

One important note with the above import is that some of those imports will themselves depend upon other parts of D3 that you need to add yourself to that array. For example in the above list d3-shape depends on d3-path so you’ll need to add both. The easiest way to achieve this is just to load the ones you directly import and check for errors when the code attempts to import.

In the example shown here, I’d need to add d3-path to the whitelist of D3 sub-libraries to include in the build.

Integrating D3 with Ember

Now we have D3 available to our Ember application, the next step is integrating it with our components.

The way I think of D3 is having two distinct functions, one is to provide utilities to help with display (for example, calculating SVG paths) and the other is DOM selection and data binding. When you’re using a client-side framework such as Ember or React you typically already have all the data binding functionality you need, so you do have the option of using the framework to provide that.

This gives you two approaches to integrating with your components:

Use D3 for data-binding and DOM manipulation

With this approach you pass the HTML element to D3 and let that manage all of the modification of data. This means you need to hook into the component lifecycle and tell D3 to run the updates at that time.

Let Ember do the data binding and DOM manipulation

This approach uses your client-side framework to update the visualisation in a similar manner to how you update data elsewhere in your application using templates.

We’ll look at how these two approaches can be implemented with an example and discuss some of the pros and cons of the two approaches. For these examples I’ve built about the simplest D3 chart I could, which is a success/failure Donut Chart. You can update the count of Passed or Failed by either changing the numbers in the input boxes or by clicking on the coloured arc in the chart itself to increment that number.

See it running here.

Use D3 for data-binding and DOM manipulation

The approach here is to create a class that manages all the D3 code and then add hooks into the component lifecycle telling it when to create and update.

The advantage of this approach is that it’s just standard D3, this means you can take code from online examples or other projects and they’re much easier to drop in. As D3 is managing the DOM transitions will also work as expected. You also end up with something that is quite portable between frameworks as you’re using a plain old Javascript class with a simple interface.

The major disadvantage with this approach is that handling events on the chart itself are tricky as you need a way to communicate back to the component. The pattern I like to use for this is to add actions into your component like you would normally and then pass the D3 class a sendAction function (with “this” bound to the component) that it can call with an action name and arguments. See the Ember send method API docs for details on this.

The component:

The template:

The DonutChart D3 class would look like this (stripped down as the D3 specifics aren’t really relevant, see the Github repo for the full code):

Let Ember do the data binding and DOM manipulation

So the other way to approach this is to create the SVG (or whatever DOM you’re creating with your chart) yourself in an Ember template, just like any other component. Then you let Ember do all of the DOM manipulation, for example if a value changes you can recalculate the SVG path yourself using the D3 utility tools. See the following example to get the idea.

The component:

The template:

You can see that the interactions on the chart here feel much more natural, in fact the whole solution feels more Ember-like and similar to the rest of your application. I also personally prefer writing the SVG into a template rather than having D3 build it. A big downside is you forgo all the coolness of D3’s transitions which is one of its major features, in a lot of cases this will be a show-stopper. You are also coupling your D3 code pretty tightly to Ember which is a problem if you plan to reuse the chart across projects not written with Ember.

Conclusion

Both approaches have a certain niche were they seem to work better. Personally I like having both available for use in project, but in general I’d lean towards the more pure D3 approach as I think transitions are a big feature of D3 and you’d usually want the option of incorporating them. I also like the idea of having a portable Javascript class. However for cases were you’re not interested in transitions and you have lots of user interaction with the chart opting for letting Ember manage the DOM and data binding may be a tidier solution.

Code: https://github.com/ewen/blog-ember-d3

Demo: https://ewen.github.io/blog-ember-d3/.

 

Banner image credit: Andrew Neel

A Day in the Life of an Ember Concurrency Task…

Media Suite's itinerant American developer explores one of the nuances of ember-concurrency.
Patrick Posted by Patrick on 19 October, 2016

Ember Blueprints part 2: putting Ember Blueprints to the test

Follow along with developer, Jonathan, for Part 2 of his Ember Blueprints discussion.
Jonathan H Posted by Jonathan H on 29 September, 2017

Ember Blueprints: why they’re awesome

Brit-turned-Queenstowner and keen coder Jonathan on why he's a fan of Ember Blueprints. Note: This is part one of a. . . (yet-to-be-decided-how-many-parts) series on this subject.
Jonathan H Posted by Jonathan H on 11 August, 2017
Comments Comments
Add comment

One Reply to “The Lost Guide to starting with Ember and D3”

Leave a Reply

Your email address will not be published.