下面的例子将从数组中绘制矩阵,但我希望在其上绘制网格,就像任何列表文本(长或短)的表格一样!
\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,positioning,calc}
\usepackage{etoolbox}
\newcommand{\JLST}{%
{0,1,2},
{a,b,c},
{f,juice,white rice}%
}
\newcommand{\TBL}[3][M] {%[#1]{name}{list}
\let\desc\empty
\foreach \col in #3 {%
\foreach \row [count=\nc] in \col {
\ifnum\nc > 1%
\expandafter\gappto\expandafter\desc\expandafter{\&}
\fi%
\expandafter\gappto\expandafter\desc\expandafter{\row}%
}%
\xappto\desc{\\}%
}%
\matrix [#1,
nodes={minimum size=1em,outer sep=0pt,inner sep=1pt},
append after command={
\pgfextra{
\draw ($(\tikzlastnode.north west)$) rectangle ($(\tikzlastnode.south east)$);
}
},
nodes in empty cells,
column sep=-0.5pt, row sep=-0.5pt,
matrix of nodes,ampersand replacement=\&] (#2) {
\desc
};
}
\begin{document}
\tiny\begin{tikzpicture}
\TBL[]{M}{\JLST}
\end{tikzpicture}
\end{document}
输出:
答案1
这可以通过 来实现eqparbox
,它允许我们确保每列中的节点具有相同的宽度,即给定列的最大宽度。所有这些都可以设置为样式。center align per column
(您还可以使用左对齐或右对齐,分别模仿列类型l
和r
。)
\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,positioning,calc}
\usepackage{etoolbox}
\usepackage{eqparbox}
\newbox\matrixcellbox
\tikzset{center align per column/.style={nodes={execute at begin
node={\setbox\matrixcellbox=\hbox\bgroup},
execute at end
node={\egroup\eqmakebox[\tikzmatrixname\the\pgfmatrixcurrentcolumn][c]{\copy\matrixcellbox}}}},
}
\newcommand{\JLST}{%
{0,1,2},
{a,b,c},
{f,juice,white rice}%
}
\newcommand{\TBL}[3][M] {%[#1]{name}{list}
\let\desc\empty
\foreach \col in #3 {%
\foreach \row [count=\nc] in \col {
\ifnum\nc > 1%
\expandafter\gappto\expandafter\desc\expandafter{\&}
\fi%
\expandafter\gappto\expandafter\desc\expandafter{\row}%
}%
\xappto\desc{\\}%
}%
\matrix [#1,
nodes={minimum size=1em,outer sep=0pt,inner sep=1pt},
draw,thick,inner sep=0pt,
% append after command={
% % \pgfextra{
% % \draw ($(\tikzlastnode.north west)$) rectangle ($(\tikzlastnode.south east)$);
% % }
% }, % replaced this by draw
nodes in empty cells,
nodes={draw,thin,anchor=center,inner sep=2pt,
text depth={depth("g")},text height={height("H")}}, %<-added
center align per column,% <-added
column sep=-0.4pt, row sep=-0.4pt, % <-changed
matrix of nodes,ampersand replacement=\&] (#2) {
\desc
};
}
\begin{document}
\tiny\begin{tikzpicture}
\TBL[]{M}{\JLST}
\end{tikzpicture}
\end{document}
或者,你可以使用来自这里. 那么你只需要添加matrix dividers,matrix frame=thick,
。
\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,positioning,calc,fit}
\makeatletter
\long\def\ifnodedefined#1#2#3{% https://tex.stackexchange.com/a/85531
\@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}
\tikzset{matrix vlines/.style={execute at end matrix={
\foreach \XX in {1,...,\the\pgf@matrix@numberofcolumns}
{\xdef\FitList{}
\foreach \YY in {1,...,\the\pgfmatrixcurrentrow}
{\ifnodedefined{\tikzmatrixname-\YY-\XX}{\xdef\FitList{\FitList (\tikzmatrixname-\YY-\XX)}}{}
}
\node[fit=\FitList,draw=none,fill=none,inner sep=0pt,draw=none] (\tikzmatrixname-col-\XX) {};
}
\foreach \XX in {2,...,\the\pgf@matrix@numberofcolumns}
{\draw[#1] ($(\tikzmatrixname-col-\XX.west)!0.5!(\tikzmatrixname-col-\the\numexpr\XX-1\relax.east)$)
coordinate (aux) (aux|-\tikzmatrixname.north)
-- (aux|-\tikzmatrixname.south);
}
}},matrix hlines/.style={execute at end matrix={
\foreach \YY in {1,...,\the\pgfmatrixcurrentrow}
{\xdef\FitList{}
\foreach \XX in {1,...,\the\pgf@matrix@numberofcolumns}
{\ifnodedefined{\tikzmatrixname-\YY-\XX}{\xdef\FitList{\FitList (\tikzmatrixname-\YY-\XX)}}{}
}
\node[fit=\FitList,draw=none,fill=none,inner sep=0pt,draw=none] (\tikzmatrixname-row-\YY) {};
}
\foreach \XX in {2,...,\the\pgfmatrixcurrentrow}
{\draw[#1] ($(\tikzmatrixname-row-\XX)!0.5!(\tikzmatrixname-row-\the\numexpr\XX-1\relax)$)
coordinate (aux) (aux-|\tikzmatrixname.west)
-- (aux-|\tikzmatrixname.east);
}
}},
matrix dividers/.style={matrix vlines=#1,matrix hlines=#1},
matrix frame/.style={execute at end matrix={
\draw[#1] (\tikz@[email protected] west) rectangle (\tikz@[email protected] east);
}}}
\makeatother
\usepackage{etoolbox}
\newcommand{\JLST}{%
{0,1,2},
{a,b,c},
{f,juice,white rice}%
}
\newcommand{\TBL}[3][M] {%[#1]{name}{list}
\let\desc\empty
\foreach \col in #3 {%
\foreach \row [count=\nc] in \col {
\ifnum\nc > 1%
\expandafter\gappto\expandafter\desc\expandafter{\&}
\fi%
\expandafter\gappto\expandafter\desc\expandafter{\row}%
}%
\xappto\desc{\\}%
}%
\matrix [#1,
nodes={minimum size=1em,outer sep=0pt,inner sep=1pt},
matrix dividers,matrix frame=thick,
nodes in empty cells,
column sep=-0.5pt, row sep=-0.5pt,
matrix of nodes,ampersand replacement=\&] (#2) {
\desc
};
}
\begin{document}
\tiny\begin{tikzpicture}
\TBL[]{M}{\JLST}
\end{tikzpicture}
\end{document}
您可能需要调整inner sep
以0pt
获得
附录(根据要求):这定义了附加样式left align per column
和right align per column
。(只需要更改中的对齐方式\eqmakebox
。)
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\usepackage{eqparbox}
\newbox\matrixcellbox
\tikzset{center align per column/.style={nodes={execute at begin
node={\setbox\matrixcellbox=\hbox\bgroup},
execute at end
node={\egroup\eqmakebox[\tikzmatrixname\the\pgfmatrixcurrentcolumn][c]{\copy\matrixcellbox}}}},
left align per column/.style={nodes={execute at begin
node={\setbox\matrixcellbox=\hbox\bgroup},
execute at end
node={\egroup\eqmakebox[\tikzmatrixname\the\pgfmatrixcurrentcolumn][l]{\copy\matrixcellbox}}}},
right align per column/.style={nodes={execute at begin
node={\setbox\matrixcellbox=\hbox\bgroup},
execute at end
node={\egroup\eqmakebox[\tikzmatrixname\the\pgfmatrixcurrentcolumn][r]{\copy\matrixcellbox}}}},
}
\begin{document}
\tiny\begin{tikzpicture}
\matrix [draw,line width=1pt,inner sep=0pt,nodes in empty cells,
nodes={
draw,thin,anchor=center,inner sep=2pt,
text depth={depth("g")},text height={height("H")},
},
column 1/.style={right align per column},
column 2/.style={center align per column},
column 3/.style={left align per column},
column sep=-0.4pt, row sep=-0.4pt,
matrix of nodes] (M) {
1 & 2 & 3 \\
aaaaa & bbbb & cccccc \\
};
\end{tikzpicture}
\end{document}
或者
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\usepackage{eqparbox}
\newbox\matrixcellbox
\tikzset{column align/.style args={#1/#2}{column #1/.style={nodes={execute at begin
node={\setbox\matrixcellbox=\hbox\bgroup},
execute at end node={%
\egroup\eqmakebox[\tikzmatrixname\the\pgfmatrixcurrentcolumn][#2]{\copy\matrixcellbox}}}}
}}
\begin{document}
\tiny\begin{tikzpicture}
\matrix [draw,line width=1pt,inner sep=0pt,nodes in empty cells,
nodes={
draw,thin,anchor=center,inner sep=2pt,
text depth={depth("g")},text height={height("H")},
},
column align/.list={1/r,2/c,3/l},
column sep=-0.4pt, row sep=-0.4pt,
matrix of nodes] (M) {
1 & 2 & 3 \\
aaaaa & bbbb & cccccc \\
};
\end{tikzpicture}
\end{document}
但是请注意,类似\multicolumn
and/or的东西\multirow
更难实现(据我所知)。
答案2
我更喜欢简单的矩阵并删除不必要的库,更容易理解:
\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usepackage{eqparbox}
\newbox\matrixcellbox
\tikzset{center align per column/.style={nodes={execute at begin
node={\setbox\matrixcellbox=\hbox\bgroup},
execute at end
node={\egroup\eqmakebox[\tikzmatrixname\the\pgfmatrixcurrentcolumn][c]{\copy\matrixcellbox}}}},
}
\begin{document}
\tiny\begin{tikzpicture}
\matrix [draw,line width=1pt,inner sep=0pt,nodes in empty cells,
nodes={
draw,thin,anchor=center,inner sep=2pt,
text depth={depth("g")},text height={height("H")},
},
center align per column,
column sep=-0.4pt, row sep=-0.4pt,
matrix of nodes] (M) {
1 & 2 & 3 \\
a & b & cccccc \\
};
\end{tikzpicture}
\end{document}