Graphviz概述
Graphviz
是一个由AT&T实验室启动的使用DOT语言来绘制关系图/流程图的开源工具包。
DOT
语言是一种文本图形描述语言,它提供了一种简单的描述图形的方法。
使用Graphviz,我们只需要将精力集中在逻辑设计上,而不需要花费大量时间在图形布局的调整上,图形绘制布局都由工具引擎来搞定。也因此,需要精确定位的图形就不适合用Graphviz来绘制了。另外,文本代码绘制图形的方式也便于版本管理。
另外,plantuml
也包含了dot语法,并且还具有更多的功能,或许你可以尝试一下。
Graphviz工具
工具善其事,必先利其器。原谅我是一个工具痴 :-)
要想使用graphviz,首先需要上
官网下载graphviz并安装。安装之后就可以使用graphviz自带的编辑器
gvedit
来编写dot代码来绘制图形了。快捷键
F5
来预览生成的图片,
Shift+F5
打开对话框并点击ok就可以生成指定类型的图片文件。
但是
graphviz自带的gvedit编辑器那是
非常非常的难用。怎么办呢?经过四处寻找和妥协,最终找到了windows平台下的还挺好用的工具,此工具不仅具有dot代码高亮、代码提示,还阔以预览生成的图片,只是暂时还不能导出图片。该工具就是github出品的代码编辑器
Atom,另外需要安装两个插件:
language-dot和
graphviz-preview。
使用Atom来编写和预览图片,最后使用gvedit来导出图片。看起来还不错的样子。
- windows中安装好graphviz之后,最好配置一下
PATH
环境变量。
- Atom的language-dot插件中的代码提示模板(snippet)可能不能满足你的需求,不过你可以自己添加和修改。这里有我自己修改的代码模板。
中文乱码解决
若渲染出的图片中出现乱码,检查两项:
- 文件编码需要使用utf-8。
- windows平台下需要在dot源码中指定字体名称。具体如下:
// 影响图片级别的字体
graph [fontname="宋体"];
// 影响节点中的文字字体
node [fontname="宋体"];
// 影响箭头或线条上的文字字体
edge [fontname="宋体"];
|
DOT基本语法
DOT语法相对简单和松散,没有特别的格式要求,也没有复杂的运算符和结构。你可以查看
官方文档以了解更多,其实安装完graphviz后,其安装目录中就有文档了,位置如下:
GRAPHVIZ_HOME/share/graphviz/doc/html/index.html
|
概述
- DOT中使用图(
digraph
/graph
)、节点(node
)和边(edge
)来描述关系图/流程图。
- DOT的注释风格和C类似(
//
用于单行注释,/* */
用于多行注释)。
图
DOT可以描述
有向图(使用
digraph
声明)和
无向图(使用
graph
声明)两种图。图由
{}
中包含的节点和边构成。
在图的开头使用
graph []
对图进行设置,如:
graph [bgcolor="gray"]
将图背景色设置为灰色。属性设置语句也可以不包含在
graph []
中而直接使用。
子图(使用
subgraph
声明)可以进行和“父图”类似的设置,唯一注意的是子图必须以
cluster
做为名称的前缀。
节点
DOT中,
节点可以不用声明直接使用,但如果需要设置节点的属性,则需声明节点并在声明处设置属性然后再使用。每个节点首次出现的名称做为该节点的唯一标识。
node []
用于设置节点默认属性(对设置位置之后的点有效),在节点后面用
[]
设置单独一个点的属性。
边
DOT中有
有向边(使用
->
表示)和
无向边(使用
--
表示)两种,有向边用于有向图,无向边用于无向图,不可混用。
和节点类似的,用
edge []
设置边默认属性,在边之后用
[]
设置单独一条边的属性。对于有向边,还可以设置边的起点/终点的位置(用n、e、s、w或它们的组合表示位置)。
常用属性
对于各种结构的
通用属性如下:
属性名称 |
默认值 |
含义 |
color |
black |
颜色,颜色设置支持形如red 和#FF0000 两种形式 |
fontcolor |
black |
文字颜色 |
fontname |
Times-Roman |
字体 |
fontsize |
14 |
文字大小 |
label |
|
显示的标签,支持’\n’换行,对于节点默认为节点名称 |
penwidth |
1.0 |
线条宽度 |
style |
|
样式 |
常用
图属性如下:
属性名称 |
默认值 |
含义 |
bgcolor |
|
背景颜色 |
concentrate |
false |
让多条边有公共部分 |
nodesep |
.25 |
节点之间的间隔(英寸) |
peripheries |
1 |
边界数 |
rank |
|
same,min,source, max,sink,设置多个节点顺序 |
rankdir |
TB |
排序方向 |
ranksep |
.75 |
间隔 |
size |
|
图的大小(英寸) |
labelloc |
|
调整图或子图的标签的上下位置 |
labeljust |
|
调整图或子图的标签的左右位置 |
compound |
false |
If true, allow edges between clusters. 配合lhead 和ltail 使用 |
常用
节点属性如下:
属性名称 |
默认值 |
含义 |
shape |
ellipse |
形状 |
sides |
4 |
当shape=polygon时的边数 |
fillcolor |
lightgrey/black |
填充颜色 |
fixedsize |
false |
标签是否影响节点的大小 |
常用
边属性如下:
属性名称 |
默认值 |
含义 |
arrowhead |
normal |
箭头头部形状 |
arrowsize |
1.0 |
箭头大小 |
arrowtail |
normal |
箭头尾部形状 |
constraint |
true |
是否根据边来影响节点的排序 |
decorate |
|
设置之后会用一条线来连接edge和label |
dir |
forward |
设置方向:forward,back,both,none |
headclip |
true |
是否到边界为止 |
tailclip |
true |
与headclip类似 |
headlabel |
|
边的头部显示的标签 |
taillabel |
|
边的尾部显示的标签 |
lhead |
|
当compound 为true时,lhead用于指定边指向的cluster |
ltail |
|
与ltail类似 |
简单示例
dot代码:
digraph simple_demo {
// 设置图、节点和边的默认属性
graph [label="simple demo", bgcolor="#EEEEEE"];
node [style="filled", fillcolor="#AAAAAA"];
edge [style="dashed", arrowsize=0.6];
// 节点和边
{a, b} -> {c, d};
}
|
图片效果:
高级用法
绘制二叉树
绘制二叉树使用到了记录形式的节点,代码如下:
digraph g {
node [shape="record", height=.1];
node0[label="<f0> |<f1> G|<f2>"];
node1[label="<f0> |<f1> E|<f2>"];
node2[label="<f0> |<f1> B|<f2>"];
node0:f0 -> node1:f1;
node0:f2 -> node2:f1;
}
|
其中,用
|
隔开的串会在绘制出来的节点中展现为一条分隔符,用
<>
括起来的串称为锚点。
效果如下:
竖排记录
记录形式的节点也可以是竖形排列的。与横向排列的记录的不同只是label的形式不同,label中内容使用
{}
包围则是竖形排列的。代码如下:
digraph g {
node [shape="record"];
a [label="{a | b | c}"];
}
|
效果如下:
自定义复杂节点
label还支持HTML格式的,这样你能想得到的大部分样子的节点都可以被自定义出来。代码如下:
digraph html {
abc [shape=none, margin=0, label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
<TR><TD ROWSPAN="3"><FONT COLOR="red">hello</FONT><BR/>world</TD>
<TD COLSPAN="3">b</TD>
<TD ROWSPAN="3" BGCOLOR="lightgrey">g</TD>
<TD ROWSPAN="3">h</TD>
</TR>
<TR><TD>c</TD>
<TD PORT="here">d</TD>
<TD>e</TD>
</TR>
<TR><TD COLSPAN="3">f</TD></TR>
</TABLE>>];
}
|
效果如下:
直接指向cluster
边直接指向cluster,需要设置
compound
为true,并配合
lhead
或
ltail
来实现。代码如下:
digraph G {
compound=true;
subgraph cluster0 {
a;
}
subgraph cluster1 {
b;
}
a -> b [lhead=cluster1];
}
|
效果如下:
简单的时序图
简单的时序图代码如下:
digraph g {
rankdir="LR";
{
rank="same";
a0 -> a1 -> a2;
}
{
rank="same";
b0 -> b1 -> b2;
}
a1 -> b1;
}
|
其中,
rankdir="LR"
表示,布局从左
L
到右
R
,每一个
rank="same"
的block中的所有节点都会在同一条线(横线或竖线)上。
效果如下:
以图片为节点
节点还可以使用图片,通过在节点中使用
image="image_path"
来设置图片。不过需要注意的是,在使用图片作为节点的时候,需要将本来的形状设置为
none
,并且将
label
置为空字符串,避免出现文字对图片的干扰。
Graphviz编程库
没有评论:
发表评论