使用DOT语言和Graphviz绘图(翻译)

Date Wed 26 November 2014 Tags graphviz / dot

简述


本文翻译自Drawing Graphs using Dot and Graphviz

1. 许可


Copyright (C) 2013, 2014 Tony Ballantyne. Permission is granted to
copy, distribute and/or modify this document under the terms of the GNU
Free Documentation License, Version 1.3 or any later version published
by the Free Software Foundation; with no Invariant Sections, no
Front-Cover Texts, and no Back-Cover Texts.

Code in this document is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This code is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

2. 介绍


2.1 什么是DOT?

DOT是纯文本图像描述语言,对于计算机和人来说,都很容易阅读。

2.2 什么是Graphviz?

Graphviz是一个开源的图像可视化的软件,所谓图像可视化就是使用一种简单的方法,来将结构化的信息表现成用抽象图片和网络构成的示意图。

2.3 谁适合看这篇文章?

这篇文章本来是我写来给自己当速成手册看的。不过现在看起来已经被我弄成给学计算机的学生看的教程了。现在这篇文章可以给任何想通过例子学习DOT的人看。

2.4 相关材料

我博客还有类似的其他文章TonyBallantyne.com/tech

如果你是想了解关于我作为一名SF and Fantasy writer的工作,但不幸点到这篇文章的话,下面的链接可能就对你比较有用:

译注:这儿所谓的相关材料其实是作者自己其他的一些文章,跟DOT关系不大

3. 安装


如果你要顺着这个教程继续下去,那你可能就需要要装Graphviz套件了。Graphviz可以在官网免费下载。

4. 基础例子


4.1 简单图例

  1. graph graphname {
  2. a -- b;
  3. b -- c;
  4. b -- d;
  5. d -- a;
  6. }


4.2 一样的图,不一样的布局

  1. graph graphname {
  2. rankdir=LR; //Rank Direction Left to Right
  3. a -- b;
  4. b -- c;
  5. b -- d;
  6. d -- a;
  7. }


4.3 简单有向图

  1. digraph graphname{
  2. a -> b;
  3. b -> c;
  4. a -> c;
  5. }


4.4 带标签的简单有向图

  1. digraph graphname{
  2.  
  3. T [label="Teacher"] // node T
  4. P [label="Pupil"] // node P
  5.  
  6. T->P [label="Instructions", fontcolor=darkgreen] // edge T->P
  7. }


4.5 同样的图,不同的形状和颜色

  1. digraph graphname {
  2. T [label="Teacher" color=Blue, fontcolor=Red, fontsize=24, shape=box] // node T
  3. P [label="Pupil" color=Blue, fontcolor=Red, fontsize=24, shape=box] // node P
  4.  
  5. T->P [label="Instructions", fontcolor=darkgreen] // edge T->P
  6. }

这儿你可以选择的形状有: box, polygon, ellipse, oval, circle, point, egg, triangle, plaintext, diamond, trapezium, parallelogram, house, pentagon, hexagon, septagon, octagon, doublecircle, doubleoctagon, tripleoctagon 更多的形状看这里


4.6  总结

  1. digraph summary{
  2. start [label="Start with a Node"]
  3. next [label="Choose your shape", shape=box]
  4. warning [label="Don't go overboard", color=Blue, fontcolor=Red,fontsize=24,style=filled, fillcolor=green,shape=octagon]
  5. end [label="Draw your graph!", shape=box, style=filled, fillcolor=yellow]
  6.  
  7. start->next
  8. start->warning
  9. next->end [label="Getting Better...", fontcolor=darkblue]
  10. }

5. 高级


5.1 节省时间的技巧

单独地去定义每一个节点其实很浪费时间的,下面这个技巧能够让你快点儿。

  1. digraph hierarchy {
  2.  
  3. nodesep=1.0 // increases the separation between nodes
  4.  
  5. node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
  6. edge [color=Blue, style=dashed] //All the lines look like this
  7.  
  8. Headteacher->{Deputy1 Deputy2 BusinessManager}
  9. Deputy1->{Teacher1 Teacher2}
  10. BusinessManager->ITManager
  11. {rank=same;ITManager Teacher1 Teacher2} // Put them on the same level
  12. }


5.2 记录

你现在可以用HTML来定义这一类节点了,这里有更多相关信息。

  1. digraph structs {
  2. node[shape=record]
  3. struct1 [label="<f0> left|<f1> mid\ dle|<f2> right"];
  4. struct2 [label="{<f0> one|<f1> two\n\n\n}" shape=Mrecord];
  5. struct3 [label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"];
  6. struct1:f1 -> struct2:f0;
  7. struct1:f0 -> struct3:f1;
  8. }

6. 例子


6.1 有限状态机

  1. digraph finite_state_machine {
  2. rankdir=LR;
  3. size="8,5"
  4. node [shape = circle];
  5. S0 -> S1 [ label = "Lift Nozzle" ]
  6. S1 -> S0 [ label = "Replace Nozzle" ]
  7. S1 -> S2 [ label = "Authorize Pump" ]
  8. S2 -> S0 [ label = "Replace Nozzle" ]
  9. S2 -> S3 [ label = "Pull Trigger" ]
  10. S3 -> S2 [ label = "Release Trigger" ]
  11. }


6.2 数据流示意图

  1. digraph dfd{
  2. node[shape=record]
  3. store1 [label="<f0> left|<f1> Some data store"];
  4. proc1 [label="{<f0> 1.0|<f1> Some process here\n\n\n}" shape=Mrecord];
  5. enti1 [label="Customer" shape=box];
  6. store1:f1 -> proc1:f0;
  7. enti1-> proc1:f0;
  8. }


6.3 数据流示意图2

  1. digraph dfd2{
  2. node[shape=record]
  3. subgraph level0{
  4. enti1 [label="Customer" shape=box];
  5. enti2 [label="Manager" shape=box];
  6. }
  7. subgraph cluster_level1{
  8. label ="Level 1";
  9. proc1 [label="{<f0> 1.0|<f1> One process here\n\n\n}" shape=Mrecord];
  10. proc2 [label="{<f0> 2.0|<f1> Other process here\n\n\n}" shape=Mrecord];
  11. store1 [label="<f0> |<f1> Data store one"];
  12. store2 [label="<f0> |<f1> Data store two"];
  13. {rank=same; store1, store2}
  14.  
  15. }
  16. enti1 -> proc1
  17. enti2 -> proc2
  18. store1 -> proc1
  19. store2 -> proc2
  20. proc1 -> store2
  21. store2 -> proc1
  22. }


6.4 对象继承

  1. digraph obj{
  2. node[shape=record];
  3. rankdir="BT";
  4.  
  5. teacher [label = "{<f0> Teacher|<f1> \n |<f2> \n }"];
  6. course [label = "{<f0> Course|<f1> \n |<f2> \n }"];
  7. student [label = "{<f0> Student|<f1> \n |<f2> \n }"];
  8. lesson [label = "{<f0> Lesson |<f1> \n |<f2> \n }"];
  9. tutorial [label = "{<f0> Tutorial|<f1> \n |<f2> \n }"];
  10. assessment[label = "{<f0> Assessment|<f1> \n |<f2> \n }"];
  11. coursework [label = "{<f0> Coursework|<f1> \n |<f2> \n }"];
  12. exam [label = "{<f0> Exam|<f1> \n |<f2> \n }"];
  13.  
  14. {rank=same; teacher course student}
  15.  
  16. teacher->course [dir="forward",arrowhead="none",arrowtail="normal",headlabel="1",taillabel="1.."];
  17. student->course [dir="forward",arrowhead="none",arrowtail="normal",headlabel="1",taillabel="1.."];
  18. lesson->course [dir="forward",arrowhead="diamond",arrowtail="normal"];
  19. tutorial->course [dir="forward",arrowhead="diamond",arrowtail="normal"];
  20. assessment->course [dir="forward",arrowhead="diamond",arrowtail="normal"];
  21. coursework->assessment;
  22. exam->assessment;
  23. }


6.5 关系型实体

  1. digraph ER{
  2. node[shape=box];
  3. Book;
  4. Customer;
  5. Loan;
  6. {rank=same;Book,Customer,Loan}
  7. Book->Loan[dir="forward",arrowhead="crow",arrowtail="normal"];
  8. Customer->Loan[dir="forward",arrowhead="crow",arrowtail="normal"];
  9. }

7. 参考


以下可能是你在画图时候最有用的一些属性,完整的列表可以在这里看。

7.1 图像属性

  1. label="My Graph"; # 给图像设置标签
  2.  
  3. rankdir=LR; # 将图片由原来的从上到下布局变成从左到右布局
  4.  
  5. {rank=same; a, b, c } # 将一组元素放到同一个level
  6.  
  7. splines="line"; # 让边框变为直线,没有曲线和锐角
  8.  
  9. K=0.6; # 用来在布局中影响spring属性,spring属性可以用于将节点往外推,这个在twopi和sfdp布局中很有用。
译注:暂时还没明白这个spring属性应该怎么翻,初步猜测是弹性。胡克定律里面的常量名也叫K。

7.2 交点属性

  1. [label="Some Label"] # 给交点打标签
  2.  
  3. [color="red"] # 给交点上色
  4.  
  5. [fillcolor="blue"] # 设置交点的填充色

7.3 边的属性

  1. [label="Some Label"] # 给边设置标签 (设置路径权重的时候很有用)
  2.  
  3. [color="red"] # 给交点上色 (标示路径的时候很有用)
  4.  
  5. [penwidth=2.0] # 给边适配厚度,标示路径的时候很有用。

7.4 尺寸, 背景颜色

  1. fixedsize=true;
  2. size="1,1";
  3. resolution=72;
  4. bgcolor="#C6CFD532";
  5.  
  6. # 不是我偷懒不翻译哦,原文就没有解释。

8. 附录


8.1 拓展阅读

An Introduction to GraphViz and dot

Graphviz Examples and Tutorial

8.2 使用Emacs的Org Mode

Emacs的Org Mode不管对于写作,还是执行和导出DOT图片都是个很理想的工作环境。

8.2.1 配置

下载并安装Graphviz,然后把相关路径加到exec-path这个变量里去。

你也要把你的.emacs文件更新成能够把DOT作为babel语言加载,下面这个配置可以很容易的设置DOT为babel语言,其他语言也可以类似操作

  1. (org-babel-do-load-languages
  2. (quote org-babel-load-languages)
  3. (quote
  4. (
  5. (emacs-lisp . t)
  6. (java . t)
  7. (dot . t)
  8. (ditaa . t)
  9. (R . t)
  10. (python . t)
  11. (ruby . t)
  12. (gnuplot . t)
  13. (clojure . t)
  14. (sh . t)
  15. (ledger . t)
  16. (org . t)
  17. (plantuml . t)
  18. (latex . t)
  19. )
  20. )
  21. )
8.2.2 将Dot嵌入Emacs

Org Mode通过使用Library of Babel来解析各种语言。要想这么做的话,就用begin_srcend_src标签把你的dot代码想下面这样包含进去。你也需要在包裹的时候像下面那样添加一些命令行参数。

<s[TAB]快捷键可以快速生成一个begin_src代码块。

  1. #+begin_src dot :file ./img/example1.png :cmdline -Kdot -Tpng
  2. graph graphname {
  3. a -- b;
  4. b -- c;
  5. b -- d;
  6. d -- a;
  7. }
  8. #+end_src
8.2.3 命令行相关

#+begin_ src dot :file ./img/example1.png :cmdline -Kdot -Tpng里的:cmdline -Kdot -Tpng就是命令行参数. 他们告诉dot如何渲染和展示。

  • -Kdot 使用dot布局方式. 你也可以尝试其他的布局方式,比如Kneato, Kcirco, Ktwopi, Kfdp, Ksfdp
  • -Tpng 渲染成png格式

完整的命令行参数可以看这里

Date: <2013-10-21 Mon>

Author: Tony Ballantyne

Translator: Casa Taloyum

Created: 2014-04-12 Sat 10:13

Emacs 23.3.1 (Org mode 8.0.2)


评论系统我用的是Disqus,不定期被墙。所以如果你看到文章下面没有加载出评论列表,翻个墙就有了。

本文遵守CC-BY。 请保持转载后文章内容的完整,以及文章出处。本人保留所有版权相关权利。

我的博客拒绝挂任何广告,如果您觉得文章有价值,可以通过支付宝扫描下面的二维码捐助我。



Comments

comments powered by Disqus


© 2017 Casa Taloyum
· Powered by pelican-bootstrap3,
Pelican,
Bootstrap

使用DOT语言和Graphviz绘图(翻译)的更多相关文章

  1. [译]使用DOT语言和GraphvizOnline来可视化你的ASP.NETCore3.0终结点01

    这是系列文章中的第一篇:使用GraphvizOnline可视化ASP.NETCore3.0终结点.. 第1部分-使用DOT语言来可视化你的ASP.NETCore3.0终结点(本文) 第2部分-向ASP ...

  2. 【翻译】Scriban README 文本模板语言和.NET引擎

    scriban Scriban是一种快速.强大.安全和轻量级的文本模板语言和.NET引擎,具有解析liquid模板的兼容模式 Github https://github.com/lunet-io/sc ...

  3. 使用Graphviz绘图(一)

    前言 日常开发或者编写课程论文时,除了代码文档的编写,其中一个很重要的部分就是需要绘制流程图.示意图 绘制流程图有很多工具,一般常见的就有如下几种: Word.PPT等办公软件 Viso以及开源的Di ...

  4. 聊聊C语言和ABAP

    这个公众号之前的文章,分享的都是Jerry和SAP成都研究院的同事在工作中学到的一些知识和感受.而今天这篇文章,写作的由来是因为最近我又参与了SAP成都数字创新空间应聘者的面试,和一些朋友聊了一些关于 ...

  5. C语言和C++中动态申请内存

      在C语言和C++的动态内存的使用方法是不同的,在C语言中要使用动态内存要包含一个头文件即 #include<malloc.h> 或者是#include<stdlib.h>  ...

  6. C语言和C++篇

    C语言和C++篇 基本上所有主流的编程语言都有String的标准库,因为字符串操作是我们每个程序员几乎每天都要遇到的.想想我们至今的代码,到底生成和使用了多少String!标题上所罗列的语言,可以看成 ...

  7. c语言和java的区别

    今晚读了一下c程序设计语言,这是一本经典书籍,发现C语言和java有很多是相同的,毕竟java是由c语言进化来的. 我大概从我自己的思考来谈谈不同点 1.c语言是面向过程,主要单位是函数,变量和函数的 ...

  8. CHENGDU1-Python编程语言和PEP8规范

    CHENGDU1-Python编程语言和PEP8规范 PEP8规范6条? 答:PEP8规范说白了就是一种规范,可以遵守,也可以不遵守,遵守PEP8可以让代码的可读性更高. 代码编排:---缩进,4个空 ...

  9. 从C,C++,JAVA和C#看String库的发展(一)----C语言和C++篇

    转自: http://www.cnblogs.com/wenjiang/p/3266305.html 基本上所有主流的编程语言都有String的标准库,因为字符串操作是我们每个程序员几乎每天都要遇到的 ...

随机推荐

  1. 用Bandwidth Controller实现局域网带宽控制

    用Bandwidth Controller实现局域网带宽控制 很多做网络管理的朋友都知晓微软的ISA Serve防火墙,在ISA Server 2000中,带宽管理功能是通过设置优先级来实现,但是管理 ...

  2. 《二》Java IO 流的分类介绍

    一.根据流向分为输入流和输出流: 注意输入流和输出流是相对于程序而言的. 输出:把程序(内存)中的内容输出到磁盘.光盘等存储设备中        输入:读取外部数据(磁盘.光盘等存储设备的数据)到程序 ...

  3. react实战项目-很适合进阶

    前言 前段时间学习完了React的基础,自己网上找了一些实战项目,做了几个感觉项目不是很全面,就想做一个完整的项目来提升自己的React水平.以前学习Vue的时候,就看过bailicangdu大神的v ...

  4. 模板 Fail树

    fail树就是将Trie图的Fail指针反指,从而生成一棵树,这个树的性质是:子节点对应字符串为以当前串为后缀,而子节点为原串的前缀,前缀的后缀就是嵌套在原串中的子串. 模板:BZOJ3172 Des ...

  5. Unity实现发送QQ邮件功能

    闲来无聊,用Unity简单实现了一个发送邮件的功能,希望与大家互相交流互相进步,大神勿喷,测试的是QQ邮件用到的是MailMessage类和SmtpClient类首先如果发送方使用的是个人QQ邮箱账号 ...

  6. C++编码优化之减少冗余拷贝或赋值

    临时变量 目前遇到的一些产生临时变量的情况:函数实参.函数返回值.隐式类型转换.多余的拷贝 1. 函数实参 这点应该比较容易理解,函数参数,如果是实参传递的话,函数体里的修改并不会影响调用时传入的参数 ...

  7. Weblogic问题汇总

    1. weblogic unable to get file lock问题 在项目使用过程中,非正常结束Weblogic进程导致Weblogic无法启动,出现以下错误: <BEA-141281& ...

  8. 【组件】微信小程序input搜索框的实现

    开发小程序的过程,是一个学习知识,解决问题的过程,每当实现了一个需求,总会有很大的成就感,每天记录一个开发过程中的细节.实现效果如下: 官方参考链接:https://developers.weixin ...

  9. 你真得懂Javascript中的==等于运算符吗?

    var i = 2; Number.prototype.valueOf = function() { return i++; }; var a = new Number( 42 ); if (a == ...

  10. amazeui学习笔记--css(常用组件12)--面板Panel

    amazeui学习笔记--css(常用组件12)--面板Panel 一.总结 1.面板基本样式:默认的 .am-panel 提供基本的阴影和边距,默认边框添加 .am-panel-default,内容 ...