如何在 tikz 中的一组节点周围添加框架

如何在 tikz 中的一组节点周围添加框架

我有一张我创建的程序的漂亮的 tikz 图:

在此处输入图片描述

不同的颜色对应不同的程序,所以我想知道是否有办法在每组相同颜色的节点周围添加一个框架(这里只会更改为浅青色的自由)。就像在另一张图片中一样

在此处输入图片描述

这是我看了之后得到的

在此处输入图片描述

从青色来看不错,但我不知道如何获得所需的宽度,因为框架被定义为适合节点......

这是我的代码:

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

答案1

这是使用minimum widthheight作为框架样式的解决方案之一。由于流程图占据了整张 A4 纸,因此此解决方案需要调整节点距离以将所有块打包在一页中。

在此处输入图片描述

代码

\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

另一种解决方案。它使用fitting库,但带有移位或辅助坐标。

框架cyan用于fit包含所有三个框

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

框架yellow使用|- -|语法来调整适配框架

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

blue框架是用垂直交叉语法和两个辅助节点绘制的(我无法混合shift|-)。

\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) {};

和框架使用坐标来定义拟合框架角。拟合节点列表yellow必须用括号括起来。redshifted{}

\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) {};

结果是:

在此处输入图片描述

完整代码如下:

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

相关内容