[Tex/LaTex] How to include labels using Tikz’s fit

fittikz-pgf

I'm creating a graph using TikZ. It's working fine, but when I try to use the fit to make a background, it's not quite large enough:

enter image description here

Notice that the green doesn't cover the labels Gateway and Root. I figure that if there's a way to reference the node's labels (similar to the way I can do node.north, etc), that should work.

Here's the code I'm using:

\documentclass{article}
\usepackage{tikz}
\begin{document}\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri}

\begin{tikzpicture}
    [gateway/.style={circle, fill=blue!20!white, draw=blue, thick, inner sep=0pt,
                     minimum size=6mm, label=below:Gateway},
     root/.style={circle, fill=red!20!white, draw=red, thick, inner sep=0pt,
                  minimum size=6mm, label=below:Root},
     node/.style={circle, fill=gray!20!white, draw=gray, thick, inner sep=0pt,
                  minimum size=6mm, label=below:Node},
     every edge/.style={<->, semithick, draw}, 
     ]
    \node[gateway] (gateway_1) at ( 0, 0) {};
    \node[root]    (root_1)    at (10, 0) {};
    \node[node]    (node_1)    at ( 5, 5) {}
         edge node [auto] {connect} (root_1)
         edge (gateway_1);
    
    \begin{pgfonlayer}{background}
        \node [fill=green!20!white, fit=(gateway_1) (root_1) (node_1)]{};
    \end{pgfonlayer}
\end{tikzpicture}
\end{document}

So of course as the title says, how do I include the labels in the background?

Thanks!

Best Answer

Relavent information from the pgf manual, section on "Establishing a Bounding Box"

There is a node that allows you to get the size of the current bounding box. The current bounding box node has the rectangle shape and its size is always the size of the current bounding box.

So, you could use the coordinates of this node to fill in the background:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri}

\begin{document}
\begin{tikzpicture}
    [gateway/.style={circle, fill=blue!20!white, draw=blue, thick, inner sep=0pt,
                     minimum size=6mm, label=below:Gateway},
     root/.style={circle, fill=red!20!white, draw=red, thick, inner sep=0pt,
                  minimum size=6mm, label=below:Root},
     node/.style={circle, fill=gray!20!white, draw=gray, thick, inner sep=0pt,
                  minimum size=6mm, label=below:Node},
     every edge/.style={<->, semithick, draw}, 
     ]
    \coordinate[gateway] (gateway_1) at ( 0, 0);
    \coordinate[root]    (root_1)    at (10, 0);
    \coordinate[node]    (node_1)    at ( 5, 5)
         edge node [auto] {connect} (root_1)
         edge (gateway_1);

    \begin{pgfonlayer}{background}
        \fill[green!20!white] (current bounding box.south west) rectangle
            (current bounding box.north east);
    \end{pgfonlayer}
\end{tikzpicture}
\end{document}

Note I also replaced your empty \node objects with \coordinate objects. Coordinates are equivalent to nodes, except for a few small details such as having no default shape. Coordinates contain no text which spares the need for a set of empty braces {}.


Update

Here is a more flexible version that uses the local bounding box parameter of scope environments to calculate bounding boxes only for the contents of a scope:

\begin{tikzpicture}
    [gateway/.style={circle, fill=blue!20!white, draw=blue, thick, inner sep=0pt,
                     minimum size=6mm, label=below:Gateway},
     root/.style={circle, fill=red!20!white, draw=red, thick, inner sep=0pt,
                  minimum size=6mm, label=below:Root},
     node/.style={circle, fill=gray!20!white, draw=gray, thick, inner sep=0pt,
                  minimum size=6mm, label=below:Node},
     every edge/.style={<->, semithick, draw},
     background fill/.store in=\bgfill,
     background fill=green!20!white,   % Default value
     fill background/.style={
       local bounding box=bbox,
       execute at end scope={
         \begin{pgfonlayer}{background}
           \coordinate[rectangle,fill=\bgfill,fit=(bbox)];
         \end{pgfonlayer}}
    }]

    \begin{scope}[fill background,background fill=red!20!white]
      \coordinate[gateway] (gateway_1) at ( 0, 0);
      \coordinate[root]    (root_1)    at (10, 0);
      \coordinate[node]    (node_1)    at ( 5, 5)
           edge node [auto] {connect} (root_1)
           edge (gateway_1);
    \end{scope}    

    \begin{scope}[fill background]
      \coordinate[gateway] (gateway_2) at ( 2.5, -2);
      \coordinate[node]    (node_2) at ( 7.5, -2)
           edge (gateway_2);
    \end{scope}    

\end{tikzpicture}

For each scope marked with fill background, the bounding box is stored in a node called bbox. execute at end scope is used to automatically create a fill on the background layer when the scope is ended. The background fill key is set up to alter the value of \bgfill so that the background color may be customized.

The results are:

Use scopes to only fill the background of part of a picture