如何从graphviz获得平衡图?

发布于 2024-09-06 15:43:18 字数 696 浏览 5 评论 0原文

graphviz 中是否有设置可以生成这样的平衡图:

正确的图 http://img3 .imageshack.us/img3/6423/testaah.png

当图像下面这样更复杂时 - 它不像上面那样平衡(4 在 ** 下面)。

未正确平衡 http://img51.imageshack.us/img51/6632/test2b.png

生成第二个图的代码:

graph
{
  n1 [label="+"];
  n1 -- n2;
  n2 [label="/"];
  n2 -- n3;
  n3 [label="*"];
  n3 -- n4;
  n4 [label="1"];
  n3 -- n5;
  n5 [label="2"];
  n2 -- n6;
  n6 [label="3"];
  n1 -- n7;
  n7 [label="**"];
  n7 -- n8;
  n8 [label="4"];
  n7 -- n9;
  n9 [label="5"];
}

Is there a setting in graphviz to generate balanced diagrams like this:

correct diagram http://img3.imageshack.us/img3/6423/testaah.png

When diagram is more complex like below - it isn't balanced like that above (4 is below **).

not correctly balanced http://img51.imageshack.us/img51/6632/test2b.png

Code to generate second diagram:

graph
{
  n1 [label="+"];
  n1 -- n2;
  n2 [label="/"];
  n2 -- n3;
  n3 [label="*"];
  n3 -- n4;
  n4 [label="1"];
  n3 -- n5;
  n5 [label="2"];
  n2 -- n6;
  n6 [label="3"];
  n1 -- n7;
  n7 [label="**"];
  n7 -- n8;
  n8 [label="4"];
  n7 -- n9;
  n9 [label="5"];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

隔岸观火 2024-09-13 15:43:18

您可以“引入新的、不可见的节点来重新平衡布局”。 (请参阅https://graphviz.org/faq/#FaqBalanceTree)。 So your code becomes :

graph
{
  n1 [label="+"];
  n2 [label="/"];
  n1 -- n2;
  n1b1 [label="", width=.1, style=invis]
  n1 -- n1b1 [style=invis]  
  n1b2 [label="", width=.1, style=invis]
  n1 -- n1b2 [style=invis]  
  n1b3 [label="", width=.1, style=invis]
  n1 -- n1b3 [style=invis]  
  n7 [label="**"];
  n1 -- n7;
  { rank=same n2 -- n1b1 -- n1b2 -- n1b3 -- n7 [style=invis] }

  n3 [label="*"];
  n2 -- n3;
  n2b1 [label="", width=.1, style=invis]
  n2 -- n2b1 [style=invis]
  n6 [label="3"];
  n2 -- n6;
  { rank=same n3 -- n2b1 -- n6 [style=invis] }

  n8 [label="4"];
  n7 -- n8;
  n7b1 [label="", width=.1, style=invis]
  n7 -- n7b1 [style=invis]
  n9 [label="5"];
  n7 -- n9;
  { rank=same n8 -- n7b1 -- n9 [style=invis] }
  
  n3 -- n4;
  n4 [label="1"];
  n3 -- n5;
  n5 [label="2"];
}

With this output :

图表

You can "introduce new, invisible nodes to re-balance the layout." (see https://graphviz.org/faq/#FaqBalanceTree). So your code becomes :

graph
{
  n1 [label="+"];
  n2 [label="/"];
  n1 -- n2;
  n1b1 [label="", width=.1, style=invis]
  n1 -- n1b1 [style=invis]  
  n1b2 [label="", width=.1, style=invis]
  n1 -- n1b2 [style=invis]  
  n1b3 [label="", width=.1, style=invis]
  n1 -- n1b3 [style=invis]  
  n7 [label="**"];
  n1 -- n7;
  { rank=same n2 -- n1b1 -- n1b2 -- n1b3 -- n7 [style=invis] }

  n3 [label="*"];
  n2 -- n3;
  n2b1 [label="", width=.1, style=invis]
  n2 -- n2b1 [style=invis]
  n6 [label="3"];
  n2 -- n6;
  { rank=same n3 -- n2b1 -- n6 [style=invis] }

  n8 [label="4"];
  n7 -- n8;
  n7b1 [label="", width=.1, style=invis]
  n7 -- n7b1 [style=invis]
  n9 [label="5"];
  n7 -- n9;
  { rank=same n8 -- n7b1 -- n9 [style=invis] }
  
  n3 -- n4;
  n4 [label="1"];
  n3 -- n5;
  n5 [label="2"];
}

With this output :

Diagram

国粹 2024-09-13 15:43:18

对于这个特定的示例,您所需要做的就是放松前 3 个边缘之间的边缘的权重

graph g{    
  n1 [label="+"];
  n1 -- n2 [weight=0];
  n2 [label="/"];
  n2 -- n3;
  n3 [label="*"];
  n3 -- n4;
  n4 [label="1"];
  n3 -- n5;
  n5 [label="2"];
  n2 -- n6;
  n6 [label="3"];
  n1 -- n7 [weight=0];
  n7 [label="**"];
  n7 -- n8;
  n8 [label="4"];
  n7 -- n9;
  n9 [label="5"];
}

输出:

graphviz output

在更复杂的情况下,不可见的节点和边以及设置权重变得难以管理,您可以尝试 Emden R. Gansner 的 gvpr 脚本来布局二叉树,如 < href="https://stackoverflow.com/a/10905657/63733">此问题的答案。

For this particular example, all you need is to loosen up the weight of the edges between the top 3 edges:

graph g{    
  n1 [label="+"];
  n1 -- n2 [weight=0];
  n2 [label="/"];
  n2 -- n3;
  n3 [label="*"];
  n3 -- n4;
  n4 [label="1"];
  n3 -- n5;
  n5 [label="2"];
  n2 -- n6;
  n6 [label="3"];
  n1 -- n7 [weight=0];
  n7 [label="**"];
  n7 -- n8;
  n8 [label="4"];
  n7 -- n9;
  n9 [label="5"];
}

Output:

graphviz output

In more complex cases where invisible nodes and edges and setting weights gets difficult to manage, you may try Emden R. Gansner's gvpr script to layout binary trees as described in an answer to this question.

黒涩兲箜 2024-09-13 15:43:18

@greg 的答案的一个变体,它更加紧凑,并且更少依赖于图中语句的顺序。

优点

  1. 它根本不使用rank=same 一般
  2. 情况下,源组织有点“树状”,这使得编辑变得容易。
  3. 如果需要,只需进行 2 个小更改即可显示/隐藏所有节点。
  4. 只要父级和子级都位于同一行,任何边的声明顺序并不重要。

缺点:

常见问题解答一样,它仍然依赖于隐藏节点来平衡树。

graph calc {
  graph[nodesep=0.25, ranksep=0.3, splines=line];
  node [fontname = "Bitstream Vera Sans", fontsize=14,
        style=filled, fillcolor=lightblue,
        shape=circle, fixedsize=true, width=0.3];

  // layout all nodes 1 row at a time
  // order matters on each line, but not the order of lines
  "+";
  "/", am, "**";

  // or can be more spread out if you need to . . .
  n1 [label="1"];
  dm;
  n2 [label="2"];
  "*", bm, "3", "4", cm, "5";

  // make 'mid' nodes invisible
  am, bm, cm, dm [style=dotted, label=""];

  // layout all visible edges as parent -> left_child, right_child
  "+" -- "/","**";
  "/" -- "*","3"
  "**"-- "4","5";
  "*" -- n1, n2;

  // link mid nodes with a larger weight:
  edge [style=dotted, weight=10];
  "+" -- am;
  "/" -- bm;
  "**"-- cm;
  "*" -- dm;
}

结果是:

平衡树图

这是我需要绘制树时通常使用的技术。

我不经常使用 gvpr 因为它不在我经常想使用图表的环境中表现不佳(sphinx doxygen 等)。
但是,如果您可以使用标准管道来制作图表并且您不关心生成的图表源是什么样子,那么 gvpr 就是您的朋友。

A variation on @greg's answer, that's a bit more compact and less dependent on the order of statements in the graph.

Upsides:

  1. It doesn't use rank=same at all
  2. Generally the source organization is a bit more 'tree-like', which makes edits easy.
  3. Only 2 minor changes to show/hide the all nodes if needed.
  4. It doesn't matter what order any of the edges are declared in, as long as the parent and children are all on the same line.

Downside:

Like the FAQ, it still depends on hidden nodes to balance the tree.

graph calc {
  graph[nodesep=0.25, ranksep=0.3, splines=line];
  node [fontname = "Bitstream Vera Sans", fontsize=14,
        style=filled, fillcolor=lightblue,
        shape=circle, fixedsize=true, width=0.3];

  // layout all nodes 1 row at a time
  // order matters on each line, but not the order of lines
  "+";
  "/", am, "**";

  // or can be more spread out if you need to . . .
  n1 [label="1"];
  dm;
  n2 [label="2"];
  "*", bm, "3", "4", cm, "5";

  // make 'mid' nodes invisible
  am, bm, cm, dm [style=dotted, label=""];

  // layout all visible edges as parent -> left_child, right_child
  "+" -- "/","**";
  "/" -- "*","3"
  "**"-- "4","5";
  "*" -- n1, n2;

  // link mid nodes with a larger weight:
  edge [style=dotted, weight=10];
  "+" -- am;
  "/" -- bm;
  "**"-- cm;
  "*" -- dm;
}

Which results in:

balanced tree graph

This is the technique I usually use when I need to draw a tree.

I don't often use gvpr because it doesn't play well in environments where I often want to use a graph (sphinx, doxygen, etc.).
But if you can use a standard pipeline to make your graph and you don't care what the resulting graph source looks like, then gvpr is your friend.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文