【问题标题】:Can you build reusable styles in GraphViz?你能在 GraphViz 中构建可重用的样式吗?
【发布时间】:2015-01-31 11:16:19
【问题描述】:

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

node[shape="box", 
     style="filled, rounded", 
     fillcolor=lightyellow, 
     fontname="Verdana", 
     fontsize=9, 
     penwidth=.5, 
     color="gray83"]
   start, end;

为平行四边形、矩形、菱形等包含这个和其他类似的声明有点痛苦。

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

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

【问题讨论】:

    标签: graphviz flowchart


    【解决方案1】:

    “有时答案是‘不’。”

    所以,。 GraphViz 缺少 Microsoft Word 和 LibreOffice 等文字处理器中的“命名样式”概念,也缺少 HTML 和 CSS 中的样式“类”概念。它的格式化属性更原始,在许多情况下,必须明确说明。

    你可以设置一些默认值,如finite state machine example:

    node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
    node [shape = circle];
    

    在这里,您可以默认为圆形(定义的最后一个形状),并显式调用之前在先前默认值 (doublecircle) 下声明的少数节点。这对某些设计来说是一种便利,但它需要很好的预先计划(例如,订单项的声明)。您有时可以使用subgraph 功能来帮助按组组织默认设置,as this Stack Overflow answer shows

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

    也不要被stylesheet 属性所迷惑;它仅用于 SVG 输出,令人失望的是,它不像最初看起来那样通用和有价值。

    所以,长话短说,“不”。 GraphViz 没有内置的可重用样式元素。如果需要,则必须使用程序、宏预处理器等单独构建它。对不起!

    【讨论】:

      【解决方案2】:

      是的。

      在节点或边中使用类属性。 在图表中使用样式表属性(或在 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 输出(这是很好的输出 ;-)

      【讨论】:

      • 如图所示,链接似乎已过期,但找不到样式表,因此您的示例似乎不起作用
      【解决方案3】:

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

      // 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;
      

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

      (3) 有一个非常好的功能请求here 已经描述了语法。无论如何,目前没有人在研究它,而且看起来不会很快开始。

      最后是这样的:

      【讨论】:

      • 我认为这行不通。我收到第 2 行中以逗号分隔的节点列表的语法错误(至少在 WebGraphViz 上)。
      • @O.R.Mapper:只需删除第 2 行和第 9 行中的 , ...。这些只是您需要的更多属性的占位符。
      • 我没有这些。我之前尝试过时,Graphviz 似乎无法应对myNode1, myNode2, myNode3
      • 你是对的。在 WebGraphViz 上它不起作用。在我的电脑上,它适用于 graphViz 2.40.1-2。正如预期的那样,我得到了圆形节点和六边形节点。现在添加生成的图像。
      【解决方案4】:

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

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

      DOT 文件示例:

      #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;
      }
      

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

      文件可以使用:

      cpp graph_file.gv | dot -Tpng >out.png
      

      所有输出模式都应该工作。结果如下:

      【讨论】:

      • 虽然我同意这是一个很好的解决方案。但我不禁想知道这是否会在某处造成问题。尤其是当 cpp 手册警告人们不要这样做时。The C preprocessor is intended to be used only with C, C++, and Objective-C source code. In the past, it has been abused as a general text processor. It will choke on input which does not obey C's lexical rules. For example, apostrophes will be interpreted as the beginning of character constants, and cause errors. 我认为基于 m4 的答案,如 this 会更好。
      【解决方案5】:

      不直接在 Graphviz 中,但 Excel to Grapvhiz Relationship Visualizer 可以根据 Sourceforge 上的功能列表执行此操作:

      ...
      用于可视化定义节点、边缘和集群属性的样式编辑器
      按名称保存样式定义以供重复使用,并包括预定义的流程图形状
      ...

      在同一个 Sourceforge 页面上,有一张显示此功能的屏幕截图:

      【讨论】:

        【解决方案6】:

        您可以使用 c 预处理器和#include

        一些 c 预处理器将输出将生成以 # 开头的行以指示原始行号,但 GraphViz 可以接受这些。 来自 GraphViz 文档“DOT 语言”: ...此外,以 '#' 字符开头的行被视为 C 预处理器的行输出(例如, # 34 表示第 34 行)并被丢弃。

        【讨论】:

          猜你喜欢
          • 2011-07-09
          • 1970-01-01
          • 2011-05-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多