Search code examples
graphgraphvizdot

Force node to be directly beneath another node


I have a graph that's laid out from left-to-right. There are some elements of this graph, however, that I want to have positioned relative to another node. For example, if I have this graph:

digraph "Test" {
    rankdir = "LR"
    A -> B
    B -> C
    D -> B
    note -> B

    note [ shape="house" ]
};

It renders like this:

Normal DOT layout

However, I'd like the "note" node to always be positioned directly underneath the node to which it's pointing, like this (manually created) graph:

Desired DOT layout

I've tried experimenting with a subgraph with a different rankdir and fiddling with rank and constraint attributes, but have been unsuccessful in getting this to work, as I've only been playing around with DOT for a couple of days.


Solution

  • You can enumerate the nodes before defining the edges, and then constrain node B to the same rank as node note by putting them in a subgraph:

    digraph "Test" {
        rankdir = "LR"
        A;D;
        {rank=same; note; B;}
        C;
    
        A -> B
        B -> C
        D -> B
        B -> note [dir=back]
    
        note [ shape="house" ]
    };
    

    Please note that in order to have node note below node B, I had to reverse the edge direction and add dir=back to have the arrow drawn correctly.

    graphviz output