Search code examples
graphvizdotgraph-layout

How can I control within level node order in graphviz's dot?


I have a graph that has a tree as its backbone. So I have, for example a node A with children B, C, and D. Assuming the graph is being drawn top-down, A will be on one level, then B, C, and D. I would like to force graphviz to lay them out in B, C, D order within their rank. Is this possible? If so, how?

If there are only A, B, C, and D, I can get this effect by just putting B, C, and D in that order in the input dot file. But if there are other edges out of B, C, and/or D, sometimes the order gets scrambled. That's what I would like to avoid.

enter image description here


Solution

  • This can be achieved with "invisible" edges as shown. Please note well the comments that describe how it works.

    digraph test{
    
    // make invisible ranks
    rank1 [style=invisible];
    rank2 [style=invisible];
    
    // make "invisible" (white) link between them
    rank1 -> rank2 [color=white];
    
    // declare nodes all out of desired order
    A -> D;
    A -> B;
    A -> C;
    A -> E;
    
    // even these new connection don't mess up the order
    B -> F -> G;
    C -> F -> G;
    
    {
    rank = same;
    // Here you enforce the desired order with "invisible" edges and arrowheads
    rank2 -> B -> C -> D -> E [ style=invis ];
    rankdir = LR;
    }
    }
    

    enter image description here