I have been spending some of my free time on working on a personal project. As part of that, I needed to figure out how can we show visualizations of my data - yep charting. To give you some background, I am playing with angular js for this application and using a python based backend. Since I wanted to have a dynamic visualization - with animations and interactions thrown around, I decided to use a client side charting library that takes in the data and does the visualization entirely on the browser. Another thing I wanted to do was to see if I could use the same code or parts of it for delivering visualizations to the mobile.
Given its immense popularity and its ability to work with svg based visualization (which I felt would work better for supporting multiple devices - of course that may not be true), I gravitated to D3. I got to the D3 site and I found so many cool looking visualizations that I was just blown away (I bet you will have the same feeling). Of course almost none of them made much sense to me. I wanted to use some simple visualizations like bar charts, line charts etc. and they were of course available on D3.
But I am building an Angular app.
Also I was lazy. I wanted to figure out if there is a pain less way to get these charts integrated into my angular app. The immediate thought was to figure out if there are any angular directives.
Angular Directives and NVD3 to the rescue
So I googled it. And lo and behold there was an entire page talking about it. After some digging around I settled on two of them - angular-nvd3 and angularjs-nvd3-directives. Both of these directive libraries leverage nvd3 underneath which itself was built on d3 (Wow! A layer above a layer above the actual thing). While both of them seemed promising to me, I somehow settled on the second one. I remember my reasons at that time were that I liked the declarative nature of the directive (I am not sure if I like that still) and that it was around for longer time (which I still think is sensible).
That was a simple bar chart (look at the various bar colors!!!) and I followed that with a simple line chart
So my immediate needs were taken care and everything was perfect. I cooked up some bar charts, line chart and even some pie charts. I tweaked some colors and axis layout through the directive provided support. All was going well. Of course, in all the tweaking I was doing (colors, date formats), I sometimes needed to get some insight into d3.js itself. But that was very minimal.
Things change, We want more
I had taken a short detour into the world of statistics earlier. So I always liked the concepts of median and percentiles. So I wanted to figure out if there is a way to depict that in a visualization. My friend then introduced me to the box plot. I won't go into the details of box plot here. There is good reference material on that on the internet.
So my mind was set on the box plot and I wanted to figure out how I can create a visualization for it. The angularjs-nvd3-directives did not have any support for them. Neither did nvd3. So I looked directly at d3 and there was an example and the associated plug-in code available for it.
My idea of living on top of the abstraction (actually an abstraction over abstraction) no longer worked. I had no choice.
Getting my feet wet into D3
I initially thought I would try to create a nvd3 based box plot but I realized that it is going to take a lot of time figuring out nvd3 when I did not even know much about d3.
So I tried to figure out some basic concepts of d3 so that I understand the plug-in code. First and foremost I understood the concept of selection and mapping the selection with data. Also got an understanding of scales. This helped me understand the plug-in code. But that was not enough. I needed to figure out how I can integrate d3 with my angular app. Again there was example readily available. A simple directive would do the trick and I created a box plot using the same.
Tweaking the box plot
I started getting interested in the box plot code itself. First thing I realized was that the box plot code in its current form (inside the plug-in) took a lot of horizontal space as you increase the number of plots. This may not work very well when you don't have a lot horizontal space (read mobile device). So I figured I needed to tweak the box plot to support a change in orientation.
The second thing I wanted to do was to figure out a way to show labels close to my plots to indicate what they are plotting.
Another thing I noticed was that the outliers plotted by the box plot could skew up your graph quite a lot if you have really high outlier values. So I felt it would be good to have a way to turn it off. That is another thing I wanted to tweak.
And that is what I did. You can find my code in plunker.
The Road forward
The plnkr code is still not the cleanest. I have done some ugly hacks to make it look reasonable. It is available publicly. If anybody wants to tweak it and make it better (and teach me in the process), that would be fantastic. Also, I have still not been able to make my changed box plot work with my angular directive reliably. That is something I would surely like to fix. If I do I will share that code.
On the library side, I want to figure out if I can find a better abstraction over d3 which is simple to use. d3 is good but it is very literal and low level in its nature (which is by design from what I understand and hence gives it a lot of power to do new things!). I don't know whether nvd3 is that abstraction. May be it is and I will find out more about it. There seem to be other alternatives as well. Also for the mobile, I am not sure whether the d3 way would be the best fit - I somehow do not feel so (anybody can correct me!!!).
Libraries aside, I feel visualization is a field to really get a good handle on. To use a cliche - A picture is 1000 times better than words (or was it a picture is better than 1000 words... either way) - good visualization can be very powerful. I think a more deeper study on visualization will be very useful to me. Hopefully I can go down that path and do something worthwhile!