【发布时间】:2021-11-19 00:54:12
【问题描述】:
我需要用 graphviz/dot 绘制一个图表,其中节点之间有共同的边缘类型,我试图找到一种方法来为每种类型的边缘定义一个标签,然后在图中多次使用该标签。
例如,想象一下传统的吊扇 FSM 示例,它最初处于关闭状态,每次有人拉动电源线时,它都会根据风扇的速度更改为新状态:
Pull Pull Pull
OFF ------> HIGH ------> MED ------> LOW
^ |
| Pull |
+------------------------------------+
每条边都被命名为“Pull”,我可以使用以下方法在点中定义它:
digraph fan {
OFF -> HIGH [label="Pull"];
HIGH -> MED [label="Pull"];
MED -> LOW [label="Pull"];
LOW -> OFF [label="Pull"];
}
但我不想每次都指定相同的文本标签,因为
- 我的标签可能会变得很长,因此很容易出错,并且
- 我的边缘除了标签之外还有其他属性,例如颜色,以及
- 我有多种不同类型的边可供选择,因此我想确保图表中不同上下文中使用的边类型“A”始终具有所有相同的属性。
我希望 dot 有一种语法,可以让我为边缘类型定义名称,例如:
digraph fan {
edge_a [label="Pull"];
OFF -> HIGH edge_a;
HIGH -> MED edge_a;
MED -> LOW edge_a;
LOW -> OFF edge_a;
}
当然,真正做的是创建一个名为“Pull”的节点和未标记的边。
我已经在网上搜索了几个小时,但没有成功。有人知道如何预先定义边缘类型以在多个位置使用吗?
更新: @vaettchen had suggested 定义一个边缘类型,然后列出该边缘类型的所有转换,然后定义下一个边缘类型,然后是它的转换。虽然这在技术上可以解决我的问题,但它会引入其他几个问题,因为我今天的图表可能看起来像:
digraph {
subgraph cluster_1 {
a -> b [label="type x", color=red, style=solid];
b -> a [label="type y", color=green, style=dashed];
b -> c [label="type x", color=red, style=solid];
c -> b [label="type y", color=green, style=dashed];
c -> d [label="type z", color=blue, style=dotted];
}
subgraph cluster_2 {
d -> e [label="type x", color=red, style=solid];
e -> d [label="type y", color=green, style=dashed];
e -> f [label="type x", color=red, style=solid];
f -> e [label="type y", color=green, style=dashed];
f -> c [label="type z", color=blue, style=dotted];
}
}
并且要通过边缘类型重新排列,我会在让双向边缘彼此相邻(a->b 和 b->a)的代码中失去直接的视觉清晰度,我必须明确列出每个子图中的节点,我必须将子图内部的边定义拉到主图中:
digraph {
edge [label="type x", color=red, style=solid];
a -> b;
b -> c;
d -> e;
e -> f;
edge [label="type y", color=green, style=dashed];
b -> a;
c -> b;
e -> d;
f -> e;
edge [label="type z", color=blue, style=dotted];
c -> d;
f -> c;
subgraph cluster_1 {
a; b; c;
}
subgraph cluster_2 {
d; e; f;
}
}
因此,虽然它可以解决我提出的问题并且我很欣赏这个建议,但我不确定它是否值得权衡,因为你最终得到了一个 C 程序,你必须在其中定义所有变量函数并按其类型而不是逻辑关联来组织它们。
为了清楚起见,如果存在这样的“edge_type”定义关键字,那么在上面的示例中,我真正希望的结果如下所示:
digraph {
edge_type edge_x [label="type x", color=red, style=solid];
edge_type edge_y [label="type y", color=green, style=dashed];
edge_type edge_z [label="type z", color=blue, style=dotted];
subgraph cluster_1 {
a -> b edge_x;
b -> a edge_y;
b -> c edge_x;
c -> b edge_y;
c -> d edge_z;
}
subgraph cluster_2 {
d -> e edge_x;
e -> d edge_y;
e -> f edge_x;
f -> e edge_y;
f -> c edge_z;
}
}
【问题讨论】:
-
亲爱的驾车投票者 - 想解释一下原因吗?该问题有示例输入、输出、尝试的解决方案和需求说明,因此不确定我可以做些什么来改进它。
-
再次感谢,我去看看。谈到 github,我希望我能找到一种方法将 .dot 规范包含在 README.md 中,并在有人在 github 上查看它时自动呈现图形。因此,如果我在 .dot 中有一个系统的文本模型,我也不必手动更新它的图像。我找到了一个站点 (github.com/TLmaK0/gravizo),我可以通过引用我的 .dot 文件链接到该站点,并且该站点确实有效,但是我正在处理的 github 站点是专有的,因此外部站点实际上看不到我的内部 .dot 文件.你遇到过类似的事情吗?
-
基本上它是一些我可以安装在 github 存储库中的软件,它可以完成 Grazivo 的工作(但现在也可以使用你的 m4 预处理器!)