# Fit around nodes and edges

I know that I can use the fit library of tikz to get a fitted background behind some nodes.

How can I get the fit to be around edges as well?

My current code:

\begin{tikzpicture}[prefix=fig/,
state/.style={circle,draw,thick},
hmm/.style={draw,rectangle}]

\node[state] (a1) at (0,0) {} edge [loop above,thick] () ;
\node[state] (a2) at (1,0) {} edge [loop above,thick] () edge[<-,thick] (a1);
\node[state] (a3) at (2,0) {} edge [loop above,thick] () edge[<-,thick] (a2);

\node[hmm,fit=(a1) (a2) (a3)] (a) {};
\end{tikzpicture}


This puts the top of the background box straight through the loops. How can I fit the box nicely around the nodes and edges (so the top of the loop must be a point somehow in the fit).

-

One way to do this is to add a coordinate at the midpoint of each loop (well, in this example it's only necessary to add it to one loop since all are the same height). Then add that coordinate to the fit.

\documentclass{article}
\pagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{fit}
\begin{document}

\begin{tikzpicture}[prefix=fig/,
state/.style={circle,draw,thick},
hmm/.style={draw,rectangle}]

\node[state] (a1) at (0,0) {} edge [loop above,thick] coordinate (l1) () ;
\node[state] (a2) at (1,0) {} edge [loop above,thick] coordinate (l2) () edge[<-,thick] (a1);
\node[state] (a3) at (2,0) {} edge [loop above,thick] coordinate (l3) () edge[<-,thick] (a2);

\node[hmm,fit=(a1) (a2) (a3) (l1) (l2) (l3)] (a) {};
\end{tikzpicture}
\end{document}


Note that the coordinate specification goes before the dummy target of the loop. This shows, incidentally, why that dummy target is useful. Placing the coordinate after the target puts the coordinate at the end of the loop, placing it before puts it at the midpoint.

I guess that a more elegant solution would be if it were possible to name a path and pass that name to the fit library, but I don't know if that's possible (however, last time I said something like that, someone came along and did it so I mention it just in case I can reinvoke the tikz-djinn).

-

One possibility is to use the current bounding box:

% snip...
\node[state] (a1) at (0,0) {} edge [loop above,thick] () ;
\node[state] (a2) at (1,0) {} edge [loop above,thick] () edge[<-,thick] (a1);
\node[state] (a3) at (2,0) {} edge [loop above,thick] () edge[<-,thick] (a2);

\draw (current bounding box.south west) rectangle (current bounding box.north east);
% snip...


It is perhaps too tight, but there is no need for fit-library.

-
If it is too tight, use fit=(current bounding box) and the inner sep of a node or coordinate will take care of the padding. Bounding boxes can also be calculated on a per-scope basis using the local bounding box option which can be handy for boxing only part of a graphic. –  Sharpie May 1 '11 at 1:40