Dave DeLong
Dave DeLong

Reputation: 243146

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.

Upvotes: 9

Views: 3099

Answers (2)

marapet
marapet

Reputation: 56446

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

Upvotes: 11

Edmund
Edmund

Reputation: 10799

A general technique for moving nodes around is to create invisible edges. In your case, you could create an edge from A to note, mark it invisible, and then mark the edge from note to B as non-constraining:

A -> note [style="invis"];
note -> B [constraint=false];

Upvotes: 3

Related Questions