簡述
本文翻譯自Drawing Graphs using Dot and Graphvizphp
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.html
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.java
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.node
2. 介紹
2.1 什麼是DOT?
DOT是純文本圖像描述語言,對於計算機和人來講,都很容易閱讀。python
2.2 什麼是Graphviz?
Graphviz是一個開源的圖像可視化的軟件,所謂圖像可視化就是使用一種簡單的方法,來將結構化的信息表現成用抽象圖片和網絡構成的示意圖。linux
2.3 誰適合看這篇文章?
這篇文章原本是我寫來給本身當速成手冊看的。不過如今看起來已經被我弄成給學計算機的學生看的教程了。如今這篇文章能夠給任何想經過例子學習DOT的人看。git
2.4 相關材料
我博客還有相似的其餘文章TonyBallantyne.com/techgithub
若是你是想了解關於我做爲一名SF and Fantasy writer的工做,但不幸點到這篇文章的話,下面的連接可能就對你比較有用:redis
- TonyBallantyne.com: 這裏有個人小說和短故事
- Emacs Tutorial: 給做家的一個關於Emacs的簡短介紹
- My Emacs Writing Setup: 關於我如何使用Emacs的Org Mode來寫小說和短故事
譯註:這兒所謂的相關材料實際上是做者本身其餘的一些文章,跟DOT關係不大
3. 安裝
若是你要順着這個教程繼續下去,那你可能就須要要裝Graphviz套件了。Graphviz能夠在官網免費下載。spring
4. 基礎例子
4.1 簡單圖例
graph graphname {
a -- b;
b -- c;
b -- d;
d -- a;
}
4.2 同樣的圖,不同的佈局
graph graphname {
rankdir=LR; //Rank Direction Left to Right
a -- b;
b -- c;
b -- d;
d -- a;
}
4.3 簡單有向圖
digraph graphname{
a -> b;
b -> c;
a -> c;
}
4.4 帶標籤的簡單有向圖
digraph graphname{
T [label="Teacher"] // node T
P [label="Pupil"] // node P
T->P [label="Instructions", fontcolor=darkgreen] // edge T->P
}
4.5 一樣的圖,不一樣的形狀和顏色
digraph graphname {
T [label="Teacher" color=Blue, fontcolor=Red, fontsize=24, shape=box] // node T
P [label="Pupil" color=Blue, fontcolor=Red, fontsize=24, shape=box] // node P
T->P [label="Instructions", fontcolor=darkgreen] // edge T->P
}
這兒你能夠選擇的形狀有: box
, polygon
, ellipse
, oval
, circle
, point
, egg
, triangle
, plaintext
, diamond
, trapezium
, parallelogram
, house
, pentagon
, hexagon
, septagon
, octagon
, doublecircle
, doubleoctagon
, tripleoctagon
更多的形狀看這裏
4.6 總結
digraph summary{
start [label="Start with a Node"]
next [label="Choose your shape", shape=box]
warning [label="Don't go overboard", color=Blue, fontcolor=Red,fontsize=24,style=filled, fillcolor=green,shape=octagon]
end [label="Draw your graph!", shape=box, style=filled, fillcolor=yellow]
start->next
start->warning
next->end [label="Getting Better...", fontcolor=darkblue]
}
5. 高級
5.1 節省時間的技巧
單獨地去定義每個節點其實很浪費時間的,下面這個技巧可以讓你快點兒。
digraph hierarchy {
nodesep=1.0 // increases the separation between nodes
node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
edge [color=Blue, style=dashed] //All the lines look like this
Headteacher->{Deputy1 Deputy2 BusinessManager}
Deputy1->{Teacher1 Teacher2}
BusinessManager->ITManager
{rank=same;ITManager Teacher1 Teacher2} // Put them on the same level
}
5.2 記錄
你如今能夠用HTML來定義這一類節點了,這裏有更多相關信息。
digraph structs { node[shape=record] struct1 [label="<f0> left|<f1> mid\ dle|<f2> right"]; struct2 [label="{<f0> one|<f1> two\n\n\n}" shape=Mrecord]; struct3 [label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"]; struct1:f1 -> struct2:f0; struct1:f0 -> struct3:f1; }
6. 例子
6.1 有限狀態機
digraph finite_state_machine {
rankdir=LR;
size="8,5"
node [shape = circle];
S0 -> S1 [ label = "Lift Nozzle" ]
S1 -> S0 [ label = "Replace Nozzle" ]
S1 -> S2 [ label = "Authorize Pump" ]
S2 -> S0 [ label = "Replace Nozzle" ]
S2 -> S3 [ label = "Pull Trigger" ]
S3 -> S2 [ label = "Release Trigger" ]
}
6.2 數據流示意圖
digraph dfd{ node[shape=record] store1 [label="<f0> left|<f1> Some data store"]; proc1 [label="{<f0> 1.0|<f1> Some process here\n\n\n}" shape=Mrecord]; enti1 [label="Customer" shape=box]; store1:f1 -> proc1:f0; enti1-> proc1:f0; }
6.3 數據流示意圖2
digraph dfd2{
node[shape=record]
subgraph level0{
enti1 [label="Customer" shape=box];
enti2 [label="Manager" shape=box];
}
subgraph cluster_level1{
label ="Level 1";
proc1 [label="{<f0> 1.0|<f1> One process here\n\n\n}" shape=Mrecord];
proc2 [label="{<f0> 2.0|<f1> Other process here\n\n\n}" shape=Mrecord];
store1 [label="<f0> |<f1> Data store one"];
store2 [label="<f0> |<f1> Data store two"];
{rank=same; store1, store2}
}
enti1 -> proc1
enti2 -> proc2
store1 -> proc1
store2 -> proc2
proc1 -> store2
store2 -> proc1
}
6.4 對象繼承
digraph obj{
node[shape=record];
rankdir="BT";
teacher [label = "{<f0> Teacher|<f1> \n |<f2> \n }"];
course [label = "{<f0> Course|<f1> \n |<f2> \n }"];
student [label = "{<f0> Student|<f1> \n |<f2> \n }"];
lesson [label = "{<f0> Lesson |<f1> \n |<f2> \n }"];
tutorial [label = "{<f0> Tutorial|<f1> \n |<f2> \n }"];
assessment[label = "{<f0> Assessment|<f1> \n |<f2> \n }"];
coursework [label = "{<f0> Coursework|<f1> \n |<f2> \n }"];
exam [label = "{<f0> Exam|<f1> \n |<f2> \n }"];
{rank=same; teacher course student}
teacher->course [dir="forward",arrowhead="none",arrowtail="normal",headlabel="1",taillabel="1.."];
student->course [dir="forward",arrowhead="none",arrowtail="normal",headlabel="1",taillabel="1.."];
lesson->course [dir="forward",arrowhead="diamond",arrowtail="normal"];
tutorial->course [dir="forward",arrowhead="diamond",arrowtail="normal"];
assessment->course [dir="forward",arrowhead="diamond",arrowtail="normal"];
coursework->assessment;
exam->assessment;
}
6.5 關係型實體
digraph ER{
node[shape=box];
Book;
Customer;
Loan;
{rank=same;Book,Customer,Loan}
Book->Loan[dir="forward",arrowhead="crow",arrowtail="normal"];
Customer->Loan[dir="forward",arrowhead="crow",arrowtail="normal"];
}
7. 參考
如下多是你在畫圖時候最有用的一些屬性,完整的列表能夠在這裏看。
7.1 圖像屬性
label="My Graph"; # 給圖像設置標籤 rankdir=LR; # 將圖片由原來的從上到下佈局變成從左到右佈局 {rank=same; a, b, c } # 將一組元素放到同一個level splines="line"; # 讓邊框變爲直線,沒有曲線和銳角 K=0.6; # 用來在佈局中影響spring屬性,spring屬性能夠用於將節點往外推,這個在twopi和sfdp佈局中頗有用。
譯註:暫時還沒明白這個spring屬性應該怎麼翻,初步猜想是彈性。胡克定律裏面的常量名也叫K。
7.2 交點屬性
[label="Some Label"] # 給交點打標籤 [color="red"] # 給交點上色 [fillcolor="blue"] # 設置交點的填充色
7.3 邊的屬性
[label="Some Label"] # 給邊設置標籤 (設置路徑權重的時候頗有用) [color="red"] # 給交點上色 (標示路徑的時候頗有用) [penwidth=2.0] # 給邊適配厚度,標示路徑的時候頗有用。
7.4 尺寸, 背景顏色
fixedsize=true; size="1,1"; resolution=72; bgcolor="#C6CFD532"; # 不是我偷懶不翻譯哦,原文就沒有解釋。
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語言,其餘語言也能夠相似操做
(org-babel-do-load-languages (quote org-babel-load-languages) (quote ( (emacs-lisp . t) (java . t) (dot . t) (ditaa . t) (R . t) (python . t) (ruby . t) (gnuplot . t) (clojure . t) (sh . t) (ledger . t) (org . t) (plantuml . t) (latex . t) ) ) )
8.2.2 將Dot嵌入Emacs
Org Mode經過使用Library of Babel來解析各類語言。要想這麼作的話,就用begin_src
和end_src
標籤把你的dot代碼想下面這樣包含進去。你也須要在包裹的時候像下面那樣添加一些命令行參數。
用<s[TAB]
快捷鍵能夠快速生成一個begin_src
代碼塊。
#+begin_src dot :file ./img/example1.png :cmdline -Kdot -Tpng
graph graphname {
a -- b;
b -- c;
b -- d;
d -- a;
}
#+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)