2010-02-16 106 views
33

我想繪製一個家庭樹Dot和GraphViz。家庭樹佈局點/ GraphViz

這是我目前有:

# just graph set-up 
digraph simpsons { 
ratio = "auto" 
mincross = 2.0 

# draw some nodes 
"Abraham" [shape=box, regular=1, color="blue"] ; 
"Mona"  [shape=box, regular=1, color="pink"] ; 
"Clancy" [shape=box, regular=1, color="blue"] ; 
"Jackeline" [shape=box, regular=1, color="pink"] ; 
"Herb"  [shape=box, regular=1, color="blue"] ; 
"Homer"  [shape=box, regular=1, color="blue"] ; 
"Marge"  [shape=box, regular=1, color="pink"] ; 
"Patty"  [shape=box, regular=1, color="pink"] ; 
"Selma"  [shape=box, regular=1, color="pink"] ; 
"Bart"  [shape=box, regular=1, color="blue"] ; 
"Lisa"  [shape=box, regular=1, color="pink"] ; 
"Maggie" [shape=box, regular=1, color="pink"] ; 
"Ling"  [shape=box, regular=1, color="blue"] ; 
# creating tiny nodes w/ no label, no color 
"ParentsHomer" [shape=diamond,style=filled,label="",height=.1,width=.1] ; 
"ParentsMarge" [shape=diamond,style=filled,label="",height=.1,width=.1] ; 
"ParentsBart" [shape=diamond,style=filled,label="",height=.1,width=.1] ; 

# draw the edges 
"Abraham"  -> "ParentsHomer" [dir=none, weight=1] ; 
"Mona"   -> "ParentsHomer" [dir=none, weight=1] ; 
"ParentsHomer" -> "Homer"  [dir=none, weight=2] ; 
"ParentsHomer" -> "Herb"   [dir=none, weight=2] ; 
"Clancy"  -> "ParentsMarge" [dir=none, weight=1] ; 
"Jackeline" -> "ParentsMarge" [dir=none, weight=1] ; 
"ParentsMarge" -> "Marge"  [dir=none, weight=2] ; 
"ParentsMarge" -> "Patty"  [dir=none, weight=2] ; 
"ParentsMarge" -> "Selma"  [dir=none, weight=2] ; 
"Homer"  -> "ParentsBart" [dir=none, weight=1] ; 
"Marge"  -> "ParentsBart" [dir=none, weight=1] ; 
"ParentsBart" -> "Bart"   [dir=none, weight=2] ; 
"ParentsBart" -> "Lisa"   [dir=none, weight=2] ; 
"ParentsBart" -> "Maggie"  [dir=none, weight=2] ; 
"Selma"  -> "Ling"   [dir=none, weight=2] ; 
} 

如果我通過點(dot simpsons.dot -Tsvg > simpsons.svg)運行此, 我得到以下佈局: Original, made by dot/graphviz

不過,我想的邊緣更像「家庭樹」一樣:兩個已婚人士之間的T形交叉口,T字形的垂直線再次在顛倒的T形交叉口分支,每個兒童都有小的分區,就像這個模型一樣在KolourPaint:

what I would like to achieve

什麼是點語法,我必須用來實現這一點?

+11

你忘記了巴特和麗莎之間的雨果 – tur1ng

回答

15

這裏有一個其他的解決方案:

digraph simpsons { 
    subgraph Generation0 { 
    rank = same 
    Abraham [shape = box, color = blue] 
    Mona [shape = box, color = pink] 
    AbrahamAndMona [shape = point] 
    Abraham -> AbrahamAndMona [dir = none] 
    AbrahamAndMona -> Mona [dir = none] 

    Clancy [shape = box, color = blue] 
    Jackeline [shape = box, color = pink] 
    ClancyAndJackeline [shape = point] 
    Clancy -> ClancyAndJackeline [dir = none] 
    ClancyAndJackeline -> Jackeline [dir = none] 
    } 

    subgraph Generation0Sons { 
    rank = same 
    AbrahamAndMonaSons [shape = point] 
    HerbSon [shape = point] 
    HomerSon [shape = point] 
    HerbSon -> AbrahamAndMonaSons [dir = none] 
    HomerSon -> AbrahamAndMonaSons [dir = none] 

    MargeSon [shape = point] 
    PattySon [shape = point] 
    SelmaSon [shape = point] 
    MargeSon -> PattySon [dir = none] 
    PattySon -> SelmaSon [dir = none] 
    } 

    AbrahamAndMona -> AbrahamAndMonaSons [dir = none] 
    ClancyAndJackeline -> PattySon [dir = none] 

    subgraph Generation1 { 
    rank = same 
    Herb [shape = box, color = blue] 
    Homer [shape = box, color = blue] 
    Marge [shape = box, color = pink] 
    Patty [shape = box, color = pink] 
    Selma [shape = box, color = pink] 

    HomerAndMarge [shape = point] 
    Homer -> HomerAndMarge [dir = none] 
    Marge -> HomerAndMarge [dir = none] 
    } 

    HerbSon -> Herb [dir = none] 
    HomerSon -> Homer [dir = none] 
    MargeSon -> Marge [dir = none] 
    PattySon -> Patty [dir = none] 
    SelmaSon -> Selma [dir = none] 

    subgraph Generation1Sons { 
    rank = same 
    BartSon [shape = point] 
    LisaSon [shape = point] 
    MaggieSon [shape = point] 

    BartSon -> LisaSon [dir = none] 
    LisaSon -> MaggieSon [dir = none] 
    } 

    HomerAndMarge -> LisaSon [dir = none] 

    subgraph Generation2 { 
    rank = same 
    Bart [shape = box, color = blue] 
    Lisa [shape = box, color = pink] 
    Maggie [shape = box, color = pink] 
    Ling [shape = box, color = blue] 
    } 

    Selma -> Ling [dir = none] 
    BartSon -> Bart [dir = none] 
    LisaSon -> Lisa [dir = none] 
    MaggieSon -> Maggie [dir = none] 
} 

而結果:

http://dl.dropbox.com/u/72629/simpsons.png

+1

你的代碼爲我生成[略有不同](http://oi61.tinypic.com/14smybl.jpg)圖片。 ;/ –

+0

@ patryk.beza使用'splines = ortho;'並且不要在名字上添加隱藏節點(比如Herb,Homer,Marge,Selma,Bart和Maggie)。 –

+1

@ patryk.beza http://stackoverflow.com/a/36953206/1312346 –

3

在graphviz中做到這一點相當簡單;有幾種你需要的語法模式: (i)語法來表示線到線的連接(上圖中的「T」連接點); (ii)執行分層結構的語法(即,垂直軸上同一平面上的相同代的節點)。它更容易顯示:

digraph G { 
    nodesep=0.6; 
    edge [arrowsize=0.3]; 

    "g1" -> "g2" -> "g3" -> "g4" 

    { rank = same; 
     "g1"; "King"; "ph1"; "Queen"; 
    }; 

    { rank = same; 
     "g2"; "ph2"; "ph2L"; "ph2R"; "ph2LL"; "ph2RR" 
    }; 

    { rank = same; 
     "g3"; "ps1"; "ps2"; "pr1"; "pr2" 
    }; 

    "King" -> "ph1" [arrowsize=0.0]; 
    "ph1" -> "Queen" [arrowsize=0.0]; 

    "ph1" -> "ph2" [arrowsize=0.0]; 
    "ph2LL" -> "ph2L" [arrowsize=0.0]; 
    "ph2L" -> "ph2" [arrowsize=0.0]; 
    "ph2" -> "ph2R" [arrowsize=0.0]; 
    "ph2R" -> "ph2RR" [arrowsize=0.0]; 

    "ph2LL" -> "ps1" [arrowsize=0.0]; 
    "ph2L"-> "pr1" [arrowsize=0.0]; 
    "ph2R" -> "ps2" [arrowsize=0.0]; 
    "ph2RR" -> "pr2" [arrowsize=0.0]; 

} 

上面的代碼將生成下面的圖(我省略了我用來着色節點的代碼)。爲了向你展示我是如何在同等級別的節點之間強制執行位置的,我可以在左邊(g1-> g2 ....)上留下可引導的「指南」,你可能想要在你自己的地塊中隱藏它。最後,標籤以'ph'開頭的節點是「T-junction」的佔位符節點。

alt text http://img525.imageshack.us/img525/352/fmtree2.png

+0

我快到了,請看下面的答案。我仍然唯一遇到的問題是控制水平軸上的放置順序(我想讓Abraham和Mona位於Clancy左側,Jackeline有一個很好的對齊圖片)。有沒有辦法做到這一點? – BioGeek

+0

當然,看看我上面的代碼 - 注意我指定邊的順序(從左到右)。 – doug

+0

對於這個有限的例子,這確實有效。但在真實家庭樹的數據中,所有的孩子都有合作伙伴。這些合作伙伴不停地跳過對方。我無法找到迫使丈夫永遠離開他們的妻子。例如http://i.imgur.com/Do7fz.png:Piet應該來到Inge的左邊,Wim(和她的第二個丈夫Jan C)應該來到Manu的左邊,Jan應該來到左邊多米尼克。 – BioGeek

1

我幾乎沒有,通過an old response on the graphviz-interest mailinglistdoug's answer啓發。

下面的代碼:

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

    "Abraham" [shape=box, regular=1, color="blue"] ; 
    "Mona"  [shape=box, regular=1, color="pink"] ; 
    "Clancy" [shape=box, regular=1, color="blue"] ; 
    "Jackeline" [shape=box, regular=1, color="pink"] ; 
    "Herb"  [shape=box, regular=1, color="blue"] ; 
    "Homer"  [shape=box, regular=1, color="blue"] ; 
    "Marge"  [shape=box, regular=1, color="pink"] ; 
    "Patty"  [shape=box, regular=1, color="pink"] ; 
    "Selma"  [shape=box, regular=1, color="pink"] ; 
    "Bart"  [shape=box, regular=1, color="blue"] ; 
    "Lisa"  [shape=box, regular=1, color="pink"] ; 
    "Maggie" [shape=box, regular=1, color="pink"] ; 
    "Ling"  [shape=box, regular=1, color="blue"] ; 

    a1 [shape=circle,label="",height=0.01,width=0.01]; 
    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; Abraham -> a1 -> Mona}; 
    {rank=same; b1 -> b2 -> b3}; 
    {rank=same; Herb; Homer}; 
    a1 -> b2 
    b1 -> Herb 
    b3 -> Homer 

    p1 [shape=circle,label="",height=0.01,width=0.01]; 
    q1 [shape=circle,label="",height=0.01,width=0.01]; 
    q2 [shape=circle,label="",height=0.01,width=0.01]; 
    q3 [shape=circle,label="",height=0.01,width=0.01]; 
    {rank=same; Homer -> p1 -> Marge}; 
    {rank=same; q1 -> q2 -> q3}; 
    {rank=same; Bart; Lisa; Maggie}; 
    p1 -> q2; 
    q1 -> Bart; 
    q2 -> Lisa; 
    q3 -> Maggie; 

    x1 [shape=circle,label="",height=0.01,width=0.01]; 
    y1 [shape=circle,label="",height=0.01,width=0.01]; 
    y2 [shape=circle,label="",height=0.01,width=0.01]; 
    y3 [shape=circle,label="",height=0.01,width=0.01]; 
    {rank=same; Clancy -> x1 -> Jackeline}; 
    {rank=same; y1 -> y2 -> y3}; 
    {rank=same; Marge; Patty; Selma}; 
    {rank=same; Bart; Ling} 
    x1 -> y2; 
    y1 -> Marge; 
    y2 -> Patty; 
    y3 -> Selma; 
    Selma -> Ling; 
} 

現在生產這樣的:

alt text

所以,看上去除了圍繞Homer.If那個奇怪的邊緣,我能找到一種方法來移動亞伯拉罕好, Mona和Herb到圖片的左側,然後我會有一個完美對齊的圖片。

關於如何實現這一點的任何想法?

4

創建儘管你無法控制節點位置,我發現你可以以不同的順序排序的節點幫助節點位置。我重新命令如下所示的一些節點,並得到一個沒有交叉替換的圖。

下面的代碼:

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

    "Herb"  [shape=box, regular=1, color="blue"] ; 
    "Homer"  [shape=box, regular=1, color="blue"] ; 
    "Marge"  [shape=box, regular=1, color="pink"] ; 
    "Clancy" [shape=box, regular=1, color="blue"] ; 
    "Jackeline" [shape=box, regular=1, color="pink"] ; 
    "Abraham" [shape=box, regular=1, color="blue"] ; 
    "Mona"  [shape=box, regular=1, color="pink"] ; 
    "Patty"  [shape=box, regular=1, color="pink"] ; 
    "Selma"  [shape=box, regular=1, color="pink"] ; 
    "Bart"  [shape=box, regular=1, color="blue"] ; 
    "Lisa"  [shape=box, regular=1, color="pink"] ; 
    "Maggie" [shape=box, regular=1, color="pink"] ; 
    "Ling"  [shape=box, regular=1, color="blue"] ; 

    a1 [shape=circle,label="",height=0.01,width=0.01]; 
    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; Abraham -> a1 -> Mona}; 
    {rank=same; b1 -> b2 -> b3}; 
    {rank=same; Herb; Homer}; 
    a1 -> b2 
    b1 -> Herb 
    b3 -> Homer 

    p1 [shape=circle,label="",height=0.01,width=0.01]; 
    q1 [shape=circle,label="",height=0.01,width=0.01]; 
    q2 [shape=circle,label="",height=0.01,width=0.01]; 
    q3 [shape=circle,label="",height=0.01,width=0.01]; 
    {rank=same; Homer -> p1 -> Marge}; 
    {rank=same; q1 -> q2 -> q3}; 
    {rank=same; Bart; Lisa; Maggie}; 
    p1 -> q2; 
    q1 -> Bart; 
    q2 -> Lisa; 
    q3 -> Maggie; 

    x1 [shape=circle,label="",height=0.01,width=0.01]; 
    y1 [shape=circle,label="",height=0.01,width=0.01]; 
    y2 [shape=circle,label="",height=0.01,width=0.01]; 
    y3 [shape=circle,label="",height=0.01,width=0.01]; 
    {rank=same; Clancy -> x1 -> Jackeline}; 
    {rank=same; y1 -> y2 -> y3}; 
    {rank=same; Marge; Patty; Selma}; 
    {rank=same; Bart; Ling} 
    x1 -> y2; 
    y1 -> Marge; 
    y2 -> Patty; 
    y3 -> Selma; 
    Selma -> Ling; 
} 

現在生產這樣的:

family tree layout

我不完全理解爲什麼它的工作,但這裏是思想的過程,到我所做的更改。

  1. 我把Clancy/Jackeline放在亞伯拉罕/莫娜面前,認爲他們錯了。這改變了圖片,但仍然不完美。
  2. 我把Homer/Marge放在首位,認爲軟件必須首先考慮這些部分,並且可能會將所有其他節點相對於Homer/Marge放置。這進一步幫助,但仍然不完美。
  3. 香草仍然放錯了位置,所以我首先放了香草,這樣graphviz可能會首先考慮放置香草。

它的工作,但我仍然不能設計一個算法,以確保一致的樹,沒有重疊的邊緣。我覺得graphviz應該在沒有這些提示的情況下做得更好。我不知道使用的算法,但如果他們考慮一個目標函數來最小化或消除重疊的邊緣,應該有可能設計一個更好的算法。

+1

+1讓我們更新! – Potherca

10

我不認爲你可以採取任意的家譜,並自動生成一個點文件,在GraphViz中它總是看起來不錯。

但我認爲你可以總是使它看起來好,如果你:

  • 使用等級=提到獲得「T」連接 由OP
  • 使用所需的相同的其他答案訂貨招布賴恩空白確實防止怪異線
  • 假設沒有第二次婚姻和半同胞
  • 繪製只有遵循以下規則樹的 子集:
    • 令S爲「中心」的人
    • 如果S有兄弟姐妹,確保S是對所有這些權利。
    • 如果S有配偶,配偶有兄弟姐妹,請確保配偶位於其所有兄弟姐妹的左邊。
    • 不顯示侄子,侄女,姑姑或S或S的配偶的叔叔
    • 不顯示兄妹
    • 的配偶不顯示配偶的兄弟姐妹S的
    • 顯示孩子的配偶,但不他們的配偶或子女
    • S的顯示父母及配偶父母

這最終會呈現一次不超過3代,以S在中間GE neration。

在下面S =荷馬的圖片(從布賴恩空白的版本略有修改):

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

    "Herb"  [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ; 
    "Homer"  [shape=box, regular=0, color="blue", style="bold, filled" fillcolor="lightblue"] ; 
    "Marge"  [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ; 
    "Clancy" [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ; 
    "Jackeline" [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ; 
    "Abraham" [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ; 
    "Mona"  [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ; 
    "Patty"  [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ; 
    "Selma"  [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ; 
    "Bart"  [shape=box, regular=0, color="blue", style="filled" fillcolor="lightblue"] ; 
    "Lisa"  [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ; 
    "Maggie" [shape=oval, regular=0, color="red", style="filled" fillcolor="pink"] ; 

    a1 [shape=diamond,label="",height=0.25,width=0.25]; 
    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; Abraham -> a1 -> Mona}; 
    {rank=same; b1 -> b2 -> b3}; 
    {rank=same; Herb; Homer}; 
    a1 -> b2 
    b1 -> Herb 
    b3 -> Homer 

    p1 [shape=diamond,label="",height=0.25,width=0.25]; 
    q1 [shape=circle,label="",height=0.01,width=0.01]; 
    q2 [shape=circle,label="",height=0.01,width=0.01]; 
    q3 [shape=circle,label="",height=0.01,width=0.01]; 
    {rank=same; Homer -> p1 -> Marge}; 
    {rank=same; q1 -> q2 -> q3}; 
    {rank=same; Bart; Lisa; Maggie}; 
    p1 -> q2; 
    q1 -> Bart; 
    q2 -> Lisa; 
    q3 -> Maggie; 

    x1 [shape=diamond,label="",height=0.25,width=0.25]; 
    y1 [shape=circle,label="",height=0.01,width=0.01]; 
    y2 [shape=circle,label="",height=0.01,width=0.01]; 
    y3 [shape=circle,label="",height=0.01,width=0.01]; 
    {rank=same; Clancy -> x1 -> Jackeline}; 
    {rank=same; y1 -> y2 -> y3}; 
    {rank=same; Patty; Selma; Marge}; 
    x1 -> y2; 
    y1 -> Marge; 
    y2 -> Patty; 
    y3 -> Selma; 
} 

這就產生了由GraphViz的下面的樹(帶有註釋的我與功率點加): enter image description here