如何使用不同的纹理定制不同的节点部分?

如何使用不同的纹理定制不同的节点部分?

我的问题是如何为节点中的不同节点部分定制填充图案(网格、垂直线等)?

以下是一次失败的尝试。

\documentclass[border=2mm,convert]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart,patterns}

\begin{document}
\begin{tikzpicture}
\node[rectangle split,rectangle split parts =2,rectangle split part fill={red!30,red!10},
rectangle split part pattern={grid,},draw]{one \nodepart{second}two};
\end{tikzpicture}
\end{document}

答案1

假设您想对节点部分的各个部分使用图案,则不能将rectangle split part fill其项目直接用作填充颜色。

然而,我们可以使用相同的过程为每个部分节点安装模式,并应用相同的规则,即,对于任何剩余的节点部分,最后的条目都会重复。

通过改变线条

\pgfsetfillcolor{\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname}%
\pgfusepath{fill}%

从形状的 behindbackground 路径的定义rectangle split

\edef\pgf@temp{\noexpand\pgfqkeys{/tikz/rectangle split pattern}{\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname}}%
\pgf@temp
\iftikz@mode@fill
  \pgfsetfillpattern{\tikz@pattern}{\tikz@pattern@color}%
  \pgfusepath{fill}%
\else
  \pgfusepath{}%
\fi

我们可以模仿 TikZ 的原始图案选项。\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname宏由填充列表的相同处理器定义:

\pgf@lib@sh@rs@process@list{\pgf@lib@sh@rs@list@pattern}{\parts}%

我为其创建了一个额外的 PGF 密钥路径,/tikz/rectangle split pattern以便在较低级别应用选项。

该序列pattern=none可用于禁用一个或多个节点部分的模式。

代码

\documentclass[tikz,border=2mm,convert=false]{standalone}
\usetikzlibrary{shapes.multipart,patterns}
\makeatletter
\newif\ifpgfrectanglesplitusecustompattern
\def\pgf@lib@sh@rs@list@pattern{none}
\tikzset{
  rectangle split part pattern/.code=\def\pgf@lib@sh@rs@list@pattern{#1}\pgfrectanglesplitusecustompatterntrue,
  rectangle split uses custom pattern/.is if=pgfrectanglesplitusecustompattern,
  rectangle split pattern/.code={\pgfqkeys{/tikz/rectangle split pattern}{#1}},
  rectangle split pattern/.cd,
    pattern color/.code=\edef\tikz@pattern@color{#1},
    pattern/.code=%
      \edef\tikz@temp{#1}%
      \ifx\tikz@temp\tikz@nonetext%
        \tikz@mode@fillfalse
      \else%
        \ifx\tikz@temp\pgfutil@empty%
          \let\tikz@pattern\pgfutil@empty
        \else%
          \def\tikz@pattern{#1}%
        \fi%
        \tikz@mode@filltrue%
      \fi,%
      .unknown/.code=
        \let\tikz@pattern@key\pgfkeyscurrentname
        \pgfutil@ifundefined{pgf@pattern@name@\tikz@pattern@key}{% must be a pattern color then:
          \pgfqkeys{/tikz/rectangle split pattern}{pattern color/.try/.expanded=\tikz@pattern@key}%
          \ifpgfkeyssuccess\else
            \pgfkeys{/errors/unknown key={/tikz/\tikz@pattern@key}{#1}}%
          \fi
        }{\pgfqkeys{/tikz/rectangle split pattern}{pattern/.expanded=\tikz@pattern@key}}%
  }
\expandafter\def\csname pgf@sh@bbg@rectangle split\expandafter\expandafter\expandafter\endcsname\expandafter\expandafter\expandafter{\csname pgf@sh@bbg@rectangle split\endcsname
    \ifpgfrectanglesplitusecustompattern%
      \pgf@lib@sh@rs@process@list{\pgf@lib@sh@rs@list@pattern}{\parts}%
      {%
        \ifpgfrectanglesplithorizontal%
          \expandafter\let\expandafter\pgf@lib@sh@rs@fill@bottomleft\expandafter=%
            \csname pgf@anchor@rectangle split@south west\endcsname%
          \pgfmathloop%
            \ifnum\pgfmathcounter>\parts%
            \else%
              \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
              \ifnum\pgfmathcounter=\parts%
                \expandafter\let\expandafter\pgf@lib@sh@rs@fill@topright\expandafter=%
                  \csname pgf@anchor@rectangle split@north east\endcsname%
              \else%
                \expandafter\let\expandafter\pgf@lib@sh@rs@fill@topright\expandafter=%
                  \csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\space split north\endcsname%
              \fi%
              \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
              \else%
                \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname\pgf@lib@sh@rs@nonetext%
                \else%
                  \pgfextract@process\pgf@lib@sh@rs@fill@bottomleft{%
                    \pgf@lib@sh@rs@fill@bottomleft%
                    \advance\pgf@y by\outerysep\relax%
                    \ifnum\pgfmathcounter=1\relax%
                      \advance\pgf@x by\outerxsep\relax%
                    \fi%
                  }%
                  \pgfextract@process\pgf@lib@sh@rs@fill@topright{%
                    \pgf@lib@sh@rs@fill@topright%
                    \advance\pgf@y by-\outerysep\relax%
                    \ifnum\pgfmathcounter=\parts\relax%
                      \advance\pgf@x by-\outerxsep\relax%
                    \fi%
                  }%
                  \ifnum\pgfmathcounter>1\relax%
                    \begingroup\pgfsetcornersarced{\pgfpointorigin}%
                  \fi%
                  \pgfpathmoveto{%
                    \pgf@lib@sh@rs@fill@topright%
                    \pgf@xa=\pgf@x%
                    \pgf@lib@sh@rs@fill@bottomleft%
                    \pgf@x=\pgf@xa%
                  }%
                  \pgfpathlineto{\pgf@lib@sh@rs@fill@bottomleft}%
                  \pgfpathlineto{%
                    \pgf@lib@sh@rs@fill@bottomleft%
                    \pgf@xa=\pgf@x%
                    \pgf@lib@sh@rs@fill@topright%
                    \pgf@x=\pgf@xa%
                  }%
                  \ifnum\pgfmathcounter>1\relax%
                    \endgroup%
                  \fi%
                  \ifnum\pgfmathcounter<\parts%
                    \begingroup\pgfsetcornersarced{\pgfpointorigin}%
                  \fi%
                  \pgfpathlineto{\pgf@lib@sh@rs@fill@topright}%
                  \pgfpathclose%
                  \ifnum\pgfmathcounter<\parts%
                    \endgroup%
                  \fi%
                  \edef\pgf@temp{\noexpand\pgfqkeys{/tikz/rectangle split pattern}{\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname}}%
                  \pgf@temp
                  \iftikz@mode@fill
                    \pgfsetfillpattern{\tikz@pattern}{\tikz@pattern@color}%
                    \pgfusepath{fill}%
                  \else
                    \pgfusepath{}%
                  \fi
                \fi%
              \fi%
              \pgfextract@process\pgf@lib@sh@rs@fill@bottomleft{%
                \pgf@lib@sh@rs@fill@bottomleft%
                \pgf@ya=\pgf@y%
                \pgf@lib@sh@rs@fill@topright%
                \pgf@y=\pgf@ya%
                \advance\pgf@y by-\outerysep%
              }%
          \repeatpgfmathloop%  
        \else%
          \expandafter\let\expandafter\pgf@lib@sh@rs@fill@topright\expandafter=%
            \csname pgf@anchor@rectangle split@north east\endcsname%
          \pgfmathloop%
            \ifnum\pgfmathcounter>\parts%
            \else%
              \pgf@lib@sh@getalpha\pgf@lib@sh@rs@number{\pgfmathcounter}%
              \ifnum\pgfmathcounter=\parts%
                \expandafter\let\expandafter\pgf@lib@sh@rs@fill@bottomleft\expandafter=%
                  \csname pgf@anchor@rectangle split@south west\endcsname%
              \else%                
                \expandafter\let\expandafter\pgf@lib@sh@rs@fill@bottomleft\expandafter=%
                  \csname pgf@anchor@rectangle split@\pgf@lib@sh@rs@number\space split west\endcsname%
              \fi%
              \expandafter\ifx\csname pgf@lib@sh@rs@empty@\pgf@lib@sh@rs@number\endcsname\pgfutil@empty%
              \else%
                \expandafter\ifx\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname\pgf@lib@sh@rs@nonetext%
                \else%
                  \pgfextract@process\pgf@lib@sh@rs@fill@bottomleft{%
                    \pgf@lib@sh@rs@fill@bottomleft%
                    \advance\pgf@x by\outerxsep\relax%
                    \ifnum\parts=1\relax%
                      \advance\pgf@y by\outerysep\relax%
                    \else%
                      \ifnum\pgfmathcounter=\parts
                        \advance\pgf@y by\outerysep\relax%
                      \fi%
                    \fi%
                  }%
                  \pgfextract@process\pgf@lib@sh@rs@fill@topright{%
                    \pgf@lib@sh@rs@fill@topright%
                    \advance\pgf@x by-\outerxsep\relax%
                    \ifnum\parts=1\relax%
                      \advance\pgf@y by-\outerysep\relax%
                    \else%
                      \ifnum\pgfmathcounter=1\relax%
                        \advance\pgf@y by-\outerysep\relax%
                      \fi%
                    \fi%
                  }%
                  \pgfpathmoveto{\pgf@lib@sh@rs@fill@bottomleft}%
                  \ifnum\pgfmathcounter>1\relax%
                    \begingroup\pgfsetcornersarced{\pgfpointorigin}%
                  \fi%
                  \pgfpathlineto{%
                    \pgf@lib@sh@rs@fill@bottomleft%
                    \pgf@xa=\pgf@x%
                    \pgf@lib@sh@rs@fill@topright%
                    \pgf@x=\pgf@xa%
                  }%
                  \pgfpathlineto{\pgf@lib@sh@rs@fill@topright}%
                  \ifnum\pgfmathcounter>1\relax%
                    \endgroup%
                  \fi%
                  \ifnum\pgfmathcounter<\parts%
                    \begingroup\pgfsetcornersarced{\pgfpointorigin}%
                  \fi%
                  \pgfpathlineto{%
                    \pgf@lib@sh@rs@fill@topright%
                    \pgf@xa=\pgf@x%
                    \pgf@lib@sh@rs@fill@bottomleft%
                    \pgf@x=\pgf@xa%
                  }%
                  \pgfpathclose%
                  \ifnum\pgfmathcounter<\parts%
                    \endgroup%
                  \fi%
                  \edef\pgf@temp{\noexpand\pgfqkeys{/tikz/rectangle split pattern}{\csname pgf@lib@sh@rs@\pgf@lib@sh@rs@number @item\endcsname}}%
                  \pgf@temp
                  \iftikz@mode@fill
                    \pgfsetfillpattern{\tikz@pattern}{\tikz@pattern@color}%
                    \pgfusepath{fill}%
                  \else
                    \pgfusepath{}%
                  \fi
                \fi%
              \fi%
              \pgfextract@process\pgf@lib@sh@rs@fill@topright{%
                \pgf@lib@sh@rs@fill@topright%
                \pgf@xa=\pgf@x%
                \pgf@lib@sh@rs@fill@bottomleft%
                \pgf@x=\pgf@xa%  
                \advance\pgf@x by\outerxsep\relax%
              }%
          \repeatpgfmathloop%
        \fi%
      }%
    \fi%
}
\makeatother
\newcommand*{\everyRectangleSplitContents}{0020\nodepart{two}001A\nodepart{three}01A0\nodepart{four}0320}
\begin{document}
\begin{tikzpicture}[nodes=rectangle split,x=1.2cm]
   \node[rectangle split part fill={red!60,blue!60,olive!60,magenta!60}] {\everyRectangleSplitContents};
   \node[rectangle split part pattern={{grid, red!60},
                                       {dots, blue!60},
                                       {horizontal lines, olive!60},
                                       {vertical lines, magenta!60}}
         ] at (1,0) {0020\nodepart{two}001A\nodepart{three}01A0\nodepart{four}0320};

    \node[rectangle split pattern/pattern=grid, % rectangle split pattern
          rectangle split part pattern={red!60,blue!60,olive!60,magenta!60}
         ] at (2,0) {0020\nodepart{two}001A\nodepart{three}01A0\nodepart{four}0320};

   \node[rectangle split pattern/pattern color=red!60,
         rectangle split part pattern={grid,dots,horizontal lines,vertical lines}
         ] at (3,0) {0020\nodepart{two}001A\nodepart{three}01A0\nodepart{four}0320};

\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案2

我认为不可能使用类似的东西rectangle split part fill来绘制背景阴影。但如果你需要这样做,你总是可以在 上为每个部分绘制阴影图案background

\documentclass[tikz,border=2mm]{standalone}

\usetikzlibrary{shapes.multipart,positioning,patterns,backgrounds}

\begin{document}
\begin{tikzpicture}
   \node[rectangle split,% 
         rectangle split part fill={red!60,blue!60,olive!60,magenta!60}] (d)   
        {0020%
         \nodepart{two}001A%
         \nodepart{three}01A0%
         \nodepart{four}0320};

   \node[rectangle split, right=1cm of d, fill=none] (e)
        {0020\nodepart{two}001A\nodepart{three}01A0\nodepart{four}0320};

   \begin{pgfonlayer}{background}
       \draw[pattern=grid, pattern color=red!60] (e.north west) rectangle (e.text split east);
       \draw[pattern=dots, pattern color=blue!60] (e.text split west) rectangle (e.two split east);
       \draw[pattern=horizontal lines, pattern color=olive!60] (e.two split west) rectangle (e.three split east);
       \draw[pattern=vertical lines, pattern color=magenta!60] (e.three split west) rectangle (e.south east);
    \end{pgfonlayer}
\end{tikzpicture}
\end{document}

在此处输入图片描述

正如 Qrrbrbirlbel 指出的那样,之前的解决方案所覆盖的区域比 更宽更高fill。可以使用以下方法更好地进行调整:

\begin{pgfonlayer}{background}
    \fill[pattern=grid, pattern color=red!60]%  
         ([shift={(.5\pgflinewidth,-.5\pgflinewidth)}]e.north west) rectangle 
         ([shift={(-.5\pgflinewidth,0)}]e.text split east);
    \fill[pattern=grid, pattern color=blue!60]%     
         ([shift={(.5\pgflinewidth,0)}]e.text split west) rectangle 
         ([shift={(-.5\pgflinewidth,0)}]e.two split east);
    \fill[pattern=grid, pattern color=olive!60]%    
         ([shift={(.5\pgflinewidth,0)}]e.two split west) rectangle 
         ([shift={(-.5\pgflinewidth,0)}]e.three split east);
    \fill[pattern=grid, pattern color=magenta!60]%  
         ([shift={(.5\pgflinewidth,0)}]e.three split west) rectangle 
         ([shift={(-.5\pgflinewidth,.5\pgflinewidth)}]e.south east);
\end{pgfonlayer}

如果节点具有其默认值,则先前的代码可以工作outer sep,否则将需要shift根据它调整值。

下图显示了第一和第二个代码的结果。

在此处输入图片描述

相关内容