How do you force rank on a node in dot?

13,620

Solution 1

Use "constraint=false".

http://www.graphviz.org/doc/info/attrs.html#d:constraint

In your graph:

FourthSTATE -> ThirdSTATE [label="No" constraint=false] ;

You'll get:

digraph {
    ERROR [label="Error"];
    FirstSTATE [label="Initial State" URL="\ref FirstSTATE"];
    FirstSTATE -> SecondSTATE;
    SecondSTATE [label="Second State" URL="\ref SecondSTATE"];
    SecondSTATE -> ThirdSTATE;
    ThirdSTATE [label="Third State" URL="\ref ThirdSTATE"];
    FourthSTATE [label="Fouth State?" shape="diamond"];
    ThirdSTATE -> FourthSTATE;
    FourthSTATE -> FifthSTATE [label="Yes" ];
    FourthSTATE -> ThirdSTATE [label="No" constraint=false] ;
    FifthSTATE [label="Fifth State" URL="\ref FifthSTATE"];
    SixthSTATE [label="Sixth State?" shape="diamond"];
    SixthSTATE -> ERROR [label="Yes" ];
    SixthSTATE -> SeventhSTATE [label="No"];
    FifthSTATE -> SixthSTATE;
    SeventhSTATE [label="Seventh State" URL="\ref SeventhSTATE"];
    SeventhSTATE -> EighthSTATE;
    EighthSTATE [label="Eighth State" URL="\ref EighthSTATE"];
    NinthSTATE [label="Ninth State?" shape="diamond"];
    NinthSTATE -> TenthSTATE [label="Yes" ];
    NinthSTATE -> EighthSTATE [label="No"];
    EighthSTATE -> NinthSTATE;
    TenthSTATE [label="Tenth State" URL="\ref TenthSTATE"];
    EleventhSTATE [label="Eleventh State?" shape="diamond"];
    EleventhSTATE -> ERROR [label="Yes" ];
    EleventhSTATE -> TwelfthSTATE [label="No" ];
    TenthSTATE -> EleventhSTATE;
    TwelfthSTATE [label="Twelfth State" URL="\ref TwelfthSTATE"];
}

Solution 2

Whenever you want an arrow that points upward, write the edge from top to bottom (i.e. backwards), then add dir=back (https://graphviz.org/docs/attrs/dir/) to make the arrow point upward instead of downward.

So instead of:

FourthSTATE -> ThirdSTATE [label="No"];

write:

ThirdSTATE -> FourthSTATE [dir=back, label="No"];

Now since all the edges go from ThirdSTATE to FourthSTATE, the rank is no longer ambiguous and Graphviz will reliably put ThirdSTATE above FourthSTATE.

This is often better than using constraint=false since edges with constraint=false are sometimes given very wiggly edges (as if they did not participate in graph layout?).

Share:
13,620

Related videos on Youtube

DrAl
Author by

DrAl

I'm an Electrical & Electronic Engineer with a background of developing embedded control systems (hardware and software) for electric motor control. I currently work for a company that develops industrial control equipment.

Updated on June 04, 2022

Comments

  • DrAl
    DrAl about 2 years

    I have a number of relatively simple (auto-generated) graphs in graphviz dot format. These show the path through a state machine, but dot has a slightly confusing habit of deciding that two nodes must be on the same rank when I would like the graph to be in state order. I've tried a lot of settings (including the :n and :s and the weight listed below), but I cannot persuade dot to place the Third State above the Fourth State.

    I have this problem with a lot of graphs: there seems to be something internal to dot that decides that it would be better if two nodes were on the same rank and there's nothing that can be done to override it. I've even had code that specifies that one node should be a rank=sink, but dot has decided to put another node below it anyway.

    Is there any way to suggest to dot that it's more important that the nodes are in order than any other constraint?

    The code that was used to generate the graph looks like this:

    digraph {
        ERROR [label="Error"];
        FirstSTATE [label="Initial State" URL="\ref FirstSTATE"];
        FirstSTATE -> SecondSTATE;
        SecondSTATE [label="Second State" URL="\ref SecondSTATE"];
        SecondSTATE -> ThirdSTATE;
        ThirdSTATE [label="Third State" URL="\ref ThirdSTATE"];
        FourthSTATE [label="Fouth State?" shape="diamond"];
        ThirdSTATE:s -> FourthSTATE:n [weight=50];
        FourthSTATE -> FifthSTATE [label="Yes" ];
        FourthSTATE -> ThirdSTATE [label="No"];
        FifthSTATE [label="Fifth State" URL="\ref FifthSTATE"];
        SixthSTATE [label="Sixth State?" shape="diamond"];
        SixthSTATE -> ERROR [label="Yes" ];
        SixthSTATE -> SeventhSTATE [label="No"];
        FifthSTATE -> SixthSTATE;
        SeventhSTATE [label="Seventh State" URL="\ref SeventhSTATE"];
        SeventhSTATE -> EighthSTATE;
        EighthSTATE [label="Eighth State" URL="\ref EighthSTATE"];
        NinthSTATE [label="Ninth State?" shape="diamond"];
        NinthSTATE -> TenthSTATE [label="Yes" ];
        NinthSTATE -> EighthSTATE [label="No"];
        EighthSTATE -> NinthSTATE;
        TenthSTATE [label="Tenth State" URL="\ref TenthSTATE"];
        EleventhSTATE [label="Eleventh State?" shape="diamond"];
        EleventhSTATE -> ERROR [label="Yes" ];
        EleventhSTATE -> TwelfthSTATE [label="No" ];
        TenthSTATE -> EleventhSTATE;
        TwelfthSTATE [label="Twelfth State" URL="\ref TwelfthSTATE"];
    }
    

    The graph currently looks like this: Dot Graph

  • Mike Finch
    Mike Finch over 2 years
    In a Confluence Flowchart macro, the constraint=false attribute on the edge had no effect.