The power of graphviz to maintain node positions

I have a graph that changes over time (usually new nodes are added). I need to regenerate the graph several times and want all the nodes to be where they were. This partially works when using graphviz with an fdp algorithm, setting pin flag and determining positions using pos -argument.

In most cases, this works very well. But especially when new nodes are added, the layout sometimes changes a lot - what should I avoid. Is there really a possibility of the strength of fixed positions? This can lead to an ugly schedule, it will be fine, but they just need to stick to it.

+8
graphviz nodes sticky
source share
1 answer

Graphviz does not allow you to keep notes in one position:

  • Adding / removing a node can lead to a completely different location.
  • Adding / removing a node can resize the bounding box to resize.

The following works if all nodes are known when creating graphs:

  • Create a graph containing all possible nodes and let the carafe lay it out. You can add nodes[pin=true]; at the beginning of the chart (then you do not have to add it later).
  • Graphics Layout:

     fdp -Tdot input.gv -o input.pos.gv 

    You now have a point file containing all nodes. You can use this as a base file for all graphs you create:

  • For each graph, create a copy of input.pos.gv and hide the unnecessary nodes and edges by adding style=invis to their attributes. This ensures that they are not displayed, but also the place that they use in the layout will not be cropped (for example, if it is at the very top of the graph).
  • Expand them with something like this ( neato and the -n2 option are important parts):

     neato -n2 -Tpng input.pos.v1.gv -o output.v1.png 

Example:

input.gv:

 digraph g{ node[pin=true]; a -> b; a -> c; b -> d; b -> e; b -> f; c -> g; } 

input.pos.modified.gv:

 digraph g { node [label="\N", pin=true]; graph [bb="0,0,187,207"]; a [pos="60.846,70.555", width="0.75", height="0.5", style=invis]; b [pos="94.351,128.04", width="0.75", height="0.5"]; c [pos="76.868,18.459", width="0.75", height="0.5"]; d [pos="119.08,188.8", width="0.75", height="0.5",style=invis]; e [pos="157.97,106.75", width="0.75", height="0.5"]; f [pos="27.319,158.05", width="0.75", height="0.5"]; g [pos="160.1,20.585", width="0.75", height="0.5"]; a -> b [pos="e,84.434,111.03 70.717,87.493 73.42,92.13 76.411,97.263 79.332,102.27", style=invis]; a -> c [pos="e,71.34,36.433 66.27,52.918 66.934,50.759 67.624,48.514 68.32,46.252", style=invis]; b -> d [pos="e,111.86,171.05 101.5,145.62 103.54,150.61 105.8,156.17 108.01,161.59", style=invis]; b -> e [pos="e,133.72,114.86 118.76,119.87 120.45,119.31 122.17,118.73 123.89,118.16"]; b -> f [pos="e,49.99,147.9 71.657,138.2 67.726,139.96 63.572,141.82 59.447,143.67"]; c -> g [pos="e,133.07,19.895 104.12,19.155 110.07,19.307 116.47,19.471 122.74,19.631"]; } 

input.png unchanged:

output.png

hidden nodes:

output with invisible nodes

+14
source share

All Articles