Graphviz工具
来源:互联网 发布:骑马动作数据 编辑:程序博客网 时间:2024/05/16 15:58
工欲善其事,必先利其器。Graphviz是图形可视化工具,doxygen等工具的重要基石,如果想摆脱visio工具的束缚,想更高效的画出各种时序图,流程图、状态图等等,可以尝试使用Graphviz,特别是doxygen工具,可以帮助你通过代码注释输出可视化的文档。本章主要介绍Graphviz工具。
Graphviz入门
简介
Graphviz (Graph visualization)缩写,即图形可视化的工具,是贝尔实验室开源的一款工具。主要用途可以将特定语言(DSL)编写的脚本进行可视化输出,支持JPEG,PDF等多种输出样式。并且其是跨平台非常好,已经支持Linux, MAC, Window多平台,二进制安装方式提供fedora, ubuntu,rhel, solaris, macos, windows等系统。
Graphviz拥有多种布局方式,默认才用Dot布局方式。
1)dot - 默认布局方式,主要用于向图。
2)neato - "spring model'' layouts。
3) fdp,sfdp - 用于无向图。
3)twopi - 径向布局。
4)circo - 环行布局。
Graphviz的官网,里面有更为详细的介绍和文档。
安装
安装方式可以选择源码方式安装或者直接使用安装包方式进行,我这里使用的二进制方式安装,MAC系统下载地址,通过可以地址可以找到其他平台安装方式。MAC下直接下载pkg文件进行安装。
傻瓜式下一步即可。
安装完成打开Graphviz
测试
编写一个脚本如下,命名为test.dot
digraph test1{a;b;c;d;a -> b;b -> d;c -> d;}
使用Graphviz->File->Open,(或花o-快捷键)打开test.dot文件
可以使用Graphviz->File->Export进行输出,可以保存你想要的格式。
应用
上面使用Graphviz一个简单的演示让我们了解到Graphviz工具的主要用途,可以使用脚本化的方式来输出可视化的图形界面,能够快速的进行思维的图形化,我们想把我们所思考的东西进行图形化表达,可以借助Graphviz。比如我们想画出一个函数的调用关系,或者类的继承、组合图等等。
现在有很大强大的工具都在使用Graphviz作为图形化基础来实现其界面展示。后续有机会对下面的几款工具进行介绍。
Doxygen - 一款可以将注释文档化的工具,能够输出CHM, HTML等多种格式的文档。
Valgrind - 一款内存泄露,内存越界等检查工具,能够输出图形化的内存异常报表。
Graphviz使用
有向图
上一节测试部分已经演示最简单的有向图的使用,Dot语法还提供修改图形的各种属性,下面一一进行介绍。
属性也分为作用域,如果是全局作用于,则对所有节点生效,也可以是只对某个节点生效。我们来演示一个使用矩形、虚线的例子。
digraph test2{node [shape="box"];edge [style="dashed"];a [shape="ellipse"];b [style="filled", color="green"];c;d;a -> b [color="red"];b -> d [style=bold,label="b to d"];c -> d;}
node,edge 作用域是全局的,全局的基调是“形状是矩形,连线是虚线”
a节点的形状是椭圆形
b节点风格是使用绿色填充
a到b的连线颜色使用红色
b到d的连线使用实心连线,并且携带注释"b to d"
下面演示一个子图绘制,我们将c和d节点定义为一个子图。
digraph test3{a;b;subgraph cluster_cd{ label="c and d"; bgcolor="mintcream"; c [shape = "polygon",sides=5]; d; }a -> b;b -> d [color = "red"];c -> d [style="dashed" color = "green"];}
使用subgraph关键字定义子图,并且子图保证使用cluster前缀作为子图名。
数据结构图
我们举例来描述一个hash表的数据结构,数据结构C代码如下:
struct hash_entry {int hashcode;char *key;char *value;hash_entry *next;};struct hash_oper {int (*compare)(int op1, int op2); //hash比较方法int (*hash)(); //hash值计算方法};struct hash_table {int slots; //槽总数int count; //数据总数struct hash_oper *oper; //hash操作封装struct hash_entry **entries; //槽数组,每个槽是一个链表};
使用Graphviz展示的效果如下图:
使用如下脚本可以输出该图:
digraph test4 {rankdir = TB;node [fontname = "Verdana", fontsize = 10, color="skyblue", shape="record"];edge [fontname = "Verdana", fontsize = 10, color="crimson", style="solid"]; hash_oper [label="{<head>hash_oper|int (*compare)|int (*hash)}"];hash_entry [label="{<head>hash_entry|hashcode|key|value|<next>next}"];hash_table [label="{hash_table|slots|count|<oper>oper|<entries>entries}"];hash_table:entries -> hash_entry:head;hash_entry:next -> hash_entry:head [style="dashed" color="green"];hash_table:oper -> hash_oper:head;}数据结构图的连线主要使用尖括号<xx>实现,使用<>可以定义一个leble,然后使用lable实现表格之间的连线。
上面是使用dot布局方式,我们可以使用circo布局方式实现哈希表数据机构,代码如下:
digraph test5 {rankdir = LR;node [ shape="record", width=.1, height=.1];node [fontname = "Verdana", fontsize = 10, color="skyblue", shape="record"]; edge [fontname = "Verdana", fontsize = 10, color="crimson", style="solid"];node [shape="plaintext"];hash_table [label=<<table border="0" cellborder="1" cellspacing="0" align="left"><tr><td>hash_table</td></tr><tr><td>slots=4</td></tr><tr><td>count</td></tr><tr><td>oper</td></tr><tr><td>entries</td></tr></table>>];node [shape="record"];num_entry [label="<b1> | <b2> | <b3> | <b4>", height=2];entry_1 [label="{<e>hash_entry|<next>next}"];entry_2 [label="<e>hash_entry|<next>null"];entry_3 [label="<e>hash_entry|<next>null"];hash_table:entries ->num_entry:b1;num_entry:b1->entry_1:e;entry_1:next->entry_2:e;num_entry:b3->entry_3:3;}
和dot布局方式一样,<>也是可以用来做标签的,可以使用<table>类似HTML的方式进行格式调整。可视化后得到下图:
我们再画一个二叉树的数据结构图,代码如下:
digraph test6 {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;}
UML图
状态图
我用一个Bug系统的状态图为例,演示下状态图。
digraph test7 {rankdir = LR;node [fontsize = 12, shape = "Mrecord", color="skyblue", style="filled"]; edge [fontsize = 12, color="darkgreen" ];created [label="created"];review [label="review"];assign [label="assign"];assigned [label="assigned"];verify [label="verify"];closed [label="closed"];start [label="", shape="circle", width=0.5, fixedsize=true, style="filled", color="black"];start -> created[label="创建"];created -> review [label="提交"];review -> assign [label="通过"];review -> created [label ="拒绝"];assign -> assigned [label="分配"];assigned-> verify [label="解决"];assigned-> closed [label="直接关闭"];verify -> closed [label="验证通过"];verify -> assigned [label="未解决"];}
类图
我用一个形状的类图来进行演示,代码如下:
digraph test8{ fontname = "Courier New"fontsize = 10 node [ fontname = "Courier New", fontsize = 10, shape = "record" ];edge [ fontname = "Courier New", fontsize = 10 ]; Animal [ label = "{Shape |+ getArea|+ draw}" ]; subgraph clusterShapeImpl{ bgcolor="yellow" Triangle [ label = "{Triangle|+ getArea | + draw}" ]; Rectangular [ label = "{Rectangular|+ getArea | + draw}" ]; }; edge [ arrowhead = "empty" ]; Triangle->Animal;Rectangular->Animal;Triangle->Rectangular [arrowhead="none", label="0..*"];}
小结
本章对Graphviz进行入门级的介绍,演示了几种类型的示例,可以更加直接的了解Graphviz使用方法。当时为了快速画出函数的调用的关系,我使用doxygen对代码进行文档化输出,然后截图,想想也够浪费时间的,如果直接使用脚本进行格式化,想必回事半功倍。后续我会介绍doxygen工具的使用,希望对大家有所帮助。
参考
Graphviz官网 官网
Dot语法 官方文档
修订
初稿 2014-11-16 Simon
1 0
- Graphviz工具
- 工具:graphviz和Ubigraph
- graphviz工具及其原理
- graphviz工具及其原理
- graphviz 工具厉害
- 画图工具使用gnuplot&graphviz
- Ubuntu上玩转graphviz绘图工具
- GraphViz
- Graphviz
- Graphviz
- Graphviz
- Graphviz
- Graphviz
- 关系图绘制工具Graphviz 的学习
- 【实践】源码分析工具Doxygen+Graphviz
- graphviz好用的程序员画图工具
- uml制图工具比较: graphviz, umlet, visio
- 决策树可视化工具Graphviz的安装
- 嵌入式数据库sqlite3的用法(转载)
- 希尔排序(间接插入排序)
- 十道大数据的题与十个海量数据处理的方法
- 数据结构:二叉树的非递归遍历
- 从hdfs读取数据写入hbase
- Graphviz工具
- 暴力破解-简单枚举
- 在你步入职业软件开发生涯那天起就该知道的五件事
- 贝叶斯、概率分布与机器学习
- 代码分析:NASM源码阅读笔记
- 程序员忠告
- 水仙花数
- CUDA编程入门指南
- 设计模式之动态模式