[Tex/LaTex] How to add frames around a group of nodes in tikz

nodestikz-pgf

I have this beautiful tikz diagram of my program that I have created :

enter image description here

The different colours correspond to different programs, so I would like to know if there is a way to add a frame around each group of nodes of the same colour (which here would only change for the free in light cyan). Like in this other picture

enter image description here

And here is what I get after a look at This

enter image description here

It looks good from the cyan one, but I do not know how to get the desired width as the frames are defined to fit the nodes…

Here is my code :

\documentclass[a4paper]{article}

\usepackage[english]{babel}
\usepackage[utf8]{inputenc}

\usepackage{tikz-cd}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{calc,trees,positioning,arrows,chains,shapes.geometric,shapes}

\begin{document}



\begin{landscape}


\tikzstyle{block2} = [rectangle, draw, fill=blue!20, text width=7cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{block} = [rectangle, draw, fill=white, text width=7cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{arrow} = [draw, -latex']
\tikzstyle{line} = [draw]
\tikzstyle{block4} = [rectangle, draw, fill=cyan!10, text width=6.5cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{through} = [rectangle, fill=white, text width=6.5cm, text centered, rounded corners, minimum height=2em]
\tikzstyle{block5} = [rectangle, draw, fill=yellow!8, text width=8cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{block6} = [rectangle, draw, fill=green!12, text width=6.5cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{block7} = [rectangle, draw, fill=blue!14, text width=12cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{block8} = [rectangle, draw, fill=red!16, text width=12cm, text centered, rounded corners, minimum height=4em]

\tikzstyle{frame_cyan} = [thick, draw=cyan, dotted,inner sep=0.2em]
\tikzstyle{frame_yellow} = [thick, draw=yellow, dotted,inner sep=0.2em]
\tikzstyle{frame_blue} = [thick, draw=blue, dotted,inner sep=0.2em, text width=12cm]
\tikzstyle{frame_red} = [thick, draw=red, dotted,inner sep=0.2em]
\tikzstyle{frame_green} = [thick, draw=green, dotted,inner sep=0.2em]

\begin{tikzpicture}[node distance = 2cm, auto]
\centering
% Place nodes
\node [block4] (Foyer) 
        {\emph{foyer.foyer \textbf{FOYER EEC}} \\
        \begin{itemize}
        \item on crée sous-table par département
        \item suppression doublons
        \end{itemize}
        };

\node [block4, right of=Foyer, node distance=8cm] (Pote) 
        {\emph{pote.dep \textbf{FOYER POTE}} \\
        \begin{itemize}
        \item  choix anrev correct
        \item  doublons dirindic
        \end{itemize}
        };


\path (Foyer) -- (Pote) node[through, pos=.5,below=1cm] (Merge1) 
        {\textbf{Fusion par dirindik}
        };


\node [block5, right of=Merge1, node distance=14cm] (Indrev) 
        {\emph{foyer.indrev \textbf{INDIVIDU EEC}}
        \\ \begin{itemize}
        \item détermine, via MDS, âge, persfipd
            \begin{itemize}
            \item $Persfip_{N-1}$
            \item $Prevu$ créé à partir de $dirindik_{N-1}$
                \begin{itemize}
                \item Oui
                \item Non
                \end{itemize}
            \end{itemize}
        \end{itemize}};


\node [block4, below of=Merge1, node distance=1.5cm] (FoyerPote) 
        {\emph{Travail.Pote\_DEP\_Clean \textbf{FOYER}} \\
        \begin{itemize}
        \item  on empile chaque département
        \end{itemize} 
        \emph{table Travail.FoyerPoteFR}
        };

\node [block6, below of=FoyerPote, node distance=2.2cm] (IRFoyer) 
        {\emph{Travail.Pote\_nat \textbf{FOYER}} \\
        \begin{itemize}
        \item  On récupère les variables idoines
            \begin{itemize}
            \item les MDS année précédente
            \item l'impôt
            \item les var pour REVDISP(N)
            \end{itemize}
        \end{itemize} 
        }; 

\path (Merge1) -- (Indrev) node[through, pos=.6,below=5cm] (Merge2) 
        {\textbf{Fusion par dirindik}
        };

\node [block7, below of=Merge2, node distance=2.5cm] (IndivPote) 
        {\emph{Travail.IndivPote \textbf{INDIVIDU EEC}} \\
        \begin{itemize}
        \item On vérifie qui on a trouvé
            \begin{itemize}
            \item  Si individu EEC trouvé dans Pote\_nat : $Trouve=Oui$
            \item  Sinon : $Trouve = Non$
            \item Femmes en MDS en N-1 : manque une déclaration : $Trouve=Partiel$
            \end{itemize}
        \item On compare $Prevu$ et $Trouve$
        \end{itemize} 
        };        

\node [block8, below of=IndivPote, node distance=3.75cm] (Menage) 
        {\emph{Travail.IndivPote \textbf{INDIVIDU EEC}} \\
        \begin{itemize}
        \item  Par nomen, on compte le nombre d'adultes\\
        si trouvé=Partiel (resp.Oui), on incrémente nbpartiel (resp. nbcomplet)\\
            \begin{itemize}
            \item Si nbadulte=nbcomplet : TROUVE
            \item Si nbadulte\textgreater nbcomplet : PARTIEL
            \item Si nbpartiel+nbcomplet=0
            \end{itemize}
        \end{itemize} 
        \emph{Travail.MenagePote \textbf{MENAGE EEC}}
        };        
\node[frame_cyan,fit=(Foyer) (Pote) (FoyerPote)]{};
\node[frame_yellow,fit=(Indrev)]{};
\node[frame_green,fit=(IRFoyer)]{};
\node[frame_blue,fit=(IndivPote)]{};
\node[frame_red,fit=(Menage)]{};

% Draw edges
\path [arrow] (Foyer)  -|  (FoyerPote);
\path [arrow] (Pote) -| (FoyerPote);
\path [arrow] (FoyerPote) -- (IRFoyer);
\path [arrow] (IRFoyer) -| (IndivPote);
\path [line] (Indrev) |- (Indrev|-IRFoyer);
\path [line] (Indrev|-IRFoyer) -| (IndivPote);
\path [arrow] (IndivPote) -- (Menage);
\end{tikzpicture}


\end{landscape}

\end{document}

Best Answer

This is one solution where minimum width and height are used for the frames style. Since the flowchart occupies the full A4 paper, this solution needs to adjust the node distances to pack all blocks in one page.

enter image description here

Code

\documentclass[a4paper]{article}
\usepackage[margin=0cm]{geometry}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage{lscape}
\usepackage{tikz-cd}
\usetikzlibrary{shapes,arrows,calc,trees,positioning}
\usetikzlibrary{chains,fit,shapes.geometric}

\begin{document}



\begin{landscape}


\tikzstyle{block2} = [rectangle, draw, fill=blue!20, text width=7cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{block} = [rectangle, draw, fill=white, text width=7cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{arrow} = [draw, -latex']
\tikzstyle{line} = [draw]
\tikzstyle{block4} = [rectangle, draw, fill=cyan!10, text width=6.5cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{through} = [rectangle, fill=white, text width=5cm, text centered, rounded corners, minimum height=2em]
\tikzstyle{block5} = [rectangle, draw, fill=yellow!8, text width=8cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{block6} = [rectangle, draw, fill=green!12, text width=6.5cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{block7} = [rectangle, draw, fill=blue!14, text width=12cm, text centered, rounded corners, minimum height=4em]
\tikzstyle{block8} = [rectangle, draw, fill=red!16, text width=12cm, text centered, rounded corners, minimum height=4em]

\tikzstyle{frame_cyan} = [line width=4pt, draw=cyan,inner sep=0.2em,minimum width=15cm,minimum height=6cm]
\tikzstyle{frame_yellow} = [line width=4pt, draw=yellow ,inner sep=0.2em,minimum width=10cm,minimum height=6cm]
\tikzstyle{frame_blue} = [line width=4pt, draw=blue, inner sep=0.2em, minimum width=15cm,minimum height=5cm]
\tikzstyle{frame_red} = [line width=4pt, draw=red, inner sep=0.2em, minimum width=15cm,minimum height=5cm]
\tikzstyle{frame_green} = [line width=4pt, draw=green, inner sep=0.2em,minimum width=15cm,minimum height=4cm]

\begin{tikzpicture}[auto]
\centering
% Place nodes
\node [block4] (Foyer) 
        {\emph{foyer.foyer \textbf{FOYER EEC}} 
        \begin{itemize}
        \item on crée sous-table par département
        \item suppression doublons
        \end{itemize}
        };

\node [block4, right =1cm of Foyer] (Pote) 
        {\emph{pote.dep \textbf{FOYER POTE}}
        \begin{itemize}
        \item  choix anrev correct
        \item  doublons dirindic
        \end{itemize}
        };


\path (Foyer) -- (Pote) node[pos=.5,below=1.2cm] (Merge1) 
        {\textbf{Fusion par dirindik}
        };


\node [block5, right = 9cm of Merge1] (Indrev) 
        {\emph{foyer.indrev \textbf{INDIVIDU EEC}}
        \begin{itemize}
        \item détermine, via MDS, âge, persfipd
            \begin{itemize}
            \item $Persfip_{N-1}$
            \item $Prevu$ créé à partir de $dirindik_{N-1}$
                \begin{itemize}
                \item Oui
                \item Non
                \end{itemize}
            \end{itemize}
        \end{itemize}};


\node [block4, below  of = Merge1, node distance=1.5cm] (FoyerPote) 
        {\emph{Travail.Pote\_DEP\_Clean \textbf{FOYER}} 
        \begin{itemize}
        \item  on empile chaque département
        \end{itemize} 
        \emph{table Travail.FoyerPoteFR}
        };

\node [block6, below =1.2cm  of FoyerPote] (IRFoyer) 
        {\emph{Travail.Pote\_nat \textbf{FOYER}} 
        \begin{itemize}
        \item  On récupère les variables idoines
            \begin{itemize}
            \item les MDS année précédente
            \item l'impôt
            \item les var pour REVDISP(N)
            \end{itemize}
        \end{itemize} 
        }; 

\path (Merge1) -- (Indrev) node[pos=.5,below=6cm] (Merge2) 
        {\textbf{Fusion par dirindik}
        };

\node [block7, below =1.4cm of Merge2] (IndivPote) 
        {\emph{Travail.IndivPote \textbf{INDIVIDU EEC}} 
        \begin{itemize}
        \item On vérifie qui on a trouvé
            \begin{itemize}
            \item  Si individu EEC trouvé dans Pote\_nat : $Trouve=Oui$
            \item  Sinon : $Trouve = Non$
            \item Femmes en MDS en N-1 : manque une déclaration : $Trouve=Partiel$
            \end{itemize}
        \item On compare $Prevu$ et $Trouve$
        \end{itemize} 
        };        

\node [block8, below = 1cm of IndivPote,] (Menage) 
        {\emph{Travail.IndivPote \textbf{INDIVIDU EEC}} 
        \begin{itemize}
        \item  Par nomen, on compte le nombre d'adultes
        si trouvé=Partiel (resp.Oui), on incrémente nbpartiel (resp. nbcomplet)
            \begin{itemize}
            \item Si nbadulte=nbcomplet : TROUVE
            \item Si nbadulte\textgreater nbcomplet : PARTIEL
            \item Si nbpartiel+nbcomplet=0
            \end{itemize}
        \end{itemize} 
        \emph{Travail.MenagePote \textbf{MENAGE EEC}}
        };        

\node[frame_cyan,fit=(Foyer)(Pote) (FoyerPote)]{};
\node[frame_yellow,fit=(Indrev)]{};
\node[frame_green,fit=(IRFoyer)]{};
\node[frame_blue,fit=(IndivPote)]{};
\node[frame_red,fit=(Menage)]{};

% Draw edges
\path [arrow] (Foyer)  -|  (FoyerPote);
\path [arrow] (Pote) -| (FoyerPote);
\path [arrow] (FoyerPote) -- (IRFoyer);
\path [arrow] (IRFoyer) -| (IndivPote);
\path [line] (Indrev) |- (Indrev|-IRFoyer);
\path [line] (Indrev|-IRFoyer) -| (IndivPote);
\path [arrow] (IndivPote) -- (Menage);
\end{tikzpicture}
\end{landscape}

\end{document}
Related Question