blaz11
blaz11

Reputation: 23

Graphviz: tree structure

I want to use graphviz to generate structures tree, left-to-right structure like that (please ignore colors):

Desired outcome

I came to the conclusion that I need to use invisible nodes to achieve that, my current code looks like that:

digraph G { 
  node [ shape="box", width = 2, height = 1, fixedsize=true];
  edge [arrowhead=none];
  nodesep = 1;
  ranksep=0.05;
  splines = ortho;
  rankdir = LR;

  A1 [ shape="box", width = 2, height = 1, fixedsize=true];
  B1 [ shape="box", width = 2, height = 1, fixedsize=true];
  B2 [ shape="box", width = 2, height = 1, fixedsize=true];
  B3 [ shape="box", width = 2, height = 1, fixedsize=true];
  B4 [ shape="box", width = 2, height = 1, fixedsize=true];
  B5 [ shape="box", width = 2, height = 1, fixedsize=true];
  B6 [ shape="box", width = 2, height = 1, fixedsize=true];

  W0 [ shape="circle", width = 0, height = 0, fixedsize=true, label=""];
  W1 [ shape="circle", width = 0, height = 0, fixedsize=true, label=""];
  W2 [ shape="circle", width = 0, height = 0, fixedsize=true, label=""];
  W3 [ shape="circle", width = 0, height = 0, fixedsize=true, label=""];
  W4 [ shape="circle", width = 0, height = 0, fixedsize=true, label=""];
  W5 [ shape="circle", width = 0, height = 0, fixedsize=true, label=""];
  W6 [ shape="circle", width = 0, height = 0, fixedsize=true, label=""];

  subgraph {
    A1 -> W0
    W0 -> W3
    W3 -> W2
    W2 -> W1
    W0 -> W4
    W4 -> W5
    W5 -> W6

    W1 -> B1
    W2 -> B2
    W3 -> B3
    W4 -> B4
    W5 -> B5
    W6 -> B6

    {rank = same; A1;}
    {rank = same; B1; B2; B3; B4; B5; B6;}
    {rank = same; W0; W1; W2; W3; W4; W5; W6;}
  }
}

And using dot engine I get:

Current outcome

My questions:

Can I force certain nodes to take center position (A1)?

Can I force edges to connect to certain places on node's shape border (e.g.: center left)?

Maybe there is a better way to achieve such a tree structure that will have nodes center (I must consider that next layers of the tree can be quite complex)

Upvotes: 0

Views: 3523

Answers (1)

vaettchen
vaettchen

Reputation: 7659

In order to get what you want, you need to

  • define the nodes in the order you want to have them drawn (not strictly necessary in the given example here but good practice)
  • make sure that the empty nodes are in the same rank (you have that already)
  • and connect these empty nodes with each other in the right order (this is the critical item here)

Applying these changes, and simplyfying your code (you may like that or not, this is just how I would do it), I get to

digraph G { 
  edge [arrowhead=none];
  nodesep = 1;
  ranksep=0.05;
  splines = ortho;
  rankdir = LR;

  node [ shape="box", width = 2, height = 1, fixedsize=true];
  A1;
  B4 B5 B6 B3 B2 B1;

  node [ shape="point", width = 0, height = 0 ];
  { rank = same; W4 W5 W6 W0 W3 W2 W1 }

  A1 -> W0;
  W4 -> W5 -> W6 -> W0 -> W3 -> W2 -> W1;        /* critical! */
  W1 -> B1;
  W2 -> B2;
  W3 -> B3;
  W4 -> B4;
  W5 -> B5;
  W6 -> B6;
}

which yields

enter image description here

Upvotes: 3

Related Questions