Graphviz:创建从结构到自身的非重叠边
Graphviz: create non overlapping edges from a struct to itself
我正在尝试在 graphviz 中重新创建一张类似于从 CLR book 中截取的图表:
我在 Python 中使用以下代码:
s = Digraph(node_attr={'shape': 'record'})
s.node('struct', '<f0> 3|<f1> 13|<f2> 1|<f3> 2|<f4> 8|<f5> 5')
s.edge("struct:f0", "struct:f1")
s.edge("struct:f0", "struct:f2")
s.edge("struct:f1", "struct:f3")
s.edge("struct:f1", "struct:f4")
s
结果是:
这非常接近我想要的,除了边缘与节点重叠而不是 above/below 它们。
我找不到修改边缘行为的方法。另外,我有一种感觉,我在滥用 graphviz 的 struct 功能,但我不知道如何强制图形元素在一行中粘在一起。
我能否避免边缘重叠(当然,除非自己修改 SVG)或完全使用不同的方法?
您可以使用“端口”来设置连接点。
我在在线服务上试过你的图表,你的渲染似乎是带点的 http://dreampuf.github.io/GraphvizOnline
你可以和其他人一起测试,Circo和其他人不跨单元格,但默认情况下它们都在一侧(底部)绘制并且边缘很乱。
然而,“端口”属性允许通过指定后缀“:s”、“:n”等来解决这个问题。n、s、e、w、nw、ne、sw、s。 - 即南、北等....
似乎 Dot 的默认端口与 Circo 和 Neato 不同,后者可以:
digraph Structs {
node [shape=record];
s [label="<f0> 3|<f1> 13|<f2> 1|<f3>2|<f4>8|<f5>5"];
s:f0 -> s:f1;
s:f0 -> s:f2;
s:f1:n -> s:f3:n;
s:f1:n -> s:f4:n;
}
dot也需要指定前两个节点的端口:
digraph Structs {
node [shape=record];
s [label="<f0> 3|<f1> 13|<f2> 1|<f3>2|<f4>8|<f5>5"];
s:f0:s -> s:f1:s;
s:f0:s -> s:f2:s;
s:f1:n -> s:f3:n;
s:f1:n -> s:f4:n;
}
所以我猜,在你的代码中:
s.edge("struct:f0:s", "struct:f1:s")
s.edge("struct:f0:s", "struct:f2:s")
s.edge("struct:f1:n", "struct:f3:n")
s.edge("struct:f1:n", "struct:f4:n")
参见:How to prevent edges in graphviz to overlap each other
Graphviz Dot Edge Ports for Family Tree
我正在尝试在 graphviz 中重新创建一张类似于从 CLR book 中截取的图表:
我在 Python 中使用以下代码:
s = Digraph(node_attr={'shape': 'record'})
s.node('struct', '<f0> 3|<f1> 13|<f2> 1|<f3> 2|<f4> 8|<f5> 5')
s.edge("struct:f0", "struct:f1")
s.edge("struct:f0", "struct:f2")
s.edge("struct:f1", "struct:f3")
s.edge("struct:f1", "struct:f4")
s
结果是:
这非常接近我想要的,除了边缘与节点重叠而不是 above/below 它们。
我找不到修改边缘行为的方法。另外,我有一种感觉,我在滥用 graphviz 的 struct 功能,但我不知道如何强制图形元素在一行中粘在一起。
我能否避免边缘重叠(当然,除非自己修改 SVG)或完全使用不同的方法?
您可以使用“端口”来设置连接点。
我在在线服务上试过你的图表,你的渲染似乎是带点的 http://dreampuf.github.io/GraphvizOnline
你可以和其他人一起测试,Circo和其他人不跨单元格,但默认情况下它们都在一侧(底部)绘制并且边缘很乱。
然而,“端口”属性允许通过指定后缀“:s”、“:n”等来解决这个问题。n、s、e、w、nw、ne、sw、s。 - 即南、北等....
似乎 Dot 的默认端口与 Circo 和 Neato 不同,后者可以:
digraph Structs {
node [shape=record];
s [label="<f0> 3|<f1> 13|<f2> 1|<f3>2|<f4>8|<f5>5"];
s:f0 -> s:f1;
s:f0 -> s:f2;
s:f1:n -> s:f3:n;
s:f1:n -> s:f4:n;
}
dot也需要指定前两个节点的端口:
digraph Structs {
node [shape=record];
s [label="<f0> 3|<f1> 13|<f2> 1|<f3>2|<f4>8|<f5>5"];
s:f0:s -> s:f1:s;
s:f0:s -> s:f2:s;
s:f1:n -> s:f3:n;
s:f1:n -> s:f4:n;
}
所以我猜,在你的代码中:
s.edge("struct:f0:s", "struct:f1:s")
s.edge("struct:f0:s", "struct:f2:s")
s.edge("struct:f1:n", "struct:f3:n")
s.edge("struct:f1:n", "struct:f4:n")
参见:How to prevent edges in graphviz to overlap each other
Graphviz Dot Edge Ports for Family Tree