Excel 有一个很酷的功能,称为“数据栏”条件格式,它允许用户部分填充单元格背景以根据单元格内容创建直方图。以下是工作簿中的屏幕截图示例:
我正在寻找 TiKZ、minipage 或其他解决方案,以便我仅对单元格的背景进行部分着色。我尝试了几个选项,但没有成功。
\cellcolor
这是使用该包的最小工作示例xcolor
。
\documentclass{article}
\usepackage[table]{xcolor}% http://ctan.org/pkg/xcolor
\begin{document}
\begin{tabular}{l|c|r}
\hline
91.41 & \cellcolor{green!25}90.81 & 38.76 \\
\cellcolor{green!25}98.75 & 13.82 & 94.62 \\
57.11 & \cellcolor{green!25}51.21 & \cellcolor{green!25}42.84 \\
\hline
\end{tabular}
\end{document}
上面的代码产生:
在理想情况下,我会有一个宏,例如\partialcellcolor{green!25}{0.41\linewidth}
或任何其他宏,来指定颜色扩展到41%
单元格的任意位置。我使用“ R
”来生成表格,因此我会让它在编写 latex 代码时进行计算。
有什么建议么?
答案1
我重写了整个答案。有关之前的版本,请参阅这个答案的历史。
为此,H
引入了采用一个可能为空的参数的 columntype。
对于正数,条形图从左到右填充,对于负数,条形图从右到左填充。
需要设置它们的值min
、max
、来缩放条形图。该值初始化为,min neg
因为它用于确定所需的节点宽度max neg
max neg
0
align=right
。(有其他方法来做到这一点,但我会保持简单。)
min
我认为设置除此之外min neg
的其他选项没有多大意义,0
但是有这个选项。
可以使用各种样式来改变外观。希望这些样式是不言自明的。
该表的最终指定方式如下:
\begin{tabular}{
| H{} | H{min=2.00,max=105.00}
| H{max neg=-10.00, max=15.00, add format={precision=0}}|}
\hline
10 & 2 & -10 \\
15.49 & 13.82 & -5 \\
100 & 105 & 5 \\
\hline
\end{tabular}
代码
\documentclass{article}
\usepackage{tikz,array,collcell}
\newcommand*\tikzcellbgset{\pgfqkeys{/tikz/cellbg}}
\tikzcellbgset{
/pgf/number format/.code=\pgfqkeys{/pgf/number format}{#1},
node/.style={
/pgf/number format={/tikz/cellbg/number format},
node contents={\strut\pgfmathprintnumber{#1}},
anchor=base, outer sep=+0pt, inner ysep=+0pt, align=right,
inner xsep=\tabcolsep,
/utils/exec=%
\pgfmathprintnumberto{\pgfkeysvalueof{/tikz/cellbg/max}}{\tempa}%
\pgfmathprintnumberto{\pgfkeysvalueof{/tikz/cellbg/max neg}}{\tempb},
text width/.expanded={max(width("\tempa"),width("\tempb"))},
path picture={
\def\tcbgvo########1{\pgfkeysvalueof{/tikz/cellbg/########1}}% Eugh!
\pgftransformshift
{\pgfpointanchor{path picture bounding box}{south west}}
\pgfsetxvec{%
\pgfpointdiff
{\pgfpointanchor{path picture bounding box}{south west}}
{\pgfpointanchor{path picture bounding box}{south east}}}
\pgfsetyvec{%
\pgfpointdiff
{\pgfpointanchor{path picture bounding box}{south west}}
{\pgfpointanchor{path picture bounding box}{north west}}}
\pgfmathifthenelse{#1<0}{"0"}{"1"}
\ifnum\pgfmathresult=0
\path[cellbg/fill neg](1,0) rectangle
++({-(#1-\tcbgvo{min neg})/(\tcbgvo{max neg}-\tcbgvo{min neg})},1);
\else
\path[cellbg/fill pos](0,0) rectangle
({(#1-\tcbgvo{min})/(\tcbgvo{max}-\tcbgvo{min})},1);
\fi
}},
max/.initial=100, min/.initial=0,
max neg/.initial=0, min neg/.initial=0,
pos color/.code=\colorlet{@tikz@cellbg@pos}{#1},
neg color/.code=\colorlet{@tikz@cellbg@neg}{#1},
fill pos/.style={fill=@tikz@cellbg@pos}, pos color=green!25,
fill neg/.style={fill=@tikz@cellbg@neg}, neg color=red!50,
number format/.style={fixed zerofill},
add format/.style={/tikz/cellbg/number format/.append style={#1}}
}
\newcommand{\tikzMe}[1]{\tikz[baseline,cellbg/pic/.try]\node[cellbg/node={#1}];}
\newcolumntype{H}[1]{%
@{}>{\tikzcellbgset{#1}\collectcell\tikzMe}c<{\endcollectcell}@{}}
\begin{document}
\begin{tabular}{
| H{} | H{min=2.00,max=105.00}
| H{max neg=-10.00, max=15.00, add format={precision=0}}|}
\hline
10 & 2 & -10 \\
15.49 & 13.82 & -5 \\
100 & 105 & 5 \\
\hline
\end{tabular}
\end{document}
输出
答案2
另一个 sans-TikZ 替代方案:
\documentclass{article}
\usepackage[table]{xcolor}% http://ctan.org/pkg/xcolor
\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\newcommand{\maxnum}{100.00}
\newlength{\maxlen}
\newcommand{\databar}[2][green!25]{%
\settowidth{\maxlen}{\maxnum}%
\addtolength{\maxlen}{\tabcolsep}%
\FPeval\result{round(#2/\maxnum:4)}%
\rlap{\color{green!25}\hspace*{-.5\tabcolsep}\rule[-.05\ht\strutbox]{\result\maxlen}{.95\ht\strutbox}}%
\makebox[\dimexpr\maxlen-\tabcolsep][r]{#2}%
}
\begin{document}
\begin{tabular}{*{3}{|l}|}
\hline
\databar{91.41} & \databar {90.81} & \databar{38.76} \\
\databar{98.75} & \databar {13.82} & \databar{94.62} \\
\databar{57.11} & \databar {51.21} & \databar{42.84} \\
\databar{20.00} & \databar{100.00} & \databar{80.00} \\
\hline
\end{tabular}
\end{document}
您提供用于计算百分比填充的最大数字(作为宏\maxnum
)。计算使用fp
。
使用这种变体\databar
可以填充.5\arrayrulewidth
表格单元格两侧的(几乎不可见的)。这只是为了避免由查看器引起的任何类型的伪影。TikZ 解决方案不会显示这一点,因为它在整个表格的背景中(几乎作为底层)绘制彩色框,因此规则会覆盖任何重叠:
%...
\newcommand{\databar}[2][green!25]{%
\settowidth{\maxlen}{\maxnum}%
\addtolength{\maxlen}{\dimexpr2\tabcolsep-\arrayrulewidth}%
\FPeval\result{round(#2/\maxnum:4)}%
\rlap{\color{green!25}\hspace*{\dimexpr-\tabcolsep+.5\arrayrulewidth}\rule[-.05\ht\strutbox]{\result\maxlen}{.95\ht\strutbox}}%
\makebox[\dimexpr\maxlen-2\tabcolsep+\arrayrulewidth][r]{#2}%
}
%...
答案3
{NiceTabular}
的一个解决方案nicematrix
。
\documentclass{article}
\usepackage{nicematrix,tikz}
\usetikzlibrary{calc}
\usepackage{collcell}
\begin{document}
\newcolumntype{B}{>{\collectcell\BarValue}c<{\endcollectcell}}
\ExplSyntaxOn
\NewDocumentCommand{\BarValue}{m}
{
#1
\tl_gput_right:Nx \g_nicematrix_code_before_tl
{
\__pantigny_bar_value:nnn
{ \int_use:c { c@iRow } }
{ \int_use:c { c@jCol } }
{ \fp_eval:n { #1 / 100 } }
}
}
\cs_new_protected:Nn \__pantigny_bar_value:nnn
{
\tikz \fill [blue!15]
(#1-|#2)
rectangle
( $ ( \int_eval:n { #1 + 1 } -| #2 )
! #3 !
( \int_eval:n { #1 + 1 } -| \int_eval:n { #2 + 1 } ) $ )
;
}
\ExplSyntaxOff
\begin{NiceTabular}{BBB}[hvlines,first-col]
A & 40.89 & 80.5 & 38.76 \\
B & 90.89 & 70 & 15.76 \\
C & 57.11 & 21.21 & 92.84
\end{NiceTabular}
\end{document}
您需要多次编译(因为nicematrix
在后台使用 PGF/Tikz 节点)。
答案4
我利用 TikZ 的功能来实现这一点:简单而灵活!
\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\newcommand\tab[2]{%
\begin{scope}[shift={(-.5,.5)}]
\fill[green!20] #1 rectangle +(#2/100,-1);
\draw #1 rectangle +(1,-1);
\end{scope}
\path #1 node{#2};
}% end of tab
\begin{tikzpicture}[yscale=.5,xscale=1.2]
\tab{(0,0)}{40.89} \tab{(1,0)}{80.5} \tab{(2,0)}{38.76}
\tab{(0,-1)}{90.89} \tab{(1,-1)}{70} \tab{(2,-1)}{15.76}
\tab{(0,-2)}{57.11} \tab{(1,-2)}{21.21} \tab{(2,-2)}{92.84}
\end{tikzpicture}
\end{document}