在Graphviz中创建直边

26

我想用Graphviz创建一个流程图(类似于Visio)。这是一个示例有向图:

digraph start_up {
node [style = rounded]; 
node [shape = rect] start end;
node [style = ""];
node [shape = diamond] "USB\nCommand\nArrived";
start -> "Initialize\nCode";
"Initialize\nCode" -> "USB\nCommand\nArrived";
"USB\nCommand\nArrived" -> "USB\nCommand\nArrived" [label="No" tailport=w headport=n];
"USB\nCommand\nArrived" -> "Has USB 3.0\nInterface Been\nSelected" [label = "Yes"];
 "Has USB 3.0\nInterface Been\nSelected" -> end
}

问题是当我在 Graphviz 中渲染它时,由 "USB\nCommand\nArrived" -> "USB\nCommand\nArrived" [label="No" tailport=w headport=n]; 创建的线条看起来很丑陋。我不介意使用曲线,但是这条线看起来变形了。您可以在此处查看 Graphviz 创建的内容:

有什么方法可以让这个看起来更好吗?


添加行“graph [splines = ortho]”-不是完整的答案,但可能有所帮助,还可以查看Graphviz文档中的属性splines。 - LOIS 16192
1个回答

41

我认为通过实例学习是最好的方法。只需阅读我的注释,如果有不清楚的地方,我很乐意回答。

顺便提一下: 虽然graphviz非常适合生成大型数据集的图形,但对于创建ER图、流程图和序列图等内容则不太理想。这是可能的,并且相对简单,但为了让某些东西正确呈现出来,你必须花费大量时间,这种时间通常是不合理的,因为你可以在更短的时间内使用所见即所得的GUI建模工具实现相同的效果。然而,你所花费的时间将有助于学习语言的语法和属性,这在需要可视化某些大型或复杂问题时非常有用(此时GUI建模工具将无用)。


digraph start_up {
    { 
/* fake levels (level0 -> level1) and support nodes
 *
 * graphviz to charts is what latex is to documents, 
 * sometimes you'll have to fight it.
 * This is typically done by defining levels and connection points that
 * don't really have anything to do with your graph, but are used to 
 * force the graph to appear in a certain way.
 */
        node [shape=none, /*label="."*/]; l1a; l2a; l3a; l4a; l5a; l6a;
        node [shape=square label="no"]; l20a; 
    }

    {   /* connectiong point for the no arrow above "arrived" */
        node [width=0 shape=point label=""];
        d1; no;
    }

    node [style = rounded]; 
    node [shape = rect] start end;
    node [style = ""];

    node [shape = diamond]; {
        node [label="USB\nCommand\nArrived"]; arrived; 
        node [label="Has USB 3.0\nInterface Been\nSelected"]; selected;
        node [label="Initialize\nCode"]; init;
    }

    start -> init; 
    /*init -> arrived; */
    init -> d1 [arrowhead=none]; 
            d1 -> arrived;

/* 
 * tricky part:
 * since nodes in a digrap go either from top to bottom or left to right, we 
 * can usually not connect (->) two nodes and have them appear on the same 
 * level unless the connection is specified within a block that has the 
 * parameter `rank' set to `same'
 */
            l20a->no [arrowhead=none];

    {   rank=same; no -> arrived [dir=back arrowtail=none]; }
    {   rank=same; l20a -> d1; }

    /*arrived       -> arrived;*/ /*  [label="No" tailport=w headport=n]; */
    arrived     -> selected [label = "Yes"];
    selected    -> end


    /* just to demonstrate */
    l1a-> l2a-> l3a-> l4a-> l5a-> l6a;
}

Solution proposal


4
顺便提一下,plantUML非常适合创建和代码相关的图表,并且它基于graphviz。 - Ярослав Рахматуллин
让PlantUML绘制复杂的UML部署图,使用正交边缘等方式使其美观起来是非常困难的。 - Alexander Ites
我理解你的回答是建议始终使用代理/虚拟节点(最好也是不可见的),包括一个简单链式有向图设置级别,然后执行类似于网格布局的操作,依赖于代理链设置的级别,并使用rank=same链接实际的图列? - Alexander Ites
@AlexanderItes 是的。我不知道2012年的网格布局。这个解决方案并不完美,而且相对复杂。你可能有什么想法。我非常想看到一个更简单或更直接的解决方案! - Ярослав Рахматуллин

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接