范围环境可以像节点一样运作吗?

范围环境可以像节点一样运作吗?

下面的流程图是在 PowerPoint 中制作的,它描述了函数的输入和输出。

函数输入输出流程图

如你所见,该图非常直观:一组文件通过管道传输到“Function”中,它返回一个数据结构“Struct”。

我正在尝试使用 TikZ 来绘制它。

我的方法是使用节点绘制前两个块,然后使用节点和范围环境内的一堆线条创建“结构”形状,以便节点和线条保持组合在一起作为单个形状。

我设法绘制并连接了前两个块。但是,我在图中放置和连接“结构”形状时遇到了麻烦。我期望范围环境会像节点一样运行,并给出了以下指令:

\begin{scope}[right of=function]

但这就是我得到的:

不完整流程图

  • 是否可以让范围环境表现得像一个节点?
  • 如果是这样,我该如何实现呢?
  • 否则我还有什么选择?

代码:

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{
    shapes.geometric,
    arrows,
    shadows
}
\usepackage{varwidth}
\usepackage{enumitem}
\usepackage{courier}

\renewcommand*\familydefault{\ttdefault}

\begin{document}

\begin{tikzpicture}[node distance=5cm]
  \tikzset{
    files/.style = {
        rectangle,
        fill=white,
        draw=black,
        minimum width=3cm,
        minimum height=1.5cm
        },
    function/.style = {
        rectangle,
        fill=white,
        draw=black,
        minimum width=3cm,
        minimum height=1.5cm,
        text centered
        },
    box/.style = {
            rectangle,
            fill=white,
            draw=black,
            minimum width=2cm,
            minimum height=0.5cm
        },
    arrow/.style={
        ->,
        >=latex,
        },
  }

  % Input
  \node (files) [files, drop shadow] {
            \begin{varwidth}{3cm}
            \begin{itemize}[noitemsep, leftmargin=*]
            \item{file1.dat}
            \item{file2.dat}
            \item{file3.dat}
            \item{file4.dat}
            \end{itemize}
            \end{varwidth}
  };

  % Function
  \node (function) [function, right of=files, drop shadow] {Function};

  % Output
  \begin{scope}[right of=function]
        \draw (0,0) -- (0,1) node[above, box, drop shadow] {Struct};
        \draw (-1.5,-1) -- (-1.5,0) -- (1.5,0) -- (1.5,-1);
        \draw (-0.5,-1) -- (-0.5,0);
        \draw (0.5,-1) -- (0.5,0);
  \end{scope}

  % Arrows
  \draw [arrow] (files) -- (function);
\end{tikzpicture}

\end{document}

答案1

您可以使用local bounding box声明来命名范围的集合内容。为了使此方法在这种情况下有效,最直接的策略是首先绘制范围中的内容。

例如(在此过程中稍微更新代码,例如使用arrows.metapositioning按照建议):

\documentclass[tikz,multi,border=10pt]{standalone}
\usetikzlibrary{arrows.meta,shadows,positioning}
\usepackage{enumitem}
\usepackage{courier}
\renewcommand*\familydefault{\ttdefault}
\begin{document}
\begin{tikzpicture}
  [
    node distance=3cm,
    basic/.style={%
      draw, fill=white
    },
    files/.style = {%
      basic,
      text width=3cm,
      minimum height=1.5cm
    },
    function/.style = {%
      basic,
      text width=3cm,
      minimum height=1.5cm,
      text centered
    },
    box/.style = {%
      basic,
      minimum width=2cm,
      minimum height=0.5cm
    },
    arrow/.style={%
      ->, >=Latex,
    },
  ]
  \begin{scope}[local bounding box=output]
    \draw (0,0) -- (0,1) node[above, box, drop shadow] {Struct};
    \draw (-1.5,-1) -- (-1.5,0) -- (1.5,0) -- (1.5,-1);
    \draw (-0.5,-1) -- (-0.5,0);
    \draw (0.5,-1) -- (0.5,0);
  \end{scope}
  \node (function) [function, left= of output, drop shadow] {Function};
  \node (files) [files, drop shadow, left=of function,] {%
    \vspace*{-.5\baselineskip}%
    \begin{itemize}[nosep,leftmargin=*]
      \item{file1.dat}
      \item{file2.dat}
      \item{file3.dat}
      \item{file4.dat}
    \end{itemize}
  };
  \draw [arrow] (files) -- (function);
\end{tikzpicture}
\end{document}

命名范围,其他内容放在左边

另一个选择是使用 ,pic但是它pic有 bug,而且没有迹象表明这些 bug 很快就会被修复。虽然pics 在许多情况下仍然运行良好,但我认为 bug 会在这里成为一个特别的缺点,因为它会影响相对定位和命名。如果这些 bug 在未来某个合适的日期被修复,这可能是最好的选择,因为它比使用命名范围更灵活。

最后,fit可以使用该库将节点放在范围内的节点和坐标周围。但是,与local bounding box上述方法相比,这并没有真正的优势,而且实施起来会更加麻烦。(您需要在fitted 节点的线上放置坐标,因为在确定其预期内容时,它不能使用路径,而不是节点和坐标。)

相关内容