Chinaunix首页 | 论坛 | 博客
  • 博客访问: 399988
  • 博文数量: 103
  • 博客积分: 3073
  • 博客等级: 中校
  • 技术积分: 1078
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-23 15:04
文章分类

全部博文(103)

文章存档

2012年(13)

2011年(76)

2010年(14)

分类:

2012-07-16 09:58:34

原文地址:graphviz笔记 作者:wahu0315210

    

    

    官方说明文档

    

    最近玩了一下graphviz,果然是最适合我这种人画图的工具。

    大体介绍下graphviz的实现,它是用c语言实现了一些图布局算法,通过这些算法,可以将图中的节点在画布上比较均匀的分布,缩短节点之间的边长,并且尽量的减少边的交叉。graphviz提供命令式的绘图方式,它提供一个dot语言 用来编写绘图脚本,然后对这个脚本进行解析,分析出其中的顶点,边以及子图,然后根据属性进行绘制。graphviz使用三种对象node,edge,graph来描述一个图,因为一个图通常就是由定点和边组成的。

    画图步骤

    (1) 编写脚本demo.dot

  1. digraph G {
  2.   main->parse->execute;
  3.   main->init;
  4.   main->cleanup
  5.   execute->make_string;
  6.   execute->printf;
  7.   init->make_string;
  8.   main->printf;
  9.   execute->compare;
  10. }

  (2) 终端执行命令生成jpg文件

  1. #dot -Tjpg demo.dot -o demo.jpg

    由此一个jpeg文件就生成了,看下效果

    除了dot语言意外,graphviz还支持其他语言。node,edge这些对象都包含属性的概念,通过为一个顶点或者边定义属性,可以规定一个顶点的形状,点的颜色等等。一个node的shape定义了顶点的形状,代表类型有这么几种:(1)多边形类型(2)纯文本类型(3)基于记录类型。这里主要解释一下记录类型,看下面这个脚本:

  1. digraph structs {
  2.   struct1 [shape=record,label=" left | mid | right"];
  3.   struct2 [shape=record,label=" one | two"];
  4.   struct3 [shape=record,label="hello\nworld | {b | {c | d | e} | f} | g | h"];
  5.   struct1->struct2;
  6.   struct1->struct3;
  7. }

    它生成的图形是这样的,

    有时候我们需要边的指向更为精确,下面脚本介绍了用法

  1. digraph G {
  2.   node[shape = record, height = .1];
  3.   node0[label = " | G | "];
  4.   node1[label = " | E | "];
  5.   node2[label = " | B | "];
  6.   node3[label = " | F | "];
  7.   node4[label = " | R | "];
  8.   node5[label = " | H | "];
  9.   node6[label = " | Y | "];
  10.   node7[label = " | A | "];
  11.   node8[label = " | C | "];
  12.   "node0":f2 -> "node4":f1;
  13.   "node0":f0 -> "node1":f1;
  14.   "node1":f0 -> "node2":f1;
  15.   "node1":f2 -> "node3":f1;
  16.   "node2":f2 -> "node8":f1;
  17.   "node2":f0 -> "node7":f1;
  18.   "node4":f2 -> "node6":f1;
  19.   "node4":f0 -> "node5":f1;
  20. }

    生成图片为

    另一个类似的例子
  1. digraph G {
  2.   nodesep = .05;
  3.   rankdir = LR;
  4.   node[shape = record, width = .1, height = .1];
  5.   node0[label = " | | | | | | ", height = 2.5];
  6.   node[width = 1.5];
  7.   node1[label = "{ n14 | 719 |}"];
  8.   node2[label = "{ a1 | 805 |}"];
  9.   node3[label = "{ i9 | 718 |}"];
  10.   node4[label = "{ e5 | 989 |}"];
  11.   node5[label = "{ t20 | 959 |}"];
  12.   node6[label = "{ o15 | 794 |}"];
  13.   node7[label = "{ s19 | 659 |}"];
  14.   node0:f0 -> node1:n;
  15.   node0:f1 -> node2:n;
  16.   node0:f2 -> node3:n;
  17.   node0:f5 -> node4:n;
  18.   node0:f6 -> node5:n;
  19.   node2:p -> node6:n;
  20.   node4:p -> node7:n;
  21. }
    生成了一个散列表
    最后,介绍下,graphviz除了以上功能外,还提供子图的概念,如以下脚本
  1. digraph G {
  2.   subgraph cluster0 {
  3.     node [style = filled, color = white];
  4.     style = filled;
  5.     color = lightgrey;
  6.     a0 -> a1 -> a2 -> a3;
  7.     label = "process #1";
  8.   }
  9.   subgraph cluster1 {
  10.     node [style = filled];
  11.     b0 -> b1 -> b2 -> b3;
  12.     label = "process #2";
  13.     color = blue;
  14.   }
  15.   start -> a0;
  16.   start -> b0;
  17.   a1 -> b3;
  18.   b2 -> a3;
  19.   a3 -> a0;
  20.   a3 -> end;
  21.   b3 -> end;
  22.   start [shape = Mdiamond];
  23.   end [shape = Msquare];
  24. }
    生成图片为
    这里只是简单的介绍一下比较有意思的概念与用法,更多用法请见官方文档。



















阅读(1276) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~