I’ve been playing with an incredible visualization library over the past few weeks called D3.js. I’m really amazed at how much work Mike Bostock and others have put into this library (they really know their stuff!) and I’ve been very impressed with the direction D3 has taken. I’ve used my fair share of charting libraries in the past and while they are good at getting you 80% of the use cases you need, they fall down in the 20% of the edge cases PM or UX inevitably throws at you. Whenever I use a charting framework, the 20% always takes A TON of time. Many times the 20% is unplanned and sprung on the developer later in the development cycle which leads to unnecessarily long timelines, or short-sighted hacks that you pay for later.
I’ve spent hours digging into charting frameworks looking for classes to extend or behaviors to inject in order to cram some functionality into it that were never intended by the framework creators. Several of my posts in the past have actually demonstrated some of the tricky solutions I’ve had to use to twist a framework’s arm to give me what I need. D3 however is very different.
D3 is built to interact with the DOM and gets you as close to the visual representation as you possibly can without hiding it behind an API you have to learn. If you know how to manipulate SVG and the DOM then you have a boost on a charting framework which requires you to learn their particular abstraction. This allows you to leverage that knowledge you may already have, or provide you the opportunity to learn techniques which will outlive any charting framework down the road.
D3 is also extremely good at providing transition support. You can easily inject transitions whenever data is added, removed, or updated with some simple method chaining. The example I created shows exactly how easy this is to pull off. I’d love to see any charting framework allow for custom transitions like the ones in my example without leaving the developer writhing on the ground in agony.
- Notice how easy it is to create transitions and even chain them with a delay by simply adding enter() and exit() handlers. Updates are handled by the selectors. Lines enter from the bottom of the y axis and drift into their positions then exit in reverse when they are destroyed.
- Each axis has beautiful transitions for adding/removing/updating grid lines and labels. The axis component comes in the D3 library and is pretty easy to configure.
- As data points increase to the point where showing circle data point renderers doesn’t make sense, I can animate them to radius = 0 and hide them from the user in a subtle way.
- D3 is really good at interpolation. You can click that “redraw” button til you’re blue in the face and D3 handles all the transitions without breaking or getting stuck in a bad state!
- D3’s scaling system is a beautiful thing. I can bind dates to the x axis with ease and request an x position for any date and receive it. It makes positioning extremely simple.
If I peaked your interest in D3, feel free to check out D3’s home on github which includes some great tutorials. I also like Mike’s basic examples of how D3 works here and his talk at W3Conf. I also found the tutorials here and here very useful.