Ubuntu下的Graphviz的基础使用方法
一、Graphviz介绍
graphviz是贝尔实验室开发的一个开源的工具包,它使用一个特定的DSL(领域特定语言):dot作为脚本语言,然后使用布局引擎来解析此脚本,并完成自动布局
1、什么是Graphviz
官网地址,https://www.graphviz.org/
Graphviz 是一款开源图形可视化软件。图形可视化是一种将结构信息表示为抽象图形和网络图的方法。它在网络、生物信息学、软件工程、数据库和网页设计、机器学习以及其他技术领域的可视化界面中有着重要的应用。
Graphviz 布局程序采用简单的文本语言描述图表,并将图表制作成有用的格式,如用于网页的图像和 SVG;用于其他文档的 PDF 或 Postscript;或在交互式图表浏览器中显示。Graphviz 有许多实用的具体图表功能,如颜色、字体、表格节点布局、线条样式、超链接和自定义形状等选项。
2、为什么需要Graphviz
支持图结构的可视化软件工具多得去,为什么需要Graphviz? 对于普通用户来说,当然可以百度搜索找到各类流程图
等各类软件,但是对于一个开发者来说,当我们在开发过程中,需要对我们的图数据结构,或某个流程等,做一个可视化,如何实现呢?市面上的软件一来过于重并不适用二次开发,二来并不开源他的文档定义你也无法基于它去输出或定制,于是Graphviz就有用武之地了;
开发过程中,我们可以根据需要生成一些开源的图结构
文件(*.dot
),然后使用Graphviz进行可视化查阅,或使用Graphviz进行格式转化,如把一个*.dot
生成*.svg
以用于web上预览
Graphviz支持几种布局引擎(即支持这读取这几种格式):
dot : 默认布局方式,主要用于有向图
neato : 主要用于无向图
twopi : 主要用于径向布局
circo : 圆环布局
fdp : 主要用于无向图
sfdp : 主要绘制较大的无向图
patchwork : 主要用于树哈希图(tree map)
说白了,Graphviz就是一个
图结构
可视化的一款软件,可以支持多种图文档的输入、输出;
这里查看官网支持的布局 https://graphviz.org/docs/layouts/
Graphviz支持输出的格式
pdf :
gif:
png :
jpeg : jpg有损压缩图片格式
bmp : 位图格式
svg : 矢量图,一般用与Web
ps : 矢量线图,多用于打印
二、Graphviz的安装及基本使用
1、下载及编译安装
下载源码graphviz-12.2.0
,点这里
# 解压
tar -zxvf graphviz-12.2.0.tar.gz
cd graphviz-12.2.0
# 编译及安装
./configure
sudo make
sudo make install
查看一下安装版本
$ dot --version
dot - graphviz version 12.2.0 (20241103.1931)
2、测试验证安装
先创建test.dot
的文件,dot的介绍见下文
$ touch test.dot
输入如下内容
digraph G{
main -> parse -> execute;
main -> init;
main -> cleanup;
execute -> make_string;
execute -> printf;
init -> make_string;
main -> printf;
execute -> compare;
}
将*.dot
解析导出*.svg
图片
$ dot -Kdot -Tsvg test.dot -o test.svg
上面的命令解析
-Kdot 采用dot布局
-Tsvg 生成svg格式图片
-o 指定输出文件名
执行完成后,生成一个test.svg
图片
我们可以查看一下当前Graphviz安装支持了哪些布局引擎及支持哪些输出格式
输入dot -K
后,按下两次Tab
健
$ dot -K
-Kcirco -Kfdp -Knop -Knop2 -Kpatchwork -Ktwopi
-Kdot -Kneato -Knop1 -Kosage -Ksfdp
输入dot -Kdot -T
后,按下两次Tab
健
$ dot -Kdot -T
-Tcanon -Tdot -Tgv -Tjson -Tplain-ext -Tsvg -Txdot
-Tcmap -Tdot_json -Timap -Tjson0 -Tpov -Tsvg_inline -Txdot1.2
-Tcmapx -Teps -Timap_np -Tpic -Tps -Tsvgz -Txdot1.4
-Tcmapx_np -Tfig -Tismap -Tplain -Tps2 -Ttk -Txdot_json
当然,ubuntu下还有更便捷的方式安装
sudo apt-get install graphviz
目前为止,我们使用Graphviz主要还是以命令行的方式进行使用,而且使用也主要是进行格式转化,基于此我们可想向一下的应用场景应该是这样,通过代码根据*.dot
的语法,创建一个*.dot
文件,将*.dot
文件采用命令行的方式,转为我们需要可视化格式(如:*.svg
)等;
有没更直接的方法,直接把Graphviz作为一个库函数,创建好图后,直接就输出*.dot
或*.svg
,而不是先自己自作*.dot
再用命令转格式呢?答案是有的,就是Graphviz的高阶应用
可以参考官方文档 Using Graphviz as a library
Graphviz提供c的库(pdf文档),同时还支持的如下一些脚本语言:
https://graphviz.org/docs/library/
三、dot脚本语言的基本语法
1、编辑工具安装
dot是作为Graphviz的主要图形描述语言,具有简洁、易用的特点,任何一款文本编辑器,都可以制作一个dot文件;
在学习dot基本语法之前,先介绍一款在VScode编辑器中,直接预览dot文件的插件——Graphviz Interactive Preview
,通过该插件可非常友好的实时编辑渲染dot文件
打开vscode,搜索Graphviz Interactive Preview
,点击install
安装
打开一个*.dot
文件,点击右侧的预览按钮,如下所示,直接可预览dot文件,生成如下右图所示
至此,我们可以非常方便的在左边编辑脚本,在右实时查看修改后的dot语法对图的影响!
2、dot语法
dot语法中的一些基本概念:图(Graph)、节点(node)、边(edge)
graph(图) 分为:无向图(Graph)
、有向图(Digraph)
,如下两个示例所示:
1)无向图
graph G {
A -- B;
A -- C;
C -- D;
D -- A;
}
上面的脚步生成图如下所示:
2)有向图
digraph G {
A -> B;
A -> C;
C -> D;
A -> D;
B -> K;
}
生成的有向图如下所示:
3)更复杂图例子
当然,我们也可以对图的一些样式进行修改,同时也可以添加一些标签;我们来看一个更复杂一点的有向图例子:
digraph G {
0 [label = A;color = red;];
1 [label = B;];
2 [label = C;];
3 [label = D;];
4 [label = E;];
0 -> 1 [label = 1.2; color = blue; style = dashed;];
0 -> 3 [label = 4.5;];
2 -> 0 [label = 2.0;];
3 -> 2 [label = 0.5;];
2 -> 4 [label = 5.2;];
1 -> 3 [label = 1.8;];
3 -> 4 [label = 3.2;];
}
首先,我们来解析一下上面的dot脚本
首先与前面两个例子,不一样之处,在于这次前面两个,我们直接给出边指向(如:A到B,A -> B
),而这里的是先逐一给出node节点,同时还对节点给了一个别名label标签,每个节点的属性,在[]
中定义;
而同时边也单独给出定义,边的指向采用的顶点的索引来声明定义;而每个边也有属性定义;
最终生成图有向图如下所示:
4)图的样式定义修改
同样我们继续完善上面的例子,对整个图的样式进行定义,添加graph
、 node
关键字
digraph G {
graph [rankdir = LR; ratio = fill; size = "3,3";];
node [shape = circle;];
edge [color =dimgrey];
0 [label = A;color = red;];
1 [label = B;];
2 [label = C;];
3 [label = D;];
4 [label = E;];
0 -> 1 [label = 1.2; color = blue; style = dashed;];
0 -> 3 [label = 4.5;];
2 -> 0 [label = 2.0;];
3 -> 2 [label = 0.5;];
2 -> 4 [label = 5.2;];
1 -> 3 [label = 1.8;];
3 -> 4 [label = 3.2;];
}
4.1 )常见的节点属性包括:
shape:节点的形状,如box(矩形)、circle(圆形)、record(记录形)、plaintext(纯文本)、point(点)等。
color:节点的颜色。
style:节点的样式,如solid(实线)、dotted(点线)、dashed(虚线)等。
label:节点的标签,用于显示节点的名称或描述。
width和height:节点的宽度和高度。
fixedsize:是否强制使用width和height属性指定的尺寸。
fontname和fontsize:节点标签的字体名称和大小。
fillcolor: 当节点的样式设置为 filled 时,此属性确定填充颜色。
4.2)常见的边属性包括:
color:边的颜色。
style:边的样式,如solid(实线)、dotted(点线)、dashed(虚线)等。
weight:边的权重,用于影响布局算法中边的相对重要性。
label:边的标签,用于显示边的描述。
arrowhead:箭头的形状,如normal(普通箭头)、dot(点箭头)、vee(倒三角箭头)等。
arrowtail:箭尾的形状,同样可以使用不同的形状值。
dir: 边的方向。例如 forward(默认,有向边)、back、both、none
5) 子图的定义
同时,我们还可以定义子图使用subgraph
来定义子图或声明为一个相关的节点集(就是为某一个或多个节点,加框框的效果)
digraph G {
graph [rankdir = LR; ratio = fill; size = "3,3";];
node [shape = circle;];
edge [color =dimgrey];
0 [label = A;color = red;];
1 [label = B;];
2 [label = C;];
3 [label = D;];
4 [label = E;];
0 -> 1 [label = 1.2; color = blue; style = dashed;];
0 -> 3 [label = 4.5;];
2 -> 0 [label = 2.0;];
3 -> 2 [label = 0.5;];
2 -> 4 [label = 5.2;];
1 -> 3 [label = 1.8;];
3 -> 4 [label = 3.2;];
subgraph cluster_1 {
label = "Cluster A";
color = blue;
bgcolor = darkgray;
node [style = filled; color = white;];
0;
0 -> 1 [label = "e1"; color = red;];
};
subgraph cluster_2 {
label = "Cluster B";
color = blue;
bgcolor = darkgray;
node [style = filled; color = white;];
3;
4;
}
}
添加子图后,图的layout如下所示:
6)注释
我们还可以在dot中添加单行,或多行注释,语法如下:
digraph G {
/* 这是一个多行注释 */
a -> b; // 这是一个单行注释
b -> c;
# 这是一个以#开头的注释
}
这里有一篇详细一点的介绍,点这里