在 tikz 中分叉/合并链

在 tikz 中分叉/合并链

我想用 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}

相关内容