这是我想要做的一部分。请记住,在原始版本中,框/节点的宽度是可变的,并且链 B 和 C 的长度并非每次都相同。
% --- --- ---
% |A| |B| |C|
% --- --- ---
% | | --- |
% | |--|X|--|
% | | --- |
% | --- ---
% | |b| |c|
% | --- ---
% | | |
% | | --- |
% ----------|E|---
% ---
我在网上和文档中找到了 TiKz 的一些示例。阅读时我理解它们,但我无法将其转移到我自己的代码中。我的问题之一是如何计算框的正确坐标X
。应该有某种(B.x+.5,B.y+.5)
。再进一步,当我尝试绘制线条时,例如从到和X
之间的线的中间,我遇到了一个无缝问题。我确信我并不真正了解包的所有细节。我甚至不确定这是否是满足我需求的正确选择。也许另一个坐标系会更好?B
b
calc
\documentclass{article}
% TiKz
\usepackage{tikz}
\usetikzlibrary{chains,scopes,positioning,calc}
\begin{document}
\begin{tikzpicture}
[
every node/.style={
draw,
align=center},
every join/.style=->
]
\node (A) {A};
{[start chain=B going below,
every node/.append style=join]
\node (B) [on chain,right=of A] {B};
\node [on chain] {b};
}
{[start chain=C going below,
every node/.append style=join]
\node (C) [on chain,right=of B] {C};
\node [on chain] {c};
}
% from here I am out of solutions!
\node (X) at ($(B-1)!0.5!(C-1)$) {X};
\node (E) at ($(B-2)!0.5!(C-2)$) {E};
\draw [->] (A) |- (E);
\end{tikzpicture}
\end{document}
答案1
命名小写节点后,计算可以嵌套在一起,如下所示。我添加了节点\vphantom{b}
的文本c
,因此它与邻居的高度相同。
|-
可以使用(先垂直,然后水平)和(先水平,然后垂直)路径说明符连接各个节点-|
。不清楚您希望如何处理这些连接的箭头,但这可以通过\draw
命令选项轻松调整。
\documentclass[tikz]{standalone}
\usetikzlibrary{chains,scopes,calc}
\begin{document}
\begin{tikzpicture}[every node/.style={draw},every join/.style=->]
\node (A) {A};
{[start chain=B going below,every node/.append style=join]
\node (B) [on chain,right=of A] {B};
\node (b) [on chain] {b};
}
{[start chain=C going below,every node/.append style=join]
\node (C) [on chain,right=of B] {C};
\node (c) [on chain] {c\vphantom{b}};
}
\node (X) at ($($(B)!0.5!(C)$)!0.5!($(b)!0.5!(c)$)$) {X};
\node (E) at ($($(B)!0.5!(C)$)-(0,2.5)$) {E};
\draw [->] (A) |- (E);
\draw (X) -| (c)
(X) -| (b)
(b) |- (E)
(c) |- (E);
\end{tikzpicture}
\end{document}
答案2
我尝试使用以下代码重现您的图像:
\documentclass[border=5mm, tikz]{standalone}
\usetikzlibrary{arrows.meta,calc,chains,positioning}
\begin{document}
\begin{tikzpicture}[
every node/.style = {draw, align=center},
arrow/.style = -{Straight Barb[]},
start chain = going right,
node distance = 18mm and 9mm
]
\node (A) [on chain] {A};
\node (B) [on chain] {B};
\node (C) [on chain] {C};
%
\node (b) [below=of B] {b};
\node (c) [below=of C] {c};
%
\coordinate[below=9mm of B] (x');
\node (X) [at={($(x')!0.5!(x'-|C)$)}] {X};
\node (E) [below=of X] {E};
%
\path[arrow] (B) edge (b) (C) edge (c)
(B |- X) edge (X) (C |- X) edge (X)
(b) edge (b |- E);
\draw[arrow] (A) |- (E);
\draw[arrow] (c) |- (E);
\end{tikzpicture}
\end{document}
如您所见,在代码中我没有使用包join
中的宏chains
。相反,我更愿意显式地绘制节点之间的路径,因为这样要求不高,使用的代码更少,并且代码结构清晰(与宏一样join
)。
链上只有第一行节点(A
、B
和C
),其他节点相对于其上方的节点定位。节点 X 是个例外,我为其定义了辅助坐标 c'
。
升级:如果你喜欢坚持使用宏join
(不惜一切代价...:-)),看看下面的代码是否满足你的要求
\documentclass[border=5mm, many, tikz]{standalone}
\usetikzlibrary{arrows.meta,calc,chains,positioning}
\begin{document}
%---------------------------------------------------------------%
\begin{tikzpicture}[
every node/.style={draw, on chain},
start chain=going below,
arrow/.style = -{Straight Barb[]},
every join/.style = {arrow},
reset/.code={\def\tikz@after@path{}}
]
\node (A) {A};
\node (B) [right=of A] {B};
\node (b) [join] {b};
%
\node (C) [right=of B] {C};
\node (c) [join] {c\vphantom{b}};
%
\node (X) [below=0.5 of $(B)!0.5!(C)$] {X};
\node (E) [below=of X] {E};
%
\draw [arrow] (A) |- (E);
\draw [arrow] (X) -| (c) (X) -| (b)
(b) |- (E) (c) |- (E);
\end{tikzpicture}
\end{document}
它给:
代码源自 Paul Gessler 答案中的代码,但与之“非常显著”不同:
- 节点“X”的位置定义更简单(如下图所示,节点“B”和“C”之间的中点)
- 参数
on chain
是样式的一部分every node
,因此不再需要在图片中定义它 join
可以利用宏的节点已在本地添加了此选项
结果:简洁、干净的代码......