美文网首页花间独酌
Graphviz 的简单使用

Graphviz 的简单使用

作者: 蓝笔头 | 来源:发表于2021-08-21 10:05 被阅读0次

    1. Graphviz 简介

    本文大部分内容摘录自: 开源项目:【自动】绘图工具 Graphviz

    1.1 Graphviz 是啥?

    Graphviz 是洋文 Graph Visualization 的缩略词,是一个开源的,跨平台的自动绘图工具,其官网在 “这里”,维基百科的介绍在 “这里”。
    这玩意儿诞生于上个世纪末,来自 AT&T 的实验室,属于名门正派出身。十多年来,它已经被广泛使用于各个领域。
    Graphviz 不但是开源软件,而且是自由软件。使用它完全【无需】付费,也【没有】任何注册码之类的恶心东西。

    1.2 Graphviz 能干啥?

    “绘图工具” 有很多种,Graphviz 主要是用来绘制【关系图】。所以它更类似于微软的 Visio

    但是它与 Visio 有一个【本质上】的差异:

    • Visio 画图是【手动】的——你需要动用你的肉眼和手指头。
    • Graphviz 画图是【自动】的——你只需要告诉 Graphviz 这张图包含哪些元素,元素之间有啥关系,然后 Graphviz 可以【自动】帮你画出来。

    那么,你如何告诉 Graphviz 你要画的图形包含哪些元素捏?这就需要用到一个名叫 DOT 的描述语言。

    1.3 为啥用 Graphviz 而不用 Visio 或类似的工具?

    客观地讲,GraphvizVisio 之类的工具,各有各的特长。

    因为本文介绍的是 Graphviz,所以下面聊一下:哪些场景是 Graphviz 胜过 Visio 类工具的。

    简而言之,Graphviz 胜过 Visio 这类工具的关键在于【自动布局】。

    如果你要绘制的关系图非常复杂,这时候【手动】布局就变得极其繁琐。而 Graphviz 的自动布局功能,再复杂的关系图,也可以自动搞定。

    提示:Graphviz 的自动布局功能,【无需】人为干预就可以做到 “最小化连线交叉”。

    可以从官网的图库查看通过 Graphviz 生成图片的例子。


    1.4 安装

    1.4.1 桌面端应用

    (1)从 Graphviz 官网 下载安装包,并进行安装操作。

    添加 Grahpviz 路径到系统 `PATH` 环境变量中

    (2)从 DotEditor - Graphviz 桌面 GUI 下载 DotEditor,可以直接打开使用。

    DotEditor 依赖 GrahpvizPATH 环境变量,如果没有配置,打开 DotEditor 软件会出现如下图所示错误。

    缺少 PATH 环境变量中缺少 Grahpviz 路径

    1.4.2 Web 端服务

    2. DOT 语言入门

    前面提到,你需要通过 DOT 语言来描述一个关系图,然后 Graphviz 根据这个 DOT 语言的描述来自动生成图形。

    很多读者一听到 “语言” 就先望而生畏,其实这个 DOT 并不复杂。

    从原则上讲,它只描述三种东西,分别是:图(graph)、节点(node)、边(edge)。

    你可以通过 DOT 语言定义这三种东西的属性(比如:颜色、形状)。

    2.1 图(graph

    DOT 语言支持两种图形,分别是 “有向图(digraph) 和 无向图(graph)”。

    通俗地说,“有向图” 里面的连线是有箭头;反之,“无向图” 里面的连线是没有箭头的。

    定义一个无向图很简单,先看下面这段代码。

    graph simple
    {
        a -- b -- c;
        b -- d;
    }
    // 这是个无向图
    

    上述代码的效果图如下:


    无向图 graph

    要定义一个有向图,也很简单,代码如下:

    digraph simple
    {
        a -> b -> c;
        b -> d;
    }
    /* 这是个有向图 */
    

    上述代码的效果图如下:


    有向图 digraph

    这 2 段代码的简单释义:

    • graph 用来表示一个无向图;digraph 用来表示一个有向图。
    • 示例中的 simple 表示图的名称。
      • 图的名称可以是【英文字母、下划线、数字、中文】。
      • 最好【不要包含】其它英文的标点符号(也就是【半角符号】),可能会导致一些语法错误。
      • 但是中文标点符号(也就【全角符号】)没有关系。
    • 花括号/大括号 里面的语句表示【图的定义】——这张图包含哪些内容。
      • 每一条语句以【分号】结尾(类似于 C、C++、Java 的语法)。

    顺便提一下 DOT 语言的注释(其注释的语法与 C、C++、Java 类似),包括如下两种:

    • 单行注释:以 // 表示——【该行】后续的内容为注释
    • 多行注释:以 /**/ 包含起来的内容为注释

    2.2 节点(node

    通过上面两个例子,你应该已经获得了感性的认识。OK,下面来讨论“ 节点”(node)的概念。

    在上面两个例子中, a b c d 都是【节点名】,分别代表节点。

    在图的定义中,相同名称就代表同一个节点。
    DOT 编译器碰到一个新的名称,就认为这是一个新的节点。

    节点的命名规范类似于图的命名规范,此次不再罗嗦。
    如果某个节点没有设置 label 属性(关于【属性】,下面会聊到),那么图形中就用节点名作为该节点的标题——就好比前面两幅简单的示意图。

    2.2.1 节点(node)的属性

    在节点名之后可以使用 方括号/中括号 来定义该节点的属性,属性之间用【半角】逗号分隔。

    属性的定义采用如下形式:

    属性名 = 属性值
    

    (如果属性值包含空格,需用【半角】引号把属性值引用起来)

    常用的【属性名】包括如下:

    • label:标题
    • color:颜色
    • style:样式
    • shape:形状

    (还有更多属性,可以参见官网 “这个链接”)

    给一个示例代码及效果图,你一看就明白了:

    digraph node_attr
    {
        shape1 [shape=box, label="编程随想注:\n矩形节点"];
        shape2 [shape=circle, label="编程随想注:\n圆形节点"];
        shape3 [shape=ellipse, label="编程随想注:\n椭圆形节点"];
        shape4 [shape=polygon, sides=4, skew=0.4, label="编程随想注:\n平行四边形节点"];
        shape5 [shape=none, label="编程随想注:\n无边框节点"];
        shape1 -> shape2 -> shape3 -> shape4 -> shape5
    
        color1 [color="blue", label="编程随想注:\n蓝色边框"]
        color2 [color="green", style=filled, label="编程随想注:\n绿色填充"]
        color3 [color="#ff0000", style=filled, fillcolor="yellow", label="编程随想注:\n红色边框+黄色填充"]
        color4 [color="#0000FF" style=filled, fillcolor="green:red", label="编程随想注:\n蓝色边框+从绿色到红色渐变填充"]
        /* 上面两个节点采用 HTML 的颜色语法,dot 支持 这种语法 */
        color1 -> color2 -> color3 -> color4
    
        text1 [shape=box, fontsize=12, label="编程随想注:\n小字体"]
        text2 [shape=box, fontsize=24, label="编程随想注:\n大字体"]
        text3 [shape=box, fontcolor="blue", label="编程随想注:\n蓝色文字"]
        text4 [shape=box, label=<编程随想注:<br/><b>粗体</b> <i>斜体</i><u>下划线</u>>]
        // 注意:text4 使用 HTML 风格的 label,无需引号,但必须用尖括号
        text1 -> text2 -> text3 -> text4
    }
    

    补充说明:

    2.3 边(edge

    如前面所示,无向图的边用 -- 表示,有向图的边用 -> 表示,非常形象。

    提示:定义边的语句也是以分号结尾。

    边与节点的关键差异之处在于——节点有名称而【边没有名称】

    2.3.1 边(edge)的属性

    边也可以设置属性,其属性写在定义连线的语句末尾,语法类似节点属性。

    常用的【属性名】包括如下:

    • label:标题
      -color:颜色
    • style:线条的样式
    • dir:边的方向(仅用于有向图,可设置:正向箭头、反向箭头、双向箭头)
    • arrowhead:前端的样式
    • arrowtail:末端的样式

    (还有更多属性,可以参见官网“这个链接”)

    下面给几个示例,你自己去揣摩(以【有向图】作示范)

    digraph edge_attr
    {
        style0[label="编程随想注:\n以下是样式的示例"];
        style1[label=""] style2[label=""] style3[label=""] style4[label=""];
    
        style0 -> style1 [style=solid, label="实线"];
        style1 -> style2 [style=bold, label="粗线"];
        style2 -> style3 [style=dashed, label="短划线"];
        style3 -> style4 [style=dotted, label="虚线"];
    
        arrow0[label="编程随想注:\n以下是箭头的示例"];
        arrow1[label=""] arrow2[label=""] arrow3[label=""] arrow4[label=""] arrow5[label=""] arrow6[label=""];
        arrow0 -> arrow1 [dir=both, label="双向箭头"];
        arrow1 -> arrow2 [arrowsize=2.0, label="大箭头"];
        arrow2 -> arrow3 [arrowhead="open", label="带倒钩的箭头"];
        arrow3 -> arrow4 [arrowhead="halfopen", label="单边倒钩"];
        arrow4 -> arrow5 [arrowhead="ediamond", label="菱形箭头"];
        arrow5 -> arrow6 [arrowhead="dot", label="圆形箭头"];
    
        color0[label="编程随想注:\n以下是颜色的示例"];
        color1[label=""] color2[label=""] color3[label=""];
        color0 -> color1 [color="blue", label="蓝色"];
        color1 -> color2 [color="red:blue", label="双色"];
        color2 -> color3 [color="green:red;0.4:blue", label="颜色分段"];
    }
    
    通过 Dot Editor 生成的图形

    【提示】
    如果会出现中文乱码。
    可以需要设置 nodeedge 以及 graphfontname 属性

    字体属性设置为 serif

    2.4 图的属性

    说完了 “节点” 和 “边”,最后稍微聊一下 “图” 本身的属性。

    常用的【属性名】包括如下:

    • label:标题
    • bgcolor:颜色
    • fontname:字体名称(【不】影响节点和边)
    • fontsize:字体大小(【不】影响节点和边)
    • fontcolor:字体颜色(【不】影响节点和边)
    • center:是否居中绘制

    (还有更多属性,可以参见官网 “这个链接”)

    digraph graph_attr
    {
        graph[bgcolor="cadetblue" label="图的标题" fontsize=24 fontcolor="green"];
    
        node0 -> node1;
        node0 -> node2;
    }
    

    参考(拓展阅读)

    相关文章

      网友评论

        本文标题:Graphviz 的简单使用

        本文链接:https://www.haomeiwen.com/subject/nxozbltx.html