使用Graphviz(dot命令)绘制流程图
安装Graphviz
在Graphviz官网下载各个操作系统的Graphviz.
安装后再将安装目录的graphviz\bin
加入环境变量PATH
里.
比如我的安装路径为C:\Program Files (x86)\Graphviz
, 我就在环境变量中的PATH
里添加C:\Program Files (x86)\Graphviz\bin
.
打开cmd
输入dot -V
, 若显示graphviz的版本即表示配置成功. 我这里显示的dot - graphviz version 2.38.0 (20140413.2041)
配置Graphviz编辑器
安装Graphviz时, 有些安装包会默认安装一个简易的编辑器gvedit, 可以实现简单的可视化. 但并没有代码补全等功能.
这里推荐使用vscoede配合插件(Graphviz (dot) language support for Visual Studio Code)进行编辑, 可以实现代码补全, 提示和实时的图像.
当然你也可以直接在cmd界面输出图像, dot -T[输出图像后缀名] [后缀为gv的文件名] -o [输出图像文件名]
图形类别
无向图
在最简单的应用中, DOT语言可以用来描述一张无向图. 无向图显示了对象间最简单的关系. 使用关键字graph
开始一张无向图的定义, 并用大括号包含要描述的节点. 双连字号(–)被用来描述节点间的关系. 另外, 一行的末尾需要加上分号(;).
1 | graph graphname { |
有向图
类似于无向图, DOT语言也可以用来描述一张有向图, 类似于流程图和树状图. 其语法与无向图相似, 但要在图的最开始使用关键字digraph
, 并用箭头(->)表示节点直接的关系.
1 | digraph graphname { |
子图
字体 subgraph
的作用主要有 3 个:
- 表示图的结构, 对节点和边进行分组.
- 提供一个单独的上下位文设置属性.
- 针对特定引擎使用特殊的布局. 比如下面的例子, 如果 subgraph 的名字以 cluster 开头, 所有属于这个子图的节点会用一个矩形和其他节点分开.
1 | digraph graphname{ |
属性
节点形状
节点的默认属性为 shape=ellipse, width=.75, height=.5
, 标签默认为节点名.
节点又分为基于多边形的节点和基于记录的节点.
基于多边形的节点
基于多边形的节点还有 box, polygon, oval, circle, point, egg, triangle, plaintext, plain, diamond, trapezium, parallelogram, house, pentagon, hexagon, septagon, octagon, doublecircle, doubleoctagon, tripleoctagon, invtriangle, invtrapezium,invhouse, Mdiamond, Msquare, Mcircle, rect, rectangle, square, star, none, underline, cylinder, note, tab, folder, box3d, component, promoter, cds, terminator, utr, primersite, restrictionsite, fivepoverhang, threepoverhang,noverhang, assembly, signature, insulator , ribosite, rnastab, proteasesite, proteinstab, rpromoter, rarrow, larrow, lpromoter
. 其中很大一部分形状都可以由属性sides
设置边的数目, 而设置regular=true
, 节点形状会强制规整, 如正三角形.
tips: 除非给定
fixedsize=true
, 不然节点的大小还是会根据实际情况(如标签长度等)而改变.
具体形状如下图:
基于记录的节点
基于记录的节点主要是shape=record
和shape=Mrecord
两种.
基于记录的节点的结构主要是由label
属性决定的, 基本结构如下例:
1 | digraph structs { |
其中name
为节点名; subname
为节点内次节点的标志, 主要用来作为边的起点或终点; |
用来分隔文本; {}
会使得括号内结构与外部方向相反.
举一个更详细的例子:
1 | digraph structs { |
想要了解更多, 可以参考 官方文档.
箭头形状
关于箭头形状, 这里就不详细讨论了, 详情可以参考 官方文档对箭头的说明.
节点和边的属性
节点和边的属性挺多的, 但是平常很少用到, 这里不详细展开了, 有兴趣可以参考 官方文档对节点和边属性的说明.
标签
之前已经提到过了, 节点默认的标签是节点名, 边默认是没有标签的, 事实上节点和边都可以使用label
属性来单独设置标签.
虽然看起来用name
来设置标签很方便, 但是很多时候我们会遇到重复的标签, 或者不能用于name
的字符, 这种时候就需要用到label
属性了.
label
属性支持逃逸字符, 同时, 也可以使用 labelloc
属性来指定标签的位置, 可选的位置有t
, 上部(top); b
, 底部(bottom). 还可以使用 labeljust
属性决定字符左对齐还是右对齐, 左对齐: l
; 右对齐: r
.
label
默认的字号是14, 字体为 Times-Roman, 黑色. 这些都可以通过 fontsize
, fontname
, fontcolor
进行修改.
节点只有一种标签, 而边有三种标签, 一种是在边头的headlabel
, 一种是在边尾的taillabel
, 还有在边中的label
.
1 | digraph{ |
除此之外, 标签还支持 html
语言, 例如:
1 | digraph html { |
颜色
布局
默认情况下图是从上到下布局的, rankdir
属性 设置图形布局的排列方向(全局只有一个生效). “TB”, “LR”, “BT”, “RL”, 分别对应于从上到下,从左到右,从下到上和从右到左绘制的有向图.
还可以通过设置rank
属性给节点排序, 最小等级是最顶部或最左侧, 最大等级是最底部或最右侧, 可选属性有:
- same: 所有节点都位于同一等级
- min source: 所有节点都位于最小等级上
- max sink: 所有节点都位于最大等级上.
例如:
1 | digraph example { |
进阶
自动生成 python UML图
Pyreverse工具就是基于Graphiviz的自动生成UML图的工具. pylint中集成了该工具.
通过命令pyreverse -ASmy -o gv test.py就可以在当前目录下生成UML类图文件.
- -o:指定输出的图形格式
- test.py: 指定要生成类图的源码文件, 也可以是目录
后记
总觉得自己教程写得挺烂的, 推荐一篇大神参考官方文档写的教程: Graphviz 画图的一些总结.
平常绘制流程图, 我还是推荐使用 draw.io.
……
虽然在最后说有点问题, 但我还是想说, mermaid其实也是挺好用的, 更美观一些, 不过二者优劣势还是挺明显的, 可以看情况选择使用哪一个.
参考文献
1. Emden R. Gansner and Eleftherios Koutsofios and Stephen North. Drawing graphs with dot. January 5, 2015.
2. lfyzjck. Graphviz 入门指南 - 知乎. 2017.
3. Graphviz 官方文档