我想更改下面的程式碼以使用鏈連接方法,而不是在中間放置一個節點。有什麼想法可以實施嗎?
\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
即可:放置一個節點。
在 a 中to path
,您可以訪問\tikztostart
和\tikztotarget
– 以及,\tikztonodes
但我們將在這裡忽略這一點……或者您是否需要在某處添加文本?
然後可以像以前一樣計算差值,veclen
此外還可以透過 計算其方向/角度atan2
。然後,結果可以node
像以前一樣與 a 一起使用,它現在是 的唯一(視覺)輸出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
樣式,它使用 anedge
來尋找邊界上的點,然後在與之前相同的計算中使用這些點。
(可選)它還接受兩個參數,這些參數要么為空(自動方法或不是節點),要么包含錨點規範(帶有.
)。
參考:我們可以在節點的樣式定義中使用“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}