0

I'm trying to expand upon this rectangular layout example. The goal is to generate a similar layout but with a dynamic distribution of nodes (within reason, say no more than 20 per row) along both the top and bottom. (For now, the sides will always be 3 nodes.)

My current simplified base example uses this code:

digraph {
  rankdir="LR";

  node [group=top];
  aa -> ab -> ac -> ad -> ae -> af -> ba;

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

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

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

Output: simple-circuit-diagram

All the SO solutions I've come across suggest using invisible nodes, but that doesn't seem practical as I'll have math out the least common multiple, space the nodes accordingly, and create an invisible edge to lock them in place. I'd like to leave that as a last resort if there aren't better options out there.

Have tried several other approaches like calculating and setting minlen separately for each edge, playing with settings like clusterrank, nodesep, ranksep, constraint.

Any other ideas on how to equally space the nodes along the top and bottom sides of the layout?

(I'm not tied to GraphViz. Alternative software libraries are welcome. Preferably free and with a Python API.)

Eok
  • 101
  • 4

1 Answers1

0

dot will always try to figure out the "right" hierarchical position of a node, so "equally spacing" is meaningless within one graph. In order to get a node to a specific position, you will always have to tell dot about that position. Empty nodes give a large amount of flexibility, but can be cumbersome.

In your case, you could calculate the nodes that should be vertically aligned, and simply use another rank = same instruction. Admittedly, this is not the real answer to your question (as I think such answer does not exist) but maybe an improvement over the empty node approach:

digraph {
  rankdir="LR";

  node [group=top];
  aa -> ab -> ac -> ad -> ae -> af -> ba;

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

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

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

  // this leads to a manually fixed "equal spacing": 
  { rank = same; ac cc }
  { rank = same; ae cb }
}

which gives you

enter image description here

vaettchen
  • 7,299
  • 22
  • 41
  • This was the approach I implied when I mentioned using invisible nodes. I might still use this option as a compromise if there really is no option. – Eok Aug 19 '19 at 16:20