5

假设这段代码使用了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
}

这给了我们这个图表:

整洁图

我需要的是放置一个 node X,始终固定在其父节点以南的位置。即如果我把另一个关系A -- XX应该总是放在南方A。而且我真的不在乎其他一切都在哪里结束。

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

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

更新

让事情更清晰的附加图像:

x 应该在他父母的南方

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

4

2 回答 2

4

为了响应更新的约束,一种解决方案是固定 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

图形输出

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

--- 较早的答案 ---

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

如果您只需要约束来申请单个节点 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也可能有用,但我不确定。希望这可以帮助。

于 2012-01-12T23:54:46.940 回答
4

neato 程序支持多种模式,其中一种模式可能会给你你想要的。特别是,如果您设置 mode=ipsep,您可以指定在布局期间遵守的点状约束。例如,我拿你的图表并使用图表属性

mode=ipsep
diredgeconstraints=true
levelsgap=0.5

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

edge[dir=none]

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

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

整洁的布局

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

于 2012-01-17T19:57:37.240 回答