是否可以让TikZ
矩阵单元跨越多行/列,就像在 LaTeX 表中使用\multirow
或 一样\multicolumn
?具体来说,我想在TikZ
矩阵中排版如下内容:
标题1 长单元格1 长单元格2 header2 单元格A 单元格B 单元格C 单元格D 标题3 XYZW
答案1
一种非常基本的方法是使用该fit
库来创建围绕空矩阵单元的节点。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit,matrix}
\begin{document}
\begin{tikzpicture}
\matrix (table) [%
matrix of nodes,
nodes in empty cells
] {%
A & B & C & D \\
E & & & G \\
H & I & J & \\
K & L & M & \\
};
\node[fit=(table-2-2)(table-2-3)]{F};
\node[fit=(table-3-4)(table-4-4)]{N};
\end{tikzpicture}
\end{document}
但是当你尝试用颜色填充这些单元格时,它首先会变得有点难看。因此你需要进行一些调整。
答案2
这是一种尝试考虑多列条目长度的方法。它并不复杂,因为它所做的只是将所需条目的长度因子分配给每个列(更好的方法是确保总长度至少为多列条目的长度)。它通过连接到和宏来\pgfmatrixendcode
相应\pgfmatrixemptycode
地调整它们的宽度。我们必须有点狡猾,因为这些宏是在实际知道宽度之前执行的,所以它们实际上做的是设置一些东西,以便在知道宽度后调整它们。
代码如下:
\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-\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[matrix of nodes,nodes={draw}] {
A &|[multicol=3]| A long entry spanning three columns &&& A \\
A B &|[multicol=2]| A shorter entry && A & D E F \\
A B & A B & A B C D E F & A B\\
};
\end{tikzpicture}
\end{document}
结果如下:
代码中要注意的一件重要事情是,多行条目后面跟着必要数量的空条目(顺便说一句,这让我认为这可能不会与在每个空节点中放置某些内容的样式很好地交互)。
显然,有很多方法可以改进这一点!而且它只适用于列。
更新 2013-04-12我已收到(通过电子邮件)通知,以下内容修复了单元格内容居中的问题。将定义的开头更改\multi@adjust@position
为:
\gdef\multi@adjust@position{%
\setbox\pgf@matrix@cell=\hbox\bgroup
\hfil\hskip-1.5\multi@col@margin
\hfil\hskip-.5\multi@col@width
答案3
您可以使用矩阵的锚点将多列节点放置在矩阵上。
一种方法是嵌套矩阵,但据我所知 TikZ 尚不支持这种方法。
答案4
一个简单的方法(可能不是在所有情况下都有效)是在超大元素和相邻空行之间设置负列间距。这不是理想的选择,因为您必须手动调整距离。
\documentclass{article}
\usepackage{tikz}\usetikzlibrary{positioning,fit,arrows,backgrounds,shapes}
\begin{document}
\begin{tikzpicture}
\matrix[column sep=1mm,row sep=1mm]{
\node[draw] {header1}; &\node[right,draw] {longcell1};&[-5mm]& \node[right,draw] {longcell2};&[-5mm]\\
\node[draw] {header2}; &\node[right,draw] {cellA}; &\node[right,draw] {cellB}; &\node[right,draw] {cellC}; &\node[right,draw] {cellD};\\
\node[draw] {header3}; &\node[right,draw] {X}; &\node[right,draw] {Y}; &\node[right,draw] {Z}; &\node[right,draw] {W};\\
};
\end{tikzpicture}
\end{document}