您可以按照graphviz FAQ about balanced trees上建議的方法添加隱形節點和不可見邊緣,以及使用邊緣權重等。在一些simple cases,這就夠了。
但是有一個更好的解決方案:Graphviz的帶有一個稱爲gvpr工具(圖模式掃描和處理語言),其允許以
拷貝輸入圖形到它的輸出,有可能改變它們的結構和屬性,創建新的圖形,或打印任意信息
而且,由於Emden R. Gansner did all the work already by creating a script which does layout nicely binary trees,繼承人如何到(全部歸功於ERG):
保存以下gvpr腳本到一個文件名爲tree.gv
:
BEGIN {
double tw[node_t]; // width of tree rooted at node
double nw[node_t]; // width of node
double xoff[node_t]; // x offset of root from left side of its tree
double sp = 36; // extra space between left and right subtrees
double wd, w, w1, w2;
double x, y, z;
edge_t e1, e2;
node_t n;
}
BEG_G {
$.bb = "";
$tvtype=TV_postfwd; // visit root after all children visited
}
N {
sscanf ($.width, "%f", &w);
w *= 72; // convert inches to points
nw[$] = w;
if ($.outdegree == 0) {
tw[$] = w;
xoff[$] = w/2.0;
}
else if ($.outdegree == 1) {
e1 = fstout($);
w1 = tw[e1.head];
tw[$] = w1 + (sp+w)/2.0;
if (e1.side == "left")
xoff[$] = tw[$] - w/2.0;
else
xoff[$] = w/2.0;
}
else {
e1 = fstout($);
w1 = tw[e1.head];
e2 = nxtout(e1);
w2 = tw[e2.head];
wd = w1 + w2 + sp;
if (w > wd)
wd = w;
tw[$] = wd;
xoff[$] = w1 + sp/2.0;
}
}
BEG_G {
$tvtype=TV_fwd; // visit root first, then children
}
N {
if ($.indegree == 0) {
sscanf ($.pos, "%f,%f", &x, &y);
$.pos = sprintf("0,%f", y);
}
if ($.outdegree == 0) return;
sscanf ($.pos, "%f,%f", &x, &y);
wd = tw[$];
e1 = fstout($);
n = e1.head;
sscanf (n.pos, "%f,%f", &z, &y);
if ($.outdegree == 1) {
if (e1.side == "left")
n.pos = sprintf("%f,%f", x - tw[n] - sp/2.0 + xoff[n], y);
else
n.pos = sprintf("%f,%f", x + sp/2.0 + xoff[n], y);
}
else {
n.pos = sprintf("%f,%f", x - tw[n] - sp/2.0 + xoff[n], y);
e2 = nxtout(e1);
n = e2.head;
sscanf (n.pos, "%f,%f", &z, &y);
n.pos = sprintf("%f,%f", x + sp/2.0 + xoff[n], y);
}
}
假設包含圖形的點文件被稱爲binarytree.gv
,您可以執行以下行:
dot binarytree.gv | gvpr -c -ftree.gv | neato -n -Tpng -o binarytree.png
結果:
通過在腳本中切換一行或兩行,您甚至可以讓單個子節點進入左側而不是右側。
我在嘗試,但我只得到'gvpr:「./tree.gv」,第46行:_nd_a0:<<< - 語法錯誤(我確認代碼被正確複製,也試圖從甘斯納職位)。現在我不知道這應該是什麼意思?我沒有看到第46行中的任何可疑內容:-( –
這是最後一個'N {}'塊,如果我刪除錯誤消失了,而且佈局還沒有完成,這可能是版本問題嗎?我有'gvpr版本2.26.3(20100126.1600)' –
我使用了2.28.0,並且它馬上就工作了.Gansner的帖子是在你的graphviz版本發佈後大約6個月完成的,所以我會試着使用更新的版本 – marapet