复杂的graphviz树结构

时间:2010-05-25 00:18:04

标签: ruby graphviz

我正在尝试使用graphviz创建树结构。我愿意手工编写graphviz代码或使用ruby-graphviz gem进行ruby。鉴于以下图片,任何人都可以提供有关必要代码的任何见解吗?忽略线条不直...它们应该是graphviz构建图形时。我也愿意在线条交叉时有点/点。

我玩过ruby-graphviz和家谱类...这让我成为了那里的一部分但是我真的需要所有的线都是直的并且以直角相交并且开箱即用代码似乎没有这样做。

代码应该足够通用,以允许“C”框也有子女,并且“A”下也有更多的孩子。

颜色无关......示例可以排除任何颜色。

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

3 个答案:

答案 0 :(得分: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没有子节点,你就必须再应用一些技巧(不可见的节点)来一直显示它。

为了获得不同图形的更通用的解决方案,可能需要进一步调整(对垂直边缘应用权重,或者必须垂直对齐的组节点,或使用子图,......)。

答案 1 :(得分: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>将图像连接添加到图表中。

答案 2 :(得分: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