eacousineau
eacousineau

Reputation: 3533

graphviz - How to arrange nodes in a cycle in a rectangular layout?

Pre-Script

... And just when I finished producing these example, I saw the 'roundtrip' flow topic, which looks nice. Since I've already put this on here, might as well ask: are there another alternatives?

Original Post

Is there a way to automatically lay out nodes in a rectangular layout when in a subgraph?

As an example, say I have the given structure:

digraph
{
    rankdir="LR";

    node [ shape="circle", style="bold, filled", fillcolor="#dddddd" ];

    a -> b -> c -> d -> e -> f -> g -> h -> b;
}

This yields the diagram test_1

My goal is to have them line up in a rectangle with rows of three nodes, forming

If I try to constrain the rank and change the rankdir, it is not as expected (I'm assuming because you can't change rankdir like this):

digraph
{
    rankdir="LR";

    node [ shape="circle", style="bold, filled", fillcolor="#dddddd" ];

    a -> b -> c -> d -> e -> f -> g -> h -> b;

    subgraph
    {
        rankdir="TB";
        rank="same";
        c; d; e;
    }

    subgraph
    {
        rankdir="TB";
        rank="same";
        f; g; h;
    }
}

test_2

If I go through and manually and assign rank to line up as I desired, it works:

digraph
{
    rankdir="LR";

    node [ shape="circle", style="bold, filled", fillcolor="#dddddd" ];

    a -> b -> c -> d -> e -> f -> g -> h -> b;

    { rank="same"; c; h; }
    { rank="same"; d; g; }
    { rank="same"; e; f; }
}

test_3

Edit

Just tried out the method, worked well. I did have to unconstrain the right-most edge to prevent it from making an asymetric shape, but overall worked like a charm (and much more intuitive)!

digraph
{
    rankdir="LR";

    node [ shape="circle", style="bold, filled", fillcolor="#dddddd" ];

    a -> b -> c -> d -> e;
    e -> f [ constraint="false" ];
    b -> h -> g -> f [ dir="back" ];
}

enter image description here

Upvotes: 4

Views: 3235

Answers (1)

eacousineau
eacousineau

Reputation: 3533

Not sure where to put this, but I will go ahead and post it here as a side answer.

I tried out a larger cycle:

digraph
{
    rankdir="LR";

    node [ shape="circle", style="bold, filled", fillcolor="#dddddd" ];

    x -> y;
    y -> aa [ constraint="false" ];
    aa -> ab -> ac -> ba;

    { rank="same"; ba -> bb -> bc -> ca; }

    da -> cc -> cb -> ca [ dir="back" ];

    { rank="same"; aa -> dc -> db -> da [ dir="back" ]; };

}

enter image description here

Also tried out a serpentine pattern:

digraph
{
    rankdir="LR";

    node [ shape="circle", style="bold, filled", fillcolor="#dddddd" ];

    x -> y;
    y -> aa [ constraint="false" ];
    aa -> ab -> ac;
    ac -> ba [ constraint="false" ];
    bc -> bb -> ba [ dir="back" ];

    bc -> ca [ constraint="false" ];
    ca -> cb -> cc;

    cc -> da [ constraint="false" ];
    dc -> db -> da [ dir="back" ];

    y -> dc [ dir="back", constraint="false" ];

    // { rank="same"; aa; bc; ca; dc; };
}

This one's still a bit messy.

enter image description here

Upvotes: 2

Related Questions