Hi, I’m Lin.

I write program.

用dot来画结构图

前两天准备画个ER图,想到很久以前有一个很帅气的工具graphviz
要说的是dot语言,花了一个下午稍微看了一下,因为不用那么精细,所以我就边做练习边写注释。
这东西其实只要会一个基本的框架,然后知道有什么内容,到需要用到什么功能再来看一下就好了(话说什么东西不是这样?!!)

  • 全局的设置:图形大小,排列方式,有向图或无向图,node之间距离
  • node的属性:形状,颜色,大小,标签
  • edge的属性:形状,颜色,大小,标签,箭头形状
    node形状, 颜色, 箭头形状

TWO EXAMPLE

digraph G {    // 第一行是digraph(有向图)或者graph(无向图)
    size = "10,10"   // 设置大小,单位是英寸
    main [shape=box] // [] 里面表示的是连接或者元素的属性,用,分开要是有不同属性的话
    main -> parse -> execute;   // 有向图用 -> 无向图用 -- ; 他们之间不可以混用
    main -> init [style=dotted];            //  语句之间用 ;  分开   或者不用分号
    cleanup [label="_cleanup"] // label 可以设置node表现的形式
    main -> cleanup
    execute -> make_string;
    printf [shape=polygon,sides=5,peripheries=3,color="#0000A0",style=filled] // 多边形的各个参数
    execute -> printf;
    init -> make_string;
    edge [color=red] // 一旦设置了edge或者node的属性,接下来创建的对象都是这个属性
    main -> printf;
    node [shape=box,style=filled,color=".7 .3 1.0"] // 颜色可以用"white","#110F9A",".7 .3 1.0"三种设置
    execute -> {make_string, printf, compare}; // {} 内可以让一个node指向多个node
}

对应的图:
dot1

digraph G {
    nodesep=.15;  //  nodesep指定两个同等级node最小距离,in inches
    ranksep=.25;     //  rangsep指定两个上下级级node最小距离,in inches
    rankdir=TB; // LR:图从左到右分布; 相应的:RL, TB, BT
    // record  
    node [shape=record];
    struct1 [label="<f0> left|<f1> mid dle|<f2> right"];
    struct2 [label="one|two"]; // 用|分开不同的空间
    struct3 [label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"]; // dot里面的转意字符符合C的规则
    struct4 [label="one | {two | three} | four"];  // 如果这里嵌套写,会自动从横着变成竖着
    struct1:f0 -> struct2;
    struct1:f1 -> struct3:here;  // 用<>括起来可以作为record中的标志,作为指向目标

    node [shape=box]
    // edge可以指向node的八个指定位置
    // 分别是 n,s,e,w,ns,ne,nw,se,ew 八个位置
    a -> b:se
    c:n -> d

    // tailport是edge开始的那一端,headport是edge指向的那一端
    e [width=1, height=2] // 指定宽度和高度
    e -> f [tailport=se, label="tailport"]
    e -> f [headport=ne, label="headport"]
}

对应的图:
dot2

PS.总觉得敲代码会比较实在一点。dot的优势在于你把图做好了,如果要修改的话实在太方便了。