Dibuja una línea que atraviesa formas y contenido de texto.

Dibuja una línea que atraviesa formas y contenido de texto.

Quiero dibujar una línea entre 2 nodos que puedan atravesar formas y contenidos de texto existentes. En el siguiente ejemplo, la línea que conecta ay bse cruza con la etiqueta del initnodo. Puedo hacer manualmente un "vuelo de línea" después de notar el hecho en el resultado de tikz. Pero, ¿existe alguna instalación que pueda juzgar tales circunstancias y realizar un manejo automático sobre la marcha? Algo como\draw [flyline, ->] (a) to (b)

\documentclass[convert]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes, positioning}

\begin{document}
    \begin{tikzpicture}[auto]
        \node[rectangle, draw=black, label={right:this is a test}] (init) {hello};
        \node[rectangle, draw=black, above right=of init] (a) {a};
        \node[rectangle, draw=black, below right=of init] (b) {b};
        \draw [->] (a) to (b);
        % I can change to use this after I find the intersect fact from the result
        %\draw (a) to (a|-init.north);
        %\draw [->] (b|-init.south) to (b);
    \end{tikzpicture}
\end{document}

Actualización: Respuesta al comentario de @Rmano: Gracias por la respuesta. Sí, usar capa puede resolver parcialmente mi problema. Utilicé el paquete `tikz-layers` que proporciona 5 capas predefinidas. Los fragmentos de código son los siguientes:
\documentclass[convert]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes, positioning, fit}
\usepackage{tikz-layers}

\begin{document}
    \begin{tikzpicture}[auto]
        \node[rectangle, draw=black, label={[fill=white, inner sep=2pt, name=lbl]right:this is a test}] (init) {hello};
        \node[rectangle, draw=black, above right=of init] (a) {a};
        \node[rectangle, draw=black, below right=of init] (b) {b};
        \begin{scope}[on behind layer]
            \draw [->] (a) to (b);
        \end{scope}
        \begin{scope}[on background layer]
            \node [fit=(init)(a)(b)(lbl), fill=cyan] () {};
        \end{scope}
    \end{tikzpicture}
\end{document}

Lo que da el siguiente resultado

Una cosa que no creo que sea del todo perfecta es que esto hace que la etiqueta que cubre el fondo se llene. Originalmente labeles solo texto, ahora tiene una forma que no es transparente para el relleno del fondo. Podemos cambiar el relleno de etiqueta igual que el relleno de fondo cyan, pero eso crea otra dependencia.

¿Es posible que labelcan tenga un límite virtual, que solo enmascare el subrayado drawpero no el subrayado fill?


Actualización: según la sugerencia de @Rmano de usar `contour`, actualice el MWE a lo siguiente
\documentclass[convert]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes, positioning, fit}
\usepackage{tikz-layers}
\usepackage{bidicontour}
\usepackage{bidi}
\bidicontourlength{2pt}

\begin{document}
    \begin{tikzpicture}[auto]
        \node[rectangle, draw=black, label={[inner sep=2pt, name=lbl]right:{\bidicontour{cyan}{this is a test}}}] (init) {hello};
        \node[rectangle, draw=black, above right=of init] (a) {a};
        \node[rectangle, draw=black, below right=of init] (b) {b};
        \begin{scope}[on behind layer]
            \draw [->] (a) to (b);
        \end{scope}
        \begin{scope}[on background layer]
            \node [fit=(init)(a)(b)(lbl), fill=cyan] () {};
        \end{scope}
        %\draw (a) to (a|-init.north);
        %\draw [->] (b|-init.south) to (b);
    \end{tikzpicture}
\end{document}

Lo que produce un resultado casi perfecto.

¡Gracias por la ayuda!

Respuesta1

¿Es posible que labelcan tenga un límite virtual, que solo enmascare el subrayado drawpero no el subrayado fill?

Supongo que no.

Además, en mi opinión, no hay mucha diferencia entre escribir label={[fill=cyan]text}y label={[...]\bidicontour{cyan}{text}}. Siempre es necesario escribir explícitamente el color de fondo label={...}.

El siguiente ejemplo muestra un intento de escribir el color de fondo solo una vez. La definición de pgfonlayerreversedentorno está copiada de mirespuesta anterior.

\documentclass[tikz]{standalone}
\usetikzlibrary{backgrounds, shapes, positioning, fit}

\usepackage{xpatch}

\makeatletter
% copied from my previous answer https://tex.stackexchange.com/a/562606
\let\pgfonlayerreversed\pgfonlayer
\let\endpgfonlayerreversed\endpgfonlayer

\xpatchcmd\pgfonlayerreversed
  {\expandafter\box\csname pgf@layerbox@#1\endcsname\begingroup}
  {\begingroup}
  {}{\fail}

\xpatchcmd\endpgfonlayerreversed
  {\endgroup}
  {\endgroup\expandafter\box\csname pgf@layerbox@\pgfonlayer@name\endcsname}
  {}{\fail}

% similar to \tikz@background@framed, but using "pgfonlayerreversed" envi
\def\tikz@background@framed@reversed{%
  \tikz@background@save%
  \pgfonlayerreversed{background}
    \path[style=background rectangle] (\tikz@bg@minx,\tikz@bg@miny) rectangle (\tikz@bg@maxx,\tikz@bg@maxy);
  \endpgfonlayerreversed
}%

% similar to option "show background rectangle"
\tikzset{
  show background rectangle reversed/.style={
    execute at end picture=\tikz@background@framed@reversed
  }
}
\makeatother

% user interface
\tikzset{
  background color/.style={
    show background rectangle reversed,
    inner frame sep=2pt,
    background rectangle/.append style={draw=none, #1},
    every node/.append style={#1},
    every label/.append style={#1}
  }
}

\begin{document}
    \begin{tikzpicture}[background color={fill=cyan}]
        \node[draw, label={[inner sep=2pt, name=lbl]right:this is a test}] (init) {hello};
        \node[draw, above right=of init] (a) {a};
        \node[draw, below right=of init] (b) {b};
        
        \begin{scope}[on background layer]
            \draw [->] (a) to (b);
        \end{scope}
    \end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

información relacionada