我想用 tikz 创建包含分叉和连接的流程图。chains 库似乎非常适合这种情况,但我发现当我分叉/连接多个链时很难调整边缘。
以下是 MWE:
\documentclass{minimal}
\newcommand{\jobdescr}[2]{\textsf{\textit{#1}} \vspace{4mm} \\ \textsf{\textbf{#2}}}
\newcommand{\tikzjob}[4]{\node[job, join, on chain=#1] (#2) {\jobdescr{#3}{#4}}}
\usepackage{tikz}
\usetikzlibrary{calc,trees,positioning,arrows,chains,shapes.geometric,%
decorations.pathreplacing,decorations.pathmorphing,shapes,%
matrix,shapes.symbols}
\tikzset{
>=stealth',
job/.style={
rectangle,
rounded corners,
% fill=black!10,
draw=black, very thick,
text width=14em,
minimum height=3em,
text centered,
on chain},
line/.style={draw, thick, <-},
element/.style={
tape,
top color=white,
bottom color=blue!50!black!60!,
minimum width=8em,
draw=blue!40!black!90, very thick,
text width=10em,
minimum height=3.5em,
text centered,
on chain},
every join/.style={->, thick,shorten >=1pt},
decoration={brace},
tuborg/.style={decorate},
tubnode/.style={midway, right=2pt},
}
\begin{document}
\begin{tikzpicture}
[node distance=.8cm,
start chain=main going below,]
\tikzjob{main} {input} {Input} {Read Input};
\node at (input.south west) (leftstart) {};
\node at (input.south east) (rightstart) {};
\begin{scope}[start chain=left going below]
\chainin (leftstart);
\tikzjob{left} {mapleft} {Map} {Job 1};
\end{scope}
\begin{scope}[start chain=right going below]
\chainin (rightstart);
\tikzjob{right} {mapright} {Map} {Job 2};
\end{scope}
\node (join) at (mapright.south -| input) {};
\begin{scope}[start chain=end going below]
\chainin (join);
\tikzjob{end} {join} {Reduce} {Join Results};
\tikzjob{end} {output} {Output} {Print Result};
\end{scope}
\end{tikzpicture}
\end{document}
如您所见,分叉/连接涉及四条链:原始链、左子链和右子链以及延续链。使用不可见节点,\chainin
很容易获得美观的间距。但边缘自然绘制在不可见节点之间,而不是实际节点之间。我宁愿像下图中注释的那样绘制边缘。
有没有简单的方法可以解决这个问题?
附言:理想情况下,我希望保留\tikzjob
宏,因为它很好地将显示与结构分开。
答案1
像这样:
上面的图像是用非常基础、简单和清晰的tikz
代码绘制的(我必须承认我迷失在你复杂的代码中了):
\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
positioning
}
\begin{document}
\begin{tikzpicture}[
node distance = 8mm and 1mm,
job/.style args = {#1/#2}{
rectangle, rounded corners, draw=black, very thick,
minimum height=3em, text width=14em, align=center,
label={[font=\sffamily,anchor=north]above:\textit{#1}},
label={[font=\sffamily,anchor=south]below:\textbf{#2}},
node contents ={}},
arr/.style = {semithick, -Stealth}
]
\node (n1) [job=Input/Read Input];
\node (n21) [job=Map/Job 1,below left=of n1.south];
\node (n22) [job=Map/Job 2,below right=of n1.south];
\node (n3) [job=Reduce/Join Results,below right=of n21.south];
\node (n4) [job=Output/Print results,below=of n3];
%
\coordinate[below=4mm of n1.south] (aux1);
\coordinate[above=4mm of n3.north] (aux2);
%
\draw[arr] (n1) -- (aux1) -| (n21);
\draw[arr] (aux1) -| (n22);
\draw[arr] (n21) |- (aux2)
(n22) |- (aux2) -- (n3);
\draw[arr] (n3) -- (n4);
\end{tikzpicture}
\end{document}