用graphviz画图

graphviz画图(转载

基本概念

计算机科学中的数据结构中,图算是最为复杂的一种数据结构了,图G由顶点(vertex),以及连接这些顶点的边(edge)组成,表示为G(V,E),其中V表示顶点的集合,E表示边的集合。图有着非常广阔的应用,如网络拓扑,函数调用结构,模拟神经网络等等。

 

graphviz中,也有对应的数据结构,如node, edge, subgraph等。一般来说,我们只需要定义好顶点,边的属性,graphviz的布局引擎可以自动完成布局工作,使得顶点的分布比较均匀,边的交叉尽可能的少。

 

如下图,为graphviz官方的一个图(UNIX系统的进化图)


http://abruzzi.javaeye.com/upload/attachment/129019/e67029e9-21a2-3345-9b44-fb68695ab671.png

 

布局方式

graphviz提供5中布局方式:

  • dot graphviz的默认布局方式,用于画有向图
  • neato spring-model(基于斥力+张力的布局)
  • twopi
  • circo 在使用过程中,感觉circo算法布局出来的图形最为合理
  • fdp

比如我另一篇文章介绍的BBMS(基于总线的消息服务) http://code.google.com/p/bbms/  的设计图,分别用dotcirco进行布局,效果如下:


http://abruzzi.javaeye.com/upload/attachment/129000/533e8377-3599-3477-b3fb-0cd3b49d2bac.png
 
上图为使用dot布局的结果

 


http://abruzzi.javaeye.com/upload/attachment/128998/a0fc6b05-b02c-3c79-8817-1d3f1914a72d.png

此图为使用circo进行布局的结果,比dot的布局要漂亮一些。

 

graphviz脚本的代码如下:

 

Graphviz代码

  1. digraph bbms{   
  2.   
  3.     size="7.5,7.5";   
  4.   
  5.     bbms_client1 [shape=box];   
  6.   
  7.     bbms_client2 [shape=box];   
  8.   
  9.     bbms_client3 [shape=box];   
  10.   
  11.     bbms_client4 [shape=box];   
  12.   
  13.     bus_server [shape=box, style="filled", color=".5 .7 1.0"];   
  14.   
  15.     net [style="filled,dotted" color="yellow"];   
  16.        
  17.   
  18.   
  19.     bbms_client1 -> bus_server [label="register", color="green"];   
  20.   
  21.     bus_server -> bbms_client1 [label="notify", color="red"];   
  22.   
  23.   
  24.     bbms_client2 -> bus_server [label="register"];   
  25.   
  26.     bus_server -> bbms_client2 [label="notify"];   
  27.   
  28.        
  29.   
  30.     bbms_client3 -> net -> bus_server [label="register"];   
  31.   
  32.     bus_server -> net -> bbms_client3 [label="notify"];   
  33.        
  34.   
  35.     bbms_client4 -> bus_server [label="register"];   
  36.   
  37.     bus_server -> bbms_client4 [label="notify"];   
  38.   
  39.   
  40. }  
digraph bbms{
 
    size="7.5,7.5";
 
    bbms_client1 [shape=box];
 
    bbms_client2 [shape=box];
 
    bbms_client3 [shape=box];
 
    bbms_client4 [shape=box];
 
    bus_server [shape=box, style="filled", color=".5 .7 1.0"];
 
    net [style="filled,dotted" color="yellow"];
    
 
 
    bbms_client1 -> bus_server [label="register", color="green"];
 
    bus_server -> bbms_client1 [label="notify", color="red"];
 
 
    bbms_client2 -> bus_server [label="register"];
 
    bus_server -> bbms_client2 [label="notify"];
 
    
 
    bbms_client3 -> net -> bus_server [label="register"];
 
    bus_server -> net -> bbms_client3 [label="notify"];
    
 
    bbms_client4 -> bus_server [label="register"];
 
    bus_server -> bbms_client4 [label="notify"];
 
 
}

 

使用circo画比较复杂的图,布局会更漂亮,最近在做一个基于java的图布局框架,jraph,初步目标就是可以支持dotcirco布局算法。


http://abruzzi.javaeye.com/upload/attachment/129008/d8124f08-c151-3e32-b58d-eb7a133ed095.png

Graphviz代码

  1. digraph gbbms{   
  2.   
  3.     node [fontname="verdana"];   
  4.   
  5.     fontname="Verdana";   
  6.   
  7.     size="8,8";   
  8.   
  9.     subgraph busmgr{   
  10.   
  11.         node [shape=box, color=blue];   
  12.   
  13.         label="BUS Manager";   
  14.   
  15.         BUS -> Daemon_Thread [label="Worker Thread"];   
  16.   
  17.     }   
  18.   
  19.   
  20.     subgraph bbmsclient1{   
  21.   
  22.         node [shape=box, color=red];   
  23.   
  24.         color=blue;   
  25.   
  26.         label="BBMS Client \#1";   
  27.   
  28.         notifiableEntry_1 -> Message_1_1;   
  29.   
  30.         notifiableEntry_1 -> Message_1_2;   
  31.   
  32.         notifiableEntry_1 -> Message_1_3;   
  33.   
  34.   
  35.     }   
  36.   
  37.   
  38.     subgraph bbmsclient2{   
  39.   
  40.         node [shape=box, color=grey];   
  41.   
  42.         label="BBMS Client \#2";   
  43.   
  44.         notifiableEntry_2 -> Message_2_1;   
  45.   
  46.         notifiableEntry_2 -> Message_2_2;   
  47.   
  48.         notifiableEntry_2 -> Message_2_3;   
  49.   
  50.     }   
  51.   
  52.   
  53.     notifiableEntry_1 -> BUS [color=green, label="register"];   
  54.   
  55.     notifiableEntry_2 -> BUS [color=green, label="register"];   
  56.   
  57.     BUS -> notifiableEntry_1 [color=red, label="notify"];   
  58.   
  59.     BUS -> notifiableEntry_2 [color=red, label="notify"];   
  60.   
  61. }  
digraph gbbms{
 
 node [fontname="verdana"];
 
 fontname="Verdana";
 
 size="8,8";
 
 subgraph busmgr{
 
  node [shape=box, color=blue];
 
  label="BUS Manager";
 
  BUS -> Daemon_Thread [label="Worker Thread"];
 
 }
 
 
 subgraph bbmsclient1{
 
  node [shape=box, color=red];
 
  color=blue;
 
  label="BBMS Client \#1";
 
  notifiableEntry_1 -> Message_1_1;
 
  notifiableEntry_1 -> Message_1_2;
 
  notifiableEntry_1 -> Message_1_3;
 
 
 }
 
 
 subgraph bbmsclient2{
 
  node [shape=box, color=grey];
 
  label="BBMS Client \#2";
 
  notifiableEntry_2 -> Message_2_1;
 
  notifiableEntry_2 -> Message_2_2;
 
  notifiableEntry_2 -> Message_2_3;
 
 }
 
 
 notifiableEntry_1 -> BUS [color=green, label="register"];
 
 notifiableEntry_2 -> BUS [color=green, label="register"];
 
 BUS -> notifiableEntry_1 [color=red, label="notify"];
 
 BUS -> notifiableEntry_2 [color=red, label="notify"];
 
}

 

从上面的图中可能会得出dot布局的结果不如circo的结论,其实不然,dot只是不适用于这个图而已,dot的布局也是非常漂亮的,比如:

 


http://abruzzi.javaeye.com/upload/attachment/129021/8267f8a6-a12b-36ab-9ac7-c35e8989b301.png

这时,如果使用circo,结果就会乱掉,如下:


 
http://abruzzi.javaeye.com/upload/attachment/129023/0f0cec87-a726-39f6-ad84-0432fc85557a.png

 

总结

graphviz的好处在于,你只需要关心数据结构的流程,或者连接的方式,而不需要考虑布局。这是经典的*nix的程序的工作方式,比如latex, mate等等,都是采用这种方式来工作的。既可以达到WYTIWYG(What you think is what you get),而不是微软所提倡的WYSIWYG(What you see is what you get).

 

 

用graphviz画图

用graphviz画图- 数据结构和算法- Tech - JavaEye论坛
1 post - Last post: Jul 26, 2009前言关于graphviz的介绍,我前面已经有专门的一篇文章了:http://abruzzi.javaeye.com/blog/429042 ,还没有接触过的可以去看一看。

用graphviz画图的相关文章推荐- 数据结构和算法- JavaEye专栏频道
用graphviz画图的相关文章:前言关于graphviz的介绍,我前面已经有专门的一篇文章了:http://abruzzi.javaeye.com/blog/429042 ,还没有接触过的可以去看一看。

用Graphviz来画图1 - Tech.Cap - BlogJava
2010年1月13日 re: 用Graphviz来画图1 2005-11-28 10:33 让变化成为计划的一部分. nice! 回复 更多评论 re: 用Graphviz来画图1 2006-10-22 17:25 煩______づの

用Graphviz来画图2 - Tech.Cap - BlogJava
2006年9月15日 re: 用Graphviz来画图2 2005-07-22 21:26 Living Not Striving re: 用Graphviz來畫圖2[未登录] 2007-04-16 23:29 jean. 你好:我想要grappa,

用Graphviz来画图2 - Java - 天天加油
用Graphviz来画图2graphviz 虽然很强大,不过有两个地方不足 对中文支持很差,在windows下还可以用utf-8来处理,在linux下面就很麻烦,我尝试多次也解决不了

使用Graphviz画图小结_互联网旁观者_百度空间
使用Graphviz画图小结. 2010-04-25 16:14 简单试用了Graphviz,非常好用。整理一些资料,做个小结。 Graphviz是贝尔实验室(AT&T Research)几个计算机牛人设计的

用Graphviz来画图1[转自JavaBlog] - 辛凯's Blog [ 效率测试] - CSDN博客
2005年7月21日 用Graphviz来画图1. Posted on 2005-07-17 23:57 cap 阅读(149) 评论(0) 于是打开google,上网查找java画图的工具,找来找去,没有看到什么好用的

用Graphviz来画图2
2005年8月10日 这下用grappa处理很成功. 顺利在java中画出图形,(效率明显比graphviz慢不少), 这样一来,第一个办法就是通过graphviz来生成dot, 然后通过grappa来显示.

某某的个人空间: 用Graphviz来画图
2007年4月10日 用Graphviz来画图1. 做了一个系统,通过配置来完成一些简单或者复杂的产品逻辑, 系统投入使用以后, 产品人员在上面配置了不少产品,产品的流程都是

Free Mind » Blog Archive » 用Graphviz 来做图的Visualization
2008年6月14日 用Graphviz 来画图最方便的就是用使用它提供的dot 语言了。例如,这样一段代码:. digraph G { main [shape=box]; /* this is a comment */ main