graphviz是一个由AT&T开源的c语言包,使用dot语言(一种DSL语言)来可视化程序的结构、流程、关系等。

graphviz有2部分构成:

  • Dot语言文件
  • 一组可以生成和/或处理DOT文件的工具

    命令

    | 命令 | 说明 | | —- | —- | | dot | 一个用来将生成的图形转换成多种输出格式的命令行工具。其输出格式包括PostScript,PDF,SVG,PNG,含注解的文本等等。 | | neato | 用于sprint model的生成(在Mac OS版本中称为energy minimized)。 | | twopi | 用于放射状图形的生成 | | circo | 用于圆形图形的生成。 | | fdp | 另一个用于生成无向图的工具。 | | dotty | 一个用于可视化与修改图形的图形用户界面程序。 | | lefty | 一个可编程的(使用一种被EZ影响的语言[4])控件,它可以显示DOT图形,并允许用户用鼠标在图上执行操作。Lefty可以作为MVC模型的使用图形的GUI程序中的视图部分。 |

dot语言

DOT语言是一种文本图形描述语言它提供了一种简单的描述图形的方法,并且可以为人类和计算机程序所理解。DOT语言文件通常是具有.gv或是.dot的文件扩展名。很多程序都可以处理DOT文件。

注释

//# 注释单行, /* */多行注释。

节点定义

通过 [ ]来定义节点属性

无属性节点(按默认属性来渲染)

  1. graph demo {
  2. foo1;
  3. foo2;
  4. bar1; bar2;
  5. }

graphviz - 图1

有属性节点:

  1. graph demo {
  2. foo1[label="foo1-name" shape="box"];
  3. foo2[label="foo2-name" shape="ellipse"];
  4. }

graphviz - 图2

追加定义属性节点

通过node关键字追加属性,来影响接下来定义的节点

  1. graph demo {
  2. foo1; foo2; foo3;
  3. node [shape=box]; bar1; bar2; bar3;
  4. node [color="#FF6347"]; baz1; baz2; baz3;
  5. }

graphviz - 图3

划分作用域定义属性节点

通过{ } 划分独立作用域

  1. graph demo {
  2. foo1; foo2; foo3;
  3. {node [shape=box, label=bar]; bar1; bar2; bar3;} //只影响本区域内的节点
  4. node [color="#FF6347"]; baz1; baz2; baz3;
  5. }

graphviz - 图4

节点之间关系定义

通过 -- -> 来定义节点之间的关系,也称为“边”, 通过 [ ] 定义边的属性

一一关联

  1. graph demo {
  2. foo1;
  3. foo2;
  4. foo3;
  5. foo1 -- foo2[label="关联", dir="both"];
  6. foo2 -- foo3;
  7. foo3 -- foo1;
  8. }

graphviz - 图5

批量关联

  1. graph demo {
  2. foo1;
  3. foo2;
  4. foo3;
  5. foo1 -- {foo2 foo3}[label="关联", dir="both"];
  6. }

graphviz - 图6``` graph demo { foo1; foo2; foo3; foo4;

  1. {foo1 foo4} -- {foo2 foo3}[label="关联", dir="both"];

}

  1. ![](https://cdn.nlark.com/yuque/__graphviz/4b93f895f2426b898c5f14a5a913fd9c.svg#lake_card_v2=eyJ0eXBlIjoiZ3JhcGh2aXoiLCJjb2RlIjoiZ3JhcGggZGVtbyB7XG5cdGZvbzE7XG5cdGZvbzI7XG5cdGZvbzM7XG5cdGZvbzQ7XG5cdFxuXHR7Zm9vMSBmb280fSAtLSB7Zm9vMiBmb28zfVtsYWJlbD1cIuWFs-iBlFwiLCBkaXI9XCJib3RoXCJdO1xufSIsInVybCI6Imh0dHBzOi8vY2RuLm5sYXJrLmNvbS95dXF1ZS9fX2dyYXBodml6LzRiOTNmODk1ZjI0MjZiODk4YzVmMTRhNWE5MTNmZDljLnN2ZyIsImlkIjoiTDlLWkkiLCJtYXJnaW4iOnsidG9wIjp0cnVlLCJib3R0b20iOnRydWV9LCJjYXJkIjoiZGlhZ3JhbSJ9)<a name="Nj8B3"></a>
  2. ### 常用属性
  3. <a name="QHPUK"></a>
  4. #### 全局属性
  5. | 属性名 | 默认值 | 说明 |
  6. | --- | --- | --- |
  7. | label | | 图片标签,如上面`示例` |
  8. | bgcolor | | 背景颜色,颜色文档[点此](http://www.graphviz.org/content/color-names) |
  9. | fontcolor | black | 字体颜色,定义上面`示例`<br />的颜色 |
  10. | fontname | Times-Roman | 字体 |
  11. | fontsize | 14 | 字体大小 |
  12. | rank | | 子图等级限制, same,min,max,source,sink |
  13. | rankdir | TB | 排序方向,LR(left to right) or TB(top to bottom) |
  14. | compound | false | If true, allow edges between clusters. 配合 lhead ltail 使用 |
  15. <a name="tGQ61"></a>
  16. #### 节点属性
  17. | 属性名 | 默认值 | 说明 |
  18. | --- | --- | --- |
  19. | label | node name | 节点显示内容 |
  20. | color | black | node边框颜色 |
  21. | fontcolor | black | 字体颜色 |
  22. | fillcolor | | 背景色 |
  23. | fontname | Times-Roman | 字体 |
  24. | fontsize | 14 | 字体大小 |
  25. | shape | ellipse | 形状,boxellipsecirclediamondplaintextpointtriangleinvtriangle |
  26. | style | | 图形样式,eg. bolddasheddottedfilled |
  27. | image | | 背景图片地址 |
  28. shape 参考

digraph demo { bgcolor=”floralwhite” “box”[shape=box] “polygon”[shape=polygon,sides=7] “ellipse”[shape=ellipse] “circle”[shape=circle] “point”[shape=point] “triangle”[shape=triangle] “invtriangle”[shape=invtriangle] “plaintext”[shape=plaintext] “diamond”[shape=diamond] }

  1. ![](https://cdn.nlark.com/yuque/__graphviz/5b186dc415eef4ca55d35686b8595785.svg#lake_card_v2=eyJ0eXBlIjoiZ3JhcGh2aXoiLCJjb2RlIjoiZGlncmFwaCBkZW1vIHtcbiAgICBiZ2NvbG9yPVwiZmxvcmFsd2hpdGVcIlxuICAgIFwiYm94XCJbc2hhcGU9Ym94XVxuICAgIFwicG9seWdvblwiW3NoYXBlPXBvbHlnb24sc2lkZXM9N10gXG4gICAgXCJlbGxpcHNlXCJbc2hhcGU9ZWxsaXBzZV1cbiAgICBcImNpcmNsZVwiW3NoYXBlPWNpcmNsZV1cbiAgICBcInBvaW50XCJbc2hhcGU9cG9pbnRdXG4gICAgXCJ0cmlhbmdsZVwiW3NoYXBlPXRyaWFuZ2xlXVxuICAgIFwiaW52dHJpYW5nbGVcIltzaGFwZT1pbnZ0cmlhbmdsZV1cbiAgICBcInBsYWludGV4dFwiW3NoYXBlPXBsYWludGV4dF1cbiAgICBcImRpYW1vbmRcIltzaGFwZT1kaWFtb25kXVxufSIsInVybCI6Imh0dHBzOi8vY2RuLm5sYXJrLmNvbS95dXF1ZS9fX2dyYXBodml6LzViMTg2ZGM0MTVlZWY0Y2E1NWQzNTY4NmI4NTk1Nzg1LnN2ZyIsImlkIjoiRHYxZEoiLCJtYXJnaW4iOnsidG9wIjp0cnVlLCJib3R0b20iOnRydWV9LCJoZWlnaHQiOjgzLCJjYXJkIjoiZGlhZ3JhbSJ9)<a name="FZ6JH"></a>
  2. #### 边属性
  3. | 属性名 | 默认值 | 说明 |
  4. | --- | --- | --- |
  5. | label | | 描述关系 |
  6. | color | black | 箭头颜色 |
  7. | fontcolor | black | 关系文字颜色 |
  8. | dir | forward | 设置方向:forward,back,both,none |
  9. | arrowhead | normal | 箭头头部形状。boxcrowdiamonddotnonenormalvee。箭头文档[点此](http://www.graphviz.org/content/arrow-shapes) |
  10. | arrowtail | | 箭头尾部形状 |
  11. | arrowsize | 1.0 | 箭头大小 |
  12. | style | | 图形样式,eg. bolddasheddottedfilled |
  13. | lhead | | compound true时,lhead用于指定边指向的cluster |
  14. | ltail | | ltail类似 |
  15. arrowhead 参考

digraph demo { bgcolor=”floralwhite” rankdir=LR

  1. "box"->"crow"[arrowhead=box]
  2. "crow"->"curve"[arrowhead=crow]
  3. "curve"->"diamond"[arrowhead=curve]
  4. "diamond"->"dot"[arrowhead=diamond]
  5. "dot"->"inv"[arrowhead=dot]
  6. "inv"->"none"[arrowhead=inv]
  7. "none"->"normal"[arrowhead=none]
  8. "normal"->"tee"[arrowhead=normal]
  9. "tee"->"vee"[arrowhead=tee]
  10. "vee"->"box"[arrowhead=vee]
  11. #来个高级的用法
  12. a->b[arrowhead=lcrowortee]

}

  1. ![](https://cdn.nlark.com/yuque/__graphviz/858ba105484a83e57d36b486583b841a.svg#lake_card_v2=eyJ0eXBlIjoiZ3JhcGh2aXoiLCJjb2RlIjoiZGlncmFwaCBkZW1vIHtcbiAgICBiZ2NvbG9yPVwiZmxvcmFsd2hpdGVcIlxuICAgIHJhbmtkaXI9TFJcblxuICAgIFwiYm94XCItPlwiY3Jvd1wiW2Fycm93aGVhZD1ib3hdXG4gICAgXCJjcm93XCItPlwiY3VydmVcIlthcnJvd2hlYWQ9Y3Jvd11cbiAgICBcImN1cnZlXCItPlwiZGlhbW9uZFwiW2Fycm93aGVhZD1jdXJ2ZV1cbiAgICBcImRpYW1vbmRcIi0-XCJkb3RcIlthcnJvd2hlYWQ9ZGlhbW9uZF1cbiAgICBcImRvdFwiLT5cImludlwiW2Fycm93aGVhZD1kb3RdXG4gICAgXCJpbnZcIi0-XCJub25lXCJbYXJyb3doZWFkPWludl1cbiAgICBcIm5vbmVcIi0-XCJub3JtYWxcIlthcnJvd2hlYWQ9bm9uZV1cbiAgICBcIm5vcm1hbFwiLT5cInRlZVwiW2Fycm93aGVhZD1ub3JtYWxdXG4gICAgXCJ0ZWVcIi0-XCJ2ZWVcIlthcnJvd2hlYWQ9dGVlXVxuICAgIFwidmVlXCItPlwiYm94XCJbYXJyb3doZWFkPXZlZV1cblxuICAgICPmnaXkuKrpq5jnuqfnmoTnlKjms5VcbiAgICBhLT5iW2Fycm93aGVhZD1sY3Jvd29ydGVlXVxufSIsInVybCI6Imh0dHBzOi8vY2RuLm5sYXJrLmNvbS95dXF1ZS9fX2dyYXBodml6Lzg1OGJhMTA1NDg0YTgzZTU3ZDM2YjQ4NjU4M2I4NDFhLnN2ZyIsImlkIjoiRm51anYiLCJtYXJnaW4iOnsidG9wIjp0cnVlLCJib3R0b20iOnRydWV9LCJjYXJkIjoiZGlhZ3JhbSJ9)<a name="FrQwE"></a>
  2. ### 示例
  3. <a name="4yvtz"></a>
  4. #### 子图
  5. 一个图可以包含多个子图,以及子图也可以嵌套子图。子图的名字须为`cluster*`,否则就直接当节点渲染了。

digraph demo { bgcolor=”beige”

  1. subgraph cluster_husband {
  2. node[color="grey"]
  3. {"爸爸", "妈妈"} -> "我"
  4. }
  5. subgraph cluster_wife {
  6. {"岳父", "岳母"} -> "老婆"
  7. }
  8. "我" -> "老婆"[label="夫妻", dir="both"]
  9. {rank=same; "我", "老婆"}

}

  1. ![](https://cdn.nlark.com/yuque/__graphviz/7aab792bce5a68e41d8998b6f0ff796f.svg#lake_card_v2=eyJ0eXBlIjoiZ3JhcGh2aXoiLCJjb2RlIjoiZGlncmFwaCBkZW1vIHtcbiAgICBiZ2NvbG9yPVwiYmVpZ2VcIlxuXG4gICAgc3ViZ3JhcGggY2x1c3Rlcl9odXNiYW5kIHtcbiAgICAgICAgbm9kZVtjb2xvcj1cImdyZXlcIl1cbiAgICAgICAge1wi54i454i4XCIsIFwi5aaI5aaIXCJ9IC0-IFwi5oiRXCJcbiAgICB9XG5cbiAgICAgc3ViZ3JhcGggY2x1c3Rlcl93aWZlIHtcbiAgICAgICAgIHtcIuWys-eItlwiLCBcIuWys-avjVwifSAtPiBcIuiAgeWphlwiXG4gICAgIH1cblxuICAgICBcIuaIkVwiIC0-IFwi6ICB5amGXCJbbGFiZWw9XCLlpKvlprtcIiwgZGlyPVwiYm90aFwiXVxuICAgICB7cmFuaz1zYW1lOyBcIuaIkVwiLCBcIuiAgeWphlwifVxufSIsInVybCI6Imh0dHBzOi8vY2RuLm5sYXJrLmNvbS95dXF1ZS9fX2dyYXBodml6LzdhYWI3OTJiY2U1YTY4ZTQxZDg5OThiNmYwZmY3OTZmLnN2ZyIsImlkIjoib3ZCRnIiLCJtYXJnaW4iOnsidG9wIjp0cnVlLCJib3R0b20iOnRydWV9LCJjYXJkIjoiZGlhZ3JhbSJ9)<a name="rFwJt"></a>
  2. #### 二叉树
  3. | 隔开的串会在绘制出来的节点中展现为一条分隔符,用 <> 括起来的串称为锚点。

digraph demo { bgcolor=”beige” node [shape=”record”, height=.1] node0[label=” | G | “] node1[label=” | E | “] node2[label=” | B | “] node0:f0 -> node1:f1 node0:f2 -> node2:f1 }

  1. ![](https://cdn.nlark.com/yuque/__puml/f932d2671119c1831f3e87d1d1496328.svg#lake_card_v2=eyJ0eXBlIjoicHVtbCIsImNvZGUiOiJkaWdyYXBoIGRlbW8ge1xuICAgIGJnY29sb3I9XCJiZWlnZVwiXG4gICAgbm9kZSBbc2hhcGU9XCJyZWNvcmRcIiwgaGVpZ2h0PS4xXVxuICAgIG5vZGUwW2xhYmVsPVwiPGYwPiB8IDxmMT4gRyB8IDxmMj5cIl1cbiAgICBub2RlMVtsYWJlbD1cIjxmMD4gfCA8ZjE-IEUgfCA8ZjI-XCJdXG4gICAgbm9kZTJbbGFiZWw9XCI8ZjA-IHwgPGYxPiBCIHwgPGYyPlwiXVxuICAgIG5vZGUwOmYwIC0-IG5vZGUxOmYxXG4gICAgbm9kZTA6ZjIgLT4gbm9kZTI6ZjFcbn0iLCJ1cmwiOiJodHRwczovL2Nkbi5ubGFyay5jb20veXVxdWUvX19wdW1sL2Y5MzJkMjY3MTExOWMxODMxZjNlODdkMWQxNDk2MzI4LnN2ZyIsImlkIjoieVZXVlAiLCJtYXJnaW4iOnsidG9wIjp0cnVlLCJib3R0b20iOnRydWV9LCJjYXJkIjoiZGlhZ3JhbSJ9)记录形式的节点也可以是竖形排列的。与横向排列的记录的不同只是label的形式不同,label中内容使用 {} 包围则是竖形排列的。

digraph demo { bgcolor=”beige” node [shape=”record”] a [label=”{a | b | c}”] }

  1. ![](https://cdn.nlark.com/yuque/__puml/2912cc2ae3fef9389b7c0188dfc22e61.svg#lake_card_v2=eyJ0eXBlIjoicHVtbCIsImNvZGUiOiJkaWdyYXBoIGRlbW8ge1xuICAgIGJnY29sb3I9XCJiZWlnZVwiXG4gICAgbm9kZSBbc2hhcGU9XCJyZWNvcmRcIl1cbiAgICBhIFtsYWJlbD1cInthIHwgYiB8IGN9XCJdXG59IiwidXJsIjoiaHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlL19fcHVtbC8yOTEyY2MyYWUzZmVmOTM4OWI3YzAxODhkZmMyMmU2MS5zdmciLCJpZCI6Ik9mTDJtIiwibWFyZ2luIjp7InRvcCI6dHJ1ZSwiYm90dG9tIjp0cnVlfSwiY2FyZCI6ImRpYWdyYW0ifQ==)<a name="opnxR"></a>
  2. #### 直接指向子图
  3. 边直接指向cluster,需要设置 compound true,并配合 lhead ltail 来实现。

digraph demo { bgcolor=”beige” compound=true subgraph cluster0 { a } subgraph cluster1 { b } a -> b [lhead=cluster1]; } ``` graphviz - 图7