我试图将一组节点并排放置(按列对齐)并垂直居中,但失败了。
尽管操作框似乎相对于左侧节点垂直完美居中,但对于右侧节点却并非如此。
我可以每次手动调整移位值,但我正在寻找更好的解决方案。
\begin{figure}[h!]
\centering
\begin{tikzpicture}[
op/.style={shape=rectangle, rounded corners, minimum width=4cm, minimum height=2cm, draw},
tab/.style={shape=circle, minimum width=1.5cm, draw},
hyp/.style={shape=circle, double, double distance=2pt, minimum width=1.5cm, draw},
]
\begin{scope}[local bounding box=ArgBox]
\node[tab] (In1) {};
\node[tab, below=of In1] (InN) {};
\node at ($(In1)!0.5!(InN)$) {\vdots};
\node[hyp, below=of InN] (Hyp1) {};
\node[hyp, below=of Hyp1] (HypN) {};
\node at ($(Hyp1)!0.5!(HypN)$) {\vdots};
\end{scope}
\begin{scope}[local bounding box=OpBox, shift={($(ArgBox.east)+(5cm,0)$)}]
\node[op] (Op) {Operation};
\end{scope}
\begin{scope}[local bounding box=OutBox, shift={($(OpBox.east)+(5cm,0)$)}]
\node[tab] (Out1) {};
\node[tab, below=of Out1] (Out2) {};
\node[tab, below=of Out2] (OutN) {};
\node at ($(Out2)!0.5!(OutN)$) {\vdots};
\end{scope}
\draw[->] (In1) -- node [above, sloped] {arg \#1} (Op);
\draw[->] (InN) -- node [above, sloped] {arg \#N} (Op);
\draw[->] (Op) -- node [above, sloped] {out \#1} (Out1);
\draw[->] (Op) -- node [above, sloped] {out \#2} (Out2);
\draw[->] (Op) -- node [above, sloped] {out \#N} (OutN);
\draw[->] (Hyp1) -- node [above, sloped] {hyp \#1} (Op);
\draw[->] (HypN) -- node [above, sloped] {hyp \#N} (Op);
\end{tikzpicture}
\caption{Caption}
\label{fig:my_label}
\end{figure}
谢谢!
编辑:我想要的是,无论左节点、操作框和右节点有多少个,它们始终位于中心。
答案1
像这样:
使用arrows.meta
、calc
、chains
和图像代码可以写成positioning
:quotes
\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{arrows.meta,
calc, chains,
positioning,
quotes}
\usepackage{bm}
\begin{document}
\begin{tikzpicture}[
node distance = 7mm and 22mm,
start chain = going below,
op/.style = {shape=rectangle, rounded corners, minimum size=12mm, draw},
vd/.style = {midway, text depth=0.25ex, text height=2.5ex,
inner ysep=0pt, node contents={$\bm{\vdots}$}},
tab/.style = {shape=circle, minimum width=9mm, draw},
hyp/.style = {tab, double},
every edge/.style = {draw, -Straight Barb, shorten >=1pt, shorten <=1pt},
every edge quotes/.style = {auto, font=\footnotesize, sloped}
]
% left in nodes
\begin{scope}[nodes={on chain}]
\node[tab] (In1) {};
\node[tab] (InN) {};
\node[hyp] (Hyp1) {};
\node[hyp] (HypN) {};
\end{scope}
\path (In1) -- (InN) node[vd]
(Hyp1) -- (HypN) node[vd];
% operation
\node[op, right=of $(In1)!0.5!(HypN)$] (Op) {Operation};
% right out nodes
\begin{scope}[nodes={on chain}]
\node[tab, above right=of Op] (Out1) {};
\node[tab] (Out2) {};
\node[tab] (OutN) {};
\end{scope}
\path (Out2) -- (OutN) node[vd];
% arrows
\draw (In1) edge ["arg \#1"] (Op)
(InN) edge ["arg \#N"] (Op)
(Op) edge ["out \#1"] (Out1)
(Op) edge ["out \#2"] (Out2)
(Op) edge ["out \#N"] (OutN)
(Hyp1) edge ["hyp \#1"] (Op)
(HypN) edge ["hyp \#N"] (Op);
\end{tikzpicture}
\end{document}
附录: 更通用的“半自动”解决方案:)。它需要:
- 节点垂直距离必须与
tab
节点直径相等(命令\vnd
) - 对于水平距离必须定义为水平长度作为命令´(
\hnd
- 定义输出节点数 (
\NUM
) - 到链的右输出节点应该插入
\NUM
节点 - 用于计算右链中第一个节点的位置的宏被定义
\K
。通过它,这个位置被计算为above right=\K*\vnd and \hnd of Op.east
- 右链为垂直链,其计算量为
(<tab minimum size>-<(inserted square minimum size)/2>
7 个输出节点的 MWE:
\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{arrows.meta,
calc, chains,
positioning,
quotes}
\usepackage{bm}
\begin{document}
\begin{tikzpicture}[
node distance = \vnd and \hnd,
start chain = going below,
op/.style = {shape=rectangle, rounded corners,
minimum size=12mm,
draw},
vd/.style = {midway, text depth=0.25*\vnd, text height=0.75*\vnd,
inner ysep=0pt, node contents={$\bm{\vdots}$}},
tab/.style = {shape=circle,
minimum size=\vnd, inner sep=0pt, outer sep=0pt, draw},
hyp/.style = {tab, double},
every edge/.style = {draw, -Straight Barb, shorten >=1pt, shorten <=1pt},
every edge quotes/.style = {auto, font=\footnotesize, inner sep=2pt, sloped}
]
\def\vnd{ 6 mm} % minimum size is 6mm
\def\hnd{21 mm}
\def\NUM{7} % number of output nodes
\pgfmathsetmacro{\K}{0.5*int(2*\NUM+1)-2}
% left input nodes
\begin{scope}[nodes={on chain}]
\node[tab] (In1) {};
\node[tab] (InN) {};
\node[hyp] (Hyp1) {};
\node[hyp] (HypN) {};
\end{scope}
\path (In1) -- (InN) node[vd]
(Hyp1) -- (HypN) node[vd];
% operation
\node[op, right=of $(In1.east)!0.5!(HypN.east)$] (Op) {Operation};
% right output nodes,
\begin{scope}[nodes={yshift=0.29289 mm, on chain}]
\node[tab, above right=\K*\vnd and \hnd of Op.east] (Out1) {};
\node[tab] (Out2) {};
\node[tab] (OutN) {};
\node[hyp] (Hyp1) {};
\node[hyp] (Hyp2) {};
\node[tab] (OutM) {};
\node[hyp] (Hyp4) {};
\end{scope}
\path (Out2) -- (OutN) node[vd];
% arrows
\draw (In1) edge ["arg \#1"] (Op)
(InN) edge ["arg \#N"] (Op)
(HypN) edge ["hyp \#N"] (Op)
(Op) edge ["out \#1"] (Out1)
(Op) edge ["out \#2"] (Out2)
(Op) edge ["out \#N"] (OutN)
(Op) edge ["hyp \#1"] (Hyp1)
(Op) edge ["hyp \#1"] (Hyp4)
;
\end{tikzpicture}
\end{document}
\NUM=3 的结果与第一个答案相同,\num=4 的结果为
对于 \NUM=7 则为