TikZ:在节点内使用节点

TikZ:在节点内使用节点

我正在尝试嵌套这样的节点:

\usemodule[tikz]
\usetikzlibrary{arrows, positioning}

\starttext
  \starttikzpicture[font=\tt, remember picture]
    \node (add-entry) {entry};
    \node[right=of add-entry] (add-b-in) {b = b\_in};
    \node[above=.1cm of add-b-in.north west, anchor=south west] (add-a-in) {\tikz[remember picture]\node(a-def){a}; = a\_in};
    \node[below=.1cm of add-b-in.south west, anchor=north west] (add-return) {add\_out = \tikz[remember picture]\node(a-use){a}; + b};

    \draw[->] (add-entry) -- (add-a-in.west);
    \draw[->] (add-entry) -- (add-b-in.west);
    \draw[->] (add-entry) -- (add-return.west);

    \coordinate[above=1.25em of a-use.north] (c1);
    \draw[-o] (a-def.south) edge[out=270,in=90] (c1) -- (a-use.north);

  \stoptikzpicture
\stoptext

(我正在使用 ConTeXt,但这与此无关。)

得出的结果为:

  • 为什么从一个地方到另一个地方的路径是a断开的?它应该到达坐标并从那里继续前进,而不是重新开始。
  • 我怎样才能将这两个a与节点其余内容的基线对齐?

答案1

在 LaTeX 中有一个tikzmark库,它提供了一个\subnode命令。但是,这个库使用了\newcommand,因此会抛出错误context。您可以\subnode按如下方式模拟该命令:

\def\subnode#1#2%
    {\tikz[remember picture,baseline=(#1.base),inner sep=0pt,
           outer sep=0pt,minimum width=0pt]\node(#1){#2};}

设置 将使与周围文本baseline对齐a。为了消除节点引入的空间,我们a通过设置周围空间和最小宽度来确保节点具有自然宽度0pt。这样做的唯一缺点是现在子节点的锚点接触内容,因此我们0.2ex在绘制线时在子节点的下方和上方添加。

在此处输入图片描述

\usemodule[tikz]
\usetikzlibrary{arrows, positioning,calc}
\def\subnode#1#2%
   {\tikz[remember picture,baseline=(#1.base),inner sep=0pt,
          outer sep=0pt,minimum width=0pt]\node(#1){#2};}
\starttext
  \starttikzpicture[font=\tt, remember picture]
    \node (add-entry) {entry};
    \node[right=of add-entry] (add-b-in) {b = b\_in};
    \node[above=.1cm of add-b-in.north west, anchor=south west]
              (add-a-in) {\subnode{a-def}{a} = a\_in};
    \node[below=.1cm of add-b-in.south west, anchor=north west]
              (add-return) {add\_out = \subnode{a-use}{a} + b};

    \draw[->] (add-entry) -- (add-a-in.west);
    \draw[->] (add-entry) -- (add-b-in.west);
    \draw[->] (add-entry) -- (add-return.west);

    \draw[-o] ($(a-def.south)+(0,-0.2ex)$) to[out=270,in=90]
              ($(a-use.north)+(0, 3.5ex)$) --
              ($(a-use.north)+(0, 0.2ex)$);
  \stoptikzpicture
\stoptext

答案2

您可以使用 库subnode中的tikzmark部分文本作为要引用的节点。

\node[above=.1cm of add-b-in.north west, anchor=south west] 
       (add-a-in) {\subnode{a-def}{a} = a\_in};

这解决了第二个问题。

关于你使用的第一个问题,edge它在两点之间画一条线,但不要移动原点,所以

\draw[-o] (a-def.south) edge[out=270,in=90] (c1) -- (a-use.north);

(a-def.south)在和之间画一条线,并在和之间画(c1)第二条线。(a-def.south)(a-use.north)

您想使用to[out=270,in=90]而不是edge

\documentclass[tikz,border=2mm]{standalone} 
\usetikzlibrary{positioning, arrows, tikzmark}


\begin{document}
\begin{tikzpicture}[remember picture]
    \node (add-entry) {entry};
    \node[right=of add-entry] (add-b-in) {b = b\_in};
    \node[above=.1cm of add-b-in.north west, anchor=south west] (add-a-in) {\subnode{a-def}{a} = a\_in};
    \node[below=.1cm of add-b-in.south west, anchor=north west] (add-return) {add\_out = \subnode{a-use}{a} + b};

    \draw[->] (add-entry) -- (add-a-in.west);
    \draw[->] (add-entry) -- (add-b-in.west);
    \draw[->] (add-entry) -- (add-return.west);

    \coordinate[above=1.25em of a-use.north] (c1);
    \draw[-o] (a-def.south) to[out=270,in=90] (c1) -- (a-use.north);
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容