Adventures with Javascript Graphing Libraries
I was looking for a Javascript library that would display a graph – in the mathematical sense of a node-arc network such as the following:
I might require curved lines and maybe arrows, and I need it to be zoomable and pannable. I also need node labels and click events on both nodes and edges.
Remembering a few links someone sent around showing off impressive applications of libraries such as d3.js and jQuery Sparklines I had high hopes of finding something I could use that was polished and snazzy with superb documentation and an enthusiastic community.
The first thing I noticed is that it seems like everyone is in love with Force-Directed Layouts these days – you know those graphs where the nodes appear “springy” and the spatial layout is “discovered” by the physics algorithm, such as this example. By their nature, however, these graphs have a dynamic layout – you generally can’t specify exact positions for your nodes.
The libraries I looked at included the following. A discussion of SVG vs Canvas is here.
d3.js – this library is SVG-based (as opposed to say, HTML5 canvas-based). With a cursory look I couldn’t see how to zoom (you should be able to though, right – it’s scalable vector graphics…!), and the docs are pretty large and initially confusing. The consensus seems to be that it is a power users tool.
Sigma.js has some nice-looking examples and appears to scale to hundreds of nodes and arcs nicely. It can use GEXF graph format. However, it lacks good documentation and doesn’t seem to have much momentum – the last source code change was 9 months ago.
jsPlumb has demos that do not appear to be zoomable, though the library seems to be still actively developed and has good docs. It can render by canvas/SVG/VML using jQuery/MooTools etc. However it seems more aimed at connecting elements with drag and drop than showing graphs per se.
Raphael seems nice enough, is SVG based, has intriguing demos and reasonable docs, the last change on github was 10 months ago, but again the demos had no zoom.
The Javascript InfoVis Toolkit strikes the right balance of functionality with simplicity for me – there’s enough simplicity that I can actually delve into the source (only one file needed – jit.js) and pretty easily see what’s going on. It’s canvas-based, but appears to mousewheel zoom (very smoothly) using canvas’ scale function. The project was also involved in a Google Summer of Code. Although there was no static graph example, I found it quite easy to adapt the force-directed example code to show a nice zoomable graph with node coordinates that I explictly specified (and has node and edge click events). (In doing this, I also discovered something interesting – the force-directed layout example gives you a totally new layout every time you refresh – you can see this by refreshing the demo page here multiple times. This randomised behaviour seems somewhat less than useful. Also interesting is the drag and drop of the nodes in the force directed example).
So I did not find anything that fit squarely with my requirements, though I’m going with the Infovis Toolit for now. (Of course there is always the possibility to handcode it myself, which for reasonably simple requirements is always an option, though less preferred particularly as you might encounter issues such as cross-browser bugs that have been addressed in the libraries and frameworks.)
On the plus side I truly learnt what Bezier curves actually are (and how they differ from quadratic Bezier curves), thanks to some help from the Wikipedia page and this neat interactive page where you can drag the control points around to see the effect on the curve.
Some time after doing the above (admittedly rather cursory) research, I then came across another cluster of libraries with a slightly different focus. These libraries are more geared towards interactive elements on canvas (e.g. drag and drop) and persisting the state of the elements when they are changed – a good starting discussion is at the Stack Overflow page here. The “master list” of these libraries I found in a Google doc here. These libraries provide more of a “scene graph” implementation which would be useful if you need a framework for proper tracking of the elements being drawn (especially if they are to be animated, e.g. a particle simulator).