anvaka / VivaGraphJS

Graph drawing library for JavaScript
Other
3.77k stars 425 forks source link

"Spiral visualization" to reduce computation and improve readability of large graphs? #151

Open gg4u opened 9 years ago

gg4u commented 9 years ago

Hi Andrei,

this is a suggestion to improve UX. I wonder if you could debrief in experimenting a new visualization, a sort of hybrid between constant layout and force-spring. My goal is also to have a neater readability of many nodes linked to a parent, and reduce overlapping.

The first can serve readability for allowing position the nodes with coordinates, but if you don't know how many nodes and if they are interconnected, it is kinda cumbersome. The latter distribute better larger graphs but often nodes needs more space for readability, at the cost of computation and shapes which are not very much organized; also, the flickering of nodes can be annoying and it would be better if children-parent nodes would stay still.

My proposal is to apply force-layout to clusters parent-children, considering them as a whole group (or sub-graph).

I am thinking on this pseudo-code. I have a weighted-graph; at each interaction for adding new nodes, a number of nodes N and R relationships are fetched on click on the parent; R can connect parent with children, and also with neighbors. The weight of the link is represented by the length: the stronger, the closer, so to adjust distance based on weight. Leaves are the nodes with only one link. I here call a "cluster" the group parent-leaves.

I would like then to apply force-layout only to nodes having more than one link, in such a way moving the whole cluster of parent and leaves as a unique object, or to apply it locally, adjusting the length of inter-links between two clusters.

As a UX example, if I click and drag the canvas, the whole graph will move with no effort. I think it would be an improvement to consider parent-leaves as a unique object while computing force-directed layout (it is a sort of "changing scale" from leaves to cluster and so reduce computation ...)

Have you maybe already thought about it? Could you give suggestions on how to implement a test? Look to hear from your feedback, thank you.

gg4u commented 9 years ago

How to modify force-layout so to consider group of nodes instead of single nodes? (A user could define arbitrarily which cluster should be fixed, allowing for more complex representation of diagrams).

anvaka commented 9 years ago

Oh @gg4u I just noticed this!

In all honesty this suggestion makes tones of sense and I truly love it. I've been thinking on this for a long time too, but still haven't come up with any solution to it. There is whole family of research dedicated to solve this problem too.

Your proposal will result in good speed up for sparsely connected graphs, yet it's not straightforward to implement.

gg4u commented 9 years ago

Hi @anvaka , maybe a suggestion - I m not skilled enough to modify and add features to your library, but Id like to share with you this. I am looking at your layout object. I see you compute bodies' masses for each node. It may be a workaround to compute the body masses for cluster of nodes - nodes that are interconnected by a link. For nodes that are just leaves, they could be placed respect to the the parent node (layout.setPositionNode()) in a way that is wanted.

It is easy to track which nodes are at the center of a cluster, I am doing it with an external - hashtable - for simplicity; so you would apply a spring force only to these parent node (leaves would have mass zero).

Would it be possible for you to add a function to layout (layout.setBodyMassNode()), so that it is possible to set custom body masses?

A second function will be real useful: to set the coordinates of a node respect to the parent. Do you think is it possible with something like layout.setPositionNode(function(parent.position))? I m not completely sure because: 1) with current force-directed the position won't be kept, everything is moving and difficult to check; 2) does layout.setPositionNode() set coordinates respect to the canvas or another node?

A third workaround - and actually another proposal that open up for whole new layout and UX possibilities - it is the possibility to pass to the graphics objects group of nodes, so to draw polygons atop of graphs.

Also in this way, it may be an attempt to pass, as polygons, custom shaped object (here, please see my attempt on a second thread I posted recently).

Sure, you may say easier said than done, but these suggestions came up from a lot of experiments on my side on UX (my core) rather than coding (learning by doing, satifing results here, but a vis-à-vis discussion with who is passioned and kick-ass on new layout based on networks - going beyond a graph concept- is what I am miss here).

Happy to share with you more ideas: write me in pvt anytime!