4

I have the following code sample with sublayouts to properly set the nodes within my graph. The problem is that I can't seem to find a way to add a background node fitting all the inner nodes.

\RequirePackage{luatex85}
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{graphdrawing}
\usetikzlibrary{graphs, backgrounds, fit, positioning, calc}
\usegdlibrary{trees, layered}

\begin{document}
\begin{tikzpicture}[layered layout, level sep=0.4cm]
        \node[draw, level sep=1.1cm] (in) {};

        \begin{scope}[tree layout]
          \node[draw] (A_t_0) {a};
          \node[draw] (A_t_1) {a};
          \node[draw] (B_0) {b};
          \node[draw] (B_1) {b};
          \node[draw] (C_t_0) {c};
          \node[draw] (C_t_1) {c};
        \end{scope}


        \begin{scope}[tree layout]
          \node[draw] (A_add) {+};
          \node[draw] (B_add) {+};
          \node[draw] (C_add) {+};
        \end{scope}

        \begin{scope}[tree layout]
          \node[draw] (A_0) {a};
          \node[draw] (A_1) {a};
          \node[draw] (C_0) {c};
          \node[draw] (C_1) {c};
        \end{scope}

        \node[draw] (add) {+};
        \node[draw] (z) {Z};
        \node[draw] (out) {};

        \begin{scope}[on background layer]
            \node[fill=red!30, fit=(A_t_0) (C_t_1) (z), inner sep=5pt] {};
        \end{scope}

        \draw (in) edge [->] (A_t_0);
        \draw (in) edge [->] (A_t_1);
        \draw (in) edge [->] (B_0);
        \draw (in) edge [->] (B_1);
        \draw (in) edge [->] (C_t_0);
        \draw (in) edge [->] (C_t_1);

        \draw (A_t_0) edge [->] (A_add);
        \draw (A_t_1) edge [->] (A_add);
        \draw (B_0) edge [->] (B_add);
        \draw (B_1) edge [->] (B_add);
        \draw (C_t_0) edge [->] (C_add);
        \draw (C_t_1) edge [->] (C_add);

        \draw (A_add) edge [->] (A_0);
        \draw (A_add) edge [->] (A_1);
        \draw (C_add) edge [->] (C_0);
        \draw (C_add) edge [->] (C_1);

        \draw (A_0) edge [->] (add);
        \draw (A_1) edge [->] (add);
        \draw (B_add) edge [->, bend left=0] (add);
        \draw (C_0) edge [->] (add);
        \draw (C_1) edge [->] (add);

        \draw(add) edge[->] (z);
        \draw(z) edge[->] (out);

  \end{tikzpicture}
\end{document}

The code produces the following image. Note that the small red rectangle is the background node which is supposed to fit the inner nodes of my graph.

enter image description here

I have also tried an alternative approach (see below) with the remember picture and overlay options from tikz. This seems to calculate the position and size of the rectangle correctly, but it is not put to the background layer. I tried that approach with the on background layer option like in the following code sample and also tried the \pgfdeclarelayer, \pgfsetlayers commands, but no success either.

\RequirePackage{luatex85}
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{graphdrawing}
\usetikzlibrary{graphs, backgrounds, fit, positioning, calc}
\usegdlibrary{trees, layered}

\begin{document}
\begin{tikzpicture}[remember picture, layered layout, level sep=0.4cm]
        \node[draw, level sep=1.1cm] (in) {};

        \begin{scope}[tree layout]
          \node[draw] (A_t_0) {a};
          \node[draw] (A_t_1) {a};
          \node[draw] (B_0) {b};
          \node[draw] (B_1) {b};
          \node[draw] (C_t_0) {c};
          \node[draw] (C_t_1) {c};
        \end{scope}


        \begin{scope}[tree layout]
          \node[draw] (A_add) {+};
          \node[draw] (B_add) {+};
          \node[draw] (C_add) {+};
        \end{scope}

        \begin{scope}[tree layout]
          \node[draw] (A_0) {a};
          \node[draw] (A_1) {a};
          \node[draw] (C_0) {c};
          \node[draw] (C_1) {c};
        \end{scope}

        \node[draw] (add) {+};
        \node[draw] (z) {Z};
        \node[draw] (out) {};

        % \begin{scope}[on background layer]
        %     \node[fill=red!30, fit=(z), inner sep=5pt] {};
        % \end{scope}

        \draw (in) edge [->] (A_t_0);
        \draw (in) edge [->] (A_t_1);
        \draw (in) edge [->] (B_0);
        \draw (in) edge [->] (B_1);
        \draw (in) edge [->] (C_t_0);
        \draw (in) edge [->] (C_t_1);

        \draw (A_t_0) edge [->] (A_add);
        \draw (A_t_1) edge [->] (A_add);
        \draw (B_0) edge [->] (B_add);
        \draw (B_1) edge [->] (B_add);
        \draw (C_t_0) edge [->] (C_add);
        \draw (C_t_1) edge [->] (C_add);

        \draw (A_add) edge [->] (A_0);
        \draw (A_add) edge [->] (A_1);
        \draw (C_add) edge [->] (C_0);
        \draw (C_add) edge [->] (C_1);

        \draw (A_0) edge [->] (add);
        \draw (A_1) edge [->] (add);
        \draw (B_add) edge [->, bend left=0] (add);
        \draw (C_0) edge [->] (add);
        \draw (C_1) edge [->] (add);

        \draw(add) edge[->] (z);
        \draw(z) edge[->] (out);
  \end{tikzpicture}
  \begin{tikzpicture}[remember picture, overlay]
    \begin{scope}[on background layer]
      \node[fill=red!30, fit=(A_t_0) (C_t_1) (z), inner sep=5pt] {};
    \end{scope}
  \end{tikzpicture}
\end{document}

enter image description here

I am really interested in why the calculation of neither size nor position is working in the first approach. My guess is that the node are not set by the graphdrawing algorithm at the time, when the background is added.

I hope someone can help me to find a proper way to add the background and also add it to the background layer.

1

Welcome! Use scopes. That way you are sure that the algorithm is "done" (or "well done"? ;-).

\RequirePackage{luatex85}
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{graphdrawing}
\usetikzlibrary{graphs, backgrounds, fit, positioning, calc}
\usegdlibrary{trees, layered}

\begin{document}
\begin{tikzpicture}
\begin{scope}[layered layout, level sep=0.4cm]
        \node[draw, level sep=1.1cm] (in) {};

        \begin{scope}[tree layout]
          \node[draw] (A_t_0) {a};
          \node[draw] (A_t_1) {a};
          \node[draw] (B_0) {b};
          \node[draw] (B_1) {b};
          \node[draw] (C_t_0) {c};
          \node[draw] (C_t_1) {c};
        \end{scope}


        \begin{scope}[tree layout]
          \node[draw] (A_add) {+};
          \node[draw] (B_add) {+};
          \node[draw] (C_add) {+};
        \end{scope}

        \begin{scope}[tree layout]
          \node[draw] (A_0) {a};
          \node[draw] (A_1) {a};
          \node[draw] (C_0) {c};
          \node[draw] (C_1) {c};
        \end{scope}

        \node[draw] (add) {+};
        \node[draw] (z) {Z};
        \node[draw] (out) {};

        \draw (in) edge [->] (A_t_0);
        \draw (in) edge [->] (A_t_1);
        \draw (in) edge [->] (B_0);
        \draw (in) edge [->] (B_1);
        \draw (in) edge [->] (C_t_0);
        \draw (in) edge [->] (C_t_1);

        \draw (A_t_0) edge [->] (A_add);
        \draw (A_t_1) edge [->] (A_add);
        \draw (B_0) edge [->] (B_add);
        \draw (B_1) edge [->] (B_add);
        \draw (C_t_0) edge [->] (C_add);
        \draw (C_t_1) edge [->] (C_add);

        \draw (A_add) edge [->] (A_0);
        \draw (A_add) edge [->] (A_1);
        \draw (C_add) edge [->] (C_0);
        \draw (C_add) edge [->] (C_1);

        \draw (A_0) edge [->] (add);
        \draw (A_1) edge [->] (add);
        \draw (B_add) edge [->, bend left=0] (add);
        \draw (C_0) edge [->] (add);
        \draw (C_1) edge [->] (add);

        \draw(add) edge[->] (z);
        \draw(z) edge[->] (out);
        \end{scope}
        \begin{scope}[on background layer]
            \node[fill=red!30, fit=(A_t_0) (C_t_1) (z), inner sep=5pt] {};
        \end{scope}
  \end{tikzpicture}
\end{document}

enter image description here

  • Damn, I was so close already. It works perfectly, thanks so much :) – schilli Sep 26 '18 at 21:19
  • @schilli Yes, you were. ;-) (The overlay would also work in connection with the right blend mode, but there is no need for that here.) – marmot Sep 26 '18 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.