Tikz desenha na pilha de camadas de cima para baixo (ordem inversa)

Tikz desenha na pilha de camadas de cima para baixo (ordem inversa)

No Tikz, gostaria de ter um comando

\StartDrawOnBottomOfLayerStack

para desenhar todos os seguintes elementos emparte inferior da camada inferiorda imagem. Isso significa que os nós e caminhos seguintes aparecem por trás de tudo na imagem. Preciso de um comando para retornar ao comportamento padrão \StartDrawOnTopOfLayerStack

No momento tenho que definir tantas camadas quantos nós de fundo a serem desenhados. Eu me pergunto se isso pode ser realizado mais facilmente?

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\begin{document}

\pgfdeclarelayer{background3}
\pgfdeclarelayer{background2}
\pgfdeclarelayer{background1}
\pgfsetlayers{background3,background2,background1,main}

\begin{tikzpicture}

%% block diagram
\node[rectangle,draw,fill=yellow] (A) at (-4,0) {A};
\node[rectangle,draw,fill=yellow] (B) at (-3,0) {B};
\node[rectangle,draw,fill=yellow] (C) at (-2,0) {C};
\node[rectangle,draw,fill=yellow] (D) at (-1,0) {D};

% \StartDrawOnBottomOfLayerStack

%% group 1
\begin{pgfonlayer}{background1}
\node[rectangle,fill=green,fit={(B) (C)}](G1) {}; 
\end{pgfonlayer}

%% group 2
\begin{pgfonlayer}{background2}
\node[fill=blue,fit={(B) (C) (D)(G1)}](G2) {}; 
\end{pgfonlayer}

%% group 3
\begin{pgfonlayer}{background3}
\node[fill=red,fit={(A)(B) (C) (D) (G1) (G2)}](G3) {}; 
\end{pgfonlayer}

\end{tikzpicture}
\end{document}

MWE

Responder1

Breve introdução, de baixo para cima:

  1. Semelhante ao ambiente pgfonlayer, o novo ambiente pgfonlayerreversedé definido. Seu conteúdo será composto na camada especificada, mas em ordem inversa, ou seja, o conteúdo mais recente será compostoabaixoconteúdos acumulados.
  2. Semelhante à opção on background layerem biblioteca backgrounds, é definida uma nova opção on background layer reversedque faz uso do novo ambiente pgfonlayerreversed(na camada background).
  3. Por fim, \StartDrawOnBottomOfLayerStacke \EndDrawOnBottomOfLayerStackconstituem um scopeambiente especial, em que todo uso de \nodeé equivalente a \scoped[on lowest layer] \node.

Implementação completa:

% from https://tex.stackexchange.com/q/562577
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds, fit}
\usepackage{xpatch}

\makeatletter
% similar to env "pgfonlayer", but the latest contents are typeset on
% lowest bottom (on reversed order)

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


\tikzset{
  on background layer reversed/.style={%
    execute at begin scope={%
      \pgfonlayerreversed{background}%
      \let\tikz@options=\pgfutil@empty
      \tikzset{every on background layer/.try,#1}%
      \tikz@options
    },
    execute at end scope={\endpgfonlayerreversed}
  }
}


\def\StartDrawOnBottomOfLayerStack{%
  \scope\relax
  % patch \path variants to auto insert "\scoped[on lowest layer]"
  % currently \node, \pic, \coordinate, and \matrix are patched
  \let\tikz@path@overlay\tikz@path@overlay@autoscoped
  \let\tikz@path@overlayed\tikz@path@overlayed@autoscoped
}

\def\EndDrawOnTopOfLayerStack{%
  \endscope
}

\def\tikz@path@overlay@autoscoped#1{%
  \let\tikz@signal@path=\tikz@signal@path% for detection at begin of matrix cell
  \pgfutil@ifnextchar<%
    {\tikz@path@overlayed{#1}}
    {\scoped[on background layer reversed] \path #1}}%
\def\tikz@path@overlayed@autoscoped#1<#2>{%
  \scoped[on background layer reversed] \path<#2> #1}%
\makeatother

\begin{document}

\begin{tikzpicture}
  % text nodes
  \node[rectangle,draw,fill=yellow] (A) at (-4,0) {A};
  \node[rectangle,draw,fill=yellow] (B) at (-3,0) {B};
  \node[rectangle,draw,fill=yellow] (C) at (-2,0) {C};
  \node[rectangle,draw,fill=yellow] (D) at (-1,0) {D};

  % background rectangles
  \StartDrawOnBottomOfLayerStack
    \node[rectangle,fill=green,fit={(B) (C)}](G1) {};
    \node[fill=blue,fit={(B) (C) (D)(G1)}](G2) {};
    \node[fill=red,fit={(A)(B) (C) (D) (G1) (G2)}](G3) {};
  \EndDrawOnTopOfLayerStack
\end{tikzpicture}
\end{document}

informação relacionada