Search code examples
alignmentgraphvizsubgraph

How to align subgraphs in dot files


I am trying to align three or more subgraphs using dot files and graphviz. I think my problem is best shown using a few examples:

My first try:

digraph FutopJobFlow {
    rankdir=LR;
    node [shape=box]
    compound=true

    subgraph clusterA {label = " A ";
        A -> a1;
        a1 -> a2;
        a2 -> a3;
    }

    subgraph clusterB {label = " B ";
        B -> b1;
        b1 -> b2;
    }

    subgraph clusterC {label = " C ";
        C -> c1;
        c1 -> c2;
    }
    A -> B [lhead=clusterB];
    B -> C [lhead=clusterC];
    X -> A [lhead=clusterA];
    Y -> B [lhead=clusterB];
    Z -> C [lhead=clusterC];
}

giving this result:

First try of aligning subgraphs

Here the individual subgraphs looks like i would like but the are not aligned. I therefore tried wit the command rank:

digraph FutopJobFlow {
    rankdir=LR;
    node [shape=box]
    compound=true

    subgraph clusterA {label = " A ";
        A -> a1;
        a1 -> a2;
        a2 -> a3;
    }

    subgraph clusterB {label = " B ";
        B -> b1;
        b1 -> b2;
    }

    subgraph clusterC {label = " C ";
        C -> c1;
        c1 -> c2;
    }

    {rank=same; A; B; C;}

    A -> B [lhead=clusterB];
    B -> C [lhead=clusterC];
    X -> A [lhead=clusterA];
    Y -> B [lhead=clusterB];
    Z -> C [lhead=clusterC];
}

which result in this graph: Second try of aligning subgraphs

Here the alignment looks good but now the 'A', 'B' and 'C' is no longer inside the subgraphs!

I have tried several other ways to achieve both the alignment and that 'A', 'B' and 'C' is inside their respective subgraphs but with no succes.

Can anybody help?

@ Marapet - Thanks it is almost perfect now - it looks like this when i add the 'constraint=false' parameter:

Graph with constraint parameter

It would be perfect if the subgraph 'A' is above 'B' which again is above 'C'.


Solution

  • In the first version of your graph, you can disable the effect on node ranking for the edges between A-B and B-C by adding the attribute constraint=false:

    A -> B [lhead=clusterB, constraint=false];
    B -> C [lhead=clusterC, constraint=false];
    

    The subgraphs should then be aligned.