如何在 TikZ 中分层?

如何在 TikZ 中分层?

我有以下 TikZ 图,其输出以图形方式显示在下方。我的问题是,我想以这样的方式扩展该图,即在覆盖“Expressive FE”的下方和外侧有另一个覆盖,而新覆盖内只有一个节点“WP4”。因此,基本上应该在“项目概述”内有两个不相交的覆盖,我已经有“Expressive FE”的覆盖,在它下面还有另一个覆盖。我已经尝试对此进行一些操作(使用下面的注释行),但它完全弄乱了图。有什么想法如何实现吗?

\documentclass[a4paper,11pt]{article}
\usepackage{xcolor}
\usepackage{tikz}
\tikzset{>=latex}
\usepackage{pgfgantt}
\usepackage{relsize}

\definecolor{cbg}{HTML}{fdf6e3} 
\definecolor{c1}{HTML}{CB4B16}
\definecolor{c2}{HTML}{586E75}
\definecolor{c3}{HTML}{6C71C4}
\definecolor{c4}{HTML}{D33682}

\newlength{\mynodedist}
\setlength{\mynodedist}{2pt}

\newlength{\mytextwidth}
\setlength{\mytextwidth}{50pt}

\newlength{\mytextheight}
\setlength{\mytextheight}{50pt}

\newcommand{\filllegendentry}[1]{\begin{tikzpicture}[scale=0.5, transform shape] \filldraw[draw=#1, fill=#1, thin] (0,0) rectangle (0.8,0.4); \end{tikzpicture}}
\newcommand{\legendentry}[2]{\begin{tikzpicture}[scale=0.5, transform shape] \filldraw[pattern color=#1, draw=#1, fill=#1, pattern=#2, thin] (0,0) rectangle (0.8,0.4); \end{tikzpicture}}

\begin{document}

\begin{figure}[ht]
\centering
\begin{tikzpicture}[
    scale=1.4,
    transform shape,
    node distance=\mynodedist,
    outer sep=0pt, 
    pqfe/.style={
        draw=none,
        fill=c10!50,
        rounded corners,
        font={\scriptsize},
        align=center,
        text width=0.5\mytextwidth,
        minimum height=0.5\mytextheight-0.5\mynodedist
    },
    adapt/.style={
        draw=none,
        fill=c4!50,
        rounded corners,
        font={\scriptsize},
        align=center,
        text width=0.5\mytextwidth,
        minimum height=0.5\mytextheight-0.5\mynodedist
    },
    wp1/.style={
        pqfe,
        draw=cbg,
        fill=c1,
        minimum height=0.5\mytextwidth-0.5\mynodedist,
        text width=3\mytextwidth
    },
    wp2/.style={
        wp1,
        fill=c2,
        text width=3\mytextwidth+\mynodedist
    },
    wp3/.style={
        wp2,
        fill=c3,
        text width=3\mytextwidth+\mynodedist
    },
    wp4/.style={
        wp3,
        fill=c4,
        text width=3\mytextwidth+\mynodedist
    },
    dummy/.style={
        pqfe,
        minimum height=0.5\mytextwidth-0.5\mynodedist
    },
]
  \node[dummy] (dummy) {~};
  \node[dummy, below=of dummy] (dummy2) {~};
  \node[dummy, below=of dummy2] (dummy3) {~};
  \node[pqfe, anchor=north] at (dummy.north) (pqfe) {~};
%  \node[adapt, below=of pqfe] (adapt) {~};
  \node[wp1, anchor=north west] at (dummy.north west) (wp1) {WP1\\{\smaller (Upper Bounds)}};
  \node[wp2, anchor=north west] (wp2) at (dummy2.north west) {WP1\\{\smaller (Lower Bounds)}};
  \node[wp3, anchor=north west] (wp3) at (dummy3.north west) {WP3\\{\smaller (New Assumptions and Security Models)}}; 
%  \node[wp4, below=of wp3] (wp4) {WP4\\{\smaller (Adaptive Security)}};

\begin{pgfonlayer}{background}
  \filldraw[pqfe,fill=c2] ([xshift=-4\mynodedist,yshift=16\mynodedist]pqfe.north west) 
                            -- ([xshift=5\mynodedist,yshift=16\mynodedist]wp1.north east) 
                            -- ([xshift=4\mynodedist,yshift=-4\mynodedist]wp3.south east)
                            -- ([xshift=-4\mynodedist,yshift=-4\mynodedist]wp3.south west)
                            -- cycle;
  \filldraw[pqfe,fill=c10!50] ([xshift=-2\mynodedist,yshift=8\mynodedist]pqfe.north west) 
                            -- ([xshift=7\mynodedist-30pt,yshift=8\mynodedist]wp1.north east) 
                            -- ([xshift=6\mynodedist-30pt,yshift=-2\mynodedist]wp3.south east)
                            -- ([xshift=-2\mynodedist,yshift=-2\mynodedist]wp3.south west)
                            -- cycle;   
%  \filldraw[adapt,fill=c2] ([xshift=-4\mynodedist,yshift=16\mynodedist]adapt.north west) 
%                            -- ([xshift=5\mynodedist,yshift=16\mynodedist]wp4.north east) 
%                            -- ([xshift=4\mynodedist,yshift=-4\mynodedist]wp4.south east)
%                            -- ([xshift=-4\mynodedist,yshift=-4\mynodedist]wp4.south west)
%                            -- cycle;
%  \filldraw[adapt,fill=c10!50] ([xshift=-2\mynodedist,yshift=8\mynodedist]adapt.north west) 
%                            -- ([xshift=7\mynodedist-30pt,yshift=8\mynodedist]wp4.north east) 
%                            -- ([xshift=6\mynodedist-30pt,yshift=-2\mynodedist]wp4.south east)
%                            -- ([xshift=-2\mynodedist,yshift=-2\mynodedist]wp4.south west)
%                            -- cycle;                                            
\end{pgfonlayer}

\node[font=\color{white},above=of wp1, anchor=south, xshift=-0pt, yshift=7\mynodedist] {\scriptsize Project Overview (Post-Quantum FE)};
\node[font=\color{black},above=of pqfe, anchor=south west, xshift=-15pt, yshift=-\mynodedist] {\scriptsize Expressive FE};
%\node[font=\color{black},below=of pqfe, anchor=south west, xshift=-15pt, yshift=-\mynodedist] {\scriptsize Adaptively-Secure FE};
\end{tikzpicture}
\caption{High-Level Project Overview}
\label{fig:overview}
\end{figure}

\end{document}

在此处输入图片描述

答案1

也许是这样的:

\documentclass[a4paper,11pt]{article}
\usepackage{relsize}
\usepackage{tikz}
\usetikzlibrary{positioning, fit}

\pgfdeclarelayer{background}
\pgfdeclarelayer{lowerbackground}
\pgfsetlayers{lowerbackground, background, main}

\definecolor{cbg}{HTML}{66CCFF} 
\definecolor{c1}{HTML}{CB4B16}
\definecolor{c2}{HTML}{586E75}
\definecolor{c3}{HTML}{6C71C4}
\definecolor{c4}{HTML}{D33682}
\definecolor{c10}{HTML}{000000}

\newlength{\mynodedist}
\setlength{\mynodedist}{2pt}

\newlength{\mytextwidth}
\setlength{\mytextwidth}{50pt}

\begin{document}

\begin{figure}[ht]
\centering
\begin{tikzpicture}[
    scale=1.4,
    transform shape,
    node distance=\mynodedist,
    outer sep=0pt, 
    pqfe/.style={
        draw=none,
        fill=c10!50,
        rounded corners,
        font={\scriptsize},
        align=center,
    },
    wp1/.style={
        pqfe,
        draw=white,
        fill=c1,
        text width=3\mytextwidth
    },
    wp2/.style={
        wp1,
        fill=c2,
    },
    wp3/.style={
        wp1,
        fill=c3,
    },
    wp4/.style={
        wp1,
        fill=c4,
    },
    legend/.style={
        font={\scriptsize}
    }
]

  \node[text=white, legend] (legend1) {Project Overview (Post-Quantum FE)};
  \node[below=of legend1, legend] (legend2) {Expressive FE};

  \node[wp1, below=of legend2] (wp1) {WP1\\{\smaller (Upper Bounds)}};
  \node[wp2, below=of wp1] (wp2) {WP1\\{\smaller (Lower Bounds)}};
  \node[wp3, below=of wp2] (wp3) {WP3\\{\smaller (New Assumptions and Security Models)}}; 

  \node[below=10pt of wp3, legend] (legend3) {Adaptively-Secure FE};

  \node[wp4, below=of legend3] (wp4) {WP4\\{\smaller (Adaptive Security)}};

  \begin{pgfonlayer}{background}
    \node[pqfe, fit={(legend2) (wp3)}, fill=cbg] (fit1) {};
    \node[pqfe, fit={(legend3) (wp4)}, fill=cbg] (fit2) {};
  \end{pgfonlayer}

  \begin{pgfonlayer}{lowerbackground}
    \node[pqfe, fit={(legend1) (fit2)}, fill=c10!50] (fit3) {};
  \end{pgfonlayer}

\end{tikzpicture}
\caption{High-Level Project Overview}
\label{fig:overview}
\end{figure}

\end{document}

在此处输入图片描述

我删除了pgfgantt您实际上不使用的包并将其替换为\usetikzlibrary{positioning}。我还加载了fit库并定义了三个层,其中两个应理解为位于主层后面的背景。

我稍微清理了一下样式,因为实际上你只需要借助库来定义内部节点的宽度和节点距离fit

然后,我只需将所有节点(包括“图例”节点)放置在彼此下方,并使用背景层和fit库来定位较大的矩形。


根据您的评论做了一些调整:

\documentclass[a4paper,11pt]{article}
\usepackage{relsize}
\usepackage{tikz}
\usetikzlibrary{positioning, fit}

\pgfdeclarelayer{background}
\pgfdeclarelayer{lowerbackground}
\pgfsetlayers{lowerbackground, background, main}

\definecolor{cbg}{HTML}{66CCFF} 
\definecolor{c1}{HTML}{CB4B16}
\definecolor{c2}{HTML}{586E75}
\definecolor{c3}{HTML}{6C71C4}
\definecolor{c4}{HTML}{D33682}
\definecolor{c10}{HTML}{000000}

\newlength{\mynodedist}
\setlength{\mynodedist}{2pt}

\newlength{\mytextwidth}
\setlength{\mytextwidth}{50pt}

\begin{document}

\begin{figure}[ht]
\centering
\begin{tikzpicture}[
    scale=1.4,
    transform shape,
    node distance=\mynodedist,
    outer sep=0pt, 
    pqfe/.style={
        draw=none,
        fill=c10!50,
        rounded corners,
        font={\scriptsize},
        align=center,
    },
    wp1/.style={
        pqfe,
        draw=white,
        fill=c1,
        text width=3\mytextwidth
    },
    wp2/.style={
        wp1,
        fill=c2,
    },
    wp3/.style={
        wp1,
        fill=c3,
    },
    wp4/.style={
        wp1,
        fill=c4,
    },
    legend/.style={
        text width=3\mytextwidth,
        font={\scriptsize}
    }
]

  \node[text=white, legend, align=center] (legend1) {Project Overview (Post-Quantum FE)};
  \node[below=of legend1, legend] (legend2) {Expressive FE};

  \node[wp1, below=of legend2] (wp1) {WP1\\{\smaller (Upper Bounds)}};
  \node[wp2, below=of wp1] (wp2) {WP1\\{\smaller (Lower Bounds)}};
  \node[wp3, below=of wp2] (wp3) {WP3\\{\smaller (New Assumptions and Security Models)}}; 

  \node[below=10pt of wp3, legend] (legend3) {Adaptively-Secure FE};

  \node[wp4, below=of legend3] (wp4) {WP4\\{\smaller (Adaptive Security)}};

  \begin{pgfonlayer}{background}
    \node[pqfe, fit={(legend2) (wp3)}, fill=cbg, inner xsep=-20pt, xshift=-24pt] (fit1) {};
    \node[pqfe, fit={(legend3) (wp4)}, fill=cbg, inner xsep=-20pt, xshift=-24pt] (fit2) {};
  \end{pgfonlayer}

  \begin{pgfonlayer}{lowerbackground}
    \node[pqfe, fit={(legend1) (fit2)}, fill=c10!50] (fit3) {};
  \end{pgfonlayer}

\end{tikzpicture}
\caption{High-Level Project Overview}
\label{fig:overview}
\end{figure}

\end{document}

在此处输入图片描述

答案2

只需这三层,我们就可以

  • 使用每个路径的内置图层
  • 中间层有一个稍微多余的循环。

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{fit, chains}
\newcommand*\legendset{\pgfqkeys{/legend}}
\definecolor{cbg}{HTML}{66CCFF} 
\definecolor {c1}{HTML}{CB4B16}
\definecolor {c2}{HTML}{586E75}
\definecolor {c3}{HTML}{6C71C4}
\definecolor {c4}{HTML}{D33682}
\definecolor{c10}{HTML}{000000}
\legendset{
  /tikz/legendset/.code=\legendset{#1},
  node distance/.initial=.2em,
  extra node distance/.initial=.7em,
  text width/.initial=\YouNeedToSetATextWidth,
  every title/.style={
    text width/.expanded=\pgfkeysvalueof{/legend/text width},
    align=center, path only},
  every header/.style={
    /legend/every title,
    yshift=-(\pgfkeysvalueof{/legend/extra node distance}),
    text depth=+0pt, text height=+.7em},
  title 1/.style={/legend/every header, text=white},
  title 2/.style={/legend/every header, align=left},
  title 3/.style={/legend/every title, draw=white, rounded corners},
  every rectangle/.style={rounded corners, fill},
  title 1 rectangle/.style={/legend/every rectangle, c10!50},
  @title 1 rectangle/.style={
    xshift/.expanded=-.5*(\pgfkeysvalueof{/pgf/inner xsep}),
    inner xsep/.expanded=1.5*(\pgfkeysvalueof{/pgf/inner xsep}),
    yshift/.expanded=-.5*(\pgfkeysvalueof{/pgf/inner ysep}),
    inner ysep/.expanded=1.5*(\pgfkeysvalueof{/pgf/inner ysep})},
  title 2 rectangle/.style={
    /legend/every rectangle, /legend/less text width=5em, cbg},
  reset counter/.code=\setcounter{legendcounter}{0},
  step  counter/.code=\stepcounter{legendcounter},
  set inner colors/.style={
    /utils/exec=\def\pgfmathcounter{0},
    /utils/temp/.style={
      /legend/inner title \pgfmathcounter/.append style={fill={##1}},
      /utils/exec=\edef\pgfmathcounter{\pgfinteval{\pgfmathcounter+1}}},
    /utils/temp/.list={#1}},
}
\newcounter{legendcounter}
\makeatletter
\legendset{less text width/.style={
  xshift={-(#1)/2},
  text width/.expanded={\tikz@text@width-(#1)}}}
\makeatother
\newcommand*\tikzlegend[2][]{%
  \path[% no ; at the end → \tikzlegend needs to end with ;
    legendset={reset counter,#1},
    node distance=\pgfkeysvalueof{/legend/node distance},
    start chain=legend going below]
    foreach[count=\iA] \TitleA/\listA in {#2}{
      node[/legend/title 1, on chain] (legendA-\iA) {\TitleA}
      foreach[count=\iB] \TitleB/\listB in \listA{
        node[/legend/title 2, on chain] (legendB-\iB) {\TitleB}
        foreach \Title/\subTitle in \listB{
          node[/legend/title 3,
               /legend/inner title \thelegendcounter/.try,
               /legend/step counter, on chain] (legendB-\iB-last)
            {\Title\\{\footnotesize(\subTitle\unskip)}}}}
      [behind path]
      node[/legend/title 1 rectangle,
           /legend/@title 1 rectangle,
           fit=(legendA-\iA)(\tikzchaincurrent)]{}
      foreach[count=\iB] \TitleB/\listB in \listA{
        node[fit=(legendB-\iB)(legendB-\iB-last), /legend/title 2 rectangle]{}}}}
\begin{document}
\tikz
\tikzlegend[
  text width=width("Project Overview (Post-Quantum FE)"),
  set inner colors={c1, c2, c3, c4}
]{
  Project Overview (Post-Quantum FE)/{
    Expressive FE/{
      WP1/Upper Bounds,
      WP1/Lower Bounds,
      WP3/New Assumptions and Security Models
    },
    Adaptively-Secure FE/{
      WP4/Adaptive Security
    }% ← these % are necessary
  }%   ← these % are necessary
};
\end{document}

输出

在此处输入图片描述

相关内容