将节点与链连接起来

将节点与链连接起来

我想将下面的代码更改为使用链连接方法,而不是在它们之间放置一个节点。有什么想法可以实现它吗?

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

在此处输入图片描述

相关内容