陈颂光
全栈工程师,能够独立开发从解释器到网站和桌面/移动端应用的各类软件。
关注我的 GitHub

用Graphviz自动布局各种图

dot是一种高层的画图语言,用dot画图只用给出结点和边,就像图论中描述图一样,然后由程序自动对结点和边进行布局,不用像在低层的画图语言(如Troff与TeX常用的子语言)那样要具体到指定坐标。graphviz极大地节省了画图所需的时间,而且自动布局的效果往往比人手更好(特别是与我这种不会画画的人比)。如果能推广它,将鼓励人们更愿意用图表达思想,使世界更美好。关于dot的更多信息见http://www.graphviz.org/

命令用法

在用dot语言写好图的描述后,就可以调用其中一个graphviz程序生成图片:

dot [options] [files]
neato [options] [files]
twopi [options] [files]
circle [options] [files]
fdp [options] [files]
sfdp [options] [files]
patchwork [options] [files]

其中不同命令作于绘制不同风格的图:

命令 用于 例子
dot 有向图(分层地画) 例子
neato 无向图(基于弹簧模型) 例子
twopi 星形图(结点中心放到同心的一系列圆上,包括圆心) 例子
circo 环状的图 例子
fdp 无向图(基于力) 例子
patchwork 方形树 例子

可用选项包括:

选项 用途
-Tps 输出PostScript
-Tsvg 输出SVG
-Tfig 输出XFIG
-Tpng 输出PNG
-Tgif 输出GIF
-G键=值 设置默认图属性
-N键=值 设置默认结点属性
-E键=值 设置默认边属性
-O 自动生成输出文件名
-sf尺度 缩放输入默认72
-y 反转输入中的y坐标

http://viz-js.com/提供了在线试用。

语法

DOT语言的语法为:

     graph : [ 'strict' ] ('graph' | 'digraph') [ ID ] '{' stmt_list '}'
 stmt_list : [ stmt [ ';' ] stmt_list ]
      stmt : node_stmt
           | edge_stmt
           | attr_stmt
           | ID '=' ID
           | subgraph
 attr_stmt : ('graph' | 'node' | 'edge') attr_list
 attr_list : '[' [ a_list ] ']' [ attr_list ]
    a_list : ID '=' ID [ (';' | ',') ] [ a_list ]
 edge_stmt : (node_id | subgraph) edgeRHS [ attr_list ]
   edgeRHS : edgeop (node_id | subgraph) [ edgeRHS ]
 node_stmt : node_id [ attr_list ]
   node_id : ID [ port ]
      port : ':' ID [ ':' compass_pt ]
           | ':' compass_pt
  subgraph : [ 'subgraph' [ ID ] ] '{' stmt_list '}'
compass_pt : ('n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | 'c' | '_')
  • graph为起始符号,用于声明顶层的图,并决定它是否有向图,有strict表示不容许重边
  • node_stmt用于声明一些结点并设置属性
  • edge_stmt用于声明一些边(必要时也创建结点)并设置属性,其中edgeop--(对无向图)或->(对有向图)
  • attr_stmt用于声明图、结点和边的默认属性
  • subgraph用于声明子图,子图用于
    • 让其中结点和边尽可能聚在一起
    • 设立新的属性作用域
    • 简化声明,如{a b c}--{d e f},即给出了$K_{3,3}$图的9条边

ID可以为以下形式之一(在语义上一样,如不区分abc_2与”abc_2”,也不区分2.34与”2.34”):

  • 由字母([a-zA-Z\200-\377])、下划线和数字([0-9])组成,不由数字开始
  • 数值 [-]?(.[0-9]+|[0-9]+(.[0-9]*)?)
  • 双引号形式字符串,其中可用\"转义和反斜杠-换行转义,还可用+串接
  • <>包围的HTML代码,可多行

另外,可用C/C++风格注释或shell风格的注释。

以下是部分属性:

图属性

属性设置 含义
size=”x,y” 最大大小(英寸)
ratio=f 垂直夸大率浮点数或fill或compress或auto.
layout=engine 布局引擎(取代命令名和-K选项)
margin=f 边界空白
nodesep=f 最小结点间隔
ranksep=f 层间最小间隔
ordering=out 出边按文件中顺序
rankdir=LR或RL或BT 从左到右、从右到左还是从下到上画
rank=same或min或max 这子图中结点的层次
rotate=90 纸张方向为横向
center=n 非零表示居中
color=颜色 前景颜色
bgcolor=颜色 背景颜色
href=”url” 基URL
URL=”url” 同上
stylesheet=”file.css” 指定样式表(用于SVG)
splines=值 true则用样条曲线画边,polyline则用折线,ortho则用垂直或水平的折线,false或line则线段,dot默认true,其它默认false。
start=val 整数随机数发生器种子,默认PID或当前时间(用于neato)
epsilon=n 求解器的截断,默认0.1(用于neato)
root=ctr 指定中心,默认为离开叶子最远的其中一个顶点,没有叶子则随意。(用于twopi)
ranksep=val 环间的距离,默认0.75(用于twopi)
overlap=mode 若结点相交,mode为”false”时调整结点,mode为”scale”时放大布局,mode为”true”时容许相交(默认)(用于twopi)
root=nodename . Specifies the name of a node occurring in the root block. If the graph is disconnected, the root node attribute can be used to specify additional root blocks.(用于circo)
mindist=value 结点的最小间隔默认1.0.(用于circo)
K=val 理想结点间隔(用于fdp)
maxiter=val 最大迭代次数(用于fdp)
start=val 整数随机数发生器种子,默认PID或当前时间(用于fdp)

结点属性

属性设置 含义
height=d 最小高度
width=d 最小宽度
fixedsize=true 强制大小
shape=record或polygon或epsf或builtin_shape 形状,其中builtin_polygon可为plaintext、ellipse、oval、circle、egg、triangle、box、diamond、trapezium、parallelogram、house、hexagon、octagon、note、tab、box3d、component等等
label=text 指定文本,其中转义\n\l\r分别表示居中、左对齐、右对齐的换行,\N引用结点名,\G引用图名。 record形状的可有用{|}分隔的方块列表。也可用一些HTML风格标记
fontsize=n 字体大小
fontname=name 字体族
color=colorvalue 轮廓颜色
fillcolor=colorvalue 填充颜色(当style=filled),默认为轮廓颜色
fontcolor=colorvalue 文本颜色
style=filled或solid或dashed或dotted或bold或invis或Postscript代码 样式
href=”url” URL,其中可用转义如label,另\L引用label属性。(用于SVG、PostScript等等)
URL=”url” 同上
target=”target” 在哪个浏览器窗口打开,”_graphviz”表示尽可能重用,”“表示不指定,其中可用转义如href。(用于SVG等等)
tooltip=”tooltip” 文本提示(用于SVG等等),默认为label属性,其中可用转义如href。(用于SVG等等)
regular=n 非零时关于x、y轴均对称
peripheries=n 画出的边数
sides=n 边数,小于3表示椭圆(只用于polygon)
orientation=f 从垂直沿逆时针方向到首个顶点的角度
distortion=f 设置顶部的扩宽和底部的收窄,从 -1 到 +1的浮点数
skew=f 设置顶部的右偏移和底部的左偏移,从 -1 到 +1的浮点数
root=true或false 结点所在块作为布局生成树的根(只用于circo)
pin=val val为”true”时结点留在初始位置(只用于fdp)

其中颜色值可为”h,s,v”(三者均为0与1间的浮点数)、X11颜色名(如white、black、red、green、blue、yellow、magenta、cyan、burlywood)或”#rrggbb”。

边属性

属性设置 含义
minlen=n 边长倍数
weight=n 整数代价,大于1导致倾向缩短边
label=text 标签文本,其中,其中转义\n\l\r分别表示居中、左对齐、右对齐的换行,\T引用开始结点名,\H引用结束结点名,\G引用图名。
fontsize=n 标签的字体大小
fontname=name 标签的字体族名字
fontcolor=颜色 标签的文本颜色
style=solid或dashed或dotted或bold或invis 样式
color=颜色 颜色
color=用:分隔的颜色列表 各平行边的颜色
dir=forward、back、both、none 控制箭头方向
tailclip,headclip=false 禁用终点形状
href=”url” URL,其中可用转义如label,另\L引用label属性。(用于SVG、PostScript等等)
URL=”url” 同上
target=”target” 在哪个浏览器窗口打开,”“表示不指定,其中可用转义如href。(用于SVG等等)
tooltip=”tooltip” 文本提示(用于SVG等等),默认为label属性,其中可用转义如href。(用于SVG等等)
arrowhead,arrowtail=样式 none, normal, inv, dot, odot, invdot, invodot, tee, empty, invempty, open, halfopen, diamond, odiamond, box, obox, crow之一
headlabel,taillabel=端点标签 可用转义如href
headhref=”url”  
headURL=”url”  
headtarget=”headtarget”  
headtooltip=”tooltip”  
tailhref=”url”  
tailURL=”url”  
tailtarget=”tailtarget”  
tailtooltip=”tooltip”  
labeldistance 首尾标签与端点距离
labelangle 首尾标签与端点角度(反时针)
decorate 画出从边到标签的线
samehead 同终点的共用端点
sametail 同起点的共用端点
constraint=false 不赋层次
layer=id或id:id或”all” 活动层,空表示不可见
w=f 弹簧常数越大边长越接近理想值,默认1.0(用于neato)
len=f 理想边长,默认1.0(用于neato)
weight=f 权重越大边长越接近理想值,默认1.0。(用于fdp)
关键词 graphviz