Graphviz 画图和例子

Graphviz 探索

  • 简介
    graphviz是贝尔实验室开发的一个开源的工具包,它使用一个特定的DSL(领域特定语言):dot作为脚本语言,然后使用布局引擎来解析此脚本,并完成自动布局。graphviz提供丰富的导出格式,如常用的图片格式,SVG,PDF格式等。

    graphviz中包含了众多的布局器:

    1. dot 默认布局方式,主要用于有向图
    2. neato 基于spring-model(又称force-based)算法
    3. twopi 径向布局
    4. circo 圆环布局
    5. fdp 用于无向图

    graphviz的设计初衷是对有向图/无向图等进行自动布局,开发人员使 用dot脚本定义图形元素,然后选择算法进行布局,最终导出结果。

      首先,在dot脚本中定义图的顶点和边,顶点和边都具有各自的属性,比如形状,颜色,填充模式,字体,样式等。然后使用合适的布局算法进行布局。布局算法除了绘制各个顶点和边之外,需要尽可能的将顶点均匀的分布在画布上,并且尽可能的减少边的交叉(如果交叉过多,就很难看清楚顶点之间的关系了)。
      所以使用graphviz的一般流程为:

    1. 定义一个图,并向图中添加需要的顶点和边
    2. 为顶点和边添加样式
    3. 使用布局引擎进行绘制
  • 绘制dot图

    常用参数
    格式:dot -T<type> -o<outfile> <infile.dot>
    【dot 可以替换为circo等其他算法】
    输入文件是<infile.dot>,生成的格式由<type>指定,生成的文件是<outfile>。
    其中-T<type>包括:
    -Tps (PostScript),
    -Tsvg -Tsvgz (Structured Vector Graphics),
    -Tfig (XFIG  graphics),
    -Tmif  (FrameMaker graphics),
    -Thpgl (HP pen plotters),
    -Tpcl (Laserjet printers),
    -Tpng -Tgif (bitmap graphics),
    -Tdia (GTK+ based diagrams),
    -Timap (imagemap files for httpd servers for each node or edge  that  has a non-null "href" attribute.),
    -Tcmapx (client-side imagemap for use in html and xhtml).
  • 下面简单介绍下DOT语言的语法:

    无向图 :在最简单的应用中,DOT语言可以用来描述一张无向图。无向图显示了对象间最简单的关系,例如人之间的友谊。使用关键字graph开始一张无向图的定义,并用大括号包含要描述的节点,双连字号(–)被用来描述节点间的关系。另外,一行的末尾需要加上分号(;)。

    graph graphname {
     a -- b -- c;
     b -- d;
    }

    有向图 :类似于无向图,DOT语言也可以用来描述一张有向图,类似于流程图和树状图。其语法与无向图相似,但要在图的最开始使用关键字’digraph’,并用箭头(->)表示节点直接的关系。

    digraph graphname {
     a -> b -> c;
     b -> d;
    } 

    属性 :DOT语言中,可以对节点和边添加不同的属性。这些属性可以控制节点和边的显示样式,例如颜色,形状和线形。可以在语句和句尾的分号间放置一对方括号,并在其中中放置一个或多个属性-值对。多个属性可以被逗号和空格(, )分开。节点的属性被放置在只包含节点名称的表达式后。

     graph graphname {
         // label属性可以改变节点的显示名称
         a [label="Foo"];
         // 节点形状被改变了
         b [shape=box];
         // a-b边和b-c边有相同的属性
         a -- b -- c [color=blue];
         b -- d [style=dotted];
     }   

    注释 :DOT语言支持C语言与C++风格的单行与多行注释。另外,也支持Shell脚本风格的以#开头的注释。

     // 单行注释
     /* 多行注释 */
     # 如此的行也会被忽略。
  • Example-1

    digraph{
            //attributes
        label="byPass-Branch"
        node[color=red];
        //nodes
        headNode->node1;
        headNode->node2;
        node1->node3;
    
        node[shape=box,color=black];
        //distribute
        headNode->fromApp1[style=dotted];
        headNode->fromApp2[style=dotted];
        headNode->headApp[style=dotted,color=blue];
    
        node1->headApp[style=dotted];
        node1->fromApp3[style=dotted];
        node1->node1App[style=dotted,color=blue];
    
        node2->headApp[style=dotted];
        node2->node2App[style=dotted,color=blue];
    
        node3->node1App[style=dotted];
        node3->fromApp4[style=dotted];
        node3->node3App[style=dotted,color=blue];
    }

    图片1

  • Example-2

    digraph G {
    size="200,200";
    center=true;
    rankdir=LR;
    //子图
    subgraph cluster_0 {
        style=filled;
        color=lightgrey;
        node [style=filled,color=white];
        a0 -> a1 -> a2 -> a3;
        label = "process #1";
    }
    subgraph cluster_1 {
        node [style=filled];
        b0 -> b1 -> b2 -> b3;
        label = "process #2";
        color=blue;
    
        subgraph cluster_2 {
            node [style=filled];
            c1[shape=circle,peripheries=3,color=red];
            c0 -> c1 -> c2 -> c3[color=yellow];
            label = "process #3";
            color=blue
        }
    }
    //定义节点和边的属性
    start -> a0[style=bold,label="first",decorate=true];
    start -> b0;
    a1 -> b3[style=dotted,color=red,dir=both];
    b2 -> a3[style=dashed,dir=back];
    a3 -> a0[weight=20];
    a3 -> end;
    {b3,c3} -> end;
    
    a3[shape=ellipse,color=green];
    a1[color=red,style=diagonals];
    a2[shape=plaintext,color=orange];
    start [shape=Mdiamond];
    end [shape=Msquare,label="make a\n End"];
    }

    图2

  • Example-3

    digraph G {
    //多边形
    end->a->{e,c,d};
    a[shape=polygon,sides=5,peripheries=3,color=lightblue,style=filled];
    c[shape=polygon,sides=4,skew=.4,label="hello world"];
    d[shape=invtriangle];
    e[shape=polygon,sides=4,distortion=.7];
    
    node1[shape=record,label="left0|middile0|right0"];
    node2[shape=record,label="O1|{O2|{O3|04}|O5}|O6"];
    node1->node2;
    
    
    //record 记录
    node[shape=record];
    struct1[shape=record,label="<f0>left|<f1> mid\ dle|<f2> right"];
    struct2[shape=record,label="<f0> one|<f1> two"];
    struct3[shape=record,label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"];
    struct1->struct2;
    struct1->struct3;
    }

    图3

  • Example-4

    digraph st2{
    
    fontname = "Verdana";
    fontsize = 10;
    rankdir=TB;
    node [fontname = "Verdana", fontsize = 10, color="skyblue", shape="record"];
    edge [fontname = "Verdana", fontsize = 10, color="crimson", style="solid"];
    
    st_hash_type [label="{<head>st_hash_type|(*compare)|(*hash)}"];
    st_table_entry [label="{<head>st_table_entry|hash|key|record|<next>next}"];
    st_table [label="{st_table|<type>type|num_bins|num_entries|<bins>bins}"];
    
    st_table:bins -> st_table_entry:head;
    st_table:type -> st_hash_type:head;
    st_table_entry:next -> st_table_entry:head [style="dashed", color="forestgreen"];
    }

    图4

    使用Circo算法
    这里写图片描述

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值