2010-05-25 135 views
11

我想用graphviz創建一個樹結構。我願意手動編寫graphviz代碼或使用ruby-graphviz gem進行ruby。鑑於下面的圖片,任何人都可以提供有關必要代碼的任何見解?忽略這些線條不是直的......當graphviz構建圖形時它們應該是。當線條相交時,我也願意有點/點。複雜的graphviz樹結構

我玩過ruby-graphviz和家族樹類......這讓我成爲了那裏的一部分,但我真的需要所有線條都是直的,並且以直角相交,盒子代碼似乎沒有這樣做。

該代碼應該足夠通用,以允許「C」框擁有孩子,並且「A」下還有更多的孩子。

顏色是無關緊要的......這些例子可以排除任何顏色。

http://docs.google.com/drawings/pub?id=1lUTfgKP_LN0x7C3ItbsFjfLBuDTL84AtmoaW7YFn32Y&w=1036&h=713

回答

4

據我知道這需要一點點變通;我只會用Graphviz DOT語言來做。我先給你解決方案,然後提供一些關於如何擴展它的解釋。

這是得出的數字:

outfile.png

這是Graphviz的代碼生成的數字:

graph atree { 
    Item1 [shape=none,label="Item 1",pos="2.2,1.1!"]; 
    Item2 [shape=none,label="Item 2",pos="2.2,0.1!"]; 
    Item3 [shape=none,label="Item 3",pos="2.9,-0.3!"]; 
    A [shape=box,color=lightblue,style=filled,pos="2,3!"]; 
    B [shape=box,color=lightblue,style=filled,pos="1,2.1!"]; 
    C [shape=box,color=lightblue,style=filled,pos="3,2.1!"]; 
    D [shape=box,color=lightblue,style=filled,pos="1.5,1.5!"]; 
    E [shape=box,color=lightblue,style=filled,pos="1.5,0.5!"]; 
    D0 [style=invisible,fixedsize=true,width=0,height=0,pos="2,2.5!",label=""]; 
    D1 [style=invisible,fixedsize=true,width=0,height=0,pos="1,2.5!",label=""]; 
    D2 [style=invisible,fixedsize=true,width=0,height=0,pos="3,2.5!",label=""]; 
    D3 [style=invisible,fixedsize=true,width=0,height=0,pos="1,1.5!",label=""]; 
    D4 [style=invisible,fixedsize=true,width=0,height=0,pos="1,0.5!",label=""]; 
    D5 [style=invisible,fixedsize=true,width=0,height=0,pos="1.5,1.1!",label=""]; 
    D6 [style=invisible,fixedsize=true,width=0,height=0,pos="1.5,0.1!",label=""]; 
    D7 [style=invisible,fixedsize=true,width=0,height=0,pos="2.2,-0.3!",label=""]; 
    A -- D0 -- D1 -- B -- D3 -- D4 -- E [color=blue]; 
    E -- D6 -- Item2 -- D7 -- Item3 [color=blue]; 
    D0 -- D2 -- C [color=blue]; 
    D3 -- D -- D5 -- Item1 [color=blue]; 
} 

如果你把它放在一個文件名爲inputfile.dot就可以得到結果圖像文件使用命令neato -Tpng inputfile.dot > outfile.png

現在有幾條關於它是如何工作的評論:用A, B, C, D, E, Item1, Item2, Item3構建樹的代碼很簡單(屬性只是設置顏色和框的樣式)。讓直線和正交直線的技巧包括:1)向圖中添加零大小的不可見節點; 2)將所有對象放置在畫布上的絕對座標中。步驟1)需要輔助節點D1, D2, D3, D4, D5, D6, D7,步驟2)需要選項pos="x,y!"。請注意,您需要在pos命令末尾使用!符號,否則這些位置將不會被視爲最終位置,並且佈局仍會變更。

可以通過第一定位添加附加節點的新節點(通過使用代碼用於節點A ... Item3作爲模板),添加不可見的,輔助節點(與pos,使得向和從它的所有連接是正交的),並然後通過<StartingNode> -- <AuxiliaryNode> -- <NewNode>將連接添加到圖表。

+0

所以它看起來像我的代碼將不得不做搞清楚絕對定位號碼困難的部分! – thomas 2010-06-01 19:17:30

+0

不幸的是,我不知道有什麼方法可以使用Graphviz繪製圖形,並在節點之間建立正交(和分離)的鏈接!如果您不需要這種行爲,Graphviz將爲您完成大部分艱苦的工作。如果你堅持這種行爲,恐怕你將不得不爲佈局做一些手動工作。 – user8472 2010-06-01 21:14:01

+0

謝謝。不幸的是我需要這種行爲。我將不得不編碼這個邏輯。 – thomas 2010-06-01 21:59:12

12

有一點晚了,我知道,但我只是想顯示其他版本,而不必弄清楚每個節點的確切位置。

digraph { 
    splines=false; 
    ranksep=0.05; 

    node[shape=box, color=lightblue, style=filled]; 
    A;B;C;D;E; 

    node[shape=none, color=none, style=solid]; 
    i1[label="Item 1"]; 
    i2[label="Item 2"]; 
    i3[label="Item 3"]; 

    node[label="", width=0, height=0]; 
    edge[arrowhead=none, color=blue]; 

    {rank=same; n2; n1; n3;} 
    n2; n1; n3; 
    A -> n1; 
    n2 -> n1 -> n3; 

    {rank=same; B; C;} 
    n2 -> B; 
    n3 -> C; 

    {rank=same; n4; D;} 
    B -> n4 -> D; 

    {rank=same; n6; n5; i1;} 
    D -> n5 -> i1; 
    n4 -> n6; 

    {rank=same; n7; E;} 
    n6 -> n7 -> E; 

    {rank=same; n8; i2;} 
    E -> n8 -> i2; 

    {rank=same; n9; i3;} 
    i2 -> n9 -> i3; 
} 

直線被強制執行:

  • splines=false - 說不花鍵
  • 無形的節點(節點N1,N2,...N9)與rank=same

它仍然是一些工作來獲取點文件的權利,但它打敗恕我直言,你自己計算每個節點的位置上同級別

  • 配售節點。

    輸出看起來是這樣的:

    graphviz output

    只要C沒有子節點,你必須運用一些掛羊頭賣狗肉(看不見的節點),以顯示它一路的權利。

    爲了得到不同圖形的更一般的解決方案,可能需要一些進一步的修改(對垂直邊緣應用權重,或者必須垂直對齊的組節點,或使用子圖...)。

  • +0

    注意:最新的GraphViz版本無法正常工作。如果刪除外部隱藏節點,則可以使用「splilines = ortho」替代方法http://stackoverflow.com/a/36953206/1312346 – 2016-04-30 09:41:39

    3

    另一個版本使用splines=ortho,這需要更少的隱藏節點,並提供相似的視覺效果。

    digraph example { 
        splines=ortho; 
        ranksep=0.05; 
    
        node[shape=box, color=lightblue, style=filled]; 
        A;B;C;D;E; 
    
        node[shape=none, color=none, style=solid]; 
        i1[label="Item 1"]; 
        i2[label="Item 2"]; 
        i3[label="Item 3"]; 
    
        node[label="", width=0, height=0]; 
        edge[arrowhead=none, color=blue]; 
        n1; n2; n3; n4; n5; 
    
        {rank=same; B; C;} 
        A -> n1; 
        n1 -> B; 
        n1 -> C; 
    
        {rank=same; n2; D;} 
        B -> n2; 
        n2 -> D; 
    
        {rank=same; n3; i1;} 
        D -> n3; 
        n3 -> i1; 
    
        {rank=same; n4; E;} 
        n2 -> n4; 
        n4 -> E; 
    
        {rank=same; n5; i2;} 
        E -> n5; 
        n5 -> i2; 
    
        {rank=same; n6; i3;} 
        i2 -> n6; 
        n6 -> i3; 
    } 
    

    dot image drawn via PlantUML.com