你能在GraphViz中构建可重用的样式吗?

Ste*_*tad 23 flowchart graphviz

我正在使用graphviz来创建流程图.我每次都通过设置节点和边缘属性来更改样式:

node[shape="box", 
     style="filled, rounded", 
     fillcolor=lightyellow, 
     fontname="Verdana", 
     fontsize=9, 
     penwidth=.5, 
     color="gray83"]
   start, end;
Run Code Online (Sandbox Code Playgroud)

将这个和其他类似的声明包括在平行四边形,矩形,菱形等中有点痛苦.

我希望能够引用可重复使用的样式文档,而不是复制和粘贴到每个.dot文件中.

有没有标准的方法来做到这一点?我可以构建一个shell脚本或python脚本来为我做这个,但似乎功能应该已经存在.

Jon*_*ice 33

"有时答案是'不'."

所以,没有.GraphViz缺乏像Word Word和LibreOffice这样的文字处理器中所见的"命名样式"的概念,缺乏HTML和CSS的风格"类"概念.它的格式属性更原始,在许多情况下,必须明确说明.

您可以设置一些默认值,如在其有限状态机示例中:

node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
node [shape = circle];
Run Code Online (Sandbox Code Playgroud)

在这里,您将默认为圆形(最后定义的形状),并显式调用先前在先前默认值(doublecircle)下声明的少数节点.这对于某些设计来说是方便的,但它需要很好的预先计划(例如,订单项被声明).您有时可以使用该subgraph功能来帮助按组组织默认值,如此Stack Overflow应答所示.

但是默认值对我们这些习惯于表达简单类型机制的人来说是一种小小的安慰.查看文档的其余部分可以确认,虽然您可以将一些HTML样式元素用于文本,例如,它们仅限于HTML标记,例如<b><i>.这是大约2001年的原始HTML样式,在优质CSS传播之前.

也不要被stylesheet属性所欺骗; 它仅适用于SVG输出,并且令人失望地比它最初看起来更不普遍和有价值.

所以,长话短说,"不." GraphViz没有内置的可重用样式元素.如果您需要,则必须使用程序,宏前导或类似程序单独构建它.抱歉!

  • 这个答案值得赞扬,尽管它压倒了我所有的希望和梦想.谢谢. (13认同)

Rob*_*ina 8

是的,它确实。

在节点或边中使用 class 属性。使用图表中的样式表属性(或在 CLI 中传递 -Gstylesheet=whatever.css。

样式表是普通的 CSS。类就像在 HTML 中一样。

您确实需要最新的graphviz才能使其工作。

例子:

https://ralsina.gitlab.io/boxes-book/part3/git_3.svg

如果您查看源代码,您会看到它加载了包含所有样式的https://ralsina.gitlab.io/boxes-book/styles/forest.css

它适用于 SVG 输出(这是很好的输出;-)


tan*_*oal 5

(1) 可能有类似于答案的烦人的解决方法:

// define some nodes which shall have common style properties:
myNode1, myNode2, myNode3 [shape="box", style="filled, rounded", ...]

// now you can define custom style properties for each node, f.e. the labels
myNode1 [label="my fancy label for node 1"]
myNode2 [label="my fancy label for node 2"]

// you can then define another common style for other nodes:
myHexNode1, myHexNode2 [shape="hexagon", ...]

// now you can define custom style properties for each node, f.e. the lables
myHexNode1 [label="my hexnode 1 text"]
myHexNode2 [label="my hexnode 2 text"]

// and now the edges
myNode1 -> myHexNode1 -> myNode2 -> myHexNode2;
Run Code Online (Sandbox Code Playgroud)

(2) 通过对子图中的元素进行分组并在子图中本地定义样式属性,如本答案中所述。

(3)这里有一个非常好的功能请求,它已经描述了语法。不管怎样,目前没有人在做这件事,而且看起来不会很快开始。

最后,看起来像这样:

在此输入图像描述

  • 我没有那些。当我之前尝试时,Graphviz 似乎无法应对“myNode1,myNode2,myNode3”。 (2认同)

小智 5

是的,你可以,但不能单独使用 GraphViz。

如前所述,C 预处理器可用于创建一些非常好的模板。

点文件示例:

#define _STR(x) #x
#define STR(x) _STR(x)

#define STYLE1 shape="box",style="filled, rounded", fillcolor=lightyellow
#define _STYLE2_l(A,B) {{<ia>|<ib>}|A|B}
#define STYLE2(A,B) shape="record" label=STR(_STYLE2_l(A,B))

digraph Orthogonal {
    graph [rankdir=LR];

    a[STYLE1,label="a"];
    b[STYLE2(B1,B2)];
    c[STYLE1,label="c"];
    d[STYLE2(D1,D2)];

    a->b:ia;
    c->d:ib;
    b->c;
    b->d:ia;
}
Run Code Online (Sandbox Code Playgroud)

已创建两个样式模板。“STYLE1”在预处理期间简单地替换为它的定义。“STYLE2”稍微复杂一些,显示了模板中参数/参数的使用。它是由几个宏构建的。

该文件可以使用以下方式呈现:

cpp graph_file.gv | dot -Tpng >out.png
Run Code Online (Sandbox Code Playgroud)

所有输出模式都应该有效。这是结果:

示例图