Drawing Graphs With Dot: Emden R. Gansner and Eleftherios Koutsofios and Stephen North December 22, 2009
Drawing Graphs With Dot: Emden R. Gansner and Eleftherios Koutsofios and Stephen North December 22, 2009
Drawing Graphs With Dot: Emden R. Gansner and Eleftherios Koutsofios and Stephen North December 22, 2009
Abstract
dot draws directed graphs as hierarchies. It runs as a command line pro-
gram, web visualization service, or with a compatible graphical interface.
Its features include well-tuned layout algorithms for placing nodes and edge
splines, edge labels, “record” shapes with “ports” for drawing data struc-
tures; cluster layouts; and an underlying file language for stream-oriented
graph tools. Below is a reduced module dependency graph of an SML-NJ
compiler that took 0.23 seconds of user time on a 3 GHz Intel Xeon.
IntNullD IntNull IntSparc IntSparcD CompSparc Stream Join LrTable Backpatch Overloads Loader MakeMos
Signs ApplyFunctor CoreLang MCopt SparcMCode SparcAsCode SparcMCEmit SparcAsEmit SparcCM CPScomp Coder
SigMatch Misc Typecheck InlineOps MCprint Prof IEEEReal SparcInstr CPSopt CPSsize Closure ClosureCallee
MLLexFun Index PrintDec Instantiate PrintAbsyn Interp Absyn Equal Reorder Convert Opt RealConst BaseCoder Hoist Contract Expand Spill Profile ContMap CPSgen
Vector BareAbsyn PrintBasics Overload CoreInfo Unboxed Lambda Bigint CPSprint Eta GlobalFix FreeMap
Types Dynamic
Pathnames
1
dot User’s Manual, December 22, 2009 2
1: digraph G {
2: main -> parse -> execute;
3: main -> init;
4: main -> cleanup;
5: execute -> make_string;
6: execute -> printf
7: init -> make_string;
8: main -> printf;
9: execute -> compare;
10: }
main
parse cleanup
init execute
size to 4,4 (in inches). This attribute controls the size of the drawing; if the
drawing is too large, it is scaled uniformly as necessary to fit.
Node or edge attributes are set off in square brackets. In line 3, the node main
is assigned shape box. The edge in line 4 is straightened by increasing its weight
(the default is 1). The edge in line 6 is drawn as a dotted line. Line 8 makes edges
from execute to make string and printf. In line 10 the default edge color
is set to red. This affects any edges created after this point in the file. Line 11
makes a bold edge labeled 100 times. In line 12, node make_string is given
a multi-line label. Line 13 changes the default node to be a box filled with a shade
of blue. The node compare inherits these values.
2 Drawing Attributes
The main attributes that affect graph drawing are summarized in Appendices A, B
and C. For more attributes and a more complete description of the attributes, you
should refer to the Graphviz web site, specifically
www.graphviz.org/doc/info/attrs.html
1: digraph G {
2: size ="4,4";
3: main [shape=box]; /* this is a comment */
4: main -> parse [weight=8];
5: parse -> execute;
6: main -> init [style=dotted];
7: main -> cleanup;
8: execute -> { make_string; printf}
9: init -> make_string;
10: edge [color=red]; // so is this
11: main -> printf [style=bold,label="100 times"];
12: make_string [label="make a\nstring"];
13: node [shape=box,style=filled,color=".7 .3 1.0"];
14: execute -> compare;
15: }
main
parse cleanup
execute
make a
printf compare
string
peripheries sets the number of boundary curves drawn. For example, a dou-
blecircle has peripheries=2. The orientation attribute specifies a clock-
wise rotation of the polygon, measured in degrees.
The shape polygon exposes all the polygonal parameters, and is useful for
creating many shapes that are not predefined. In addition to the parameters regular,
peripheries and orientation, mentioned above, polygons are parameter-
ized by number of sides sides, skew and distortion. skew is a floating
point number (usually between −1.0 and 1.0) that distorts the shape by slanting
it from top-to-bottom, with positive values moving the top of the polygon to the
right. Thus, skew can be used to turn a box into a parallelogram. distortion
shrinks the polygon from top-to-bottom, with negative values causing the bottom
to be larger than the top. distortion turns a box into a trapezoid. A variety of
these polygonal attributes are illustrated in Figures 6 and 5.
Record-based nodes form the other class of node shapes. These include the
shapes record and Mrecord. The two are identical except that the latter has
rounded corners. These nodes represent recursive lists of fields, which are drawn
as alternating horizontal and vertical rows of boxes. The recursive structure is
determined by the node’s label, which has the following schema:
Literal braces, vertical bars and angle brackets must be escaped. Spaces are
interpreted as separators between tokens, so they must be escaped if they are to
appear literally in the text. The first string in a boxLabel gives a name to the field,
and serves as a port name for the box (cf. Section 3.1). The second string is used as
a label for the field; it may contain the same escape sequences as multi-line labels
(cf. Section 2.2). The example of Figures 7 and 8 illustrates the use and some
properties of records.
2.2 Labels
As mentioned above, the default node label is its name. Edges are unlabeled by
default. Node and edge labels can be set explicitly using the label attribute as
shown in Figure 4.
Though it may be convenient to label nodes by name, at other times labels
must be set explicitly. For example, in drawing a file directory tree, one might have
several directories named src, but each one must have a unique node identifier.
dot User’s Manual, December 22, 2009 7
1: digraph G {
2: a -> b -> c;
3: b -> d;
4: a [shape=polygon,sides=5,peripheries=3,color=lightblue,style=filled];
5: c [shape=polygon,sides=4,skew=.4,label="hello world"]
6: d [shape=invtriangle];
7: e [shape=polygon,sides=4,distortion=.7];
8: }
a e
hello world d
1: digraph structs {
2: node [shape=record];
3: struct1 [shape=record,label="<f0> left|<f1> mid\ dle|<f2> right"];
4: struct2 [shape=record,label="<f0> one|<f1> two"];
5: struct3 [shape=record,label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"];
6: struct1 -> struct2;
7: struct1 -> struct3;
8: }
The inode number or full path name are suitable unique identifiers. Then the label
of each node can be set to the file name within its directory.
Multi-line labels can be created by using the escape sequences \n, \l, \r to
terminate lines that are centered, or left or right justified.2
Graphs and cluster subgraphs may also have labels. Graph labels appear, by
default, centered below the graph. Setting labelloc=t centers the label above
the graph. Cluster labels appear within the enclosing rectangle, in the upper left
corner. The value labelloc=b moves the label to the bottom of the rectangle.
The setting labeljust=r moves the label to the right.
The default font is 14-point Times-Roman, in black. Other font families,
sizes and colors may be selected using the attributes fontname, fontsize and
fontcolor. Font names should be compatible with the target interpreter. It is
best to use only the standard font families Times, Helvetica, Courier or Symbol
as these are guaranteed to work with any target graphics language. For example,
Times-Italic, Times-Bold, and Courier are portable; AvanteGarde-
DemiOblique isn’t.
For bitmap output, such as GIF or JPG, dot relies on having these fonts avail-
able during layout. Most precompiled installations of Graphviz use the fontconfig
library for matching font names to available fontfiles. fontconfig comes with a
set of utilities for showing matches and installing fonts. Please refer to the font-
config documentation, or the external Graphviz FontFAQ or for further details. If
Graphviz is built without fontconfig (which usually means you compiled it from
source code on your own), the fontpath attribute can specify a list of directo-
ries3 which should be searched for the font files. If this is not set, dot will use the
DOTFONTPATH environment variable or, if this is not set, the GDFONTPATH
environment variable. If none of these is set, dot uses a built-in list.
Edge labels are positioned near the center of the edge. Usually, care is taken to
prevent the edge label from overlapping edges and nodes. It can still be difficult,
in a complex graph, to be certain which edge a label belongs to. If the decorate
attribute is set to true, a line is drawn connecting the label to its edge. Sometimes
avoiding collisions among edge labels and edges forces the drawing to be bigger
than desired. If labelfloat=true, dot does not try to prevent such overlaps,
allowing a more compact drawing.
An edge can also specify additional labels, using headlabel and taillabel,
which are be placed near the ends of the edge. The characteristics of these la-
bels are specified using the attributes labelfontname, labelfontsize and
2
The escape sequence \N is an internal symbol for node names.
3
For Unix-based systems, this is a concatenated list of pathnames, separated by colons. For
Windows-based systems, the pathnames are separated by semi-colons.
dot User’s Manual, December 22, 2009 9
labelfontcolor. These labels are placed near the intersection of the edge and
the node and, as such, may interfere with them. To tune a drawing, the user can set
the labelangle and labeldistance attributes. The former sets the angle,
in degrees, which the label is rotated from the angle the edge makes incident with
the node. The latter sets a multiplicative scaling factor to adjust the distance that
the label is from the node.
b
hello
one two c d e g h
world
f
1: digraph html {
2: abc [shape=none, margin=0, label=<
3: <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
4: <TR><TD ROWSPAN="3"><FONT COLOR="red">hello</FONT><BR/>world</TD>
5: <TD COLSPAN="3">b</TD>
6: <TD ROWSPAN="3" BGCOLOR="lightgrey">g</TD>
7: <TD ROWSPAN="3">h</TD>
8: </TR>
9: <TR><TD>c</TD>
10: <TD PORT="here">d</TD>
11: <TD>e</TD>
12: </TR>
13: <TR><TD COLSPAN="3">f</TD>
14: </TR>
15: </TABLE>>];
16: }
b
hello
g h
world c d e
f
choose a narrower range of colors, or to vary saturation along with hue. Sec-
ond, when nodes are filled with dark or very saturated colors, labels seem to be
more readable with fontcolor=white and fontname=Helvetica. (We
also have PostScript functions for dot that create outline fonts from plain fonts.)
Third, in certain output formats, you can define your own color space. For exam-
ple, if using PostScript for output, you can redefine nodecolor, edgecolor,
or graphcolor in a library file. Thus, to use RGB colors, place the following
line in a file lib.ps.
and none (cf. Appendix I). The attribute arrowsize specifies a multiplica-
tive factor affecting the size of any arrowhead drawn on the edge. For example,
arrowsize=2.0 makes the arrow twice as long and twice as wide.
In terms of style and color, clusters act somewhat like large box-shaped nodes,
in that the cluster boundary is drawn using the cluster’s color attribute and, in
general, the appearance of the cluster is affected the style, color and fillcolor
attributes.
If the root graph has a bgcolor attribute specified, this color is used as the
background for the entire drawing, and also serves as the default fill color.
order by R.
If center=true and the graph can be output on one page, using the default
page size of 8.5 by 11 inches if page is not set, the graph is repositioned to be
centered on that page.
A common problem is that a large graph drawn at a small size yields unreadable
node labels. To make larger labels, something has to give. There is a limit to the
amount of readable text that can fit on one page. Often you can draw a smaller
graph by extracting an interesting piece of the original graph before running dot.
We have some tools that help with this.
sccmap decompose the graph into strongly connected components
gvpr graph processor to select nodes or edges, and contract or remove the rest of
the graph
unflatten improve aspect ratio of trees by staggering the lengths of leaf edges
With this in mind, here are some thing to try on a given graph:
1. Increase the node fontsize.
3. Use ratio=auto.
5. A sans serif font (such as Helvetica) may be more readable than Times when
reduced.
In graphs with time-lines, or in drawings that emphasize source and sink nodes,
you may need to constrain rank assignments. The rank of a subgraph may be set
to same, min, source, max or sink. A value same causes all the nodes in the
subgraph to occur on the same rank. If set to min, all the nodes in the subgraph
are guaranteed to be on a rank at least as small as any other node in the layout7 .
This can be made strict by setting rank=source, which forces the nodes in the
subgraph to be on some rank strictly smaller than the rank of any other nodes
(except those also specified by min or source subgraphs). The values max or
sink play an analogous role for the maximum rank. Note that these constraints
induce equivalence classes of nodes. If one subgraph forces nodes A and B to be
on the same rank, and another subgraph forces nodes C and B to share a rank, then
all nodes in both subgraphs must be drawn on the same rank. Figures 11 and 12
illustrate using subgraphs for controlling rank assignment.
In some graphs, the left-to-right ordering of nodes is important. If a subgraph
has ordering=out, then out-edges within the subgraph that have the same tail
node wll fan-out from left to right in their order of creation. (Also note that flat
edges involving the head nodes can potentially interfere with their ordering.)
There are many ways to fine-tune the layout of nodes and edges. For example,
if the nodes of an edge both have the same group attribute, dot tries to keep
the edge straight and avoid having other edges cross it. The weight of an edge
provides another way to keep edges straight. An edge’s weight suggests some
measure of an edge’s importance; thus, the heavier the weight, the closer together
its nodes should be. dot causes edges with heavier weights to be drawn shorter and
straighter.
Edge weights also play a role when nodes are constrained to the same rank.
Edges with non-zero weight between these nodes are aimed across the rank in
the same direction (left-to-right, or top-to-bottom in a rotated drawing) as far as
possible. This fact may be exploited to adjust node ordering by placing invisible
edges (style="invis") where needed.
The end points of edges adjacent to the same node can be constrained using the
samehead and sametail attributes. Specifically, all edges with the same head
and the same value of samehead are constrained to intersect the head node at the
same point. The analogous property holds for tail nodes and sametail.
During rank assignment, the head node of an edge is constrained to be on a
higher rank than the tail node. If the edge has constraint=false, however,
this requirement is not enforced.
In certain circumstances, the user may desire that the end points of an edge
never get too close. This can be obtained by setting the edge’s minlen attribute.
7
Recall that the minimum rank occurs at the top of a drawing.
dot User’s Manual, December 22, 2009 16
digraph asde91 {
ranksep=.75; size = "7.5,7.5";
{
node [shape=plaintext, fontsize=16];
/* the time-line graph */
past -> 1978 -> 1980 -> 1982 -> 1983 -> 1985 -> 1986 ->
1987 -> 1988 -> 1989 -> 1990 -> "future";
/* ancestor programs */
"Bourne sh"; "make"; "SCCS"; "yacc"; "cron"; "Reiser cpp";
"Cshell"; "emacs"; "build"; "vi"; "<curses>"; "RCS"; "C*";
}
{ rank = same;
"Software IS"; "Configuration Mgt"; "Architecture & Libraries";
"Process";
};
node [shape=box];
{ rank = same; "past"; "SCCS"; "make"; "Bourne sh"; "yacc"; "cron"; }
{ rank = same; 1978; "Reiser cpp"; "Cshell"; }
{ rank = same; 1980; "build"; "emacs"; "vi"; }
{ rank = same; 1982; "RCS"; "<curses>"; "IMX"; "SYNED"; }
{ rank = same; 1983; "ksh"; "IFS"; "TTU"; }
{ rank = same; 1985; "nmake"; "Peggy"; }
{ rank = same; 1986; "C*"; "ncpp"; "ksh-i"; "<curses-i>"; "PG2"; }
{ rank = same; 1987; "Ansi cpp"; "nmake 2.0"; "3D File System"; "fdelta";
"DAG"; "CSAS";}
{ rank = same; 1988; "CIA"; "SBCS"; "ksh-88"; "PEGASUS/PML"; "PAX";
"backtalk"; }
{ rank = same; 1989; "CIA++"; "APP"; "SHIP"; "DataShare"; "ryacc";
"Mosaic"; }
{ rank = same; 1990; "libft"; "CoShell"; "DIA"; "IFS-i"; "kyacc"; "sfio";
"yeast"; "ML-X"; "DOT"; }
{ rank = same; "future"; "Adv. Software Technology"; }
1987 DAG CSAS Ansi cpp fdelta 3D File System nmake 2.0
1990 DOT DIA libft CoShell sfio IFS-i ML-X kyacc yeast
This defines the minimum difference between the ranks of the head and tail. For
example, if minlen=2, there will always be at least one intervening rank between
the head and tail. Note that this is not concerned with the geometric distance be-
tween the two nodes.
Fine-tuning should be approached cautiously. dot works best when it can
makes a layout without much “help” or interference in its placement of individual
nodes and edges. Layouts can be adjusted somewhat by increasing the weight of
certain edges, or by creating invisible edges or nodes using style=invis, and
sometimes even by rearranging the order of nodes and edges in the file. But this can
backfire because the layouts are not necessarily stable with respect to changes in
the input graph. One last adjustment can invalidate all previous changes and make
a very bad drawing. A future project we have in mind is to combine the mathemat-
ical layout techniques of dot with an interactive front-end that allows user-defined
hints and constraints.
3 Advanced Features
3.1 Node Ports
A node port is a point where edges can attach to a node. (When an edge is not
attached to a port, it is aimed at the node’s center and the edge is clipped at the
node’s boundary.)
There are two types of ports. Ports based on the 8 compass points "n", "ne",
"e", "se", "s", "sw", "w" or "nw" can be specified for any node. The end
of the node will then be aimed at that position on the node. Thus, if se port is
specified, the edge will connect to the node at its southeast “corner”.
In addition, nodes with a record shape can use the record structure to define
ports, while HTML-like labels with tables can make any cell a port using the PORT
attribute of a <TD> element. If a record box or table cell defines a port name, an
edge can use that port name to indicate that it should be aimed at the center of the
box. (By default, the edge is clipped to the box’s boundary.)
There are also two ways to specify ports. One way is to use an edge’s headport
and tailport attributes, e.g.
a -> b [tailport=se]
Alternatively, the portname can be used to modify the node name as part of the
edge declaration using the syntax node name:port name. Thus, another way to
handle the example given above would be
a -> b:se
dot User’s Manual, December 22, 2009 19
Since a record box has its own corners, one can add a compass point port to
record name port. Thus, the edge
a -> b:f0:se
will attach to the southeast corner of the box in record node b whose port name is
f0.
Figure 13 illustrates the declaration and use of port names in record nodes, with
the resulting drawing shown in Figure 14.
Figures 15 and 16 give another example of the use of record nodes and ports.
This repeats the example of Figures 7 and 8 but now using ports as connectors
for edges. Note that records sometimes look better if their input height is set to a
small value, so the text labels dominate the actual size, as illustrated in Figure 13.
Otherwise the default node size (.75 by .5) is assumed, as in Figure 16. The
example of Figures 17 and 18 uses left-to-right drawing in a layout of a hash table.
3.2 Clusters
A cluster is a subgraph placed in its own distinct rectangle of the layout. A sub-
graph is recognized as a cluster when its name has the prefix cluster. (If the
top-level graph has clusterrank=none, this special processing is turned off).
Labels, font characteristics and the labelloc attribute can be set as they would
be for the top-level graph, though cluster labels appear above the graph by default.
For clusters, the label is left-justified by default; if labeljust="r", the label is
right-justified. The color attribute specifies the color of the enclosing rectangle.
In addition, clusters may have style="filled", in which case the rectangle
is filled with the color specified by fillcolor before the cluster is drawn. (If
fillcolor is not specified, the cluster’s color attribute is used.)
Clusters are drawn by a recursive technique that computes a rank assignment
and internal ordering of nodes within clusters. Figure 19 through 21 are cluster
layouts and the corresponding graph files.
dot User’s Manual, December 22, 2009 20
1: digraph g {
2: node [shape = record,height=.1];
3: node0[label = "<f0> |<f1> G|<f2> "];
4: node1[label = "<f0> |<f1> E|<f2> "];
5: node2[label = "<f0> |<f1> B|<f2> "];
6: node3[label = "<f0> |<f1> F|<f2> "];
7: node4[label = "<f0> |<f1> R|<f2> "];
8: node5[label = "<f0> |<f1> H|<f2> "];
9: node6[label = "<f0> |<f1> Y|<f2> "];
10: node7[label = "<f0> |<f1> A|<f2> "];
11: node8[label = "<f0> |<f1> C|<f2> "];
12: "node0":f2 -> "node4":f1;
13: "node0":f0 -> "node1":f1;
14: "node1":f0 -> "node2":f1;
15: "node1":f2 -> "node3":f1;
16: "node2":f2 -> "node8":f1;
17: "node2":f0 -> "node7":f1;
18: "node4":f2 -> "node6":f1;
19: "node4":f0 -> "node5":f1;
20: }
E R
B F H Y
A C
1: digraph structs {
2: node [shape=record];
3: struct1 [shape=record,label="<f0> left|<f1> middle|<f2> right"];
4: struct2 [shape=record,label="<f0> one|<f1> two"];
5: struct3 [shape=record,label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"];
6: struct1:f1 -> struct2:f0;
7: struct1:f2 -> struct3:here;
8: }
b
hello
one two c d e g h
world
f
1: digraph G {
2: nodesep=.05;
3: rankdir=LR;
4: node [shape=record,width=.1,height=.1];
5:
6: node0 [label = "<f0> |<f1> |<f2> |<f3> |<f4> |<f5> |<f6> | ",height=2.5];
7: node [width = 1.5];
8: node1 [label = "{<n> n14 | 719 |<p> }"];
9: node2 [label = "{<n> a1 | 805 |<p> }"];
10: node3 [label = "{<n> i9 | 718 |<p> }"];
11: node4 [label = "{<n> e5 | 989 |<p> }"];
12: node5 [label = "{<n> t20 | 959 |<p> }"] ;
13: node6 [label = "{<n> o15 | 794 |<p> }"] ;
14: node7 [label = "{<n> s19 | 659 |<p> }"] ;
15:
16: node0:f0 -> node1:n;
17: node0:f1 -> node2:n;
18: node0:f2 -> node3:n;
19: node0:f5 -> node4:n;
20: node0:f6 -> node5:n;
21: node2:p -> node6:n;
22: node4:p -> node7:n;
23: }
Figure 17: Hash table graph file
n14 719
t20 959
digraph G {
subgraph cluster0 {
start
node [style=filled,color=white];
style=filled;
color=lightgrey; process #1 process #2
a0 -> a1 -> a2 -> a3;
label = "process #1"; a0 b0
}
subgraph cluster1 {
node [style=filled]; a1 b1
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
} a2 b2
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3; a3 b3
a3 -> a0;
a3 -> end;
b3 -> end;
end
start [shape=Mdiamond];
end [shape=Msquare];
}
If the top-level graph has the compound attribute set to true, dot will allow
edges connecting nodes and clusters. This is accomplished by an edge defining
an lhead or ltail attribute. The value of these attributes must be the name of
a cluster containing the head or tail node, respectively. In this case, the edge is
clipped at the cluster boundary. All other edge attributes, such as arrowhead
or dir, are applied to the truncated edge. For example, Figure 22 shows a graph
using the compound attribute and the resulting diagram.
3.3 Concentrators
Setting concentrate=true on the top-level graph enables an edge merging
technique to reduce clutter in dense layouts. Edges are merged when they run
parallel, have a common endpoint and have length greater than 1. A beneficial
side-effect in fixed-sized layouts is that removal of these edges often permits larger,
more readable labels. While concentrators in dot look somewhat like Newbery’s
[New89], they are found by searching the edges in the layout, not by detecting
complete bipartite graphs in the underlying graph. Thus the dot approach runs
much faster but doesn’t collapse as many edges as Newbery’s algorithm.
1:digraph G {
2: size="8,6"; ratio=fill; node[fontsize=24];
3:
4: ciafan->computefan; fan->increment; computefan->fan; stringdup->fatal;
5: main->exit; main->interp_err; main->ciafan; main->fatal; main->malloc;
6: main->strcpy; main->getopt; main->init_index; main->strlen; fan->fatal;
7: fan->ref; fan->interp_err; ciafan->def; fan->free; computefan->stdprintf;
8: computefan->get_sym_fields; fan->exit; fan->malloc; increment->strcmp;
9: computefan->malloc; fan->stdsprintf; fan->strlen; computefan->strcmp;
10: computefan->realloc; computefan->strlen; debug->sfprintf; debug->strcat;
11: stringdup->malloc; fatal->sfprintf; stringdup->strcpy; stringdup->strlen;
12: fatal->exit;
13:
14: subgraph "cluster_error.h" { label="error.h"; interp_err; }
15:
16: subgraph "cluster_sfio.h" { label="sfio.h"; sfprintf; }
17:
18: subgraph "cluster_ciafan.c" { label="ciafan.c"; ciafan; computefan;
19: increment; }
20:
21: subgraph "cluster_util.c" { label="util.c"; stringdup; fatal; debug; }
22:
23: subgraph "cluster_query.h" { label="query.h"; ref; def; }
24:
25: subgraph "cluster_field.h" { get_sym_fields; }
26:
27: subgraph "cluster_stdio.h" { label="stdio.h"; stdprintf; stdsprintf; }
28:
29: subgraph "cluster_<libc.a>" { getopt; }
30:
31: subgraph "cluster_stdlib.h" { label="stdlib.h"; exit; malloc; free; realloc; }
32:
33: subgraph "cluster_main.c" { main; }
34:
35: subgraph "cluster_index.h" { init_index; }
36:
37: subgraph "cluster_string.h" { label="string.h"; strcpy; strlen; strcmp; strcat; }
38:}
main
util.c ciafan.c
query.h error.h
strcat strcpy strlen strcmp sfprintf get_sym_fields stdprintf stdsprintf realloc malloc exit free
digraph G {
compound=true;
subgraph cluster0 { a
a -> b;
a -> c;
b -> d;
b c
c -> d;
}
subgraph cluster1 {
e -> g; d
e -> f;
}
b -> f [lhead=cluster1];
h e
d -> e;
c -> g [ltail=cluster0,
lhead=cluster1];
c -> e [ltail=cluster0]; f g
d -> h;
}
Figure 22: Graph with edges on clusters
dot User’s Manual, December 22, 2009 28
pdf Adobe PDF via the Cairo library. We have seen problems when embedding
into other documents. Instead, use -Tps2 as described below.
ps2 PostScript (EPSF) output with PDF annotations. This output should be dis-
tilled into PDF, such as for pdflatex, before being included in a document.
(Use ps2pdf; epstopdf doesn’t handle %%BoundingBox: (atend).)
svg SVG output. The alternate form svgz produces compressed SVG.
5 Miscellaneous
In the top-level graph heading, a graph may be declared a strict digraph.
This forbids the creation of self-arcs and multi-edges; they are ignored in the input
file.
Nodes, edges and graphs may have a URL attribute. In certain output formats
(ps2, imap, cmapx, or svg), this information is integrated in the output so that
dot User’s Manual, December 22, 2009 29
nodes, edges and clusters become active links when displayed with the appropriate
tools. Typically, URLs attached to top-level graphs serve as base URLs, supporting
relative URLs on components. When the output format is imap, or cmapx, a
similar processing takes place with the headURL and tailURL attributes.
For certain formats (ps, fig or svg), comment attributes can be used to
embed human-readable notations in the output.
6 Conclusions
dot produces pleasing hierarchical drawings and can be applied in many settings.
Since the basic algorithms of dot work well, we have a good basis for fur-
ther research into problems such as methods for drawing large graphs and on-line
(animated) graph drawing.
7 Acknowledgments
We thank Phong Vo for his advice about graph drawing algorithms and program-
ming. The graph library uses Phong’s splay tree dictionary library. Also, the users
of dag, the predecessor of dot, gave us many good suggestions. Guy Jacobson and
Randy Hackbarth reviewed earlier drafts of this manual, and Emden contributed
substantially to the current revision. John Ellson wrote the generalized polygon
shape and spent considerable effort to make it robust and efficient. He also wrote
the GIF and ISMAP generators and other tools to bring Graphviz to the web.
dot User’s Manual, December 22, 2009 30
References
[Car80] M. Carpano. Automatic display of hierarchized graphs for computer
aided decision analysis. IEEE Transactions on Software Engineering,
SE-12(4):538–546, April 1980.
[War77] John Warfield. Crossing Theory and Hierarchy Mapping. IEEE Trans-
actions on Systems, Man, and Cybernetics, SMC-7(7):505–523, July
1977.
dot User’s Manual, December 22, 2009 31
G Layers
dot has a feature for drawing parts of a single diagram on a sequence of overlapping
“layers.” Typically the layers are overhead transparencies. To activate this feature,
one must set the top-level graph’s layers attribute to a list of identifiers. A node
or edge can then be assigned to a layer or range of layers using its layer attribute..
all is a reserved name for all layers (and can be used at either end of a range, e.g
design:all or all:code). For example:
layers = "spec:design:code:debug:ship";
node90 [layer = "code"];
node91 [layer = "design:debug"];
node90 -> node91 [layer = "all"];
node92 [layer = "all:code"];
In this graph, node91 is in layers design, code and debug, while node92 is
in layers spec, design and code.
In a layered graph, if a node or edge has no layer assignment, but incident
edges or nodes do, then its layer specification is inferred from these. To change the
default so that nodes and edges with no layer appear on all layers, insert near the
beginning of the graph file:
node [layer=all];
edge [layer=all];
There is currently no way to specify a set of layers that are not a continuous
range.
When PostScript output is selected, the color sequence for layers is set in the
array layercolorseq. This array is indexed starting from 1, and every ele-
ment must be a 3-element array which can interpreted as a color coordinate. The
adventurous may learn further from reading dot’s PostScript output.
dot User’s Manual, December 22, 2009 38
H Node Shapes
These are the principal node shapes. A more complete description of node shapes
can be found at the web site
www.graphviz.org/doc/info/shapes.html
plaintext
none
record Mrecord
dot User’s Manual, December 22, 2009 39
I Arrowhead Types
These are some of the main arrowhead types. A more complete description of these
shapes can be found at the web site
www.graphviz.org/doc/info/arrows.html
diamond none
dot User’s Manual, December 22, 2009 40
J Color Names
Here are some basic color names. More information about colors can be found at
www.graphviz.org/doc/info/colors.html
www.graphviz.org/doc/info/attrs.html#k:color
Whites Reds Yellows turquoise[1-4]
antiquewhite[1-4] coral[1-4] darkgoldenrod[1-4]
azure[1-4] crimson gold[1-4] Blues
bisque[1-4] darksalmon goldenrod[1-4] aliceblue
blanchedalmond deeppink[1-4] greenyellow blue[1-4]
cornsilk[1-4] firebrick[1-4] lightgoldenrod[1-4] blueviolet
floralwhite hotpink[1-4] lightgoldenrodyellow cadetblue[1-4]
gainsboro indianred[1-4] lightyellow[1-4] cornflowerblue
ghostwhite lightpink[1-4] palegoldenrod darkslateblue
honeydew[1-4] lightsalmon[1-4] yellow[1-4] deepskyblue[1-4]
ivory[1-4] maroon[1-4] yellowgreen dodgerblue[1-4]
lavender mediumvioletred indigo
lavenderblush[1-4] orangered[1-4] Greens lightblue[1-4]
lemonchiffon[1-4] palevioletred[1-4] chartreuse[1-4] lightskyblue[1-4]
linen pink[1-4] darkgreen lightslateblue[1-4]
mintcream red[1-4] darkolivegreen[1-4] mediumblue
mistyrose[1-4] salmon[1-4] darkseagreen[1-4] mediumslateblue
moccasin tomato[1-4] forestgreen midnightblue
navajowhite[1-4] violetred[1-4] green[1-4] navy
oldlace greenyellow navyblue
papayawhip Browns lawngreen powderblue
peachpuff[1-4] beige lightseagreen royalblue[1-4]
seashell[1-4] brown[1-4] limegreen skyblue[1-4]
snow[1-4] burlywood[1-4] mediumseagreen slateblue[1-4]
thistle[1-4] chocolate[1-4] mediumspringgreen steelblue[1-4]
wheat[1-4] darkkhaki mintcream
white khaki[1-4] olivedrab[1-4] Magentas
whitesmoke peru palegreen[1-4] blueviolet
rosybrown[1-4] seagreen[1-4] darkorchid[1-4]
Greys saddlebrown springgreen[1-4] darkviolet
darkslategray[1-4] sandybrown yellowgreen magenta[1-4]
dimgray sienna[1-4] mediumorchid[1-4]
gray tan[1-4] Cyans mediumpurple[1-4]
gray[0-100] aquamarine[1-4] mediumvioletred
lightgray Oranges cyan[1-4] orchid[1-4]
lightslategray darkorange[1-4] darkturquoise palevioletred[1-4]
slategray[1-4] orange[1-4] lightcyan[1-4] plum[1-4]
orangered[1-4] mediumaquamarine purple[1-4]
Blacks mediumturquoise violet
black paleturquoise[1-4] violetred[1-4]