Zeichnen Sie eine Linie, die über Formen und Textinhalte verläuft

Zeichnen Sie eine Linie, die über Formen und Textinhalte verläuft

Ich möchte eine Linie zwischen zwei Knoten zeichnen, die über vorhandene Formen und Textinhalte hinwegfliegen kann. Im folgenden Beispiel schneidet die Verbindungslinie adie bBeschriftung des initKnotens. Ich kann manuell eine „Linienüberquerung“ durchführen, nachdem ich dies anhand des Tikz-Ergebnisses festgestellt habe. Aber gibt es eine Funktion, die solche Umstände beurteilen und automatisch im Lauf bearbeiten kann? So etwas wie\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}

Update: Antwort auf @Rmanos Kommentar: Danke für die Antwort. Ja, die Verwendung von Ebenen kann mein Problem teilweise lösen. Ich habe das Paket „tikz-layers“ verwendet, das 5 vordefinierte Ebenen bereitstellt. Die Codeausschnitte sind wie folgt:
\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}

Das ergibt das folgende Ergebnis

Eine Sache, die ich nicht ganz perfekt finde, ist, dass dadurch das Etikett die Hintergrundfüllung überdeckt. Ursprünglich labelist es nur Text, jetzt bekommt es eine Form, die für die Hintergrundfüllung nicht transparent ist. Wir können die Beschriftungsfüllung genauso ändern wie die Hintergrundfüllung cyan, aber das erzeugt eine weitere Abhängigkeit.

Ist es möglich, dass labeles eine virtuelle Grenze gibt, die nur Unterstreichungen maskiert draw, aber nicht die Unterstreichung selbst fill?


Update: Gemäß dem Vorschlag von @Rmano, `contour` zu verwenden, aktualisieren Sie das MWE wie folgt
\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}

Das ergibt ein nahezu perfektes Ergebnis

Danke für die Hilfe!

Antwort1

Ist es möglich, dass labeles eine virtuelle Grenze gibt, die nur Unterstreichungen maskiert draw, aber nicht die Unterstreichung selbst fill?

Ich denke nicht.

Meiner Meinung nach gibt es auch keinen großen Unterschied zwischen dem Schreiben von label={[fill=cyan]text}und label={[...]\bidicontour{cyan}{text}}. Man muss die Hintergrundfarbe immer explizit in schreiben label={...}.

Das folgende Beispiel zeigt einen Versuch, die Hintergrundfarbe nur einmal zu schreiben. Die Definition von pgfonlayerreversedenvironment ist aus meinemvorherige Antwort.

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

Bildbeschreibung hier eingeben

verwandte Informationen