\section{Unconnected graphs}
\label{sec:unconnect}
All of the basic layouts provided by \gviz\ are based on a connected graph.
Each is then extended to handle the not uncommon case of having
multiple components. Most of the time, the obvious approach is used:
draw each component separately and then assemble the drawings into a single
layout. The only place this is not done is in \neato\ when the mode is
{\tt "KK"} and {\tt pack="false"} (cf. Section~\ref{sec:neato}).

For the \dot\ algorithm, its layered drawings make the merging simple:
the nodes on the highest rank of each component are all put
on the same rank. For the other layouts, it is not obvious how to put
the components together. 

The \gviz\ software provides the library \pack\ to assist
with unconnected graphs, especially by supplying a technique for
packing arbitrary graph drawings together quickly, aesthetically and
with efficient use of space. The following code indicates how the
library can be integrated with the 
basic layout algorithms given an input graph {\tt g} and a \gvc\ value
{\tt gvc}.

\begin{verbatim}
    Agraph_t *sg;
    FILE *fp;
    Agraph_t** cc;
    int       i, ncc;

    cc = ccomps(g, &ncc, (char*)0);

    for (i = 0; i < ncc; i++) {
	    sg = cc[i];
        nodeInduce (sg);
        gvLayout(gvc, sg, "neato");
    }
    pack_graph (ncc, cc, g, 0);

    gvRender(gvc, g, "ps", stdout);

    for (i = 0; i < ncc; i++) {
        sg = cc[i];
        gvFreeLayout(gvc, sg);
        agdelete(g, sg);
    }
\end{verbatim}

The call to {\tt ccomps} splits the graph {\tt g} into its connected
components. {\tt ncc} is set to the number of components. 
The components are represented by subgraphs of the input graph, and are
stored in the returned array. The function gives names to the components
in a way that should not conflict with previously existing subgraphs.
If desired, the third argument to {\tt ccomps} can be used to designate
what the subgraphs should be called. Also, for flexibility, the
subgraph components do not contain the associated edges.

Certain layout algorithms, such as \neato, allow the input graph to
fix the position of certain nodes, indicated by {\tt ND\_pinned(n)} being
non-zero. In this case, all nodes with a
fixed position need to be laid out together, so they should all
occur in the same ``connected'' component. The \pack\ library 
provides {\tt pccomps}, an analogue to {\tt ccomps} for this
situation. It has almost the same interface as {\tt ccomps}, but takes
a {\tt boolean*} third parameter. The function sets the boolean pointed
to to true if the graph has nodes with fixed positions. In this case,
the component containing these nodes is the first one in the returned array.

Continuing with the example,
we take one component at a time, use {\tt nodeInduce} to create the 
corresponding node-induced subgraph, and then lay out the component
with {\tt gvLayout}. Here, we use \neato\ for each layout, but it
is possible to use a different layout for each component.\footnote{
At present, the \dot\ layout has a limitation that it only works on
a root graph. Thus, to use \dot\ for a component, one needs to create
a new copy of the subgraph, apply \dot\, and then copy the position
attributes back to the component.}

Next, we use the \pack\ function {\tt pack\_graph} to reassemble
the graph into a single drawing. To position the components, \pack\
uses the polyomino-based approach described by
Freivalds et al\cite{pack}. The first three arguments to the
function are clear. The fourth argument indicates whether or not
there are fixed components.

The {\tt pack\_graph} function uses the graph's {\tt packmode}
attribute to determine how the packing should be done. At
present, packing uses the single algorithm mentioned above, but allows
three varying granularities, represented by the values {\tt "node"},
{\tt "clust"} and {\tt "graph"}. In the first case, packing is done at
the node and edge level. This provides the tightest packing, using the
least area, but also allows a node of one component to lie between
two nodes of another component. The second value, {\tt "clust"}, 
requires that the packing treat top-level clusters with a set
bounding box {\tt GD\_bb} value like a large node. Nodes and edges not
entirely contained within a cluster are handled as in the previous
case. This prevents any components which do not belong to the cluster 
from intruding within the cluster's bounding box. The 
last case does the packing at the graph granularity. Each component
is treated as one large node, whose size is determined by its
bounding box.

Note that the library automatically computes the bounding box of
each of the components. Also,
as a side-effect, {\tt pack\_graph} finishes by recomputing and
setting the bounding box attribute {\tt GD\_bb} of the graph.

The final step is to free the component subgraphs.

Although \dot\ and \neato\ have their specialized approaches to
unconnected graphs, it should be noted that these are not without
their deficiencies. The approach used by \dot, aligning the drawings
of all components along the top, works well until the
number of components grows large. When this happens, the aspect
ratio of the final drawing can become very bad. \neato 's handling
of an unconnected graph can have two drawbacks. First, there can be
a great deal of wasted space. The value chosen to separate
components is a simple function of the number of nodes. With a
certain edge structure, component drawings may use much less area.
This can produce a drawing similar to a classic atom: a large nucleus
surrounded by a ring of electrons with a great deal of empty space
between them. Second, the \neato\ model is essentially quadratic.
If the components are drawn separately, one can see a dramatic
decrease in layout time, sometimes several orders of magnitudes.
For these reasons, it sometimes makes sense to apply the \twopi\
approach for unconnected graphs to the \dot\ and \neato\ layouts.
In fact, as we've noted, {\tt neato\_layout} typically uses the \pack\
library by default.
