Graphviz介绍

像写代码一样画图。

Graphviz是一个从dot语言生成图片的工具,下面是一个dot示例和它对应的图片:

digraph G {
    a -> b;
    a -> c;
    a -> d;
}

相关链接:

Graphviz官网:https://graphviz.org/

dot语言官方文档:https://graphviz.org/doc/info/lang.html

dota语言维基百科:https://zh.wikipedia.org/wiki/DOT语言

测试工具:

在vscode上安装Graphviz (dot) language support for Visual Studio Code这个插件,创建dot文件,按Ctrl+Shift+P后输入Graphviz,选择Graphviz: Open Preview to the Side即可实时预览dot图片。

几个图形示例

示例来源:https://zh.wikipedia.org/wiki/DOT语言https://graphviztutorial.readthedocs.io/zh_CN/latest/index.html

无向图

graph {
    a -- b -- c;
    b -- d;
}

有向图

digraph G {
    a -> b -> c;
    b -> d;
}

节点属性和边属性

digraph G {
    // label属性可以改变节点显示的名称
    a [label = "Foo"];
    // shape属性可以改变节点的形状
    b [shape = box];
    // color指定连接线的颜色
    a -> b -> c [color = blue];
    // style指定连接线的风格
    b -> d [style = dotted];
}

控制边的方向

digraph {
    a -> b [dir = both];
    b -> c [dir = none];
    c -> d [dir = back];
    d -> a [dir = forward];
}

控制边的起点位置和终点位置

digraph {
    // 统一将下面的节点设置成矩形
    node [shape = box];
    // n/e/s/w分别表示north, east, south, west, 可组合使用
    c1:n  -> d1    [label=n];
    c2:ne -> d2:ne [label=ne];
    c3:e  -> d3:ne [label=e];
    c4:se -> d4:n  [label=se];
    c5:s  -> d5:n  [label=s];
    c6:sw -> d6:n  [label=sw];
    c7:w  -> d7:nw [label=w];
    c8:nw -> d8:nw [label=nw];
}


Dot语法

整体语法如下:

[strict] (graph | digraph) [ID] {
	stmt_list;
}

strict关键字表示是否允许重复的边,graph | digraph表示无向图或有向图,ID表示图的名称,stmt_list是图的具体内容。

关于图的具体内容定义如下:

stmt_list : [ stmt [';'] stmt_list ]

这是一个递归的定义,表示stmt_list由多个stmt组成,每个stmt表示一个语句,后面可用分号结尾。对于stmt,也就是语句的定义如下:

stmt: node_stmt | edge_stmt | attr_stmt | ID='ID' | subgraph

这里表示语句可以分成几种类型,包括node_stmt,表示节点类型,edge_stmt,表示边类型,attr_stmt,表示属性类型,ID类型,表示ID重命名,以及subgraph,表示子图。以下表格描述了各种类型的格式:

类型形式说明示例示例说明
node_stmtID [attr_list]声明一个节点,ID是表示节点名称的字符串,可以带双引号a [label = "Foo"];a节点使用Foo作为显示文本
attr_list[k1=v1 k2=v2 ...]声明属性列表,key=value形式,多个属性空格隔开[style=bold, label="hello world"]修饰的类型具有加粗属性,显示文本为"helloworld"
attr_stmt(graph | node | edge) attr_list定义图,节点,边的全局属性,三选一,该语句之后生效,前面的不影响

graph [ fontsize=10 fontname="Verdana" ]

全图字体为Verdana,大小为10
node [shape=box]该语句后面的所有节点形状为矩形
edge [style=dotted] 全图的边都使用虚线
edge_stmt(node_id | subgraph) edgeRHS [attr_list] 定义一条边,包括起始位置,连接操作(->--),结束位置,以及可选的后续位置

a -> b -> c
a -- b -- c

a:ne -> b:n


edgeRHSedgeop (node_id | subgraph) [edgeRHS]
node_idID[:n | ne | e | se | s | sw | w | nw | c]表示一个位置,最常见的是用节点名称来表示,也可以后面跟上:表示方向
subgraph[ subgraph [ID] ] { stmt_list }表示一个子图

subgraph sub_0 { a->b  }

{ rank=same; a b c }


属性

参考官方文档:https://graphviz.org/doc/info/attrs.html

支持对图的各项元素设置属性,比如修改节点形状,边的类型,图的字体和大小等。属性有具体的作用对象,并且属性并不是通用的,也就是一类属性只能修饰一类元素。属性具有属性名和属性值,两者都是区分大小写的。具体的属性列表可以参考上面的官方文档,下面列表一些常用的属性,作用对象中的E, N, G, S, C分别表示edge, node, the root graph, subgraph, cluster subgraph。

名称作用对象类型默认值说明示例
labelENGCstring
标签文本a -> b [label="Foo"]


















节点形状


箭头形状


一些其他的示例

子图1

A -> {B C}

上面的语句等效于:


A -> B
A -> C

子图2

subgraph {
    rank=same; A; B; C;
}

这个子图含有3个节点,并且这3个节点会并排显示。

以cluster开头命名的子图

以cluster开头命名的子图会被渲染引擎进行特殊渲染,包括将节点画在一起,并且用一个矩形框包括起来,支持设置矩形框的颜色和文文本,以下是一个示例:

digraph {
    node [shape=record];

    subgraph cluster_0 {
        node [style=filled];
        label = "cluster 0";
        color = blue;
        a -> b;
    }
    
    subgraph cluster_1 {
        node [style=filled];
        label = "cluster 1";
        color = blue;
        c -> d;
    }
}


其他

. 关键字不区别大小写。

. 有向图用 digraph ,无向图用 graph ,有向图节点之间使用 -> 连接,无向图节点使用 -- 连接。

. 支持注释,支持C风格的注释, /*...*/ 多行注释, // 单行注释,也可以用Shell风格的 # 开头的注释。

. 语句结尾的分号可选。

. 给图加上strict 关键字可消除重复的边,对有向图和无向图都适用。






















  • 无标签