graphviz 程序生成多种类型图表详解
简介
一幅图抵得上千言万语,这在描述复杂的计算机系统时尤为正确。当系统环境变得更加复杂时,用图将它们表示出来并记入文档就显得更加重要。例如,虚拟化技术有很多优点,但它们通常会让环境变得更加复杂和更难理解。Graphviz 是一个可以创建图表的灵活应用程序,可以轻松实现脚本化。本文将介绍 Graphviz 的安装、使用,以及其中使用 DOT 语言的基础知识,并提供了一些示例脚本。本文有助于您了解 Graphviz 应用程序的基础知识,以及如何编写自动创建图表的脚本。
还有另外一个我觉得更加牛逼的作用,在使用 markdown 时无法直接将图片直接粘贴上去,还得想办法将图片传到某一个中间服务再引入,有么有?而 graphviz 可以完美的解决这个问题,在 markdown 中也可以直接编写相应的代码生成相应的图表,使用起来相当 easy,越用越 happy。
针对 graphviz 想要了解更加详细内容,请查看其对对应的 官方网址
安装 graphviz
Graphviz 是一个开源工具,可以运行在类似于 UNIX® 的大多数平台和 Microsoft® Windows® 之上。graphviz 支持 Windows、Mac OS X、FreeBSD、Solaris、Linux 等多种系统
- Ubuntu 或 Debian 下安装:
sudo apt-get install graphviz
或
sudo yum install graphviz
- Mac 下安装使用 brew 命令:
我本人 mac 上安装的时候并没有装 ruby,故需要先安装 ruby 再进行安装 graphviz
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null ; brew install caskroom/cask/brew-cask 2> /dev/null
brew install graphviz
- Windows 下安装:
由于本人一直使用的是 mac 和 linux,故此次试验并没有在 windows 上做验证,请查看官方文档进行安装。
DOT 语言基础
安装 Graphviz 之后,就可以开始使用工具创建图表,第一步是创建一个 DOT 文件。该 DOT 文件是一个文本文件,描述了图表的组成元素以及它们之间的关系,以便该工具可以生成这些组成元素和它们之间的关系的图形化表示。
1. 编写以 dot 为后缀的源代码文件 hello.dot,内容如下:
digraph {
hello -> world;
}
2. 使用 dot 命令编译
dot hello.dot -T png -o hello.png
完整的命令格式为:
<cmd> <inputfile> -T <format> -o <outputfile>
其中graphviz 的 <cmd>
有好几种,每种使用方法都完全相同,差别只在于渲染出来的图片效果不一样。 man
中的简介是这样的
<cmd> | 介绍 |
---|---|
dot | 渲染的图具有明确方向性。 |
neato | 渲染的图缺乏方向性。 |
twopi | 渲染的图采用放射性布局。 |
circo | 渲染的图采用环型布局。 |
fdp | 渲染的图缺乏方向性。 |
sfdp | 渲染大型的图,图片缺乏方向性。 |
可以透过 man <cmd>
取得进一步说明。但还是亲自用用比较容易理解。在本文中,凡没有说明的图,预设都是以 dot
渲染出来的。
3. 查看效果
运行 2 中的命令后会生成对应的 png 文件,双击打开查看效果如下所示:
基础应用
1. 编写一个案例 dot 文件为:example1.dot
graph example1 {
Server1 -- Server2
Server2 -- Server3
Server3 -- Server1
}
上述内容中共有三个节点(Server1、Server2 和 Server3)。--
定义了节点之间的联系。这个使用 DOT 语言的例子说明,Server2、 Server2 连接到 Server3,而 Server3 连接到 Server1。
创建 DOT 文件后,可以运行 dot
命令来生成图表,如 2 中所示。–
T png
将输出格式指定为 PNG,而 –o example1.png
指定必须将输出保存到一个名叫 example1.png 的文件中。
2. 从 DOT 文件生成图像
$ dot example1.dot –T png –o example1.png
生成的图表如下:
第一个示例 (example1.dot) 描述了一个无向图,即用不带箭头的直线表示节点之间的联系的图。
有向图不仅能表示节点之间的联系,而且能用箭头表示节点之间流动的方向。要创建有向图,可以在 DOT 文件的第一行上指定 digraph
而非 graph
,并在节点之间使用 ->
,而不是 --
。
3. 生成有向图,创建 dot 文件:example2.dot
digraph example2 {
Server1 -> Server2
Server2 -> Server3
Server3 -> Server1
}
使用 dot 命令生成对应的图表如下:
你也可以轻松控制图中每个节点的形状、颜色和标签。具体方法是列出每个节点的名称,然后将选项放在名称后面的括号中。例如,代码行
Server1[shape=box, label="Server1\nWebServer", fillcolor="#ABACBA", style=filled]
定义了 Server1 节点应该是一个长方形,有一个 Server1\nWeb Server 标签(\n 表示一个新行),颜色设为十六进制 (hex) 颜色 #ABACBA,而且该颜色应该填充了节点。
4. 生成有颜色和形状的图表
创建 dot 文件:example3.dot
digraph example3 {
Server1 -> Server2
Server2 -> Server3
Server3 -> Server1 Server1 [shape=box, label="Server1\nWeb Server", fillcolor="#ABACBA", style=filled]
Server2 [shape=triangle, label="Server2\nApp Server", fillcolor="#DDBCBC", style=filled]
Server3 [shape=circle, label="Server3\nDatabase Server", fillcolor="#FFAA22", style=filled]
}
对应的生成相应图表如下:
编写脚本创建 Graphviz 图表
在了解了 Graphviz DOT 语言的基础知识之后,您可以开始创建脚本,从而动态创建一个 DOT 文件。这允许您动态创建始终准确且保持最新的图表。
以下示例是一个 bash shell 脚本(hmc_to_dot.sh),它连接到 Hardware Management Console (HMC),收集托管服务器和逻辑分区 (LPAR) 的相关信息,然后使用这些信息来创建 DOT 输出。
#!/bin/bash HMC="$1"
serverlist=`ssh -q -o "BatchMode yes" $HMC lssyscfg -r sys -F "name" | sort` echo "graph hmc_graph{"
for server in $serverlist; do
echo " \"$HMC\" -- \"$server\" "
lparlist=`ssh -q -o "BatchMode yes" $HMC lssyscfg -m $server -r lpar -F "name" | sort`
for lpar in $lparlist; do
echo " \"$server\" -- \"$lpar\" "
done
done
echo "}"
通过提供一个 HMC 服务器名称作为参数传递给脚本,便可运行此脚本。该脚本将传递的第一个参数设置为 $HMC 变量。设置 $serverlist 变量的方法是连接到 HMC 并获得该 HMC 控制的所有托管服务器的清单。在这些托管服务器上进行循环,而脚本将为每台托管服务器打印一行 "HMC" -- "server" ,这表明 Graphviz 在每台 HMC 与其托管服务器之间绘制了一条直线。此外针对每台托管服务器,脚本再次连接到 HMC 并获得该托管系统上的 LPAR 清单,然后通过它们循环打印一行 "server" -- "LPAR"。这表明 Graphviz 在每台托管服务器与其 LPAR 之间都绘制了一条直线。(此脚本要求您在运行脚本的服务器与 HMC 之间设置 Secure Shell (SSH) 密钥身份验证)。
命令执行如下:
./hmc_to_dot.sh hmc_name
以上执行对应输出的内容如下所示:
graph hmc_graph{
"hmc01" -- "test520"
"test520" -- "lpar2"
"test520" -- "lpar3"
"hmc01" -- "test570"
"test570" -- "aixtest01"
"test570" -- "aixtest02"
"test570" -- "aixtest03"
"hmc01" -- "test510"
"test510" -- "lpar1"
}
你可以轻松从脚本生成图,具体方法是运行以下命令:
./hmc_to_dot.sh hmc_server_name | dot -T png -o hmc_graph.png
运行脚本,该脚本会动态创建 DOT 语言,然后将这些输出传递给 dot 命令,以便让它创建一个文件名为 hmc_graph.png 的图表。下图显示了创建的图表。
基础语法总结(供有识之士参考)
具体的图说明内容包含属性(attr)、节点(node)、边(edge)和子图(subgraph)说明。
节点属性如下 :
Name | Default | Values |
---|---|---|
color | black | node shape color |
comment | any string (format-dependent) | |
distortion | 0.0 | node distortion for shape=polygon |
fillcolor | lightgrey/black | node fill color |
fixedsize | false | label text has no affect on node size |
fontcolor | black | type face color |
fontname | Times-Roman | font family |
fontsize | 14 | point size of label |
group | name of node’s group | |
height | .5 | height in inches |
label | node name | any string |
layer | overlay range | all, id or id:id |
orientation | 0.0 | node rotation angle |
peripheries | shape-dependent | number of node boundaries |
regular | false | force polygon to be regular |
shape | ellipse | node shape; see Section 2.1 and Appendix E |
shapefile | external EPSF or SVG custom shape file | |
sides | 4 | number of sides for shape=polygon |
skew | 0.0 | skewing of node for shape=polygon |
style | graphics options, e.g. bold, dotted, filled; cf. Section 2.3 | |
URL | URL associated with node (format-dependent) | |
width | .75 | width in inches |
z | 0.0 | z coordinate for VRML output |
边框属性:
Name | Default | Values |
---|---|---|
arrowhead | normal | style of arrowhead at head end |
arrowsize | 1.0 | scaling factor for arrowheads |
arrowtail | normal | style of arrowhead at tail end |
color | black | edge stroke color |
comment | any string (format-dependent) | |
constraint | true | use edge to affect node ranking |
decorate | if set, draws a line connecting labels with their edges | |
dir | forward | forward, back, both, or none |
fontcolor | black | type face color |
fontname | Times-Roman | font family |
fontsize | 14 | point size of label |
headlabel | label placed near head of edge | |
headport | n,ne,e,se,s,sw,w,nw | |
headURL | URL attached to head label if output format is ismap | |
label | edge label | |
labelangle | -25.0 | angle in degrees which head or tail label is rotated off edge |
labeldistance | 1.0 | scaling factor for distance of head or tail label from node |
labelfloat | false | lessen constraints on edge label placement |
labelfontcolor | black | type face color for head and tail labels |
labelfontname | Times-Roman | font family for head and tail labels |
labelfontsize | 14 | point size for head and tail labels |
layer | overlay range | all, id or id:id |
lhead | name of cluster to use as head of edge | |
ltail | name of cluster to use as tail of edge | |
minlen | 1 | minimum rank distance between head and tail |
samehead | tag for head node; edge heads with the same tag are | |
sametail | merged onto the same port | |
style | tag for tail node; edge tails with the same tag are merged onto the same port | |
taillabel | graphics options, e.g. bold, dotted, filled; cf. Section 2.3 | |
tailport | label placed near tail of edge n,ne,e,se,s,sw,w,nw | |
tailURL | URL attached to tail label if output format is ismap | |
weight | 1 | integer cost of stretching an edge |
图属性如下:
Name | Default | Values |
---|---|---|
bgcolor | background color for drawing, plus initial fill color | |
center | false | center drawing on page |
clusterrank | local | may be global or none |
color | black | for clusters, outline color, and fill color if fillcolor not defined |
comment | any string (format-dependent) | |
compound | false | allow edges between clusters |
concentrate | false | enables edge concentrators |
fillcolor | black | cluster fill color |
fontcolor | black | type face color |
fontname | Times-Roman | font family |
fontpath | list of directories to search for fonts | |
fontsize | 14 | point size of label |
label | any string | |
labeljust | centered | ”l” and ”r” for left- and right-justified cluster labels, respectively |
labelloc | top | ”t” and ”b” for top- and bottom-justified cluster labels, respectively |
layers | id:id:id… | |
margin | .5 | margin included in page, inches |
mclimit | 1.0 | scale factor for mincross iterations |
nodesep | .25 | separation between nodes, in inches. |
nslimit | if set to f, bounds network simplex iterations by (f)(number of nodes) when setting x-coordinates | |
nslimit1 | if set to f, bounds network simplex iterations by (f)(number of nodes) when ranking nodes | |
ordering | if out out edge order is preserved | |
orientation | portrait | if rotate is not used and the value is landscape, use landscape orientation |
page | unit of pagination, e.g. “8.5,11” | |
pagedir | BL | traversal order of pages |
quantum | if quantum ¿ 0.0, node label dimensions will be rounded to integral multiples of quantum | |
rank | same, min, max, source or sink | |
rankdir | TB | LR (left to right) or TB (top to bottom) |
ranksep | .75 | separation between ranks, in inches. |
ratio | approximate aspect ratio desired, fill or auto | |
remincross | if true and there are multiple clusters, re-run crossing minimization | |
rotate | If 90, set orientation to landscape | |
samplepoints | 8 | number of points used to represent ellipses and circles on output (cf. Appendix C |
searchsize | 30 | maximum edges with negative cut values to check when looking for a minimum one during network simplex |
size | maximum drawing size, in inches | |
style | graphics options, e.g. filled for clusters | |
URL | URL associated with graph (format-dependent) |
具体实例
这里列举几个常用到的例子,还有更加详细的例子还可以参考 官网例子中心
下面是一个二叉树代码:
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> "];
node3[label = "<f0> |<f1> F|<f2> "];
node4[label = "<f0> |<f1> R|<f2> "];
node5[label = "<f0> |<f1> H|<f2> "];
node6[label = "<f0> |<f1> Y|<f2> "];
node7[label = "<f0> |<f1> A|<f2> "];
node8[label = "<f0> |<f1> C|<f2> "];
"node0":f2 -> "node4":f1;
"node0":f0 -> "node1":f1;
"node1":f0 -> "node2":f1;
"node1":f2 -> "node3":f1;
"node2":f2 -> "node8":f1;
"node2":f0 -> "node7":f1;
"node4":f2 -> "node6":f1;
"node4":f0 -> "node5":f1;
}
python 调用
除了可以使用 dot
文件编写图形外,也可以使用python编写相关的代码,生成图形文件, 安装 python 对应的 graphviz 相应的模块
pip install pygraphviz
引用 pygraphviz
import pygraphviz as pgv
初始化图类
G = pgv.AGraph()
增加节点和边
G.add_node('a') # adds node 'a'
G.add_edge('b','c') # adds edge 'b'-'c' (and also nodes 'b', 'c')
设置属性
G.graph_attr['label'] = 'test graphf'
G.node_attr['shape'] = 'circle'
G.edge_attr['color'] = 'red'
设置输出的格式
G.layout() # default to neato
G.layout(prog='dot') # use do
输出到文件
G.draw('file.png') # write previously positioned graph to PNG file
G.draw('file.ps',prog='circo') # use circo to position, write PS file
效果如下图所示:
结束语
由于当今的动态虚拟环境的存在,系统在不断变化,很难保持文档与图表的时效性和准确性。本文介绍了 Graphviz 的基础知识,以及如何通过编写脚本,利用 Graphviz 的强大功能来创建最新、最准确的自动化环境图表。您可以从 cron 运行这些脚本,并将图表放在 Web 服务器上,这样就可以在您需要时随时重新创建图表,并通过 Web 浏览器轻松访问它们。
总结使用案例
案例一:
digraph startgame {
label="游戏资源更新流程"
rankdir="TB"
start[label="启动游戏" shape=circle style=filled]
ifwifi[label="网络环境判断是否 WIFI" shape=diamond]
needupdate[label="是否有资源需要更新" shape=diamond]
startslientdl[label="静默下载" shape=box]
enterhall[label="进入游戏大厅" shape=box] enterroom[label="进入房间" shape=box]
resourceuptodate[label="资源不完整" shape=diamond]
startplay[label="正常游戏" shape=circle fillcolor=blue]
warning[label="提醒玩家是否更新" shape=diamond]
startdl[label="进入下载界面" shape=box]
//{rank=same; needupdate, enterhall} {shape=diamond; ifwifi, needupdate} start -> ifwifi
ifwifi->needupdate[label="是"]
ifwifi->enterhall[label="否"]
needupdate->startslientdl[label="是"]
startslientdl->enterhall
needupdate->enterhall[label="否"] enterhall -> enterroom
enterroom -> resourceuptodate
resourceuptodate -> warning[label="是"]
resourceuptodate -> startplay[label="否"]
warning -> startdl[label="确认下载"]
warning -> enterhall[label="取消下载"]
startdl -> enterhall[label="取消下载"]
startdl -> startplay[label="下载完成"]
}
案例二:
digraph G{ size = "5, 5";//图片大小
main[shape=box];/*形状*/ main->parse;
parse->execute; main->init[style = dotted];//虚线 main->cleanup;
edge[color = green]; // 连接线的颜色 execute->{make_string; printf}//连接两个 init->make_string;
main->printf[style=bold, label="100 times"];//线的 label make_string[label = "make a\nstring"]// \n, 这个node的label,注意和上一行的区别 node[shape = box, style = filled, color = ".7.3 1.0"];//一个node的属性 execute->compare;
}
graphviz 程序生成多种类型图表详解的更多相关文章
- Python绘制六种可视化图表详解,三维图最炫酷!你觉得呢?
Python绘制六种可视化图表详解,三维图最炫酷!你觉得呢? 可视化图表,有相当多种,但常见的也就下面几种,其他比较复杂一点,大都也是基于如下几种进行组合,变换出来的.对于初学者来说,很容易被这官网上 ...
- Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 莱特币ltc在linux下的多种挖矿方案详解
莱特币ltc在linux下的多种挖矿方案详解 4.0.1 Nvidia显卡Linux驱动Nvidia全部驱动:http://www.nvidia.cn/Download/index.aspx?lang ...
- Elasticsearch-2.4.3的3节点安装(多种方式图文详解)(含 head、kopf、marvel、shield和watcher插件安装和使用)
前提: Elasticsearch-2.4.3的下载(图文详解) Elasticsearch-2.4.3的单节点安装(多种方式图文详解) 我这里,以192.168.80.10(HadoopMaster ...
- Vue通信、传值的多种方式,详解
Vue通信.传值的多种方式,详解 转自:https://blog.csdn.net/qq_35430000/article/details/79291287 一.通过路由带参数进行传值 ①两个组件 A ...
- JS类型转换规则详解
JS类型转换规则详解 一.总结 一句话总结:JS强制类型转换中的类型名强制类型转换和其它语言不同,是类型类的构造方法,Number(mix) 一句话总结(JS类型本质):因为js是弱类型语言,所以它相 ...
- Vue通信、传值的多种方式,详解(都是干货)
Vue通信.传值的多种方式,详解(都是干货) 可参考博客: https://blog.csdn.net/qq_35430000/article/details/79291287
- Struts2中 Result类型配置详解
一个result代表了一个可能的输出.当Action类的方法执行完成时,它返回一个字符串类型的结果码,框架根据这个结果码选择对应的result,向用户输出.在com.opensymphony.xwor ...
随机推荐
- 北航MOOC系统Android客户端NABC
北航MOOC手机客户端NABC分析 1) N (Need 需求) MOOC是Massive Open Online Course的缩写,通常被译为大型开放式网络课程,它最早在08年的时候由一位加拿大的 ...
- 【CSAPP笔记】3. 浮点数
回想起刚学C语言时,我对浮点数的印象大概是"能够表示小数"的数据类型.还死记硬背过例如什么"小数用double存,用%f输出"这类的话.实际上呢,浮点数可以用这 ...
- 软件工程实践2018第六次作业——现场UML作图
团队信息 学号 姓名 博客链接 124 王彬(组长) 点击这里 206 赵畅 点击这里 215 胡展瑞 点击这里 320 李恒达 点击这里 131 佘岳昕 点击这里 431 王源 点击这里 206 陈 ...
- 用windbg检查.NET线程池设置
比如我们在machine.config中进行了这样的设置(8核CPU): <processModel maxWorkerThreads="100" maxIoThreads= ...
- OpenGL三维与光照
#include<windows.h> #include<gl/glut.h> #include<gl/gl.h> #include<gl/glu.h> ...
- Linux adduser
- .NET Core 中的并发编程
今天我们购买的每台电脑都有一个多核心的 CPU,允许它并行执行多个指令.操作系统通过将进程调度到不同的内核来发挥这个结构的优点. 然而,还可以通过异步 I/O 操作和并行处理来帮助我们提高单个应用程序 ...
- P1198 [JSOI2008]最大数
题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当前数列的长度.(L>0) ...
- 【BZOJ1041】圆上的整点(数论)
[BZOJ1041]圆上的整点(数论) 题面 BZOJ 洛谷 题解 好神仙的题目啊. 安利一个视频,大概是第\(7\)到\(19\)分钟的样子 因为要质因数分解,所以复习了一下\(Pollard\_r ...
- 【转载】dfs序七个经典问题
作者:weeping 出处:www.cnblogs.com/weeping/ 原文链接 https://www.cnblogs.com/weeping/p/6847112.html 参考自:<数 ...