复杂表格的布局

复杂表格的布局

数学家协会

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{amsmath}
\usepackage{tabularx}
\usepackage{colortbl}
\usepackage{multirow}
\usepackage{ragged2e}

\newcolumntype{C}{>{\Centering\arraybackslash}X}

\renewcommand{\arraystretch}{1.7}

\definecolor{ColHead}{gray}{0.6}
\definecolor{ColDiag}{gray}{0.7}
\definecolor{ColBelow}{gray}{0.9}

\newcommand{\NA}{\cellcolor{ColDiag}}
\newcommand{\B}{\cellcolor{ColBelow}}

\begin{document}

\begin{tabularx}{20em}{|>{\columncolor{ColHead}}C|>\columncolor{ColHead}}C|C|C|C|C|C|C|} \hline
\rowcolor{ColHead} & & \multicolumn{6}{c|}{$\vec{x}$} \\ \hline
\rowcolor{ColHead} & & $\vec{a}$ & $\vec{b}$ & $\vec{c}$ & $\vec{d}$ & $\vec{e}$ & $\vec{f}$ \\ \hline
\multirow{6}{*}{$\vec{y}$}
& $\vec{a}$ & \NA & $-\tfrac{1}{2}$ & & & & \\ \cline{2-8}
& $\vec{b}$ & \B $-2$ & \NA & & & & \\ \cline{2-8}
& $\vec{c}$ & \B & \B & \NA & & & \\ \cline{2-8}
& $\vec{d}$ & \B & \B & \B & \NA & & $-\tfrac{1}{3}$ \\ \cline{2-8}
& $\vec{e}$ & \B & \B & \B & \B & \NA & \\ \cline{2-8}
& $\vec{f}$ & \B & \B & \B & \B $-3$ & \B & \NA \\ \hline
\end{tabularx}

\end{document}

产生以下结果。

MWE 的输出

存在四个问题:

  1. $vec{y}$最左边的多行单元格中不显示。
  2. 似乎有些线(例如图中标记的)太短了。
  3. \multirow我未能成功使用和的组合来合并左上角的四个单元格\multicol
  4. 我希望单元格是正方形。到目前为止,我已经调整了宽度tabularx\arraystretch因子。

在这种情况下,使用tikzpicture而不是环境会更好吗?tabularx

编辑

使用 TikZ 代码

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{amsmath}
\usepackage{tikz}

\definecolor{ColHead}{gray}{0.6}
\definecolor{ColDiag}{gray}{0.7}
\definecolor{ColBelow}{gray}{0.9}

\begin{document}

\begin{tikzpicture}

\fill [fill=ColHead] (0, 0) rectangle (8, -2);
\fill [fill=ColHead] (0, -2) rectangle (2, -8);

\foreach \i in {1, ..., 6}
  \fill [fill=ColDiag] (\i + 1, -1 - \i) rectangle (\i + 2, -2 - \i);

\foreach \i/\j in {2/1, 3/1, 3/2, 4/1, 4/2, 4/3, 5/1, 5/2, 5/3, 5/4, 6/1, 6/2, 6/3, 6/4, 6/5}
  \fill [fill=ColBelow] (\j + 1, -1 - \i) rectangle (\j + 2, -2 - \i);

\draw (0, 0) rectangle (8, -8);
\draw (0, -2) -- (8, -2);
\draw (2, 0) -- (2, -8);
\draw (2, -1) -- (8, -1);
\draw (1, -2) -- (1, -8);

\node (x) at (5, -0.5) {$\vec{x}$};
\node (y) at (0.5, -5) {$\vec{y}$};

\foreach \i in {2, ..., 6}
{
  \draw (1, -1 - \i) -- (8, -1 - \i);
  \draw (1 + \i, -1) -- (1 + \i, -8);
}

\foreach \i/\v in {1/a, 2/b, 3/c, 4/d, 5/e, 6/f}
{
  \node (ch\i) at (\i + 1.5, -1.5) {$\vec{\v}$};
  \node (rw\i) at (1.5, -1.5 - \i) {$\vec{\v}$};
}

\node (12) at (3.5, -2.5) {$-\tfrac{1}{2}$};
\node (21) at (2.5, -3.5) {$-2$};
\node (46) at (7.5, -5.5) {$-\tfrac{1}{3}$};
\node (64) at (5.5, -7.5) {$-3$};

\end{tikzpicture}

\end{document}

我达到了预期的结果。

TikZ 版本

不过 TikZ 的编码似乎不太优雅。与表格版本相比,很难看出源代码想要产生什么结果。

答案1

这是leandriis 的精彩回答单元格以编程方式填充。这是通过样式完成的

colorize cells/.style={/utils/exec={%
   \pgfmathsetmacro{\mycolor}{ifthenelse(\the\pgfmatrixcurrentrow>\the\pgfmatrixcurrentcolumn,
   "gray!20",ifthenelse(\the\pgfmatrixcurrentrow==\the\pgfmatrixcurrentcolumn,
   "gray!50","white"))]}},fill=\mycolor}

它查看当前列和行索引(分别存储在计数\pgfmatrixcurrentcolumn\pgfmatrixcurrentrow中),并根据列索引是大于、小于还是等于行索引来选择填充颜色。

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}

\begin{tikzpicture}[nodes in empty cells,
   colorize cells/.style={/utils/exec={%
   \pgfmathsetmacro{\mycolor}{ifthenelse(\the\pgfmatrixcurrentrow>\the\pgfmatrixcurrentcolumn,
   "gray!20",ifthenelse(\the\pgfmatrixcurrentrow==\the\pgfmatrixcurrentcolumn,
   "gray!50","white"))]}},fill=\mycolor}]
  \matrix(mat)[matrix of nodes,column 1/.style={nodes={fill=gray!50}},
  row 1/.style={nodes={fill=gray!50}},  
  row sep =-\pgflinewidth,column sep = -\pgflinewidth,
  nodes={anchor=center,draw,text height=2ex,text depth=0.25ex,
  minimum width=1cm,colorize cells}] 
  {   
  |[fill=white,draw=none]| & $\vec{a}$ & $\vec{b}$ & $\vec{c}$ & $\vec{d}$ & $\vec{e}$ & $\vec{f}$\\
  $\vec{a}$ &  & $-\tfrac{1}{2}$ & & & &  \\ 
  $\vec{b}$ & $-2$ &  & & & &  \\ 
  $\vec{c}$ & & &  & & &  \\ 
  $\vec{d}$ & & & &  & & $-\tfrac{1}{3}$ \\ 
  $\vec{e}$ & & & & &  & \\ 
  $\vec{f}$ & & & & $-3$ & &  \\ 
  };
  \draw[fill=gray!50] ([yshift=-\pgflinewidth]mat-1-2.north west) rectangle ([yshift=4ex]mat-1-7.north
  east) coordinate(TR) node[midway]{$\vec x$};
  \draw[fill=gray!50] ([xshift=\pgflinewidth]mat-2-1.north west) rectangle ([xshift=-1cm]mat-7-1.south
  west) coordinate(BL) node[midway]{$\vec y$};
  \draw[fill=gray!50] ([yshift=-\pgflinewidth,xshift=\pgflinewidth]mat-2-2.north west) rectangle
  (BL|-TR);
\end{tikzpicture}
\end{document}

在此处输入图片描述

一个更容易推广的版本可能是将颜色存储在列表中,然后定义一个函数,该函数根据列和行索引计算列表索引,在这种情况下,可以选择

 colorize cells/.style={
/utils/exec=\pgfmathsetmacro{\mycolor}{{\LstColors}[1-sign(\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn)]},fill=\mycolor}

连同。正如您所说,\edef\LstColors{"gray!50","gray!20","white"}这个也有。minimum height=1cm

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}

\begin{tikzpicture}[nodes in empty cells,
   colorize cells/.style={
    /utils/exec=\pgfmathsetmacro{\mycolor}{{\LstColors}[1-sign(\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn)]},
   fill=\mycolor}]
  \edef\LstColors{"gray!50","gray!20","white"} 
  \matrix(mat)[matrix of nodes,column 1/.style={nodes={fill=gray!50}},
  row 1/.style={nodes={fill=gray!50}},  
  row sep =-\pgflinewidth,column sep = -\pgflinewidth,
  nodes={anchor=center,draw,minimum height=1cm,%text height=2ex,text depth=0.25ex,
  minimum width=1cm,colorize cells}] 
  {   
  |[fill=white,draw=none]| & $\vec{a}$ & $\vec{b}$ & $\vec{c}$ & $\vec{d}$ & $\vec{e}$ & $\vec{f}$\\
  $\vec{a}$ &  & $-\tfrac{1}{2}$ & & & &  \\ 
  $\vec{b}$ & $-2$ &  & & & &  \\ 
  $\vec{c}$ & & &  & & &  \\ 
  $\vec{d}$ & & & &  & & $-\tfrac{1}{3}$ \\ 
  $\vec{e}$ & & & & &  & \\ 
  $\vec{f}$ & & & & $-3$ & &  \\ 
  };
  \draw[fill=gray!50] ([yshift=-\pgflinewidth]mat-1-2.north west) rectangle
  ([yshift=1cm]mat-1-7.north east) coordinate(TR) node[midway]{$\vec x$};
  \draw[fill=gray!50] ([xshift=\pgflinewidth]mat-2-1.north west) rectangle ([xshift=-1cm]mat-7-1.south
  west) coordinate(BL) node[midway]{$\vec y$};
  \draw[fill=gray!50] ([yshift=-\pgflinewidth,xshift=\pgflinewidth]mat-2-2.north west) rectangle
  (BL|-TR);
\end{tikzpicture}
\end{document}

在此处输入图片描述

但我们不能就此止步:

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}

\begin{tikzpicture}[nodes in empty cells,
   colorize cells/.style={
    /utils/exec=\pgfmathsetmacro{\mygraylevel}{40-10*\the\pgfmatrixcurrentrow
    +10*\the\pgfmatrixcurrentcolumn},
   fill=gray!\mygraylevel}]
  \matrix(mat)[matrix of nodes,column 1/.style={nodes={fill=gray!50}},
  row 1/.style={nodes={fill=gray!50}},  
  row sep =-\pgflinewidth,column sep = -\pgflinewidth,
  nodes={anchor=center,draw,text height=2ex,text depth=0.25ex,
  minimum width=1cm,colorize cells}] 
  {   
  |[fill=white,draw=none]| & $\vec{a}$ & $\vec{b}$ & $\vec{c}$ & $\vec{d}$ & $\vec{e}$ & $\vec{f}$\\
  $\vec{a}$ &  & $-\tfrac{1}{2}$ & & & &  \\ 
  $\vec{b}$ & $-2$ &  & & & &  \\ 
  $\vec{c}$ & & &  & & &  \\ 
  $\vec{d}$ & & & &  & & $-\tfrac{1}{3}$ \\ 
  $\vec{e}$ & & & & &  & \\ 
  $\vec{f}$ & & & & $-3$ & &  \\ 
  };
  \draw[fill=gray!50] ([yshift=-\pgflinewidth]mat-1-2.north west) rectangle ([yshift=4ex]mat-1-7.north
  east) coordinate(TR) node[midway]{$\vec x$};
  \draw[fill=gray!50] ([xshift=\pgflinewidth]mat-2-1.north west) rectangle ([xshift=-1cm]mat-7-1.south
  west) coordinate(BL) node[midway]{$\vec y$};
  \draw[fill=gray!50] ([yshift=-\pgflinewidth,xshift=\pgflinewidth]mat-2-2.north west) rectangle
  (BL|-TR);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

\documentclass{article}
\usepackage[T1]{fontenc}

\usepackage{amsmath}
\usepackage[table]{xcolor}
\definecolor{ColHead}{gray}{0.6}
\definecolor{ColDiag}{gray}{0.7}
\definecolor{ColBelow}{gray}{0.9}
\newcommand{\NA}{\cellcolor{ColDiag}}
\newcommand{\B}{\cellcolor{ColBelow}}
\usepackage{ragged2e}
\usepackage{multirow, tabularx}
\newcolumntype{C}{>{\Centering}X}

\begin{document}
\begin{tabularx}{20em}{ >{\columncolor{ColHead}}C| 
                        >{\columncolor{ColHead}}C| 
                   *{6}{C<{\rule[-0.75em]{0pt}{2.5em}}|}}
                                            \hline
\rowcolor{ColHead}
\multicolumn{2}{c|}{}
    & \multicolumn{6}{c|}{$\vec{x}$}    \\ \cline{3-8}
\rowcolor{ColHead}
\multicolumn{2}{c|}{}
    & $\vec{a}$ & $\vec{b}$ & $\vec{c}$ & $\vec{d}$ & $\vec{e}$ & $\vec{f}$ \\ \cline{2-8}
& $\vec{a}$ & \NA & $-\tfrac{1}{2}$ & & & & \\ \cline{2-8}
& $\vec{b}$ & \B $-2$ & \NA & & & & \\ \cline{2-8}
& $\vec{c}$ & \B & \B & \NA & & & \\ \cline{2-8}
& $\vec{d}$ & \B & \B & \B & \NA & & $-\tfrac{1}{3}$ \\ \cline{2-8}
& $\vec{e}$ & \B & \B & \B & \B & \NA & \\ \cline{2-8}
\multirow{-12}{*}{$\vec{y}$}
& $\vec{f}$ & \B & \B & \B & \B $-3$ & \B & \NA \\ \hline
\end{tabularx}

\bigskip
slightly better:

\begin{tabularx}{20em}{ C|
>{\columncolor{ColHead}}C|
                   *{6}{C<{\rule[-0.75em]{0pt}{2.5em}}|}}
\multicolumn{2}{c}{}
    & \multicolumn{6}{c}{$\vec{x}$}    \\ \cline{3-8}
\rowcolor{ColHead}
\multicolumn{2}{>{\cellcolor{white}}c|}{}
            & $\vec{a}$
                        & $\vec{b}$
                            & $\vec{c}$
                                & $\vec{d}$
                                    & $\vec{e}$
                                        & $\vec{f}$ \\ \cline{2-8}
& $\vec{a}$ & \NA       & $-\frac{1}{2}$
                            &   &   &   &           \\ \cline{2-8}
& $\vec{b}$ & \B $-2$   &\NA&   &   &   &           \\ \cline{2-8}
& $\vec{c}$ & \B        &\B &\NA&   &   &           \\ \cline{2-8}
& $\vec{d}$ & \B        &\B &\B &\NA&   & $-\tfrac{1}{3}$ \\ \cline{2-8}
& $\vec{e}$ & \B        &\B &\B &\B &\NA&           \\ \cline{2-8}
\multirow{-12}{*}{$\vec{y}$}
& $\vec{f}$ & \B        &\B &\B &\B $-3$
                                    &\B & \NA       \\ \cline{2-8}
\end{tabularx}
\end{document}

给出

在此处输入图片描述

请注意,multirow单元格被移动到最后一行(其他行的跨行数为负数)。对于精确的正方形,我添加了rule零粗细和 2.5 em 高度(什么是20em/8

但是,如果您将表格绘制为图片,例如使用tikz包,那么您将获得更好的结果。在这种情况下,您将不会遇到彩色单元格中线条可见性的问题(就像您现在遇到的那样)。

答案3

这是一个 tikz 解决方案(很可能仍然需要一些改进):

在此处输入图片描述

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit,matrix}
\usepackage{amsmath}
\usepackage{multirow}
\usepackage{tabulary}
\colorlet{mylightgray}{gray!20}
\colorlet{mygray}{gray!50}

\begin{document}

\begin{tikzpicture}[cell/.style={rectangle,draw=black}, nodes in empty cells]
  \matrix(table)[
  matrix of nodes,
  row sep =-\pgflinewidth,
  column sep = -\pgflinewidth,
  nodes={anchor=center,text height=2ex,text depth=0.25ex},
  column 1/.style = {nodes={cell, minimum width=1cm, fill=white, draw=none}},
  column 2/.style = {nodes={cell, minimum width=1cm, fill=mygray}},
  column 3/.style = {nodes={cell, minimum width=1cm}},
  column 4/.style = {nodes={cell, minimum width=1cm}},
  column 5/.style = {nodes={cell, minimum width=1cm}},
  column 6/.style = {nodes={cell, minimum width=1cm}},
  column 7/.style = {nodes={cell, minimum width=1cm}},
  column 8/.style = {nodes={cell, minimum width=1cm}},
  row 1/.style={nodes={cell, minimum height=1cm, fill=white, draw=none}},
  row 2/.style={nodes={cell, minimum height=1cm, fill=mygray}},
  row 3/.style={nodes={cell, minimum height=1cm}},
  row 4/.style={nodes={cell, minimum height=1cm}},
  row 5/.style={nodes={cell, minimum height=1cm}},
  row 6/.style={nodes={cell, minimum height=1cm}},
  row 7/.style={nodes={cell, minimum height=1cm}},
  row 8/.style={nodes={cell, minimum height=1cm}},
  ] 
  { & & & & & & & & \\
  |[fill=white,draw=none]| & |[fill=white,draw=none]| & $\vec{a}$ & $\vec{b}$ & $\vec{c}$ & $\vec{d}$ & $\vec{e}$ & $\vec{f}$\\
|[draw=none]| & $\vec{a}$ & |[fill=mygray]| & $-\tfrac{1}{2}$ & & & &  \\ 
|[draw=none]| & $\vec{b}$ & |[fill=mylightgray]| $-2$ & |[fill=mygray]| & & & &  \\ 
|[draw=none]| & $\vec{c}$ & |[fill=mylightgray]| & |[fill=mylightgray]| & |[fill=mygray]| & & &  \\ 
|[draw=none]| & $\vec{d}$ & |[fill=mylightgray]| & |[fill=mylightgray]| & |[fill=mylightgray]| & |[fill=mygray]| & & $-\tfrac{1}{3}$ \\ 
|[draw=none]| & $\vec{e}$ & |[fill=mylightgray]| & |[fill=mylightgray]| & |[fill=mylightgray]| & |[fill=mylightgray]| & |[fill=mygray]| & \\ 
|[draw=none]| & $\vec{f}$ & |[fill=mylightgray]| & |[fill=mylightgray]| & |[fill=mylightgray]| & |[fill=mylightgray]| $-3$ & |[fill=mylightgray]| & |[fill=mygray]| \\ 
  };
  \node[fit=(table-1-5)(table-1-6)]{$\vec{x}$};
  \node[fit=(table-5-1)(table-6-1)]{$\vec{y}$};
\end{tikzpicture}

\end{document}

相关内容