关于 Graphviz
Graphviz 是一个我始终无法绕开的软件,既然不能绕开,那就直面好了。(另一款让我无法绕开的,是 Total Commander,虽然我(Jony Zhu)很想绕开。)
1、Graphviz 是什么?
Graphviz 是一款基于命令行的“图”的可视化软件。
这里的“图”是计算机图论里面的图(有向图、无向图等等),不是“图片”的图。Graphviz 就是将“图”的关系生成图片文件,从而可以直观的看到图中的节点关系。下面就是使用 Graphviz 将数据关系可视化的流程:
图的描述文件(文本)–> Graphviz –> 图片
比如,下面这个图就是 Graphviz 生成的:
理论上,仅仅是理论上,任何 Graphviz 可以生成的可视化结果,都可以用类似 Visio 这样的软件绘制出来(你强的话,用 PowerPoint 甚至 Excel 都可以)。但是,类似下面这样的复杂关系图的绘制和布局如果徒手绘制,会让人发疯的吧:
现在,你知道为什么我绕不开这个软件了吧。
2、在哪里可以弄得到呢?
免费开源的 Graphviz:
http://www.graphviz.org/Download_windows.php
3、怎么用呢?
其实,下面解释的是为什么我想绕开这个软件。
3.1 基本使用方法
首先,你要知道,Graphviz 不是一个软件,而是一~堆软件。
仅就生成图的图片来说,就有 dot、dotty、neato、lneato、fdp、sfdp、twopi、circo 等等,每个软件用不同的算法和设置来让图可视化。各种不同的图形
其次,你是要用文本编辑器来手写图的关系。这个比手写 HTML 难多了。
比如,hello.cs 调用了 base.cs 里面的方法,你想绘制这个关系,那么,就需要手写一段这样的文本文件(假设文件名是 demo.dot):
然后,手动打个命令,来让 Graphviz 解析这个文件,生成图片:
就可以看到图片了:
然后,你发现,hello.cs 还调用了 tool.cs 文件,于是,demo.dot 就变成了:
保存以后,继续敲命令来更新关系图的图片文件。周而复始的进行下去。
3.2 中文问题
这里包含 2 个问题:中文的显示问题,和,使用中文的便利性问题。
首先,是中文的显示问题。
默认的,Graphviz 是现实不出中文的,所以,下面的内容:
会显示成方块:(顺便插一句,我不喜欢 Java,很大程度上就是因为它的字符编码的处理太麻烦了。虽然我也认真用过一段时间的 Java。)
于是,我们需要手动指定中文字体,并且,将文件保存成 utf-8 的格式:
接下来,是中文输入的便利性问题。
Graphviz 中,使用“->”来连接图的两个节点。不幸的是,如果你在节点中使用了中文的话,那么,当你通过中文输入法输入“->”,将会变成“-》”。你当然可以通过切换中英文标点来改变,可是,每次切换英文到中文输入法时,默认又会转成中文标点,烦不胜烦。
我的解决方法是,先不管那个中文的书名号,等全部内容写完了,再全文做一次替换。
3.3 绘制复杂的节点
有的时候,节点里面包含有复杂的结构。比如,ATMEL 的 TWI 协议。
TWI 协议是与 I2C 协议完全兼容的 2 线数据传输协议,支持协议的硬件之间(可多达 127 个),只需要 3 根线(1 根地线,2 根数据线)即可实现双线数据互传。
可以想象,这种略显复杂的协议用这样少的数据线,里面每个传输状态的设置也是略显复杂的。
举例来说,每次数据传输前,都需要收发双方对寄存器 TWCR 进行设置:
1、发送方,TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA) 这将启动一次发送
2、发送方,启动成功的话,会进入 TWI_vect 中断,此时TWI 的状态寄存器 TWSR 的值将会是 0x08 或者 0x10,此时,发送方需要将接收方的地址写入 TWDR 寄存器,并接着设置 TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA);
3、接收方,设置 TWCR = (1<<TWEA)|(1<<TWEN)|(1<<TWIE);
4、接收方,发现与自己地址匹配的信号的话,也会进入自己的 TWI_vect 中断,此时 TWSR 的值是 0x60 或者 0xa0,接收方此时要设置 TWCR 告知发送方自己已经收到信号并且可以开始准备传送数据了 TWCR =(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE);
5、balabala 。。。地双方互传数据
那么,对应的 Graphviz 文件可能就是这样的:
其中一个节点可能要这样写:masterStart [shape=record,label=”TWSR\n0xf8|{TWCR|{{TWINT|1}|{TWEA|1}|{TWSTA|1}|{TWSTO|0}|{TWWC|0}|{TWEN|1}|{-|0}|{TWIE|1}}}”]
才能出来下面这样的图:
虽然是这样麻烦的一个工具,但是,在用过无数自动、半自动、手动,图形化的、命令行的类似“图”的可视化工具以后,我每次还是都会回到 Graphviz 上面来,这真是件奇怪的事情啊!
也许下次可以谈谈 Total Commander,这个让 Jony 有类似感觉的工具软件。