Layout Problem between Labels Dot Language Graphviz

348 views Asked by At

I am having issues on keeping Marge near Homer and Herb near Lucia to avoid this above-line (check the image). Basicly i need to keep married couples together and push aside brothers to fix the lines from mixing. Here is my source code:

digraph G {
  edge [dir=none];
  node [shape=box];
  graph [splines=ortho];

  "Abraham"   [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  "Mona"      [shape=box, regular=0, color="red", style="filled" fillcolor="pink"] ;
  a1 [shape=diamond,label="",height=0.25,width=0.25];
  {rank=same; Abraham -> a1 -> Mona};
  "Herb"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  "Lucia"     [shape=box, regular=0, color="red", style="filled"fontcolor="", fillcolor="pink"] ;
  "Homer"     [shape=box, regular=0, color="blue",fontcolor="blue", style="bold, filled" fillcolor="lightblue"] ;
  "Marge"     [shape=box, regular=0, color="red", style="bold,filled"fontcolor="red", fillcolor="pink"] ;
  p2 [shape=diamond,label="",style="",height=0.25,width=0.25];
  {rank=same; Herb -> p2 -> Lucia };
  {rank=same; Herb; Homer}
  b1 [shape=circle,label="",height=0.01,width=0.01];
  b2 [shape=circle,label="",height=0.01,width=0.01];
  b3 [shape=circle,label="",height=0.01,width=0.01];
{rank=same; b1 -> b2 -> b3};
  a1 -> b2;
  b1 -> Herb;
  b3 -> Homer;
  "Gendry"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  Herb -> Gendry;
  p2 -> c2;
  c1 -> Bob;
  c3-> John;
  {rank=same;  c1 -> c2 -> c3}
   c1 [shape=circle,label="",height=0.01,width=0.01];
  "Bob"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  c2 [shape=circle,label="",height=0.01,width=0.01];
  "John"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  c3 [shape=circle,label="",height=0.01,width=0.01];
   
  p1 [shape=diamond,label="",style="bold",height=0.25,width=0.25];
  {rank=same; Homer -> p1 -> Marge};
  {rank=same; Bob; John; Gendry}
}

family-tree-image

1

There are 1 answers

1
sroush On BEST ANSWER

What you want should be straight-forward using dot, but as you found, it is impressively difficult. Two techniques that should get you there are adding weight attributes to edges to keep nodes close to each other and/or using clusters to explicitly group the couples close. Using clusters does keep the couples together, but it resulted in ugly edges. Adding weights helped to get the invisible nodes placed "correctly" and resulted in nicer-looking edges.

digraph G {
  edge [dir=none];
  node [shape=box];
  graph [splines=ortho];

  subgraph cluster1{
      peripheries=0
  "Abraham"   [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  "Mona"      [shape=box, regular=0, color="red", style="filled" fillcolor="pink"] ;
  a1 [shape=diamond,label="",height=0.25,width=0.25];
  {rank=same; Abraham -> a1 -> Mona};
  }

  subgraph cluster3{
  peripheries=0
  "Homer"     [shape=box, regular=0, color="blue",fontcolor="blue", style="bold, filled" fillcolor="lightblue"] ;
  "Marge"     [shape=box, regular=0, color="red", style="bold,filled"fontcolor="red", fillcolor="pink"] ;
  {rank=same; Homer -> p1 -> Marge};
  p1 [shape=diamond,label="",style="bold",height=0.25,width=0.25];
  }
  subgraph cluster2{
      peripheries=0
  "Herb"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  "Lucia"     [shape=box, regular=0, color="red", style="filled"fontcolor="", fillcolor="pink"] ;
  {rank=same; Herb -> p2 -> Lucia };
  p2 [shape=diamond,label="",style="",height=0.25,width=0.25];
  }

  b1 [shape=point style=invis width=0 label=""]  //,height=0.01,width=0.01];
  b2 [shape=point style=invis width=0 label=""]  //,height=0.01,width=0.01];
  b3 [shape=point style=invis width=0 label=""]  //,height=0.01,width=0.01];
  {rank=same; weight=0   b1 -> b2 -> b3};
  {
  a1 -> b2;
  b1 -> Herb  [weight=9]
  b3 -> Homer [weight=9]
  }

  "Gendry"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;

  {rank=same; weight=0  c1 -> c2 -> c3}
   c1 [shape=circle,label="",height=0.01,width=0.01];
  "Bob"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  c2 [shape=circle,label="",height=0.01,width=0.01];
  "John"      [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ;
  c3 [shape=circle,label="",height=0.01,width=0.01];
   
  Herb -> Gendry;
  p2 -> c2 weight=99;
  c1 -> Bob weight=99;
  c3-> John weight=99;
  {rank=same; Bob; John; Gendry}
}  

Produces this (not great, but better): enter image description here