3

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}
  • You can widen the green frame using \node[frame_green,fit=(IRFoyer) (IRFoyer-|Pote.east) (IRFoyer-|Foyer.west)]{}; – John Kormylo Oct 6 '14 at 14:19
  • Use calc library to place fitting corners where you need it and draw a rectangle or a fitting node, like in Thorsten's answer in linked question. – Ignasi Oct 6 '14 at 14:49
3

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}
2

Another solution. It uses fitting library but with shifted or auxiliary coordinates.

The cyan frame uses fit to encompass all three boxes

\node[frame=cyan,fit=(Foyer)(Pote)(FoyerPote)] (cyan) {};

The yellow frame uses |- -| syntax to adjust fitting frame

\node[frame=green,fit=(IRFoyer.north-|Foyer.west) (IRFoyer.south-|Pote.east)] (green) {};

The blue frame is drawn with perpendicular intersection syntax and two auxiliary nodes (I couldn't mix shift and |-).

\coordinate (aux1) at ([xshift=-1cm]Indrev.west);
\coordinate (aux2) at ([xshift=1cm]Indrev.east);
\node[frame=blue,fit=(Foyer.north-|aux1) (FoyerPote.south-|aux2)] (blue) {};

The yellow and red frames use shifted coordinates to define fitting frame corners. Fit nodes list must be surrounded by braces {}.

\node[frame=yellow,fit={([xshift=-1cm]IndivPote.north west) ([xshift=1cm]IndivPote.south east)}] (yellow) {};
\node[frame=red,fit={([xshift=-1cm]Menage.north west) ([xshift=1cm]Menage.south east)}] (red) {};

The result is:

enter image description here

and the complete 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]

\tikzset{frame/.style={line width=4pt, inner sep=1em, draw=#1}}

\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)] (cyan) {};
\node[frame=green,fit=(IRFoyer.north-|Foyer.west) (IRFoyer.south-|Pote.east)] (green) {};
\coordinate (aux1) at ([xshift=-1cm]Indrev.west);
\coordinate (aux2) at ([xshift=1cm]Indrev.east);
\node[frame=blue,fit=(Foyer.north-|aux1) (FoyerPote.south-|aux2)] (blue) {};
\node[frame=yellow,fit={([xshift=-1cm]IndivPote.north west) ([xshift=1cm]IndivPote.south east)}] (yellow) {};
\node[frame=red,fit={([xshift=-1cm]Menage.north west) ([xshift=1cm]Menage.south east)}] (red) {};
-
% 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}

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.