Search code examples
graphvizrankdot

dot graphviz Different ranking of nodes


I need to draw a complex control flow where the divisions into horizontal and vertical axies are important. Dot only allows you to set rankdir (LR, TB) and one perpendicular axis (using rank = same ) how do I achieve more complex branching?

Truncated version of the target graph:

Added current code:

digraph G {
    rankdir = "LR";

    A1 -> A2 -> A3 -> A4 -> A5;
    
    
    {rank=same; A2 B2 C2}
    A2 -> B2 -> C2;

    C2 -> C3 -> C4;
    
    {rank=same; C3 D3}
    C3 -> D3;
    
    {rank=same; A3 E3}
    A3 -> E3;
    
    E3 -> E4 -> E5 -> E6;
    
    {rank=same; E4 F4}
    E4 -> F4;
    {rank=same; E5 F5}
    E5 -> F5;
    
    
    {rank=same; A4 B4}
    A4 -> B4;
}

Solution

  • To produce an "up" arrow, swap the head & tail, then set dir=back (see below).
    Unfortunately, a side-effect of the up arrows seems to be an ugly rearrangement of the rows, along with goofy edges.
    The fix for this seems to be declaring the nodes in the desired row (non rank) order (again see below)

    digraph G {
        rankdir = "LR";
        nodesep=.5  // spread things out a bit
    
    //  define the nodes in top-to-bottom (row) order
    //     the sequence within the definition is not important,
    //     rank=same will straighten that out
    //  these could all be on one line, as long as the sequence is correct
    
       D3
       C3 C2 C4
       B4 B2
       A4  A3 A1  A2
       E5 E6  E3 E4
       F5 F4
    
        {rank=same; A2 [group=g1] B2[group=g2] C2[group=g3]}
        {rank=same; A4 [group=g1] B4[group=g2]}
        {rank=same; C3 [group=g3] D3}
        {rank=same; A3 [group=g1] E3[group=g5]}
        {rank=same; E4 [group=g5] F4[group=g6]}
        {rank=same; E5[ group=g5] F5[group=g6]}
    
        // edges
        A1 -> A2 -> A3 -> A4 -> A5;
        C2 -> C3 -> C4;
        E3 -> E4 -> E5 -> E6;
    
        // up arrow edge
        { edge[dir=back]
          C2 -> B2 -> A2;
        }
        {edge[dir=back]
          D3:s -> C3:n;
        }
        {edge[dir=back]
          B4:s -> A4:n;
        }
        A3:s -> E3:n
        E4 -> F4;
        E5 -> F5;
    }
    

    Giving:
    enter image description here