在 TikZ 矩阵中,如何自动为多列加下划线,如下所示(尤其是当一个标题单元格的高度大于其他单元格时):
来自这个问题:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\def\totcvtext{$\begin{array}{c}{{\rm tot}\ {\rm comm}}\\[-.8ex]{\rm vol (words)}\end{array}$}
\makeatletter
\newdimen\multi@col@width
\newdimen\multi@col@margin
\newcount\multi@col@count
\multi@col@width=0pt
\tikzset{
multicol/.code={%
\global\multi@col@count=#1\relax
\global\let\orig@pgfmatrixendcode=\pgfmatrixendcode
\global\let\orig@pgfmatrixemptycode=\pgfmatrixemptycode
\def\pgfmatrixendcode##1{\orig@pgfmatrixendcode%
##1%
\pgfutil@tempdima=\pgf@picmaxx
\global\multi@col@margin=\pgf@picminx
\advance\pgfutil@tempdima by -\pgf@picminx
\divide\pgfutil@tempdima by #1\relax
\global\multi@col@width=\pgfutil@tempdima
\pgf@picmaxx=.5\multi@col@width
\pgf@picminx=-.5\multi@col@width
\global\pgf@picmaxx=\pgf@picmaxx
\global\pgf@picminx=\pgf@picminx
\gdef\multi@adjust@position{%
\setbox\pgf@matrix@cell=\hbox\bgroup
\hfil\hskip-1.5\multi@col@margin
\hfil\hskip-.5\multi@col@width
% \gdef\multi@adjust@position{%
% \setbox\pgf@matrix@cell=\hbox\bgroup
% \hfil\hskip-\multi@col@margin
% \hfil\hskip-.5\multi@col@width
\box\pgf@matrix@cell
\egroup
}%
\gdef\multi@temp{\aftergroup\multi@adjust@position}%
\aftergroup\multi@temp
}
\gdef\pgfmatrixemptycode{%
\orig@pgfmatrixemptycode
\global\advance\multi@col@count by -1\relax
\global\pgf@picmaxx=.5\multi@col@width
\global\pgf@picminx=-.5\multi@col@width
\ifnum\multi@col@count=1\relax
\global\let\pgfmatrixemptycode=\orig@pgfmatrixemptycode
\fi
}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix (mat) [matrix of nodes] {
L2A &|[multicol=2]| L2B && |[multicol=2]| L2C & \\
L3A & L3B & L3C & \totcvtext & L3E \\
10 & 20 & 30 & 40 & 50 \\
};
\draw[thick,black,shorten >=0.5mm,shorten <=0.5mm] (mat-2-2.north west) -- (mat-2-3.north east);
\draw[thick,black,shorten >=0.5mm,shorten <=0.5mm] (mat-2-4.north west) -- (mat-2-5.north east);
\end{tikzpicture}
\end{document}
请注意,包含数字的其他单元格的高度不应改变。
答案1
笔记:
- 您可以将矩阵
i
第 行第 列的单元格引用为,并且j
mat
mat-i-j
- 正如 Ignasi 上面指出的那样,您可以
shorten
稍微调整一下线条,以避免出现连续合并单元格的问题。
结果:
修改后的代码:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\makeatletter
\newdimen\multi@col@width
\newdimen\multi@col@margin
\newcount\multi@col@count
\multi@col@width=0pt
\tikzset{
multicol/.code={%
\global\multi@col@count=#1\relax
\global\let\orig@pgfmatrixendcode=\pgfmatrixendcode
\global\let\orig@pgfmatrixemptycode=\pgfmatrixemptycode
\def\pgfmatrixendcode##1{\orig@pgfmatrixendcode%
##1%
\pgfutil@tempdima=\pgf@picmaxx
\global\multi@col@margin=\pgf@picminx
\advance\pgfutil@tempdima by -\pgf@picminx
\divide\pgfutil@tempdima by #1\relax
\global\multi@col@width=\pgfutil@tempdima
\pgf@picmaxx=.5\multi@col@width
\pgf@picminx=-.5\multi@col@width
\global\pgf@picmaxx=\pgf@picmaxx
\global\pgf@picminx=\pgf@picminx
\gdef\multi@adjust@position{%
\setbox\pgf@matrix@cell=\hbox\bgroup
\hfil\hskip-1.5\multi@col@margin
\hfil\hskip-.5\multi@col@width
% \gdef\multi@adjust@position{%
% \setbox\pgf@matrix@cell=\hbox\bgroup
% \hfil\hskip-\multi@col@margin
% \hfil\hskip-.5\multi@col@width
\box\pgf@matrix@cell
\egroup
}%
\gdef\multi@temp{\aftergroup\multi@adjust@position}%
\aftergroup\multi@temp
}
\gdef\pgfmatrixemptycode{%
\orig@pgfmatrixemptycode
\global\advance\multi@col@count by -1\relax
\global\pgf@picmaxx=.5\multi@col@width
\global\pgf@picminx=-.5\multi@col@width
\ifnum\multi@col@count=1\relax
\global\let\pgfmatrixemptycode=\orig@pgfmatrixemptycode
\fi
}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix (mat) [matrix of nodes] {
L2A &|[multicol=2]| L2B && |[multicol=2]| L2C & \\
L3A & L3B & L3C & L3D & L3E \\
10 & 20 & 30 & 40 & 50 \\
};
\draw[thick,black,shorten >=0.5mm,shorten <=0.5mm] (mat-2-2.north west) -- (mat-2-3.north east);
\draw[thick,black,shorten >=0.5mm,shorten <=0.5mm] (mat-2-4.north west) -- (mat-2-5.north east);
\end{tikzpicture}
\end{document}
更新
OP 指出,当矩阵中的单元格高度不同时,此解决方案效果不佳。问题在于,尽管 TikZ 矩阵中的单元格水平和垂直对齐,但它们并未拉伸成均匀的镶嵌网格。也就是说,一个单元格的西南点不一定与其正下方单元格的西北点重合。下图通过将每个单元格涂成红色来澄清这种情况。
解决此情况的一种方法是手动指定每行的高度。这可以仅使用键为第二行执行row 2/.style={text height=2ex, text depth=1ex}
。结果如下。
完整代码:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\makeatletter
\newdimen\multi@col@width
\newdimen\multi@col@margin
\newcount\multi@col@count
\multi@col@width=0pt
\tikzset{
multicol/.code={%
\global\multi@col@count=#1\relax
\global\let\orig@pgfmatrixendcode=\pgfmatrixendcode
\global\let\orig@pgfmatrixemptycode=\pgfmatrixemptycode
\def\pgfmatrixendcode##1{\orig@pgfmatrixendcode%
##1%
\pgfutil@tempdima=\pgf@picmaxx
\global\multi@col@margin=\pgf@picminx
\advance\pgfutil@tempdima by -\pgf@picminx
\divide\pgfutil@tempdima by #1\relax
\global\multi@col@width=\pgfutil@tempdima
\pgf@picmaxx=.5\multi@col@width
\pgf@picminx=-.5\multi@col@width
\global\pgf@picmaxx=\pgf@picmaxx
\global\pgf@picminx=\pgf@picminx
\gdef\multi@adjust@position{%
\setbox\pgf@matrix@cell=\hbox\bgroup
\hfil\hskip-1.5\multi@col@margin
\hfil\hskip-.5\multi@col@width
% \gdef\multi@adjust@position{%
% \setbox\pgf@matrix@cell=\hbox\bgroup
% \hfil\hskip-\multi@col@margin
% \hfil\hskip-.5\multi@col@width
\box\pgf@matrix@cell
\egroup
}%
\gdef\multi@temp{\aftergroup\multi@adjust@position}%
\aftergroup\multi@temp
}
\gdef\pgfmatrixemptycode{%
\orig@pgfmatrixemptycode
\global\advance\multi@col@count by -1\relax
\global\pgf@picmaxx=.5\multi@col@width
\global\pgf@picminx=-.5\multi@col@width
\ifnum\multi@col@count=1\relax
\global\let\pgfmatrixemptycode=\orig@pgfmatrixemptycode
\fi
}
}
}
\makeatother
\begin{document}
\def\totcvtext{\begin{tabular}{c}tot comm \\[-0.8ex] vol(words)\end{tabular}}
\begin{tikzpicture}
\matrix (mat) [matrix of nodes, nodes={fill=red}, row 2/.style={text height=2ex, text depth=1ex}
] {
L2A &|[multicol=2]| L2B && |[multicol=2]| L2C & \\
L3A & L3B & L3C & \totcvtext & L3E \\
10 & 20 & 30 & 40 & 50 \\
};
\draw[thick,black,shorten >=0.5mm,shorten <=0.5mm] (mat-2-2.north west) -- (mat-2-3.north east);
\draw[thick,black,shorten >=0.5mm,shorten <=0.5mm] (mat-2-4.north west) -- (mat-2-5.north east);
\end{tikzpicture}
\end{document}