使用 tikz 设置表格背景阴影和阴影

使用 tikz 设置表格背景阴影和阴影

我正在寻找一种方便的方式来设置表格单元格的背景。我想做两件事:(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

我的回答表格中某个单元格的渐变颜色产生阴影单元,并且可以轻松调整以产生阴影图案。此解决方案适用于tabulartabularxtabulary我想也可以,尽管我没有测试过)和\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库在背景中着色,以便着色不会过多地影响数字的可见性(注意有点问题的模式)。

根据您想要实现的结果,您应该使用不同的命令:

  1. \highlight是最简单的命令,它为整个部分着色;
  2. \vshade允许插入垂直阴影;
  3. \oshade相当于水平阴影;
  4. \inshade允许实现径向阴影;
  5. \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}

输出是一样的。

相关内容