在 graphviz 上设置节点方向

发布于 2024-12-26 10:57:45 字数 897 浏览 5 评论 0 原文

假设此代码使用neato:

graph sample {
  layout=neato
  overlap=false
  splines=true
  tailclip=false
  headclip=false
  A -- I
  A -- J
  A -- B
  A -- H
  A -- E
  A -- K
  B -- D
  B -- C
  B -- L
  C -- M
  C -- N
  C -- O
  D -- P
  D -- Q
  E -- R
  F -- A
  G -- F
  H -- J
}

这给了我们这个图:

我需要的是放置一个节点X ,始终固定在其父节点以南的位置。即,如果我放置另一个关系 A -- X,则 X 应始终放置在 A 的南边。我并不关心其他一切的结局。

我已经研究过 pos 属性,但这似乎不是解决方案,因为 X 并不是真正处于固定位置,而是相对于他的位置关系。

还有 tailportheadport,但它们只定义边缘从哪里出来/进入,但并不真正影响节点的方向。

更新

附加图像以使事情更清楚:

x 应该在他父母的南边

我不'不需要neato,但我不希望图形看起来像UD或LR点树,我不希望它是线性排序的。 circo、fdp、sfdp、twopi 也可以。

Suppose this code using neato:

graph sample {
  layout=neato
  overlap=false
  splines=true
  tailclip=false
  headclip=false
  A -- I
  A -- J
  A -- B
  A -- H
  A -- E
  A -- K
  B -- D
  B -- C
  B -- L
  C -- M
  C -- N
  C -- O
  D -- P
  D -- Q
  E -- R
  F -- A
  G -- F
  H -- J
}

This gives us this diagram:

neato diagram

What I need is to place a node X, always fixed in a position south from his parent node. i.e. If I put another relation A -- X, X should be always placed south from A. And I don't really care where everything else ends up.

I've looked into the pos attribute, but it doesn't seems to be the solution since X is not really in a fixed position, but on a position relative to his relation.

Also tailport and headport, but they only define from where the edge will come out/in, but don't really affect the direction of the node.

Update

An additional image to make things clearer:

x should be south from his parent

I don't require neato, but I don't want the graph to look like a UD or LR dot tree, I don't want it to be linearly ordered. circo, fdp, sfdp, twopi are alright too.

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

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

发布评论

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

评论(2

护你周全 2025-01-02 10:57:45

为了响应更新的约束,一种解决方案是固定 A 和 X,然后在它们周围布置图形:

graph sample {
overlap=false;
splines=true;
tailclip=false;
headclip=false;

A [pin=true,pos="0,.2"]
X [pin=true,pos="0,.1"]
A -- I
A -- J
A -- B
A -- H
A -- E
A -- K
B -- D
B -- C
B -- L
C -- M
C -- N
C -- O
D -- P
D -- Q
E -- R
F -- A
G -- F
H -- J
A -- X

graph output

我尝试使用neato和fdp进行布局,它似乎生成了一个像你想要的那样的图表。当然,如果您想对同一图中的任意一对节点施加这样的约束,则此解决方案可能行不通。

--- 较早的答案 ---

如果您致力于使用 neato,我不确定是否有一种方法可以在不修改后处理步骤中的图形的情况下解决问题。如果neato只是一个方便的默认值,那么您应该能够通过使用点作为布局引擎并使用“rankdir = UD”来解决您的问题,如果X需要位于正南,则再加上一些额外的组装。

如果您只需要约束应用于单个节点 X,那么将 X 和 A 放在一个集群中应该可以完成这项工作:

graph sample {
  rankdir=UD 
  layout=dot
  overlap=false
  // .. as before
  A -- X
  subgraph clusterone {
   style=invisible
   A
   X
  }
}

如果您需要严格南向约束来应用于 A 的任意子节点,那么这种情况聚类,然后是以下描述的技巧:

如何强迫所有graphviz 中同一列中的节点?

可能可以解决问题。在这种情况下,属性 clusterrank=local 也可能有用,但我不确定。希望这有帮助。

In response to the updated constraints, one solution is to pin A and X, and then lay out the graph around them:

graph sample {
overlap=false;
splines=true;
tailclip=false;
headclip=false;

A [pin=true,pos="0,.2"]
X [pin=true,pos="0,.1"]
A -- I
A -- J
A -- B
A -- H
A -- E
A -- K
B -- D
B -- C
B -- L
C -- M
C -- N
C -- O
D -- P
D -- Q
E -- R
F -- A
G -- F
H -- J
A -- X

graph output

I tried layout with both neato and fdp, and it seems to produce a graph like what you want. Naturally, if you want to impose such a constraint on arbitrary pairs of nodes in the same graph, this solution may not work.

--- Earlier answer ---

If you're committed to using neato, I'm not certain there is a way to solve the problem without modifying the graph in a post-processing step. If neato is just a convenient default, then you should be able to solve your problem by using dot as your layout engine instead, and using "rankdir=UD", plus a couple of additional kludges if X needs to be due south.

In the event that you only need the constraint to apply for a single node X, then putting X and A together in a cluster should do the job:

graph sample {
  rankdir=UD 
  layout=dot
  overlap=false
  // .. as before
  A -- X
  subgraph clusterone {
   style=invisible
   A
   X
  }
}

If you need a strictly-south constraint to apply to arbitrary children of A, then that kind of clustering followed by the trick described in:

How to force all nodes in the same column in graphviz?

might do the trick. The attribute clusterrank=local might also be useful in that case, but I'm not certain. Hope this helps.

顾忌 2025-01-02 10:57:45

neato 程序支持多种模式,其中一种可能可以满足您的需求。特别是,如果设置 mode=ipsep,则可以指定在布局期间遵循的点状约束。例如,我获取您的图形并使用图形属性

mode=ipsep
diredgeconstraints=true
levelsgap=0.5

第一个打开 ipsep 模式,第二个告诉模型支持点中的有向边,
最后一个指定分离的强度。然后,我将边缘 dir 属性设置为 none

edge[dir=none]

并添加边缘 A -- X [dir=1]

dir=1 指示该边缘应引起方向约束。如果我然后运行neato,我会得到附加的图片。

neato layout

Graphviz 属性文档 http://www.graphviz.org/content/attrs 提供有关这些属性的更多信息。

The neato program supports multiple modes, one of which can probably give you what you want. In particular, if you set mode=ipsep, you can specify dot-like constraints that are honored during the layout. For example, I take your graph and use the graph attributes

mode=ipsep
diredgeconstraints=true
levelsgap=0.5

The first turns on ipsep mode, the second tells the model to support directed edges as in dot,
and the last specifies how strong the separation should be. I then set the edge dir attribute to none

edge[dir=none]

and add an edge A -- X [dir=1]

The dir=1 indicates this edge should induce a directional constraint. If I then run neato, I get the appended picture.

neato layout

The Graphviz attribute documentation http://www.graphviz.org/content/attrs provides more information about these attributes.

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