ラインとは異なるレイヤーにライン上のノードを設定するにはどうすればよいでしょうか?

ラインとは異なるレイヤーにライン上のノードを設定するにはどうすればよいでしょうか?

線が背景レイヤーにあるかどうかに関係なく、線上のノードがメイン レイヤーにあると宣言することは可能ですか? 例: ここに画像の説明を入力してください

次の MWE の場合:

\documentclass[12pt,tikz,border=3mm]{standalone}
    \usetikzlibrary{arrows,arrows.meta,%
        backgrounds,positioning}
\pgfdeclarelayer{foreground} 
\pgfdeclarelayer{background}
   \pgfsetlayers{background,main,foreground}

    \usepackage{amsmath}
\begin{document}
    \begin{tikzpicture}[
    node distance = 0mm,
        LC/.style = {draw=#1,
            line width=1mm,
            arrows={-Stealth[fill=#1,inset=0pt,length=0pt 1.6,angle'=90]},
            },
         X/.style = {draw, very thin, fill=white, fill opacity=0.75,
            font=\scriptsize,
            text=black, text opacity=1, align=left,
            inner sep=2pt, sloped, anchor=west,pos=0.07},
                        ]\sffamily
%---
\linespread{0.8}
%-------
\coordinate                     (a0)    at (0,0);
\coordinate[right=77mm of a0]   (b0);
    \foreach \i [count=\xi from 0] in {1,2,...,4}
{
    \coordinate[below=7mm of a\xi]  (a\i);
    \coordinate[below=7mm of b\xi]  (b\i);
}
\draw[|->]  (a0) -- (a3) node[above left]   {$t$};
\draw[|->]  (b0) -- (b3) node[above right]  {$t$};
\draw[LC=gray]  (a1)
    to node[X] {data\\
                $(\text{SeqNum}=0,\ell=1000)$}
                (b2);
%-------
    \begin{scope}[ X/.append style={anchor=east},
                  LC/.append style={transform canvas={yshift=-2mm}},
                  on background layer]
\draw[LC=teal]  (b1)
    to node[X] {ACK(AckNum$=$1000)}
                (a2);
   \end{scope}
%----------------
    \end{tikzpicture}
        \end{document}

次のような結果になります:

ここに画像の説明を入力してください

最初の図は、2 つ目の線を 2 回描画して得られたものです。最初は線として、次にその上にノードを含む目に見えない線として描画します。実際の図にはこのような線が最大 12 個あるため、線が背景にある場合でもノードがメイン プレーンにあることを宣言するためのより便利なソリューションを探しています。

答え1

箱で遊びましょう。

ある時点で、TikZはキーを導入しますbehind pathおよびin front of path(切り替えて) は基本的に、ノードが配置されるパス ボックスを指定します。パスが最終的に描画されるとき (;パスの末尾の 内)、これらのボックスが「使用されます」。

  1. 背景のもの(\tikz@figbox@bg
  2. 実際のパスが描かれる
  3. フォアグラウンドのもの(\tikz@figboxノードのデフォルト)

TikZがパス上のノードを見つけると、実際には引き分けこれにより、これら 2 つのボックスのいずれかにノードが描画されます。

これらのボックスは、パスの開始時にリセットされます。これらのボックスは、ノードがパスの上に配置される理由です (ノード自体がそもそもパスであるにもかかわらず)。


とともにPGF層非常によく似たことが起こりますが、単なるノードではなく\begin{pgfonlayer}、 との間にあるすべてのもの\end{pgfonlayer}がそのボックス内に配置されます。

画像の最後で、これらのボックスが「使用」されます。(ネストされた画像のためと思われる追加の管理作業があります。)

;さて、TikZが使用するボックスにノードを配置する代わりに、試すいずれかのレイヤーに直接配置します。

これはいくつかのグループのどこか深いところで発生するため、これはグローバルである必要があります (そして、\pgfonlayerこれはどこかのスコープ内で使用できるため、実際にグローバルになります。そして、 を使用すると実際にそうなりますon background layer)。


\setboxこれを実装するには、パスのボックスにノードを配置するマクロ内で、1 つ(幸運にも最初の 1 つ) をカスタム(通常どおりに動作するように\tikz@setbox@which設定) に置き換えます。\setbox

キーは、グローバルを実行し、ボックスがパス ボックスの 1 つではなくレイヤーの 1 つになるnode on layerようにします。\tikz@setbox@which\setbox

さて、こう言えるでしょう

\begin{scope}[
  X/.append style={anchor=east},
  LC'/.style={yshift=-2mm}, % no transform canvas
  on background layer]
\draw[LC=teal] ([LC'] b1) % ........ ←
  to node[X, node on layer=foreground] {ACK(AckNum$=$1000)} ([LC'] a2);
\end{scope}

そして、これで何が機能しないかがすでに示されています:

  • レイヤーmainは選択できません(どちらでも選択できない特殊なレイヤーです\pgfonlayer)。

  • transform canvasは動作しません (ただし、 も動作しませんbehind path)。回避策はあるかもしれませんが、マニュアルでは次の方法が推奨されています。

    つまり、何をしているのかを本当に理解していない限り、キャンバス変換を使用しないでください。

    そして私は付け加える…本当に必要な場合を除いて

    私は、あなたが追加した部分を、各座標に手動で追加されるキーLC内の通常の変換LC'に置き換えました。(座標/ノードを「固定解除」して通常の座標として動作させ、変換もそれらに適用できるようにする方法があればいいのですが、マニュアルでさえ@を使った回避策

さらに、ノード以外では使用しないでください。「decider」マクロは、\tikz@whichboxノードだけでなく、エッジ、プロット マーク、マトリックス、子ノード (プレーン ノードとは異なります)、および画像にも使用されます。\node on layerそこで使用しても機能せず、エッジ、プロット マーク、マトリックス、子、および画像が表示されない程度です (いずれにしても、現在のパスの後ではボックスへの追加は忘れられるためです)。そのためには、さらにパッチを適用する必要があります。


とはいえ、パスに沿って空のノード/座標を配置し (位置と回転を保存するため)、それを参照してすべての線描画の最後に実際のノードを配置することもできます。ただし、使いやすくするためには、適切なハウスキーピングが必要になります。

そして、全体的に遅延ノード配置最初にノードを「実行」しますが、後で配置します (forestグラフ描画ライブラリによって使用されます)。ただし、これもあまり簡単ではありません。 (ボックスがさらに表示されます)。

コード

\documentclass[12pt, tikz, border=3mm]{standalone}
\usetikzlibrary{arrows, arrows.meta, backgrounds, positioning}
\pgfdeclarelayer{foreground}\pgfdeclarelayer{background}
\pgfsetlayers{background,main,foreground}
\makeatletter\ExplSyntaxOn % replace only first one
\tl_replace_once:Nnn \tikz@fig@continue { \setbox } { \tikz@setbox@which }
\ExplSyntaxOff
\let\tikz@setbox@which\setbox
\tikzset{node on layer/.code={%
  \expandafter\def\expandafter\tikz@whichbox\expandafter
    {\csname pgf@layerbox@#1\endcsname}%
  \def\tikz@setbox@which{\global\setbox}}}
\makeatother
\usepackage{amsmath}
\begin{document}
\begin{tikzpicture}[
  node distance = 0mm,
  LC/.style = {draw=#1, line width=1mm,
    arrows={-Stealth[fill=#1,inset=0pt,length=0pt 1.6,angle'=90]}},
  X/.style = {draw, very thin, fill=white, fill opacity=0.75,
    font=\scriptsize, text=black, text opacity=1, align=left,
   inner sep=2pt, sloped, anchor=west,pos=0.07}]
\sffamily\linespread{0.8}

\coordinate                     (a0)    at (0,0);
\coordinate[right=77mm of a0]   (b0);
\foreach \i [count=\xi from 0] in {1,2,...,4}
  \coordinate[below=7mm of a\xi]  (a\i)
   coordinate[below=7mm of b\xi]  (b\i);
\draw[|->] (a0) -- (a3) node[above left]   {$t$};
\draw[|->] (b0) -- (b3) node[above right]  {$t$};
\draw[LC=gray] (a1) to node[X] {data\\$(\text{SeqNum}=0,\ell=1000)$} (b2);

\begin{scope}[
  X/.append style={anchor=east},
  LC'/.style={yshift=-2mm}, % no transform canvas
  on background layer]
\draw[LC=teal] ([LC'] b1)
  to node[X, node on layer=foreground] {ACK(AckNum$=$1000)} ([LC'] a2);
\end{scope}
\end{tikzpicture}
\end{document}

出力

ここに画像の説明を入力してください

答え2

後続のパス コマンドを使用して、ノードを最前面レイヤーに配置するのはどうでしょうか。

\path (b1) to node[X,anchor=east,yshift=-2mm] {ACK(AckNum$=$1000)} (a2);

完全な文書は次のとおりです:

\documentclass[12pt,tikz,border=3mm]{standalone}
\usetikzlibrary{arrows,arrows.meta,backgrounds,positioning}
\pgfdeclarelayer{foreground} 
\pgfdeclarelayer{background}
\pgfsetlayers{background,main,foreground}
\usepackage{amsmath}

\begin{document}

\begin{tikzpicture}
  [
    node distance = 0mm,
    LC/.style = {draw=#1,
                 line width=1mm,
                 arrows={-Stealth[fill=#1,inset=0pt,length=0pt 1.6,angle'=90]},
                },
    X/.style = {draw, 
                very thin, 
                fill=white, 
                fill opacity=0.75,
                font=\scriptsize,
                text=black, 
                text opacity=1, 
                align=left,
                inner sep=2pt, 
                sloped, 
                anchor=west,
                pos=0.07},
  ]
 \sffamily
%---
  \linespread{0.8}
%-------
  \coordinate                     (a0)    at (0,0);
  \coordinate[right=77mm of a0]   (b0);
  \foreach \i [count=\xi from 0] in {1,2,...,4}
    {
      \coordinate[below=7mm of a\xi]  (a\i);
      \coordinate[below=7mm of b\xi]  (b\i);
    } 
  \draw[|->]  (a0) -- (a3) node[above left]   {$t$};
  \draw[|->]  (b0) -- (b3) node[above right]  {$t$};
  \draw[LC=gray]  (a1)
                  to 
                  node[X] {data\\
                  $(\text{SeqNum}=0,\ell=1000)$}
                  (b2);
%-------
  \begin{scope}[X/.append style={anchor=east},
                LC/.append style={transform canvas={yshift=-2mm}},
                on background layer]
    \draw[LC=teal]  (b1)
                    to 
                    (a2);
 \end{scope}
%----------------
  \path (b1) to node[X,anchor=east,yshift=-2mm] {ACK(AckNum$=$1000)} (a2);
\end{tikzpicture}
\end{document}

ここに画像の説明を入力してください

関連情報