Graphviz: Control node align in a subgraph

2.5k views Asked by At

Consider the following subgraph, with 5 Mrecod nodes:

enter image description here

Is there a way to force a vertical orientation, with the nodes above each other? I've tried rankdir=TB in the subgraph, with no effect.

I am running graphviz under Ubuntu with no special parameters:

dot -Tpng graph.dot -o img/graph.png
1

There are 1 answers

1
Rod On

Adam, just to clear up a couple of potentially confusing points:

  1. I'm pretty sure that the rankdir attribute applies to the entire graph, you cannot isolate that particular subgraph.

  2. rankdir=TB is the default value to begin with, so adding it isn't really going to do anything.

That said, if I am reading your subgraph correctly, it looks like:

  • You have a collection of 5 record-type nodes in a cluster.

  • Each of those nodes have inbound edges from one or more nodes outside the cluster.

  • None of the nodes within the cluster have edges between them.

If that's correct, then the nodes in your subgraph have the same rank (or probably do, depending upon the rank of the nodes that connect to them). Setting rankdir=LR (or rankdir=RL) will change the orientation of that subgraph so the nodes are aligned vertically, but it will also change the alignment of the overall graph.

One way to get just those nodes to be aligned vertically is to add an invisible edge between them. For example, if you have nodes A, B, C, D and E, your cluster definition might look something like this:

digraph G {
   // ...skipping stuff outside the cluster...
   subgraph clusterFoo {
      node [shape=record]
      A [label="..."]
      B [label="..."]
      C [label="..."]
      D [label="..."]
      E [label="..."]
      edge [style=invis]
      A -> B -> C -> D -> E
   }
}

Adding the edges will force the nodes in the subgraph to have a different rank, so the default rankdir=TB will lay out the nodes from top to bottom rather than from left to right. The style=invis attribute on these "false" edges will make them invisible.

If you want to tweak the spacing or alignment of the nodes within the cluster you might also want to play with edge attributes such as weight or minlen/attrs.html#d:minlen), or consider constraint=false on the inbound edges.

If I've misinterpreted your graph or if this doesn't help you at all, can you update your question to add a minimal example of the DOT file you are working with?

PS: On Ubuntu, you can use:

dot -Txlib graph.dot

to quickly open up a window with a rendering of the graph in graph.dot without first writing it to a file. The rendered image will even automatically update when you modify the source file.