GraphViz is a software package for drawing directed and undirected graphs [1]. Developed by AT&T [2], GraphViz is mainly written in C, although newer parts are written in C++ and Java. Bindings for GraphViz exist in many high-level languages. For C++, mfgraph [6] is a simple binding to dot, the GraphViz language, although it appears unmaintained. A more recent binding is contained in the Boost Graph Library (BGL) [7]. The BGL offers a generic interface for representing and manipulating graphs, so its connection to GraphViz is natural. In this article, we present examples of using the BGL to create GraphViz graphs. Although there are graphical tools based on GraphViz that can graphically create graphs, in this article we focus on command-line tools in combination with C++. We use GraphViz 2.0, g++ 3.4.1, and Boost 1.32.0.
There are three major programs for creating graphs, all of which use the dot language:
- dot is a utility program for drawing directed graphs [5].
- NEATO is a utility program for drawing undirected graphs. This kind of graph is commonly used in telecommunications and computer programming. NEATO uses an implementation of the Kamada-Kawai algorithm for "symmetric" layouts [4].
- twopi can draw graphs using a circular layout. One of the nodes is chosen as the center, and the other nodes are placed around the center node in a circular way. If a node is connected to the center node, it is placed at distance 1; if a node is connected to a node that is directly connected to the center node, it is placed at distance 2, and so on.
A graph contains nodes and edges, each of them having attributes. Table 1 shows some of the available attributes for dot nodes, while Table 2 shows part of the available edge attributes. There are also attributes for the graph that are not mentioned here. Similar attributes exist for the NEATO program.
Table 1: Node attributes.
Name | Explanation | Allowed Values |
shape | Shape of the node | ellipse, diamond, box, circle, etc. |
height | Height in inches | number |
width | Width in inches | number |
label | Name of the node | alphanumeric |
fontsize | Size of the font | number |
fontname | Name of the font | Courier, Helvetica, Times-Roman |
fontcolor | Color of the font | white, black, blue, etc. |
style | Style name | bold, dotted, filled, etc. |
color | Color of the node shape | white, black, etc. |
pos | Coordinates of the position | |
Table 2: Edge attributes.
Name | Explanation | Allowed Values |
label | Label of the edge | alphanumeric |
fontsize | Size of the font | |
fontname | Name of the font | |
fontcolor | Color of the font | |
style | Style name | bold, dotted, filled, etc. |
color | Color of the edge | white, black, blue, etc. |
len | Length of the edge | |
dir | Direction of the edge | forward, back, both or none |
decorate | Draws line that connects labels with their edges | 0 or 1 |
id | Optional value to denote different edges | alphanumeric |
Before getting the output of a GraphViz source file, the source file should be compiled. The general form of execution is:
toolname -Tps ftc.dot -o output.ps
where toolname denotes the name of the tool to execute (dot, NEATO, or twopi); -Tps denotes that the output file is in PostScript (other supported output formats are GIF, PNG, JPEG, HP-GL/2 vector format, VRML, and FrameMaker MIF); ftc.dot shows the name of the file to be processed; and -o output.ps tells what the output filename should be.
Figure 1: "Hello world!" in the dot language.
To illustrate how you can use the GraphViz language, we start with the familiar "Hello world!" example. This code produces the output in Figure 1:
digraph G { "Hello world!"; }
while this command produces the PostScript file for Figure 1:
dot -Tps hw.dot -o hw.ps
The word digraph
means that a directed graph is going to be created. For creating an undirected graph, use the word graph
instead.
Listing One is dot code to draw the hash table in Figure 2. The command rankdir = LR
denotes that the graph nodes are going to be drawn from left to right. The command node [shape=record, width=.1, height=.1]
defines some node attributes. The {}
characters inside the label parameter of the nodes tell the dot language to arrange the record parts left to right instead of one above another. Commands of the type nd0:p2 -> nd6:e
create the connections between the nodes (the edges of the graph).
Listing One
digraph G { rankdir = LR; node [shape=record, width=.1, height=.1]; nd0 [label = "<p0> | <p1> | <p2> | <p3> | <p4> | | ", height = 4]; node[ width=1.5 ]; nd1 [label = "{<e> HA0 | 123 | <p> }" ]; nd2 [label = "{<e> HA10 | PIK | <p> }" ]; nd3 [label = "{<e> HA11 | 23 | <p> }" ]; nd6 [label = "{<e> HA20 | 123 | <p> }" ]; nd7 [label = "{<e> HA40 | CUJ | <p> }" ]; nd8 [label = "{<e> HA41 | C++ | <p> }" ]; nd9 [label = "{<e> HA42 | DDJ | <p> }" ]; nd0:p0 -> nd1:e; nd0:p1 -> nd2:e; nd2:p -> nd3:e; nd0:p2 -> nd6:e; nd0:p4 -> nd7:e; nd7:p -> nd8:e; nd8:p -> nd9:e; }
Figure 2: A hash table using dot.
The command that produces Figure 2 is:
dot -Tps hashtable.dot -o hashtable.ps