dot


一、简介DOT & graphviz



  1. DOT
    DOT是一种文本图形描述语言。DOT语言文件通常具有.gv或是.dot的文件扩展名。当然,在编写好.dot或者.gv的文件之后,需要有专门的程序处理这些文件并将其渲染成为图片,dot就是其中一款程序,它可以将DOT语言描述的图形渲染成.png、.jpg、.pdf等多种类型。
    当然,作为工具,dot本身是很原始的,就像gcc之于c代码,g++之于cpp代码一样,或许某些程序员会热衷于在终端使用这些工具,但也有很多人喜欢交互式的界面,所以就有了gvedit之类的工具,它提供交互式的窗口来使用dot等工具渲染DOT语言描述的图形。

  2. graphviz
    graphviz是一个开源软件包,上述dot和gvedit等工具都在该软件包中。
    所以,不妨简单的认为DOT是一门图形描述语言而graphviz是处理该语言文件的一个集成化的工具。

  3. DOT & graphviz的局限性
    graphviz中有很多工具可以将DOT语言的文本渲染成为图片,但正如我们所见,我们在享受方便的编码的同时,将图片的布局等任务交给了这些工具,虽然这些工具有很不错的布局算法支持,但仍不一定能满足我们的要求,所以当对图片的布局有特殊要求时,DOT & graphviz就显示出了它的局限性。当然,我们可以再使用其他图片编辑器校正DOT语言生成的图片,但这种时候,DOT & graphviz的方便性或许早就消失殆尽了。

  4. 什么人适合使用DOT & graphviz
    就我个人体会而言,DOT & graphviz适合这些人使用:
    1> 像我一样的画图小白并且喜欢操作键盘远胜于鼠标;
    2> 没有熟练的掌握其他作图工具;
    3> 对图片布局等没有特殊要求;
    4> 要绘制的是流程图结构图之类的图而不是画小狗小猫山山水水。



二、使用DOT & graphviz



  1. 环境配置
    graphviz的官网(http://www.graphviz.org)上可以下载适用于多个OS的graphviz版本,包括Linux的多个发行版(Fedora、Ubuntu等)、Solaris、Windows、Mac等,下载对应版本安装即可。Windows下安装时,官网有提示需要手动配置环境变量。


  2. 开始战斗
    完成了安装之后,就可以编写DOT文本并用graphviz下的工具渲染图片了。
    打开gvedit,新建一个.gv或者点.dot的文件并输入DOT文本,在工具栏graph下选择layout(快捷键f5)即可在窗口中看到图片,graph下选择settings(快捷键shift+f5)可以进行设置,在设置里也可以看出有多种处理DOT文本的工具可以选择(默认dot),也可以选择多种导出的文件类型(默认.png)。gvedit实例截图如下:



    你还可以在终端直接调用dot命令处理文本并生成图片(again:需要配置环境变量)。以把test.dot导出为test.png为例,命令为:





[plain] view plain copy
dot -Tpng -o test.png test.dot

该命令会在当前目录下生成test.png。
当然,作为一个vim党,肯定是不愿意去用gvedit了,何况gvedit确实没有那么好使(主要是文本编辑功能确实不够强大),所以在vim中编辑文本,在终端调用命令生成图片就是一种不错的选择了。为了方便,我这里进行了简单配置,设置F8为快捷键,直接调用上述命令生成图片并打开:
[plain] view plain copy
map :w:!dot -Tpng -o %<.png % && start %<.png
截图如下:



三、DOT语法
现在已经可以愉快的使用DOT & graphviz绘图了,唯一需要的就是更好的了解DOT语法,以绘出我们期望的效果。
DOT语法相对简单和松散,没有特别的格式要求,也没有复杂的运算符和结构。



  1. 基本语法
    graph(无向图)或者digraph(无向图)表示图,然后{}中的内容是对图的描述,注释风格和C类似(“//”用于单行注释,/**/用于多行注释)。如一个无向图:



[plain] view plain copy
graph graph1 { //无向图graph1

a – b //节点a和b之间连线

}



  1. 节点
    DOT中,节点可以不用声明直接使用。每个节点首次出现的名称做为该节点的唯一标识。
    属性设置:对节点可以设置的常见通用属性有shape、label、style、color、fillcolor、rank等,对于不同的形状,可能还有不同的属性可以设置,如对于多边形可以设置边数等。节点属性设置时,node用于设置默认属性(对设置位置之后的点有效),在点后面用[]设置单独一个点的属性。
    [plain] view plain copy
    graph node_settings {

    node [shape = “box”, style = “filled”, color = “black”, fillcolor = “green”] //设置节点的默认形状,类型,颜色,填充颜色

    a [shape = “ellipse”, color = “red”, label = “this is a”] //设置节点a的颜色,注意默认节点类型是filled,所以这里的color只是设置a的边框颜色

    b [label = “two\nlines”] //label支持’\n’换行

    a – b

    a – c //如果不需要设置c的属性,可以不用声明c而直接使用

    node [shape = “circle”]

    d [label = “cicle”]

    c – d //d使用之前最后出现的node设置,形状为circle

    {rank = same a, d} //设置a和d在同一层

    }


  2. 边有有向边和无向边两种,无向边用于无向图,有向边用于有向图,不可混用。
    属性设置:边的常见设置有style、color、weight、label、labelfontcolor、headlabel、taillabel、decorate等,对于有向边,还可以设置边的起点位置等(用n、e、s、w和相邻字母的组合表示位置)。和节点类似的,边属性设置时,用edge[]设置默认属性,在边之后用[]设置单独一条边的属性。
    [plain] view plain copy
    digraph edge_settings {

    edge [color = “green”, decorate = false] //设置边的默认属性

    node [shape = “polygon”, sides = 4, color = “blue”]

    a -> b [style = “dotted”, color = “red”, label = “a to b”] //设置style、color、label

    b: se -> c: w [headlabel = “end”, taillabel = “start”] //设置边从b的“东南方”出发,从c的“西方”结束,设置有向边起点和重点的label

    edge [style = “bond”, decorate = true] //设置之后的边加粗并且标签和连线之间有线标注

    {c, f} -> {d, e} [label = “multi-lines”] //可以用这种方式同时画多条边

    }



  3. 从前面的例子中已经可以看出,DOT语言可以描述无向图和有向图两种图,graph标识无向图,digraph标识有向图。
    属性设置:在一个图的开头写入属性即可设置图形的属性,常用的图形属性有size、label、labelloc、labeljust、bgcolor、rankdir等。
    子图,可以进行和“父图”类似的设置,唯一注意的是子图必须以”cluster”做为名称的开始。
    下面是实现的官网首页上的图:
    [plain] view plain copy
    digraph graph_settings {

    start [shape = “Mdiamond”]

    end [shape = “Msquare”]



    subgraph cluster_sub1 {

    label = “process #1”

    labelloc = “t”

    bgcolor = “gray55”

    node [style = “filled”, color = “white”]

    a0 -> a1 -> a2 -> a3 -> a0

    }

    subgraph cluster_sub2 {

    label = “process #2”

    labelloc = “t”

    color = “blue”

    node [style = “filled”, color = “black”, fillcolor = “gray55”]

    b0 -> b1 -> b2 -> b3

    }



    start -> {a0, b0}

    a1 -> b3

    b2 -> a3

    {a3, b3} -> end

    }



  4. 语法总结
    DOT的语法非常简单,基本保证了随便可以“现炒现卖”,只不过用的越多可能对各种属性越熟悉罢了。具体的属性等可以参见官网的Document:http://www.graphviz.org/Documentation.php。



1 简单图的绘制
dot用于绘制有向图。他读取各个图表(graph)的属性并画图,并可以输出包括GIF、PNG、SVG、PostScript(可以转换成PDF)等等多种图片格式。



dot绘图有四个主要步骤,了解这些有助于你理解你需要何种dot布局和如何控制他们。布局程序依赖于没有循环的图表。所以,第一步就是打破当前图表中形成循环的边缘。第二步是指定各个结点的离散层级。在一个从上到下的图表,dot会按照Y轴构造层级跨越超过一层的。超过一层的边缘需要使用虚拟节点来打破成单位长度。第三步排序结点避免交叉。第四步设置X轴保持边缘最短,并且作为最后一步路由各个边缘连接点。这是大多数分级有向图的绘制程序,基于 Warfield [War77] 、 Carpano [Car80] 和 Sugiyama [STT81] 。我们引用了 [GKNV93] 用于解释dot的算法。



Note



这里的图表,指原文中的graph。这里的边缘,指原文中的edge,实际上是指对象之间的连接线。



dot接受DOT语言(见附录A)的代码。这种语言是包含三种对象的解释性语言:图表、结点、边缘。最外层的主要图表可以是可控制的(digraph)或不可控制的(graph)。因为dot会自动调整布局并生成有向图,所有下面的例子都使用digraph。(一旦单独的布局调整工具 neato 用于绘制可控制的图表 [Nor92] )。在主图表中,还允许定义子图表(subgraph)来定义结点和边缘的子集。



图1是一个DOT语言的例子,第一行给出了图表的名字和类型。随后的行创建了结点、边缘和子图表,并设置属性。所有这些对象可以使C标识符、数字或引用的C标识符。引用会保留标点和空白。



digraph G {
main -> parse -> execute;
main -> init;
main -> cleanup;
execute -> make_string;
execute -> printf;
init -> make_string;
main -> printf;
execute -> compare;
}
_images/dot_guide_00.jpg
一个结点在其名字首次出现时创建。一个边缘在使用 -> 连接两个结点时创建。例子中,第二行就创建了从main到parse的边缘,等等。运行dot命令可以输出文件:



$ dot -Tps graph1.dot -o graph1.ps
这样就产生了图2。命令行选项 -Tps 选择使用PostScript来输出。而输出文件就随便玩了。



调节各个结点、边缘的布局是比较常见的操作,这些都可以通过属性来描述。属性就是键值对。图3和图4距离说明了一些布局属性。在图3中,第二行设置图表大小为4,4(单位是英寸)。这个属性控制了图表尺寸,如果图表太大则会自动缩放。



digraph G {
size=”4,4”;
main [shape=box]; /注释/
main -> parse [weight=8];
parse -> execute;
main -> init [style=dotted];
main -> cleanup;
execute -> {make_string; printf}
init -> make_string;
edge [color=red];
main -> printf [style=bold,label=”100 times”];
make_string [label=”make a\nstring”];
node [shape=box, style=filled, color=”.7 .3 1.0”];
execute -> compare;
}
_images/dot_guide_01.jpg
结点和边缘属性在方括号中设置。在第三行,结点main指定形状为box。第四行的边缘则使用之前并增加宽度(weight)。第六行的边缘则绘制成了点线。第八行使得边缘分别指向了两个目标。第十行设置缺省的边缘颜色为红色。这些设置会自动影响后面创建的边缘。第十一行设置边缘为粗体并设置标签。第十二行,结点make_string使用了多行标签。第十三行改变了缺省结点为box形状,并使用蓝色填充。结点compare继承了这些值。



2 绘制属性
完整的绘图属性列表见附表1/2/3。



2.1 结点形状
绘制结点的缺省属性为 shape=ellipse,width=.75,height=.5 而标签为节点名。其他允许的形状有 box 、 circle 、 record 、 plaintext 。附录E中有完整的节点形状列表。结点的形状 plaintext 就是不包含外部形状的,这也是一个重要的约定。仅用于结构不太复杂的图表中节省空间。绘图时生成的图形大小一般比指定的要大,当然标签也是如此。除非使用 fixedsize=true ,否则高度和宽度都是固定的。



结点形状可以归于两大类:多边形和记录。除了 record 和 Mrecord 以外都可以归于多边形,并且可以用有限的边和几何属性来定义。这其中的一些属性可以在图表中定义,如果 regular=true ,则结点会强制为规则图形。参数 peripheries 设置需要绘制的边界曲线数量。例如,一个双圆(doublecircle?)的peripheries=2 。而 orientation 属性指定多边形的曲线方向和角度。



Note



有一种方法可以自定义结点形状,使用 shape=epsf 和 shapefile 属性并以来PostScript输出。细节参考本手册其他部分。



形状 polygon 可以指定所有多边形参数,适用于创建自定义形状。附加参数如 regular 、 peripheries 和 orientation 等等,还有数字化参数 sides 、 skew 、distortion 。 skew 是一个-1.0到1.0之间的浮点数,指从上到下的倾斜度。比如,可以用 skew 把一个矩形转换成平行四边形。 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=.4,label=”hello world”];
d[shape=invtriangle];
e[shape=polygon,sides=4,distortion=.7];
}
_images/dot_guide_02.jpg
基于记录的结点使用其他结点类。这包括 record 和 Mrecord 。他们俩除了后面那个拥有圆角以外,是相同的。他们用于描述递归列表,比如以横向或纵向描绘的多行矩形。递归结构依靠结点的 label 来识别,如下样式:



rlabel -> field(‘|’field)*
field -> boxLabel|’‘rlabel’’
boxLabel -> [’<’string’>’][string]
有如上面写的,竖线符号和尖括号必须使用转义,空格用于区别各个记号,所以用于表示字面意义时也必须转义。 boxLabel 的第一个字符串提供了字段名,用于提供矩形的端口名。第二个字符串用作字段的标签;当然可以包含多行转义的标签。一个例子:



digraph structs {
node[shape=record];
struct1[shape=record,label=” left| mid\ dle| right"];
struct2[shape=record,label=" one| two"];
struct3[shape=record,label="hello\nworld |{ b |{c| d|e}| f}| g | h"];
struct1->struct2;
struct1->struct3;
}
_images/dot_guide_03.jpg
2.2 标签
缺省标签就是结点名称。边缘默认没有标签。结点和边缘可以设置 label 属性来设置标签。



虽然可以直接使用结点名作为标签,但是有些时候还是需要手动设置为好。例如画一个文件目录树,可能有多个目录有相同的名字,但是他们却不同。结点号或全路径名可能更适合做唯一标识符。因此每个结点的标签可以设置成完整文件名。



多行标签可以使用转义符来实现,包括 \n 、 \l 、 \r 。



Note



\N 是结点名中可以使用的一种内部符号。



图形和子图分组也可以有标签。图形标签默认显示在正下方。设置 labelloc=t 可以把标签放在正上方。分组标签放在矩形边框内,在左上角。设置labelloc=b 可以把标签放到矩形下边,而设置 labeljust=r 可以放到右侧。



缺省字体是 14-point Times-Roman black 。其他字体族,大小和颜色可以使用 fontname 、 fontsize 、 fontcolor 来设置。字体名需要与解释器兼容。最好是用标准字体族,如 Times 、 Helvetica 、 Courier 或 Symbol 这些确保可以工作的很好的字体。例如 Times-Italic 、 Times-Bold 和可移植的 Courier ,而不是AvanteGardeDemiOblique 。



对于点位图输出,或者GIF和JPG,dot依赖于有效的字体。可以设置 fontpath 属性来指定搜索字体文件的路径列表,如果没有设置则会到 DOTFONTPATH和 GDFONTPATH 环境变量去找。如果仍然找不到,则会用内置字体列表。



边缘标签在边缘中间的一侧。要小心边缘标签与结点标签太近时发生的混淆。但是在复杂的图形里确实很难分辨一个标签属于哪个边缘。如果设置了decorate=true 则画线时会把标签嵌入其中。有时为了避免混淆还会强制把边缘画的更大一些。如果设置 labelfloat=true ,则不会做这些更改,以兼容模式来绘图。



边缘还可以拥有附加标签,使用 headlabel 和 taillabel 来设置近端和远端的边缘标签。而标签也可以单独设置字体,使用 labelfontname 、 labelfontsize 和labelfontcolor 。这些标签会放置在边缘和结点的交汇处。想要调整,可以设置 labelangle 和 labeldistance 属性。调整边缘与结点间的角度,后面那个调整边缘到结点的距离的比例参数。



结点属性:



名称 缺省值 值
color black 结点颜色
comment – 字符串,(format-dependent)
distortion 0.0 供 shape=polygon 使用的结点扭曲
fillcolor lightgrey/black 结点填充色
fixedsize false 标签文字不影响结点大小
fontcolor black 字体颜色
fontname Times-Roman 字体名
fontsize 14 字体大小
group – 节点所属的组
height .5 以英寸为单位的高度
label 结点名 任意字符串
layer 覆盖范围 all 、 id 或 id:id
orientation 0.0 结点旋转角度
peripheries 形状依赖 结点界限数量
regular false 使多边形变得规则
shape ellipse 结点形状
shapefile – 扩展的EPSF或SVG自定义形状文件
sides 4 shape=polygon 时边的数量
skew 0.0 shape=polygon 时的相位差
style – 图形选项,例如 bold 、 dotted 、 filled 等
URL – 指定结点的URL(format-dependent)
width .75 以英寸为单位的宽度
z 0.0 VRML输出的z轴数据
边缘属性:



名称 缺省值 值
arrowhead normal 箭头的样式
arrowsize 1.0 箭头的比例因子
arrowtail normal 箭头尾部的样式
color black 边缘的颜色
comment – 任意字符串,依赖于格式
constraint true 强制约束,通过边缘限制结点范围
decorate – 修饰,如果设置了,会画线连接标签到其他边缘
dir forward forward,back,both,none
fontcolor black 字体颜色
fontname Times-Roman 字体族
headlabel – 箭头标签
headport – n,ne,e,se,s,sw,w,nw
headURL – 如果输出格式为ismap时,标签附上URL
label – 边缘标签
labelangle -25.0 边缘标签的旋转角度
labeldistance 1.0 边缘标签距离结点的比例因子
labelfloat false 边缘标签位置的强制约束
labelfontcolor black 标签字体颜色
labelfontname Times-Roman 标签字体族
labelfontsize 14 标签字体大小
layer overlay range all,id,或id:id
lhead – 箭头使用的簇(cluster)的名字
ltail – 箭尾使用的簇(cluster)的名字
minlen 1 头尾间最小长度
samehead – 头结点的tag,拥有相同头结点tag的边缘会使用统一端点
sametail – 同上,尾结点
style – 图形选项,例如bold,dotted,filled
taillabel – 箭尾标签
tailport – n,ne,e,se,s,sw,w,nw
tailURL – 当输出格式为ismap时箭尾标签附加的URL
weight 1 边缘的延伸花费整数
图形属性:



名称 缺省值 值
bgcolor – 画图的背景图
center false 在page的中心画图
clusterrank local global或none
color black 对cluster,outline颜色等等的没有指定fillcolor时的默认颜色
comment – 注释
compound false 允许cluster之间的边缘
concentrate false 允许边缘的集中
fillcolor black cluster的填充色
fontcolor black 字体颜色
fontname Times-Roman 字体族
fontpath – 字体搜索路径
fontsize 14 字体大小
label – 任意字符串
labeljust centered l和r用于cluster标签的左对齐和右对齐
labelloc top t和b用于cluster标签的上对齐和下对齐
layers – id:id:id…
margin .5 page的空白,英寸
mclimit 1.0 mincross的跌带比例因子
nodesep .25 结点之间的间隔,英寸
nslimit – 如果设置了f,则使用网络界限迭代f(结点数)来设置x坐标
nslimit1 – 如果设置了f,则使用网络界限迭代f(结点数)设置结点排名(rank)
ordering – 如果out则外部边缘顺序会保留
orientation portrait 如果没用rotate,而值为landscape,使用风景画定位
page – 标记页,例如”8.5,11”
pagedir BL 多页之间的横断
quantum – 结点标签的尺寸根据quantum的量度
rank – same,min,max,source,sink
rankdir TB LR(从左向右)或TB(从上到下)
ranksep .75 等级之间的间隔,英寸
ratio – 近似朝向approximate aspect ratio desired,fill或auto
remincross – 如果为true且有多个集群,重新运行crossing最小化
rotate – 如果为90,设置朝向
samplepoints 8 输出时用以表现椭圆和圆所用的点数,参见附录C
searchsize 30 切除的最大边缘,当用以寻找网络中的最小一个(完全没看懂?)
size – 最大绘图尺寸,英寸
style – 图形选项,例如集群的filled
URL – 图形锚点,依赖于格式
2.3 图形样式
结点和边缘可以指定color属性,默认是黑色。这是绘制结点形状和边缘时使用的颜色。一个color值可以用灰度三角标识(以逗号分隔的3个0-1之间的浮点数);每个颜色的名字在附录G中列出(从X window系统借用的);或者是RGB颜色(3个十六进制的00-FF之间的数字,以”#”开头)。这样值”orchid”、”0.8396,0.4862,0.8549”和”#DA70D6”是同一种颜色的不同表示方式。数字形式会自动转换为实际的颜色。颜色名的会忽略大小写然后忽略非数字字符,所以warngrey和Warn_Grey是等同的。



我们可以提供一些绘图中使用颜色的建议。首先,不要使用太多亮色。彩虹效应会让人很混乱。最好选择很窄范围的几种颜色,或者达到颜色饱和。第二如果结点填充深色或饱和颜色,标签设置为 fontcolor=white 或 fontname=Helvetica 会更容易阅读。(我们也有PostScript函数用以生成轮廓字体)。第三,在适应的输出格式,你可以定义自己的颜色空间。例如,如果使用PostScript输出,你可以重新定义 nodecolor 、 edgecolor 、 graphcolor 在库文件中。这样,想要使用RGB颜色,在 lib.ps 中定位如下行:



/nodecolor {setrgbcolor} bind def
使用 -l 命令载入这个文件:



dot -Tps -l lib.ps file.dot -o file.ps
style 属性控制图形中结点和边缘的多种功能。这个属性是以逗号分隔的一列参数。预定义的参数包括 solid 、 dashed 、 dotted 、 bold 和 invis 。前四个控制结点界限与边缘的绘制,意思代表实线、虚线、点线、粗线。而invis会让结点或边缘留空而不绘制。结点的 style 还可以包括 filled 、 diagonals 和rounded ,表示结点的填充方式为填充(默认用fillcolor,否则用color,如果还没有就用浅灰)、对角线(绘制最近两个边的定点的连线)、环绕(环绕多边形的各个角)。



用户定义的风格元素可以使用自定义PostScript过程实现。这种元素(primitive)在 gsave 上下文中执行,在其他标签绘制前。参数列表会翻译成PostScript的表示法(notation)。例如,一个结点有 style=”setlinewidth(8) ,就会绘制很粗的轮廓。这里 setlinewidth 是PostScript内置的,但是用户自定义的过程也是一样的调用方式。这些过程的定义可以用库文件的方式用”-l”参数导入。



边缘有 dir 属性以设置箭头。dir可以是 forward (缺省)、 back 、 both 、 none 。这只是改变箭头的绘制,而不是下面(underlying)的图形。例如设置dir=back 会使得箭头相反,但是它并不交换边缘的端点。属性 arrowhead 和 arrtail 设置箭头的样式,方便分别设置。允许的值有 normal 、 inv 、 dot 、invdot 、 odot 、 invodot 、 none ,具体的意思详见附录F。属性 arrowsize 设置箭头的多个因素的大小。例如 arrowsize=2.0 会让箭头两倍大和两倍宽。



在演示和颜色的概念中,cluster作为一个盒子样的结点存在,cluster的界限(boundary)使用color属性绘制。而一般cluster的外貌(appearance)依赖于style、color、fillcolor属性。



如果根图有 bgcolor 属性。这个颜色会用于整个背景的绘制。同时也作为缺省的填充色。



2.4 绘图方向、大小和间隔
有两个属于对于dot的大小有重要的作用,是 nodesep 和 ranksep 。 nodesep 指定了以英寸为单位的最小占用空间,在同一范围内临近的两个结点的最小距离。 ranksep 指定了各个层次(rank)之间的间隔,就是在上一个rank中最下那个node到下一个rank中最上那个node之间的距离,单位是英寸。同时也可以设置 ranksep=equally ,可以使所有的rank拥有相同的间隔空间,特别适合于中心结点对旁边的结点进行等距离分配。在这种情况下,两个rank之间的间隔至少为上面设置的间隔。两种使用的 rankrep 是相互独立的,可以同时使用,例如 rankrep=”1.0 equally” 语句就会设置固定的相等间隔。



大多数时候默认的结点尺寸和间距对打印机或者文档页面来说太大了。有很多种方式可以解决这个问题。首先我们复习一下dot如何计算最终的布局尺寸。



首先布局按照初始的”natural”大小,使用缺省设置(除非 ratio=compress 设置,下面描述)。没有限制大小和方向(aspect)的比率(ratio),所以如果图形很大,布局也会很大。如果你不指定size和ratio,就会打印自然大小。



控制输出大小最简单的方式是设置 size=”x,y” ,在图形文件中(或者命令行选项的-G)。这会先决定于最终布局的大小。例如, size=”7.5,10” 会适应8.5x11的页面(假设缺省页方向)而无论初始布局有多大。



ratio 也作用于布局大小。有几种情况,依赖于size和ratio的设置:



Case1 : ratio 设置了。如果绘图已经适应到给出的size,那么什么都不会发生。否则,绘图会自动减小到临界(critical)尺寸(dimension)。如果ratio设置了,则有四种子情况。
@page 15



2.5 结点与边缘定位
dot中有多种方式处理大尺寸的结点和边缘布局,让用户感觉使用起来极其方便。这一节就是讨论这些事情。



有时候需要让边缘从左到右,而不是从上到下。如果 rankdir=LR 定义于图的顶层,绘图会旋转以实现这种样式。TB(top to bottom)是缺省的。模式rankdir=BT 适用于从下到上的图。当然了还有 rankdir=RL 。



在时间线、强调源和下沉结点,你可能需要强制定义下沉。子图的rank可以设置为 same 、 min 、 source 、 max 、 sink 。意义如下:



same :让子图继承相同的排列
min :子图中所有结点至少比布局中其他结点的排列(rank)要小
source :强制子图所有结点严格基于某个排列,同时比其他结点排列要小(除非这些子图也指定了min或source)(?)
max 或 sink :做与最大排列接近的事情。
注意这些约束对结点都是相同的。如果一个子图强制结点A和B使用相同排列,而其他子图强制C和B共享排列,那么两个子图的其他结点也必须以相同排列绘图。例子9和10使用子图控制排列。



在一些图中从左到右的顺序很重要。如果子图含有 ordering=out ,则每条产生的边都按照从左到右排列。同时注意平坦的边(edge)会扰乱这种排序。



有很多方式微调(find-tune)结点与边缘的布局。例如,如果结点的一些边缘拥有相同的 group 属性,绘制时就会保持边缘是笔直的(straight)且进制其他边缘与其交叉。边缘的 weight 属性也会控制边缘的笔直。一个边缘的weight建议边缘的量度(measure);这样weight的行为贴近于其结点。dot会让边缘更短与更直。



边缘的weight与结点被强制相同rank时也有用。结点间拥有非零weight的边缘在同一方向跨越rank时会尽可能避免交叉。(此句不确定)。这个事实可以用于调整(adjust)结点顺序,通过指定边缘的 style=”invis” 。



边缘的端点临近(adjacent)的结点可以被约束(constraint)使用 samehead 和 sametail 属性。特别的,所有边缘都有相同的箭头且有相同的 samehead 约束,则会指向结点的同一点。类似的(analogous)作用于箭尾的是 sametail 。



@page 20



3 高级特性
3.1 结点端口
结点端口是允许边缘连接的一个点。当没有指定端口时,边缘会自动连接指向结点中心并忽略结点的边界。



@page 20



3.2 cluster
cluster是一个子图,定位于一个举行区域中,并有自己的布局。一个子图被认为是一个cluster,如果其名字拥有前缀 cluster 。(如果顶级图有clusterrank=none ,那么这个处理就被关闭了。)标签、字体和 labelloc 属性可以设置顶级图形,然而cluster标签则是缺省显示的。对于cluster,标签默认左对齐,如果 labeljust=”r” 则标签就右对齐了。 color 属性指定了包围矩形的颜色。另外,cluster可以有 style=”filled” ,先定义包围矩形的颜色为fillcolor 。如果没指定fillcolor,则使用cluster的color属性。



cluster的绘制通过递归技术,计算分配的rank和内部结点的布局。下面Finger17-19是cluster的例子。



如果顶级图的 compound 属性设置为true,就会允许结点与cluster之间绘制边缘。这是通过定义边缘的 lhead 和 ltail 属性实现(accomplished)的。这些属性的值必须是包含头或尾结点的cluster的名字。这种情况下,边缘省略了cluster的边框。所有其他边缘的属性,例如 arrowhead 或 dir ,都被截断了。例如Finure20展示了图形使用compound属性的结果。



3.3 集中器
@page 27



4 命令行选项
缺省时,dot以过滤器模式工作,从stdin读取图形,然后写入图形到stdout,以DOT格式。 dot 支持一系列的命令行选项:



-Tformat :设置输出格式,允许的format如下:



canon :很好的打印输入,没有布局
dot :属性DOT,打印输入布局附加在属性上,查看附录C
fit :FIG输出
gd :GD格式,这是GD图形库的内部格式,另一个可选的是gd2
gif :GIF输出
hpgl :HP-GL/2生成的打印机语言
imap :生成服务器端图像地图。可以算作图像输出,使用 -Tgif 或 -Tjpg ,在网页附加链接到结点和边缘。格式ismap是imap格式的预处理器
cmap :在客户端生成HTML地图文件
mif :FrameMaker MIF格式。可以载入FrameMake并编辑,限于8种基本颜色
mp :MetaPost输出
pc1 :PCL-5输出,用于HP打印机
pic :PIC输出
plain :简单的,基于线的ASCII格式。附录B描述了这种输出。另一种可选格式是 plain-ext ,会提供边缘头尾端口名
png :PNG(Portable Network Graphics)格式
ps :PostScript(EPSF)输出
ps2 :PostScript(EPSF)输出包含PDF注释,假设最终用于生成PDF
svg :SVG输出,另一种选择 svgz 是压缩过的SVG
vrml :VRML输出
vtx :VTX格式用于Visual Thought
wbmp :Wireless BitMap(WBMP)格式
-Gname=value :设置缺省的图形属性。一般是设置大小、分页等参数。类似的选项 -N 和 -E 用于设置结点和边缘的缺省属性。不过注意,文件内容可以重载命令行参数。



-llibfile :指定设备相关的图形库文件。可以指定多个库。这些名字会被传递到代码生成器那里。



-ooutfile :指定输出文件名



-v :提供更多输出信息。在处理大的布局时,会给出处理进度的评估信息



-V :打印版本号



5 有趣的功能
在顶级图之前,可以声明 strict digraph 。这会禁止自引用(self-arcs)和多条边缘(multi-edges)。他们会在输入文件中自动忽略。



结点、边缘、图形可以有 URL 属性。在适当的输出格式(ps2、imap、ismap、cmap、svg)中,这些信息会整合(integrated)到输出中,所以这些结点、边缘和cluster就会变成链接。典型的URL附加到顶层图会作为基础URL,以便支持组件的相对URL。当输出格式是imap或cmap,类似的处理过程会被替换成headURL 和 tailURL 属性。



对于适当的格式(ps2、fig、mif、mp、vtx、svg), comment 属性可以用于嵌入式的人类可读的注释表示法。



6 结论
dot语言可以构造复杂的分级图形并设置很多属性。



虽然这些简单的方法已经工作的很好了,但是未来仍然有做复杂图形方面的研究和WEB动态图形生成。



7 感谢
@page 32



8 引用
[Car80]
Carpano. Automatic display of hierarchized graphs for computer aided decision analysis. IEEE Transactions on Software Engineering, SE-12(4):538–546, April 1980.
[GKNV93] Emden R. Gansner, Eleftherios Koutsofios, Stephen C. North, and Kiem-Phong Vo. A Technique for Drawing Directed Graphs. IEEE Trans. Sofware Eng., 19(3):214–230, May 1993.
[New89] Frances J. Newbery. Edge Concentration: A Method for Clustering Directed Graphs. In 2nd International Workshop on Software Configuration Management, pages 76–85, October 1989. Published as ACM SIGSOFT Software Engineering Notes, vol. 17, no. 7, November 1989.
[Nor92] Stephen C. North. Neato User’s Guide. Technical Report 59113-921014-14TM, AT&T Bell Laboratories, Murray Hill, NJ, 1992.
[STT81]
Sugiyama, S. Tagawa, and M. Toda. Methods for Visual Understanding of Hierarchical System Structures. IEEE Transactions on Systems, Man, and Cybernetics, SMC-11(2):109–125, February 1981.
[War77] JohnWarfield. Crossing Theory and Hierarchy Mapping. IEEE Transactions on Systems, Man, and Cybernetics, SMC-7(7):505–523, July 1977.
9 附录
9.1 图形文件语法
如下是DOT语言的抽象语法。终止符以粗体,非终止符以斜体。单字符(literal)以单引号。在需要时使用圆括号(parentheses)来表示组。方括号标识可选项。竖线分隔符分隔二选一的值。










graph -> [ strict ] ( digraph graph ) id ‘{‘ stmt-list ‘}’


stmt-list -> [ stmt [ ‘;’ ][ stmt-list ]]













stmt -> attr-stmt node-stmt edge-stmt subgraph id ‘=’ id










attr-stmt -> ( graph node edge ) attr-list


attr-list -> ‘[’ [ a-list ] ‘]’ [ attr-list ]



a-list -> id ‘=’ id [ ‘,’ ] [ a-list ]



@page 34



9.2 原始输出文件格式(-Tplain)
Warning



pause @ page 35



9.3 DOT属性格式(-Tdot)
Warning



pause @ page 36



9.4 层
Warning



pause @ page 37



9.5 结点形状
_images/dot_guide_nodeshape.png
9.6 箭头类型
_images/dot_guide_arrowhead.png
9.7 颜色名
Warning



pause @ page 40


Category web