DOT语言学习笔记
设置点和线的形状与颜色
digraph是有向图,graph是无向图。要注意,->和–都表示图中的一条边,但是前者用于有向图中,而后者用于无向图中,不能混用。
代码示例
diaGraph G{
main -> parse -> execute
main -> init
main -> cleanup
execute -> make_string
execute -> printf
init -> make_string
main -> printf
execute -> compare
}
然后在命令行(cmd)中运行此文件,
dot -T输出格式 程序文件名.dot -o 输出文件名.输出格式
我们可以手动设置图的属性,即设置图中边的属性与图中点的属性。
我们可以在每条边后面添加中括号,在其中设置边的相关属性,也可以使用edge设置边的默认值。点的属性设置方法相同,node表示点的默认值。
diGraph G{
size = "4, 4" /*设置图片尺寸为4 * 4(英寸)*/
main[shape = box] /*设置点main形状为矩形,默认为椭圆形*/
main -> parse[weight = 8] /*设置main到parse的边的重要程度,默认为1*/
parse -> execute
main -> init[style = dotted] /*设置main到init的边的样式为点,默认为实线*/
main -> cleanup
execute -> {make_string printf} /*一次连接两条边,以隔开目标点*/
init -> make_string
edge[color = red] /*将此语句后的边的颜色设置为红色*/
main -> printf[style = bold, label = "100 times"]
node[shape = box, style = filled, color = ".7 .3 1.0"] /*设置此语句后的点的默认属性, 其中color的值采用RGB标准*/
make_string[label = "make a\nstring"]
execute -> compare
compare -> return
}
此外,还可以使用dir设置每条边的箭头方向,有forward(default),back,both,nonc,分别表示前向,反向,双向和无。如下所示:
digraph G{
A -> B[dir = both]
B -> C[dir = nonc]
C -> D[dir = back]
D -> A[dir = forward]
}
点的属性除了record和Mrecord这两种之外,其他的形状都是多边形,而我们可以对多边形进行设置。sides用于设置边数,peripheries用于设置多边形外框的层数,regular = true可以使你的多边形是一个规则的多边形,orientation = * 可以让你的多边形旋转*角度,skew后面跟一个(-1.0~1.0)的小数,能使你的图形斜切一个角度,distortion则可以令你的图形产生透视效果。
digraph G{
a -> b -> c
b ->d
a[shape = polygon, sides = 5, peripheries = 3, color = lightblue, style = filled]
c[shape = polygon, sides = 4, skew = 0.4, label = "hello world"]
d[shape = invtriangle]
e[shape = polygon, sizes = 4, distortion = .7]
}
digraph G{
A -> B
A[orientation = 15, regular = true, shape = polygon, sides = 8, peripheries = 4, color = red, style = filled]
B[shape = polygon, sides = 4, skew = 0.5, color = blue]
}
record与Mrecord的区别就是Mrecord的角是圆的,而record是由横竖的矩形组成的图形。
digraph G{
node[shape = record]
struct1[label = "<f0> left | <f1> middle | <f2> right"]
struct2[label = "<f0> one | <f1> two"]
struct3[label = "hello \nworld | {b | {c | <here> d | e} | f} | g | h"]
struct1 -> struct2
struct1 -> struct3
}
当你的线与线的label较多时,可以设置线的属性decorate=true使得每条线与其属性之间产生连线。你还可以为每条线设置属性headlabel,taillabel,给每条线的起始点和终点设置属性,它们的颜色由labelfontcolor决定,而label的颜色由fontcolor来决定。
graph G{
label = "我爱你" /*为图设置标签*/
labelloc = b /*图标签的位置在底部,也可以设置为r到顶部*/
labeljust = l /*图标签的位置在左边,也可以设置为r到右边*/
edge[decorate = true]
C -- D[label = "s1"]
C -- E[label = "s2"]
C -- F[label = "s3"]
D -- E[label = "s4"]
D -- F[label = "s5"]
edge[decorate = false, labelfontcolor = blue, fontcolor = red]
C1 -- D1[headlabel = "d1", taillabel = "c1", label = "c1 - d1"]
}
在dot语言中,我们可以使用html语言制作表格。在label后添加<>,而不是""就能添加html语言。
digraph html{
abc[shape = none, margin = 0, label = <
<TABLE BORDER = "0" CELLBORDER = "1" CELLSPACING = "0" CELLPADDING = "4">
<TR><TD ROWSPAN = "3"><FONT COLOR = "red">hello</FONT><BR/>world</TD>
<TD COLSPAN = "3">b</TD>
<TD ROWSPAN = "3" BGCCOLOR = "lightgrey">g</TD>
<TD ROWSPAN = "3">h</TD>
</TR>
<TR><TD>c</TD>
<TD PORT = "here">d</TD>
<TD>e</TD>
</TR>
<TR><TD COLSPAN = "3">f</TD>
</TR>
</TABLE>
>]
}
设置点,线的位置以及子图的概念
图中的线默认是从上往下的,我们可以通过在文件的最上层设置rankdir=LR将其改为从左往右。同理,rankdir可以设置为TB(默认),BT,RL。
当图中时间表之类的东西时,我们可能需要点排列成一行(列),这时我们就需要rank,在花括号中设置rank=same,然后将需要并排的点一次输入。
digraph G{
rankdir = LR
{
node[shape = plaintext]
1995 -> 1996 -> 1997 -> 1998 -> 1999 -> 2000 -> 2001
}
{
node[shape = box, style = filled]
WAR3 -> Xhero -> Footman -> DOTA
WAR3 -> Battleship
}
{
{rank = same 1996 WAR3}
{rank = same 1998 Xhero Battleship}
{rank = same 1999 Footman}
{rank = same 2001 DOTA}
}
}
设立一条边时,我们可以制定这条边从起点的哪个位置出发,到终点的哪个位置结束。控制符有"n",“ne”,“e”,“se”,“s”,“sw”,“w"和"nw”,具体效果见下:
digraph G{
node[shape = box]
c:n -> d[label = n]
c1:ne -> d1[label = ne]
c2:e -> d2[label = e]
c3:se -> d3[label = se]
c4:s -> d4[label = s]
c5:sw -> d5[label = sw]
c6:w -> d6[label = w]
c7:nw -> d7[label = nw]
}
我们也可以在record中给点定义一些port,以确定record中哪个部分用于连线。
digraph G{
label = "Binary Search Tree"
node[shape = record]
A[label = "<f0> | <f1> A | <f2>"]
B[label = "<f0> | <f1> B | <f2>"]
C[label = "<f0> | <f1> C | <f2>"]
D[label = "<f0> | <f1> D | <f2>"]
E[label = "<f0> | <f1> E | <f2>"]
A: f0: sw -> B: f1
A: f2: se -> C: f1
B: f0: sw -> D: f1
B: f2: se -> E: f1
}
我们可以借此构建一个Hash表。
digraph G{
nodesep = .05
rankdir = LR
node[shape = record, width = .1, height = .1]
node0[label = "<f0> | <f1> | <f2> | <f3> | <f4> | <f5> | <f6>",height = 2.5]
node[width = 1.5]
node1[label = "{<n> n14 | 719 | <p>}"]
node2[label = "{<n> a1 | 805 | <p>}"]
node3[label = "{<n> i9 | 718 | <p>}"]
node4[label = "{<n> e5 | 989 | <p>}"]
node5[label = "{<n> t20 | 959 | <p>}"]
node6[label = "{<n> o15 | 794 | <p>}"]
node7[label = "{<n> s19 | 659 | <p>}"]
node0: f0 -> node1: n
node0: f1 -> node2: n
node0: f2 -> node3: n
node0: f5 -> node4: n
node0: f6 -> node5: n
node2: p -> node6: n
node4: p -> node7: n
}
画一个子图就是subgraph cluster#,必须有clutser前缀。这里"#“代表任意字符,当然为了便于区分,最好将”#"设置为非英文字母。
digraph G{
subgraph cluster1{
node[style = filled, color = white]
style = filled
color = lightgrey
a0 -> a1 -> a2 -> a3
label = "process1"
}
subgraph cluster2{
node[style = filled]
color = blue
b0 -> b1 -> b2 -> b3
label = "process2"
}
start -> a0
start -> b0
a1 -> b3
b2 -> a3
a3 -> a0
a3 -> end
b3 -> end
start[shape = Mdiamond]
end[shape = Msquare]
}
如果你想将一条边连到一个子图的边界上,先输入compound=true,然后就能用lhead和ltail设置连接的子图。