我经常需要在表格中表示层次结构,但我还没有找到一种优雅的方式来做到这一点。我经常对以下主题进行变体,在类别列中使用嵌套空格:
\documentclass{article}
\usepackage{booktabs}
\newcommand{\lvl}{~~~}
\begin{document}
\begin{tabular}{lr}
\toprule
\textbf{Category} & \textbf{\%}\\
\midrule
Animal & 100 \\
\lvl Human & 50 \\
\lvl\lvl Man & 20 \\
\lvl\lvl Woman & 30 \\
\lvl Fox & 30 \\
\lvl\lvl Vixen & 16 \\
\lvl\lvl Dog & 14 \\
\lvl Chicken & 20 \\
\lvl\lvl Cock & 8 \\
\lvl\lvl Hen & 12 \\
\bottomrule
\end{tabular}
\end{document}
我可能会将其与类别之间的中间规则以及不同级别的不同字体等混合使用。但结果有时会非常“混乱”,尤其是在级别很多的情况下。
相反,我尝试添加线条来更优雅地表示层次结构,如下所示用红色勾勒出轮廓(以同样的精神实现类似的效果也足够了):
但我不确定如何在 LaTeX 中以优雅的方式实现这一点。我猜我可以用 TikZ 来装饰表格,但我只知道如何指定手动点(例如,我不确定如何在表格中固定行)。
因此,我正在寻找任何优雅的解决方案来实现上述效果的建议。(理想的答案是避免使用明确的坐标/距离,并且“高度可重用”。)
答案1
您可能对具有 的解决方案感兴趣pst-node
,更准确地说是其psmatrix
环境和一些\rlap
s。此解决方案支持颜色:
\documentclass[12pt, a4paper, pdf, x11names]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{MinionPro}
\usepackage{pst-node}
\begin{document}
\begin{pspicture}
\psset{rowsep=0.5ex, colsep=0.4, angleA=-90, angleB=180,mcol=l, nodesep =1ex, linewidth=0.4pt, linecolor=red, }
\def\pscolhookiv{\psset[pst-node]{mcol =r, colsep = 1cm, href = 1}}
\begin{psmatrix}
[name = Cat]\pnode[-0.5em]{c}\rlap{\textbf{Category}} & & & [name = Pct]\textbf{\%}\pnode[0.5em]{t}\\[0.6ex]
\midrule
[name = A] A\rlap{nimal} & & & 100 \\
& [name = H] \makebox[0.8em][l]{Human} & & 50 \\
& & [name = HM]Man & 20 \\
& & [name = HF] Woman & 30 \\
& [name = F] \makebox[0.8em][l]{Fox} & & 30 \\
& & [name = FF] Vixen & 16 \\
& & [name = FM] Dog & 14 \\
& [name = C] \makebox[0.8em][l]{Chicken} & & 20 \\
& & [name = CM] Cock & 8 \\
\pnode[-0.5em]{d} & &[name = CF] Hen & 12\pnode[0.5em]{u} \\
\end{psmatrix}
\ncangle{A}{H}\ncangle{A}{F}\ncangle{A}{C}
\ncangle{H}{HM}\ncangle{H}{HF}
\ncangle{F}{FM}\ncangle{F}{FF}
\ncangle{C}{CM}\ncangle{C}{CF}
\psset{linecolor = black}
\ncline[offset = -1.4ex]{c}{t}
\psset{linewidth = 0.8pt}
\ncline[offset =2.5ex]{c}{t}
\ncline[offset =-1.25ex]{d}{u}
\end{pspicture}
\end{document}
答案2
感谢 Peter Grill 的建议尝试dirtree
包裹,我找到了这个问题在这里,这促使我尝试了这个解决方案:
\documentclass{article}
\usepackage{dirtree,array}
\usepackage{booktabs}
\begin{document}
\renewcommand{\DTstyle}{\textrm}
% if you need to fiddle with row space
% in the tree
%\setlength{\DTbaselineskip}{20pt}
\begin{tabular}{lrr}
\toprule
\textbf{Category} & \textbf{\% (tree)} & \textbf{\%}\\
\midrule
\DTsetlength{0.2em}{0.7em}{0.2em}{0.4pt}{0pt}
\begin{minipage}{2cm}\dirtree{%
.1 Animal.
.2 Human.
.3 Man.
.3 Woman.
.2 Fox.
.3 Vixen.
.3 Dog.
.2 Chicken.
.3 Cock.
.3 Hen.
}\end{minipage}
&
\DTsetlength{0pt}{0pt}{0pt}{0pt}{0pt}
\begin{minipage}{0.4cm}\dirtree{%
.1 100.
.1 50.
.1 20.
.1 30.
.1 30.
.1 16.
.1 14.
.1 20.
.1 8.
.1 12.
}\end{minipage}
&
\begin{tabular}{r}%
100\\
50\\
20\\
30\\
30\\
16\\
14\\
20\\
8\\
12
\end{tabular}
\\
\bottomrule
\end{tabular}
\end{document}
虽然边缘有些粗糙,但效果还不错。我仍需要弄清楚列与标题的水平对齐方式(例如,如何最好地删除层次结构左侧的空白或导致空白的原因)。
我展示了制作第二列的两个选项:一个使用dirtree
确保相同间距,另一个使用tabular
允许更改列对齐方式(但其垂直对齐方式可能需要摆弄)。
就代码而言,配置层次结构和修改层次深度等非常容易。任何手动维度都是表级的。
最大的缺点是您必须将整列格式化为一个单元格。这在许多情况下可能会有问题,例如涉及多行或您想要添加中间规则等。
因此,尽管这个解决方案绝对可行,但仍然可以考虑与表格更好地集成的替代方案。:)