Search code examples
graphvizdot

How can I combine rank=same with dir=back, while specifying ports?


I have a graph that uses HTML-like labels to create tables where some cells are connected by an edge.

This works well, but when I specify rank=same for two nodes, dir=back for the connecting edge and at least one port position the edge direction is not respected.

This shows an example:

digraph so {
    // This all works
    a -> b [label="Regular direction" dir="forward"]
    c -> d [label="Reverse direction", dir="back"]
    e:w -> f:w [label="Reverse direction\n + port choice", dir="back"]
    g -> h [label="Reverse direction\n + rank=same", dir="back"]
    {rank=same; g; h}
    
    // This fails
    i:s -> j [label="Reverse direction\n + port choice\n + rank=same", dir="back"]
    {rank=same i; j}
}

I've highlighted the failing part below: enter image description here

Is there a combination of graph/node/edge options that would allow me to draw a reverse edge from one node port to another, while the two nodes are at the same rank?

What I've tried

Instead of using dir=back on the edge, I tried setting the arrowhead=none and arrowtail=normal in combination with dir=both. That didn't work either and somehow even affects the i -> j edge as well.

digraph so {
    // This fails
    i:s -> j [label="Reverse direction\n + port choice\n + rank=same", dir="back"]
    {rank=same i; j}
    
    // This fails
    k:s -> l [label="Reverse direction\n + port choice\n + rank=same\n + arrowhead/tail", arrowhead=none, arrowtail=normal, dir="both"]
    {rank=same k; l}
}

enter image description here


Solution

  • I found that mentioning the dir attribute before the label attribute gets you what you want:

    digraph so {
        i:s -> j [dir="back", label="Reverse direction\n + port choice\n + rank=same"]
        {rank=same; i;j}
    }