[Tex/LaTex] Draw edges and paths in the background of nodes in TikZ

nodestikz-pgf

Is it possible to draw edges or paths in the background of nodes independently of whether they are constructed before or after the nodes are defined?

In the following example, the \draw instruction comes after the nodes are declared and so the path from (foo) to (baz) crosses the node (bar).

\documentclass{article}

\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \node [fill=gray!30] (foo) at (0,0) { foo };
    \node [fill=gray!30] (bar) at (2,0) { bar };
    \node [fill=gray!30] (baz) at (4,0) { baz };

    \draw (foo) -- (baz);
  \end{tikzpicture}
\end{document}

What I would like to achieve is that the path crosses (bar) in the background, so the node is not crossed visually. Is this possible without changing the order of the instructions (in particular, without moving the creation of (bar) below the \draw instruction)?

Here is how the above example looks like:

edge crossing the node in the foreground

And here is the desired result:

edge crossing the node in the background

Best Answer

TikZ/PGF has a concept of layers. They are described in chapter 82 “Layered Graphics” in the (v2.10) manual and can be used to have later commands be drawn below the things before them. In your example, you could write

\documentclass{article}
\usepackage{tikz}

\pgfdeclarelayer{bg}    % declare background layer
\pgfsetlayers{bg,main}  % set the order of the layers (main is the standard layer)

\begin{document}
  \begin{tikzpicture}
    \node [fill=gray!30] (foo) at (0,0) { foo };
    \node [fill=gray!30] (bar) at (2,0) { bar };
    \node [fill=gray!30] (baz) at (4,0) { baz };

    \begin{pgfonlayer}{bg}    % select the background layer
        \draw (foo) -- (baz);
    \end{pgfonlayer}
  \end{tikzpicture}
\end{document}

Actually, the backgrounds library (see chapter 25 in v2.10) already defines a background layer and a key that has to be used on a scope to select the layer:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds}

\begin{document}
  \begin{tikzpicture}
    \node [fill=gray!30] (foo) at (0,0) { foo };
    \node [fill=gray!30] (bar) at (2,0) { bar };
    \node [fill=gray!30] (baz) at (4,0) { baz };

    \begin{scope}[on background layer]
        \draw (foo) -- (baz);
    \end{scope}
  \end{tikzpicture}
\end{document}

(The two solutions compile to the same code (except that the backgrounds library calls the layer background).)