我有一张我创建的程序的漂亮的 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 width
和height
作为框架样式的解决方案之一。由于流程图占据了整张 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
必须用括号括起来。red
shifted
{}
\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}