How do I get graphviz to generate fixed sized subgraphs?

user1818047 picture user1818047 · Nov 12, 2012 · Viewed 8.1k times · Source

I've been struggling with this for a while and cannot seem to find a straight answer. I'm working with compound subgraphs in graphviz and cannot seem to find the right combination of settings to force two subgraphs to align with each other.

Enclosed is a simple example to show the problem...

digraph g {
  compound=true;

  subgraph cluster_top {
    graph [color=black, label="Top", rank=min];

    nodeA; nodeB; nodeC
    cluster_top_DUMMY [shape=point style=invis]
  }

  subgraph cluster_service {
    graph [color=black, label="Bottom", rank=min];
    node1; node2; node3; node4; node5; extra_long_node
    cluster_bottom_DUMMY [shape=point style=invis]
  }
  cluster_top_DUMMY -> cluster_bottom_DUMMY [ style=invis ]
}

This generates output with the Bottom subgraph significantly wider than the Top subgraph.

enter image description here

What I really want is for to ensure that both Top and Bottom are always exactly the same width. In addition, if there are too many nodes to fit into the available width, it would generate additional rows of nodes.

Answer

Assaf Mendelson picture Assaf Mendelson · Mar 28, 2013

A possible (bad but working) solution would be to use invisible nodes and set width. Consider the following:

digraph g {
  compound=true;

    subgraph cluster_top {
      graph [color=black, label="Top", rank=min];

      nodeAI0 [style=invisible]
      nodeAI1 [style=invisible]
      nodeAI2 [style=invisible,fixedsize=true,width=1.65]
      nodeA; nodeB; nodeC
      cluster_top_DUMMY [shape=point style=invis]
    }

    subgraph cluster_service {
      graph [color=black, label="Bottom", rank=min];
      node1; node2; node3; node4; node5; extra_long_node
      cluster_bottom_DUMMY [shape=point style=invis]
    }
    cluster_top_DUMMY -> cluster_bottom_DUMMY [ style=invis ]
}

enter image description here

The invisible nodes (NodeAI0-NodeAI2) take the space. fixedsize=true,width=1.65 makes the last one take exactly 1.65 inches.

Another, better solution would be to also set the relevant longer node specifically (to avoid having to look for the correct value) by adding something like:

  node [fixedsize=true,width=0.75]

after the compound=true portion.