我正在寻找一种方便的方式来设置表格单元格的背景。我想做两件事:(1)将背景设置为阴影颜色(2)将背景设置为阴影
我了解到 TikZ 包提供了执行此操作的方法,但我无法想出不使用矩阵的解决方案(例如这里:http://www.texample.net/tikz/examples/timetable/) 而是使用 tabular 包。
以下是我想要做的事情:
\documentclass{article}
\begin{document}
\begin{tabular}{|l|l|l|}
\hline
1 & \setBGGray 2 & 3 \\\hline
4 & 5 & 6 \\\hline
7 & \setBGHatched 8 & 9 \\\hline
\end{tabular}
\end{document}
输出应如下所示:
有人可以帮我使用tabular
(或tabularx
) 和 TikZ 实现这个吗?
答案1
我的回答表格中某个单元格的渐变颜色产生阴影单元,并且可以轻松调整以产生阴影图案。此解决方案适用于tabular
、tabularx
(tabulary
我想也可以,尽管我没有测试过)和\multicolumn
:
\documentclass[10pt]{article}
\usepackage[margin=2cm]{geometry} % just for the example
\usepackage{fourier}
\usepackage[table]{xcolor}
\usepackage{array}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{calc,shadings,patterns}
% Andrew Stacey's code from
% https://tex.stackexchange.com/a/50054/3954
\makeatletter
\tikzset{%
remember picture with id/.style={%
remember picture,
overlay,
save picture id=#1,
},
save picture id/.code={%
\edef\pgf@temp{#1}%
\immediate\write\pgfutil@auxout{%
\noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
},
if picture id/.code args={#1#2#3}{%
\@ifundefined{save@pt@#1}{%
\pgfkeysalso{#3}%
}{
\pgfkeysalso{#2}%
}
}
}
\def\savepointas#1#2{%
\expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}
\def\tmk@labeldef#1,#2\@nil{%
\def\tmk@label{#1}%
\def\tmk@def{#2}%
}
\tikzdeclarecoordinatesystem{pic}{%
\pgfutil@in@,{#1}%
\ifpgfutil@in@%
\tmk@labeldef#1\@nil
\else
\tmk@labeldef#1,(0pt,0pt)\@nil
\fi
\@ifundefined{save@pt@\tmk@label}{%
\tikz@scan@one@point\pgfutil@firstofone\tmk@def
}{%
\pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
\pgfsys@getposition{\pgfpictureid}\save@this@pic%
\pgf@process{\pgfpointorigin\save@this@pic}%
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgf@process{\pgfpointorigin\save@orig@pic}%
\advance\pgf@x by -\pgf@xa
\advance\pgf@y by -\pgf@ya
}%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] {#1;}}
\makeatother
% end of Andrew's code
\newcommand\ShadeCell[4][0pt]{%
\begin{tikzpicture}[overlay,remember picture]%
\shade[#4] ( $ (pic cs:#2) + (0pt,1.9ex) $ ) rectangle ( $ (pic cs:#3) + (0pt,-#1*\baselineskip-.8ex) $ );
\end{tikzpicture}%
}%
\newcommand\HatchedCell[4][0pt]{%
\begin{tikzpicture}[overlay,remember picture]%
\fill[#4] ( $ (pic cs:#2) + (0,1.9ex) $ ) rectangle ( $ (pic cs:#3) + (0pt,-#1*\baselineskip-.8ex) $ );
\end{tikzpicture}%
}%
\newcommand\Text{Quisque ullamcorper placerat ipsum. Cras nibh. Lorem ipsum dolor sit amet.}
\begin{document}
\ShadeCell{start1}{end1}{%
top color=gray!60,bottom color=gray!20}
\ShadeCell{start2}{end2}{%
left color=gray!50,right color=gray!20}
\HatchedCell{start3}{end3}{%
pattern color=black!70,pattern=north east lines}
\noindent\begin{tabular}{| c | c | c |}
\hline
1 & \multicolumn{1}{!{\hspace*{-0.4pt}\vrule\tikzmark{start1}}c!{\vrule\tikzmark{end1}}}{2} & 3 \\
\hline
\multicolumn{1}{!{\vrule\tikzmark{start2}}c!{\vrule\tikzmark{end2}}}{4} & 5 & 6 \\
\hline
7 & 8 & \multicolumn{1}{!{\hspace*{-0.4pt}\vrule\tikzmark{start3}}c!{\vrule\tikzmark{end3}}}{9} \\
\hline
\end{tabular}
\vspace{10pt}
\ShadeCell[3]{start4}{end4}{%
top color=gray!40}
\HatchedCell[3]{start5}{end5}{%
pattern color=gray!40,pattern=vertical lines}
\HatchedCell[3]{start6}{end6}{%
pattern color=gray!50,pattern=north east lines}
\noindent\begin{tabularx}{.6\textwidth}{| X | X | X |}
\hline
\Text & \multicolumn{1}{!{\hspace*{-0.4pt}\vrule\tikzmark{start4}}X!{\vrule\tikzmark{end4}}}{\Text} & \Text \\
\hline
\multicolumn{1}{!{\vrule\tikzmark{start5}}X!{\vrule\tikzmark{end5}}}{\Text} & \Text & \Text \\
\hline
\Text & \multicolumn{2}{!{\hspace*{-0.4pt}\vrule\tikzmark{start6}}>{\hsize=2\hsize}X!{\vrule\tikzmark{end6}}}{\Text} \\
\hline
\end{tabularx}
\end{document}
数值矩阵放大后:
如果您需要在多个单元格中重复使用相同的阴影,上述方法就有点笨拙了。但您可以定义一个计数器和一个命令来完成所有必要的工作(我删除了垂直线,因为有一些我无法轻松修复的小故障,但无论如何您都不应该在表格中使用垂直线 ;-):
\newcounter{hatchNumber}
\setcounter{hatchNumber}{1}
\newcommand\myHatch[2]{
\multicolumn{1}{
!{\HatchedCell{startMyHatch\arabic{hatchNumber}}{endMyHatch\arabic{hatchNumber}}{%
pattern color=black!70,pattern=north east lines}
\tikzmark{startMyHatch\arabic{hatchNumber}}}
#1
!{\tikzmark{endMyHatch\arabic{hatchNumber}}}}
{#2}
\addtocounter{hatchNumber}{1}
}
% Using the simplified command myHatch
\noindent\begin{tabular}{ c c c }
\hline
1 & \myHatch{c}{2} & 3 \\
\myHatch{c}{4} & 5 & \myHatch{c}{6}
答案2
我的解决方案基于突出显示矩阵中的元素. 事实上,这里的一种可能性是利用矩阵。
代码:
\documentclass[a4paper,12pt]{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{calc,matrix,patterns,shadings,backgrounds}
\pgfdeclarelayer{myback}
\pgfsetlayers{myback,background,main}
\tikzset{myfillcolor/.style = {draw,fill=#1}}%
\NewDocumentCommand{\highlight}{O{blue!40} m m}{%
\draw[myfillcolor=#1] (#2.north west)rectangle (#3.south east);
}
\NewDocumentCommand{\vshade}{O{blue!40} O{white} m m}{%
\draw[bottom color =#1,top color=#2] (#3.north west)rectangle (#4.south east);
}
\NewDocumentCommand{\oshade}{O{blue!40} O{white} m m}{%
\draw[right color =#1,left color=#2] (#3.north west)rectangle (#4.south east);
}
\NewDocumentCommand{\inshade}{O{blue!40} O{white} m m}{%
\draw[inner color =#1,outer color=#2] (#3.north west)rectangle (#4.south east);
}
\NewDocumentCommand{\fillpattern}{O{north west lines} O{blue!50} m m}{%
\draw[pattern=#1, pattern color=#2] (#3.north west)rectangle (#4.south east);
}
\begin{document}
\begin{tikzpicture}
\matrix (m)[matrix of nodes, style={nodes={rectangle,draw,minimum width=3em}}, minimum height=3em, row sep=-\pgflinewidth, column sep=-\pgflinewidth,ampersand replacement =\&]
{
1 \& 2 \& 3 \\
4 \& 5 \& 6 \\
7 \& 8 \& 9 \\
};
\begin{pgfonlayer}{myback}
\highlight{m-1-1}{m-1-1}
\vshade{m-2-2}{m-2-2}
\vshade[white][red]{m-2-3}{m-2-3}
\oshade{m-1-3}{m-1-3}
\oshade[white][orange]{m-1-2}{m-1-2}
\inshade[orange][white]{m-2-1}{m-2-1}
\fillpattern{m-3-2}{m-3-2}
\fillpattern[dots][green!50!black]{m-3-1}{m-3-1}
\fillpattern[sixpointed stars][violet!50]{m-3-3}{m-3-3}
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
结果是(请原谅我的配色不好:)
):
一些解释
如前所述,这里的基本思想是利用矩阵,因此要做的第一件事就是在数字周围绘制网格。这已通过选项实现style={nodes={rectangle,draw,minimum width=3em}}, minimum height=3em, row sep=-\pgflinewidth, column sep=-\pgflinewidth
。
每个元素都通过background
库在背景中着色,以便着色不会过多地影响数字的可见性(注意有点问题的模式)。
根据您想要实现的结果,您应该使用不同的命令:
\highlight
是最简单的命令,它为整个部分着色;\vshade
允许插入垂直阴影;\oshade
相当于水平阴影;\inshade
允许实现径向阴影;\fillpattern
插入图案。
通过 TikZ 矩阵,您可以使用以下语法突出显示元素name_matrix-row-colum
:在我们的例子中,元素可以是m-1-1
。所有命令都旨在填充与 相对应的区域,(element.north west)rectangle (element.south east)
并允许您自定义颜色。实际上,甚至可以选择更大的区域,例如两个或更多数字;这种选择类型的一个例子可能是:
\vshade{m-1-1}{m-2-2}
为 的相应区域着色1, 2, 4, 5
。
对于\fillpattern
,您甚至可以选择使用哪种图案样式(第一个可选参数)及其颜色(第二个可选参数)。
利用该fit
库可以达到同样的效果:
\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc,matrix,patterns,shadings,backgrounds,fit}
\pgfdeclarelayer{myback}
\pgfsetlayers{myback,background,main}
\begin{document}
\begin{tikzpicture}
\matrix (m)[matrix of nodes, style={nodes={rectangle,draw,minimum width=3em}}, minimum height=3em, row sep=-\pgflinewidth, column sep=-\pgflinewidth,ampersand replacement =\&]
{
1 \& 2 \& 3 \\
4 \& 5 \& 6 \\
7 \& 8 \& 9 \\
};
\begin{pgfonlayer}{myback}
\node[fit=(m-1-1),fill=blue!40,inner sep=0cm]{};
\node[fit=(m-2-2),bottom color=blue!40,top color= white,inner sep=0cm]{};
\node[fit=(m-2-3),bottom color=white,top color= red,inner sep=0cm]{};
\node[fit=(m-1-3),right color=blue!40,left color= white,inner sep=0cm]{};
\node[fit=(m-1-2),right color=white,left color= orange,inner sep=0cm]{};
\node[fit=(m-2-1),outer color=white,inner color= orange,inner sep=0cm]{};
\node[fit=(m-3-2),pattern=north west lines, pattern color=blue!50,inner sep=0cm]{};
\node[fit=(m-3-1),pattern=dots, pattern color=green!50!black,inner sep=0cm]{};
\node[fit=(m-3-3),pattern=sixpointed stars, pattern color=violet!50,inner sep=0cm]{};
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
答案3
该包提供了一个类似于经典的nicematrix
环境,但它在数组的单元格、行和列下构建 PGF/Tikz 节点。 中提供的所有经典工具都可以在 中使用,但我们也可以使用该节点和 Tikz 来填充单元格。{NiceTabular}
{tabular}
array
{tabular}
{NiceTabular}
\documentclass{article}
\usepackage{nicematrix}
\usepackage{tikz}
\usetikzlibrary{patterns,shadings}
\begin{document}
\begin{NiceTabular}{cccc}[hvlines,cell-space-limits=3pt]
\CodeBefore
\begin{tikzpicture}
\path [pattern = grid, pattern color=gray] (1-|1) rectangle (2-|2) ;
\path [pattern = north west lines,pattern color=red] (1-|3) rectangle (2-|5) ;
\path [top color=red!50] (2-|1) rectangle (3-|2) ;
\path [pattern=fivepointed stars,pattern color=lightgray] (2-|2) rectangle (4-|4) ;
\path [fill=blue!15] (4-|1) rectangle (5-|3) ;
\path [left color=red!50] (4-|4) rectangle (5-|5) ;
\end{tikzpicture}
\Body
zero & one & \Block{1-2}{two} & \\
\Block{}{\rotate three} & \Block{2-2}{four} & & five \\
\rotate six & & & seven \\
\Block{1-2}{eight} & & nine & ten \\
\end{NiceTabular}
\end{document}
您需要多次编译。
事实上,使用最新版本nicematrix
(2021-07-23 的 v 5.19),还可以为tikz
命令\Block
(合并单元格)提供一个键,以直接指定如何填充该块。
\documentclass{article}
\usepackage{nicematrix}
\usepackage{tikz}
\usetikzlibrary{patterns,shadings}
\begin{document}
\begin{NiceTabular}{cccc}[hvlines,cell-space-limits=3pt]
\Block[tikz={pattern = grid, pattern color=gray}]{}{zero} & one
& \Block[tikz={pattern = north west lines,pattern color=red}]{1-2}{two} \\
\Block[tikz={top color=red!50}]{}{\rotate three} & \Block[tikz={pattern=fivepointed stars,pattern color=lightgray}]{2-2}{four} && five \\
\rotate six & & & seven \\
\Block[fill=blue!15]{1-2}{eight} && nine & \Block[tikz={left color=red!50}]{}{ten}
\end{NiceTabular}
\end{document}
输出是一样的。