下面的流程图是在 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.meta
并positioning
按照建议):
\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 很快就会被修复。虽然pic
s 在许多情况下仍然运行良好,但我认为 bug 会在这里成为一个特别的缺点,因为它会影响相对定位和命名。如果这些 bug 在未来某个合适的日期被修复,这可能是最好的选择,因为它比使用命名范围更灵活。
最后,fit
可以使用该库将节点放在范围内的节点和坐标周围。但是,与local bounding box
上述方法相比,这并没有真正的优势,而且实施起来会更加麻烦。(您需要在fit
ted 节点的线上放置坐标,因为在确定其预期内容时,它不能使用路径,而不是节点和坐标。)