eclipse / elk

Eclipse Layout Kernel - Automatic layout for Java applications.
https://www.eclipse.org/elk/
Other
247 stars 83 forks source link

Feature request: simulation controls to avoid edge overlap in force layout #811

Open timothypratley opened 2 years ago

timothypratley commented 2 years ago

One potential control would be overriding the force or charge for nodes and edges

graph root
algorithm: force
node n1 {
    layout [ size: 30, 30 ]
    repulsion: 1000
}
node n2 {
    layout [ size: 30, 30 ]
}
node n3 {
    layout [ size: 30, 30 ]
}
edge e1: n1 -> n2 {
}
edge e2: n2 -> n3 {
}

repusion-on-node

Potential feature: when repulsion is applied to a node (or some similar property) one can make that node more or less repulsive than other nodes. Annotation in red indicating I'd like to push n1 further away.

Relates to #806 in that it would be nice to be able to do this for edge bendPoints.

Motivation:

The ability to more nicely distribute edges. Here is an example of a layout I made in D3 which allows me to set the force per particle. Each edge can thus be constructed with an intermediate force point of lesser power than nodes. D3 additionally allows one to specify a desirable distance for the edge, which is even more useful (see that visually I am able to make the red line double the length of blue lines, allowing me to spatially represent a negative relationship).

Figure 1: My existing D3 force layout with intermediate nodes, gravity, and distance

d3-force

By specifying simulation controls I am able to put certain nodes far from each other, edges do not overlap each other or nodes except when unavoidable, and the curves for edges are relatively shallow.

The technique of adding intermediate nodes can be employed in ELK, but the lack of control over the repulsive power causes a more "messy" outcome (see Example 2 below).

Example 2: intermediate nodes on edges elkt demonstrator

graph root
algorithm: force
iterations: 2000
node n1 {
    layout [ size: 30, 30 ]
}
node n1n2 {
    layout [ size: 1, 1]
}
node n2 {
    layout [ size: 30, 30 ]
}
node n2n3 {
    layout [ size: 1, 1]
}
node n3 {
    layout [ size: 30, 30 ]
}
edge e11: n1 -> n1n2
edge e12: n1n2 -> n2
edge e22: n2 -> n2n3
edge e23: n2n3 -> n3

elk-force

Note that the layout is susceptible to the number of iterations (iterations: 10000+ seem pretty stable, but the default number 300 produces poor edge layouts).

repulsivePower currently behaves equivalent to the "edge distance" in that setting it does result in the edge being longer, but as described in #806 it does not create particles. If repulsivePower did create bendPoints, it would be useful to allow repulsion to be configured such that a different sized force is applied).

Example 3: ELK's repulsivePower can "sort of" be currently be used to control edge distance elkt demonstrator

graph root
algorithm: force
iterations: 20000
node n1 {
    layout [ size: 30, 30 ]
}
node n1n2 {
    layout [ size: 1, 1]
}
node n2n1 {
    layout [ size: 1, 1]
}
node n2 {
    layout [ size: 30, 30 ]
}
node n2n3 {
    layout [ size: 1, 1]
}
node n3 {
    layout [ size: 30, 30 ]
}
edge e11: n1 -> n1n2 {
    repulsivePower: 2
}
edge e122: n1n2 -> n2 {
    repulsivePower: 2
}
edge e221: n2 -> n2n1 {
    repulsivePower: 2
}
edge e211: n2n1 -> n1 {
    repulsivePower: 2
}
edge e223: n2 -> n2n3
edge e233: n2n3 -> n3

This simple example results in a very unstable layout... it changes dramatically for different iteration counts and does not appear to ever stabilize no matter how many iterations are taken.

unstable-repulsion

Note that specifying model: EADES does result in a stable (but messy) layout:

eades

The "edge nodes" for the dual linked nodes are distributed too widely, and the single linked "edge node" underlaps another edge node for no apparent reason... it should have been pushed to the opposite side (this may have been prevented by initial conditions).

Some layouts do stabilize:

intermediate-nodes

The force layout provided by ELK might not be able to achieve my goal of distributing nodes and edges with few overlaps. But I'd like to be wrong about that as ELK provides a much nicer structure for selecting layouts and layout properties, which is in my opinion superior to what D3 offers.

A very simple example demonstration of a (somewhat tangential) fundamental difference is that nodes without edges do not cluster into a triangle:

no-gravity

I guess that this is due to a lack of gravity... so another possible feature would be gravity :) For reference here are the configuration options available in D3 There aren't a whole lot more than ELK, so I'm hopeful that the gap isn't insurmountable.

Sorry for the long, winding explanation; I thought it important to provide some context of what I am trying to achieve, and how more control over the simulation would bring me a step closer in that direction.

timothypratley commented 2 years ago

For reference, here is the equivalent ELK version for the full graph:

elkt demonstrator

elk-soci

I think it's a good layout that would be improved with some controls to avoid edge overlap.

soerendomroes commented 2 years ago

A very simple example demonstration of a (somewhat tangential) fundamental difference is that nodes without edges do not cluster into a triangle:

This happens because separate connected components are layouted separately by default. Setting spearateConnectedComponents to false creates the same problem.