制作graphviz树让父母集中在孩子身上

时间:2015-06-16 05:22:08

标签: tree drawing graphviz

我有以下graphviz代码:

graph {
    node[width = 0.6, height = 0.6, fixedsize=true, shape=circle];
    a[label="22"];
    b[label="22"];
    c[label="34"];
    d[label="22"];
    e[label="99"];
    f[label="34"];
    g[label="40"];
    h[label="37"];
    i[label="22"];
    j[label="99"];
    k[label="135"];
    l[label="129"];
    m[label="40"];
    edge[penwidth=3.0];
    a -- b;
    b -- d;
    c -- f;
    d -- i;
    e -- j;
    g -- m;
    edge[penwidth=1.0];
    a -- c;
    b -- e;
    c -- g;
    d -- h;
    e -- k;
    g -- l;
}

这是为了绘制一个二进制树,其中一些边突出显示。然而,树看起来不太正确 - 特别是在树的下方,父母和孩子的安排看起来像这样:

          parent
child     child

虽然我希望它看起来更像这样:

    parent
child    child

(即让父母居中于其子女之上,而不是坐在其中一个之上)。这是可能的,如果是这样我该怎么做?

2 个答案:

答案 0 :(得分:2)

按照this linked answer using gvpr and Emden R. Gansner's script中的说明很好地布局二叉树,我得到以下输出:

Graphviv binary tree with Emden R. Gansner's gvpr power

想不出更好或更快的方式。

答案 1 :(得分:1)

我确实玩了很多,我认为没有完美的解决方案。有一些方法。

带有额外隐形边和节点的经典方法。这适用于小图形,但在大图形上变得非常难看。为了确保这是成功的,你必须用不可见的节点填充整个网格。否则点引擎会否决你。

我期望解决的是这种方法

digraph {
    edge [weight=1]
    0->L
    0->R
    edge [weight=10]
    L->LL
    L->LR
    R->RL
    R->RR
    edge [weight=100]
    LL->LLL
    LL->LLR
    LR->LRL
    LR->LRR
    RL->RLL
    RL->RLR
    RR->RRL
    RR->RRR
}

不幸的是没有。似乎点布局引擎试图最小化边缘长度,但仅水平部分,即子节点之间的任何父位置都被认为是理想的。

我试过的另一个是

digraph {
    splines=line
    style=dotted
    edge [weight=1]
    subgraph cluster_0 {
        subgraph cluster_L {
            subgraph cluster_LL {
                LLL
                LLM [style=dotted]
                LLR
                LL->LLL
                LL->LLM [style=dotted weight=100]
                LL->LLR
            }
            LM [style=dotted]
            subgraph cluster_LR {
                LRL
                LRM [style=dotted]
                LRR
                LR->LRL
                LR->LRM [style=dotted weight=100]
                LR->LRR
            }
            L->LL
            L->LM [style=dotted weight=100]
            L->LR
        }
        M [style=dotted]
        subgraph cluster_R {
            subgraph cluster_RL {
                RLL
                RLM [style=dotted]
                RLR
                RL->RLL
                RL->RLM [style=dotted weight=100]
                RL->RLR
            }
            RM [style=dotted]
            R->RL
            R->RM [style=dotted weight=100]
            R->RR
        }
        0->L
        0->M [style=dotted weight=100]
        0->R
    }
}

给出了

enter image description here

似乎确实有效,水平顺序取决于外观。但是群集在许多其他构造中表现不佳,你必须尝试它是否适合你。

如果省略群集,布局将水平更紧凑。不可见的中间节点仍会阻止垂直边缘。

digraph {
    splines=line
    style=dotted
    edge [weight=1]
    LLL
    LLM [style=dotted]
    LLR
    LL->LLL
    LL->LLM [style=dotted weight=100]
    LL->LLR
    LM [style=dotted]
    LRL
    LRM [style=dotted]
    LRR
    LR->LRL
    LR->LRM [style=dotted weight=100]
    LR->LRR
    L->LL
    L->LM [style=dotted weight=100]
    L->LR
    M [style=dotted]
    RLL
    RLM [style=dotted]
    RLR
    RL->RLL
    RL->RLM [style=dotted weight=100]
    RL->RLR
    RM [style=dotted]
    R->RL
    R->RM [style=dotted weight=100]
    R->RR
    0->L
    0->M [style=dotted weight=100]
    0->R
}

给出了

enter image description here

最后还剩下一件事,一个用于ERG树形布局的gvpr脚本。您在marapets中找到的详细信息可以回答question