Open rrwright opened 5 years ago
a library to consider: http://visjs.org
An elm solution: https://github.com/jhrcek/graph-editor (with an interactive demo). I'm not sure it supports animations or curved edges though...
Nice find @harpocrates! I'm a little embarrassed I didn't see graph-editor myself earlier; I probably would have started with that instead of the drag-and-drop package. It weighs 1380 lines of code over 11 files, where I currently have 1 file with 307 lines of code.
In its current state, graph-editor is already pretty close to the basics of what we want, I think: it's built around directed graphs with labelled nodes and links. It already has zoom, but not panning. It doesn't provide color or images for nodes, or style (curvature etc) for links, but adding all that should be more or less trivial. Similar (albeit more work) for animations: I don't think it's really any more effort to add those kinds of features to graph-editor than to my own elm project. Elm is much easier and more pleasant to refactor than Javascript. I not really sure exactly what you meant by 'animation', but looking at the vis.js network examples, I suppose you mean the animated auto-layout that vis.js calls 'physics'? That would be more effort to implement, but I'm not convinced it's a feature we'd really want. It already provides several standard algorithms for layout via remote API calls to viz-js, which provides GraphViz as an http service. We could run it locally if we wanted.
The graph-editor package is under current development (last commit late December). The package author intends to implement browser-local saving and loading of graphs soon, which may be useful, although I imagine that for our application, that would be better done on the back-end. It does not support multiple links with the same source and target nodes; adding one will implicitly delete the already present link. Of course this could be added as well, but that might change the underlying model to a multi-digraph. This may not be such a big deal, but it's hard to say ahead of actually doing it.
I'm not a huge fan of the modal interaction idiom used by graph-editor, although I think it gets the link-adding action right. I'd rather see contextual affordances. The vis.js network examples have very fluid interactions, and that library provides tons of configuration options, but it's not immediately clear to me how flexible it really is. It's definitely in the giant-swiss-army-knife school of API design. My hunch is that using vis.js would immediately give us lots of features with very little effort, but if we ever wanted something that it didn't already provide, it would not be much fun to work with. If you like, I can spend some time with it and get a better feel for what it does and how. At a glance, it definitely doesn't provide as much functionality as d3.js, but is probably easier to use.
I get the impression that there are lots of javascript graph-manipulation and visualization libraries out there. No doubt they all have their advantages. Rather than shopping around for the most featureful one and then accommodating our design to whatever it provides, I would advocate for first doing some more careful and structured design thinking about the specific capabilities we want to provide to the user. If, having done this, we can't think of anything that vis.js doesn't already provide in an acceptable form, then by all means let's use that. But I think it's a mistake to determine the 'how' too far ahead of the 'what'.
To my mind, Elm is more or less ideal for iteratively building a relatively simple custom UI with complete control over all aspects of visual presentation and interaction. This is not as fast as slapping together some high-level JS libraries, but it is more sustainable. That may not matter, though, if we're just trying to build a rapid throwaway prototype and can live with the design decisions imposed by the libraries.
Here's a custom digraph editor built with d3.js, as a comparison point. It also does animated force-directed auto-layout, but doesn't have labels. I like the 'click to select' affordances. Looking at the code, it's pretty straightforward as is, but I suspect it could quickly descend into callback hell when adding features.