Looking for a layout algorithm

746 Views Asked by At

I'm working with the sigma.parsers.cypher.js plugin for Linkurious, which seems to lay nodes out on the viewport by rather unimaginatively assigning the x and y coordinates random values which, with enough nodes basically creates an unreadable mess - the graph generation built into the Neo server does a much better job.

in thinking about it, an algorithm to lay stuff out better could work like this:

  1. select the first node in the graph and position it at (0,0)
  2. select all directly related nodes and position them a {minimum distance} away from the parent node
  3. if any two siblings are closer than {minimum distance}, increase the distance from the parent until the siblings can be sufficiently separated
  4. for each sibling perform steps 2 & 3 above

but I'm wondering is there anything out there I could leverage so I don't have to write the functionality from scratch?

* Update I *

maybe 2) select all (childless) directly related nodes ... and then 2a) child nodes with children should be positioned at twice the distance + the diameter of the node of siblings (this gives room for its children)

* Update II *

if the radius of the circle is {minimum distance} and there are more childless nodes than will fit, we can either: 1) increase the radius until all the nodes fit, or 2) create a second layer

1

There are 1 best solutions below

1
On

So for graph layout, a lot of people use either the d3 force directed layout or some tweaked variant of the same. I'm not sure if the neo4j browser uses d3 or not, but the graph display there looks like a force directed variant to me.

Graph visualization is a really deep topic, and there's a lot out there. To see a sampling of what's possible, peruse the d3 gallery.

EDIT although I'm less familiar with sigma.js, I think in sigma land the equivalent is forceAtlas2.

I can't comment on your specific algorithm; sounds like it might be reasonable, but for me the real question is, "how do you exploit the semantics of the data you're dealing with, in order to present a reasonable layout"? For example, I deal with a lot of time-based graph data. So we use force-directed layouts, but rather than displaying things in concentric circles, with well-connected stuff in the center and other stuff pushed outwards, we tend to lay things out left flowing to right along with the temporal aspect of the data. This works for us because we know what the timestamp property in all of the nodes is, and we know that in this domain, the time element is extremely meaningful.

If you had geo data, then maybe force-directed would be a bad idea, and you'd rather plot things on a map. If you had social network data, maybe you'd want to lay it out clustered around "supernodes" like Lady Gaga, to show who is most popular in the network.

The point of all of this is that it depends. It's difficult to say whether your visualization ideas are any good without understanding the semantics of the data and the underlying domain. I think of force directed layouts as a reasonable default to start with, and then customize. They're not really customized to any particular domain, which makes them kinda-sorta OK for most things, but not really great for really anything.

But bottom line, there are piles of javascript frameworks that will implement a dozen different algorithms for you. You're best off tweaking from a starting point of d3 or similar, I would not at all recommend implementing your chosen algorithm by yourself, rather do it as a set of configuration tweaks to an existing layout engine.