官方说明文档
最近玩了一下graphviz,果然是最适合我这种人画图的工具。
大体介绍下graphviz的实现,它是用c语言实现了一些图布局算法,通过这些算法,可以将图中的节点在画布上比较均匀的分布,缩短节点之间的边长,并且尽量的减少边的交叉。graphviz提供命令式的绘图方式,它提供一个dot语言 用来编写绘图脚本,然后对这个脚本进行解析,分析出其中的顶点,边以及子图,然后根据属性进行绘制。graphviz使用三种对象node,edge,graph来描述一个图,因为一个图通常就是由定点和边组成的。
画图步骤
(1) 编写脚本demo.dot
- digraph G {
- main->parse->execute;
- main->init;
- main->cleanup
- execute->make_string;
- execute->printf;
- init->make_string;
- main->printf;
- execute->compare;
-
}
(2) 终端执行命令生成jpg文件
- #dot -Tjpg demo.dot -o demo.jpg
由此一个jpeg文件就生成了,看下效果
除了dot语言意外,graphviz还支持其他语言。node,edge这些对象都包含属性的概念,通过为一个顶点或者边定义属性,可以规定一个顶点的形状,点的颜色等等。一个node的shape定义了顶点的形状,代表类型有这么几种:(1)多边形类型(2)纯文本类型(3)基于记录类型。这里主要解释一下记录类型,看下面这个脚本:
- digraph structs {
- struct1 [shape=record,label=" left | mid | right"];
- struct2 [shape=record,label=" one | two"];
- struct3 [shape=record,label="hello\nworld | {b | {c | d | e} | f} | g | h"];
- struct1->struct2;
- struct1->struct3;
-
}
它生成的图形是这样的,
有时候我们需要边的指向更为精确,下面脚本介绍了用法
- digraph G {
- node[shape = record, height = .1];
- node0[label = " | G | "];
- node1[label = " | E | "];
- node2[label = " | B | "];
- node3[label = " | F | "];
- node4[label = " | R | "];
- node5[label = " | H | "];
- node6[label = " | Y | "];
- node7[label = " | A | "];
- node8[label = " | C | "];
- "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;
-
}
生成图片为
另一个类似的例子
- digraph G {
- nodesep = .05;
- rankdir = LR;
- node[shape = record, width = .1, height = .1];
- node0[label = " | | | | | | ", height = 2.5];
- node[width = 1.5];
- node1[label = "{ n14 | 719 |}"];
- node2[label = "{ a1 | 805 |}"];
- node3[label = "{ i9 | 718 |}"];
- node4[label = "{ e5 | 989 |}"];
- node5[label = "{ t20 | 959 |}"];
- node6[label = "{ o15 | 794 |}"];
- node7[label = "{ s19 | 659 |}"];
-
- node0:f0 -> node1:n;
- node0:f1 -> node2:n;
- node0:f2 -> node3:n;
- node0:f5 -> node4:n;
- node0:f6 -> node5:n;
- node2:p -> node6:n;
- node4:p -> node7:n;
-
}
生成了一个散列表
最后,介绍下,graphviz除了以上功能外,还提供子图的概念,如以下脚本
- digraph G {
- subgraph cluster0 {
- node [style = filled, color = white];
- style = filled;
- color = lightgrey;
- a0 -> a1 -> a2 -> a3;
- label = "process #1";
- }
- subgraph cluster1 {
- node [style = filled];
- b0 -> b1 -> b2 -> b3;
- label = "process #2";
- color = blue;
- }
- start -> a0;
- start -> b0;
- a1 -> b3;
- b2 -> a3;
- a3 -> a0;
- a3 -> end;
- b3 -> end;
-
- start [shape = Mdiamond];
- end [shape = Msquare];
-
}
生成图片为
这里只是简单的介绍一下比较有意思的概念与用法,更多用法请见官方文档。
阅读(7256) | 评论(0) | 转发(1) |