用鏈連接連接節點

用鏈連接連接節點

我想更改下面的程式碼以使用鏈連接方法,而不是在中間放置一個節點。有什麼想法可以實施嗎?

\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}

在此輸入影像描述

相關內容