我想将下面的代码更改为使用链连接方法,而不是在它们之间放置一个节点。有什么想法可以实现它吗?
\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows, calc,chains}
\tikzset{
myarr/.style args={#1 -- #2}{
insert path={let \p1=($(#1)-(#2)$) in},
single arrow, draw=black, minimum width=20mm, minimum height={veclen(\x1,\y1)},
inner sep=0mm, single arrow head extend=1pt,
},
every join/.style={->},
}
\begin{document}
\begin{tikzpicture}[start chain=going right,node distance= 2cm and 2cm]
\def\data{
A,
B,
C,
D%
}
\foreach \p [count=\i from 1] in \data {
\node[draw,on chain,join,minimum width=2cm,minimum height=4cm] (P\i) {\p};
}
% move below logic to use join method
\path (P1) -- (P2) node[midway,->,myarr={P1.east -- P2.west},single arrow] {};
\path (P2) -- (P3) node[midway,->,myarr={P2.east -- P3.west},single arrow] {};
\path (P3) -- (P4) node[midway,->,myarr={P3.east -- P4.west},single arrow] {};
\end{tikzpicture}
\end{document}
答案1
您可以通过链上的连接放置一个节点,只需设置一个to path
就可以了:放置一个节点。
在里面to path
,您可以访问\tikztostart
和\tikztotarget
——以及\tikztonodes
但我们将在这里忽略它……或者您是否需要某处有文本?
然后可以像以前一样计算出差值,以及它的veclen
,此外,还可以通过 计算出它的方向/角度atan2
。然后可以像以前一样将结果与 一起使用,node
它现在是 的唯一(视觉)输出to path
。
这一切都是按照以下myarr with anchors
风格完成的:
\tikzset{
myarr with anchors/.style 2 args={
to path={
let \p0=($(\tikztotarget.#2)-(\tikztostart.#1)$) in
node[myarr node,
minimum height={veclen(\x0,\y0)},
shape border rotate={atan2(\y0,\x0)}] at (\tikztostart.#1) {}}}}
对于简单的链来说,
\tikz[
start chain=going right, node distance=2cm and 2cm,
every join/.style={myarr with anchors={east}{west}},
every on chain/.append style={draw, minimum width=2cm, minimum height=4cm}]
\node foreach \t in {A, ..., D} [on chain, join]{\t};
我确实喜欢更自动化的方法,它可以自己找到边界上的点。
为此,我提供了一种myarr
样式,它使用来edge
查找边界上的点,然后在与之前相同的计算中使用这些点。
或者,它还接受两个参数,这两个参数要么为空(自动方法或不是节点),要么包含锚点规范(使用.
)。
参考:我们可以在节点的样式定义中使用 `let`(来自 `TikZ`)吗?。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.arrows, calc, chains}
\tikzset{
myarr node/.style={
shape=single arrow, draw=black, minimum width=20mm, anchor=tail,
shape border uses incircle, single arrow head extend=+1pt,
inner sep=+0pt, outer sep=+0pt},
%
myarr with anchors/.style 2 args={
to path={
let \p0=($(\tikztotarget.#2)-(\tikztostart.#1)$) in
node[myarr node,
minimum height={veclen(\x0,\y0)},
shape border rotate={atan2(\y0,\x0)}] at (\tikztostart.#1) {}}},
%
myarr/.default={}{},
myarr/.style 2 args={
to path={
\expanded{
(\tikztostart#1) edge[path only, overlay, line to]
coordinate[at start] (@start)
coordinate[at end] (@end) (\tikztotarget#2)}
let \p0=($(@end)-(@start)$) in
node[myarr node,
minimum height={veclen(\x0,\y0)},
shape border rotate={atan2(\y0,\x0)}] at (@start) {}}}}
\begin{document}
\pgfmathsetseed{872607}
\tikz[
start chain=going right, node distance=2cm and 2cm,
every join/.style={myarr with anchors={east}{west}},
every on chain/.append style={draw, minimum width=2cm, minimum height=4cm}]
\node foreach \t in {A, ..., D} [on chain, join]{\t};
\tikz[
start chain=going right, node distance=2cm and 2cm,
every join/.style=myarr,
every on chain/.append style={draw, minimum width=2cm, minimum height=4cm}]
\node foreach \t in {A, ..., D} [on chain, join]{\t};
\tikz[
start chain=going above right, node distance=.4cm and 2cm,
every join/.style=myarr,
every on chain/.append style={draw, circle, minimum size=2cm}]
\node foreach \t in {A, ..., D} [on chain, join, shift={(3*rand, 3*rand)}]{\t};
\tikz[
start chain=going above right, node distance=.4cm and 2cm,
every join/.style={myarr={.north east}{.south west}},
every on chain/.append style={draw, minimum width=2cm, minimum height=1cm}]
\node foreach \t in {A, ..., D} [on chain, join]{\t};
\end{document}
输出
答案2
我不确定您想做什么,但可能您想要下面这样的东西?
\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows, calc,chains}
\tikzset{
myarr/.style args={#1 -- #2}{
insert path={let \p1=($(#1)-(#2)$) in},
single arrow, draw=black, minimum width=20mm, minimum height={veclen(\x1,\y1)},
inner sep=0mm, single arrow head extend=1pt,
},
my arr/.style={
insert path={let \p1=(20mm,0pt) in},
single arrow, draw=black, minimum width=20mm, minimum height={veclen(\x1,\y1)},
inner sep=0mm, single arrow head extend=1pt,
},
}
\begin{document}
\begin{tikzpicture}[start chain=going right,node distance=2cm and 0cm]
\def\data{
A,
B,
C,
D%
}
\foreach \p [count=\i from 1,remember=\i as \ilast] in \data {
\edef\tempa{1}\edef\tempb{\i}%
\ifx\tempa\tempb\relax
\else \node (A-\ilast-\i) [draw,on chain,my arr] {};
\fi
\node[draw,on chain,join,minimum width=2cm,minimum height=4cm] (P\i) {\p};
}
\end{tikzpicture}
\end{document}
答案3
不错的@cfr 答案的一个小变化。
- 宏连接的目的(似乎)仅用于在节点之间绘制箭头(任何类型),但不能在节点之间插入节点。
- 由于上述原因,您无法
single arrow
通过宏在链中的主节点之间插入具有形状的节点join
。它们只能作为链中的普通节点插入。 - 该
single arrow
节点可以很好地适应链中的两个主节点之间,您需要相应地定义其样式(请参阅下面的 MWE)。 - 梅威瑟:
\documentclass[margin=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, chains,
shapes.arrows}
\begin{document}
\begin{tikzpicture}[
node distance = 0mm,
start chain = going right,
SA/.style = {% single arrow
single arrow, single arrow head extend=3mm,
draw, minimum width=20mm, minimum height=20mm,
inner sep=0mm,
node contents=\vphantom{A},
on chain
},
N/.style = {draw, semithick, on chain,
minimum width=2cm, minimum height=4cm}
]
\def\data{A, B, C, D}
\foreach \i [count=\j] in \data
{
\node[N] {\i};
\ifnum\j<4
\node[SA];
\fi
}
\end{tikzpicture}
\end{document}