我的问题是如何为节点中的不同节点部分定制填充图案(网格、垂直线等)?
以下是一次失败的尝试。
\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
根据它调整值。
下图显示了第一和第二个代码的结果。