0
votes

I have a digraph which I've set to "rankdir=LR;" so that "rank=same" will be top-to-bottom.

I decided to add a few clusters to this graph, but as a result "rank=same" has now become bottom-to-top.

A minimal example shows the problem:

digraph graph {
graph [
    rankdir=LR;
    nodesep = "0.5 equally",
    newrank = true;
];

/* Guide Nodes */
rank1 [style=dotted];
rank2 [style=dotted];
rank1 -> rank2 [style=dotted];

/* Node Clusters */
subgraph cluster1 {
A;
B;
C;
}

/* Node Hierarchy */
A -> Z;
B -> Z;
C -> Z;

/* Node Rank */
{   rank=same;
rank1 -> A -> B -> C [style=dotted];
}

} /* Closes the digraph */

The result that I want is to have from top to bottom: rank1, A, B, C.

The result that I get is from top to bottom: C, B, A, rank1 --- as seen in the picture below.

enter image description here

How can I get the correct order back?

  • Option 1: Just don't use clusters.
  • Option 2: Rewrite the "rank=same" line to fit the bottom-to-top direction.

Given the size of my graph, option 2 is simply too much work for too little gain. Is there another option?

EDIT: The answer that marapet gave, does most of what I wanted. However, that solution doesn't work with the following minimal problem:

digraph g {
graph [
    rankdir=LR;
    nodesep = "0.5 equally",
    newrank = true;
];

/* Node Clusters */
subgraph cluster1 {
    subgraph cluster2 {
    A;
    B;
    C;
    }
P;
    subgraph cluster4 {
    D;
    E;
    F;
    }
Z;
}

/* Guide Nodes */
rank1 [style=dotted];
rank2 [style=dotted];

/* Guide Nodes Hierarchy */
rank1 -> rank2 [style=dotted];

/* Node Hierarchy */
A -> Z;
B -> Z;
C -> Z;
P -> Z;
D -> Z;
E -> Z;
F -> Z;

/* Rank Constraints */
rank1 -> A -> B -> C -> P -> D -> E -> F [style=dotted, constraint=false];

} /* Closes the digraph */

This results in the following picture:

enter image description here

I can only conclude that the issue I'm having is the result of mixing clusters and non-clusters in the same-rank-edges.

2

2 Answers

1
votes

Instead of using rank=same, you may use constraint=false for the same-ranke-edges:

/* Node Rank */
rank1 -> A -> B -> C [style=dotted, constraint=false];

The order of appearance of the nodes (guide nodes and node clusters) should also be changed:

digraph g {
graph [
    rankdir=LR;
    nodesep = "0.5 equally",
    newrank = true;
];

/* Node Clusters */
subgraph cluster1 {
A;
B;
C;
}

/* Guide Nodes */
rank1 [style=dotted];
rank2 [style=dotted];
rank1 -> rank2 [style=dotted];

/* Node Hierarchy */
A -> Z;
B -> Z;
C -> Z;

/* Node Rank */
rank1 -> A -> B -> C [style=dotted, constraint=false];
}

In general, for LR layouts, it helps to lay out the graph top-down and imagine it rotate 90 degrees counterclockwise.

1
votes

Small extension to edit in the question. In the edit the lone node 'p' is used, packing it in a subgraph gives a better result, especially when setting the color to white: like:

subgraph cluster3 {
P;
graph[color=white];
}

Only strange thing I get in my output is that there are 2 dotted lines between 'C' and 'P'/ Playing around with the 'dir=back' gave a solution. Complete code:

digraph g {
graph [
    rankdir=LR;
    nodesep = "0.5 equally",
    newrank = true;
];

/* Node Clusters */
subgraph cluster1 {
    subgraph cluster2 {
    A;
    B;
    C;
    }
    subgraph cluster3 {
    P;
    graph[color=white];
    }
    subgraph cluster4 {
    D;
    E;
    F;
    }
    Z;
}

/* Guide Nodes */
rank1 [style=dotted];
rank2 [style=dotted];

/* Guide Nodes Hierarchy */
rank1 -> rank2 [style=dotted];

/* Node Hierarchy */
A -> Z;
B -> Z;
C -> Z;
P -> Z;
D -> Z;
E -> Z;
F -> Z;

/* Rank Constraints */
rank1 -> A -> B -> C [style=dotted, constraint=false];
D -> E -> F [style=dotted, constraint=false];
P -> C [dir=back, style=dotted, constraint=false];
P -> D [style=dotted, constraint=false];

} /* Closes the digraph */