考虑以下模拟所需输出的示例:
\documentclass{article}
\usepackage[edges]{forest}
\begin{document}
\footnotesize\sffamily one~~~~~~~~two~~~~~~~~~~~~~~three~~~~~~~~~~~~~~four
\bigskip
\begin{forest}
forked edges, for tree={grow=0, s sep=0pt, edge=thick, anchor=base west, font=\strut\footnotesize\sffamily}
[aaaa [bbb [eeeeeeeeeeee, tier=x, [fff]]] [ccc [gg, tier=x] [hhh, tier=x]] [ddddddddd [iii, tier=x]]]
\end{forest}
\end{document}
如何使级别标签(“一”、“二”等)成为森林图的真正组成部分?
当然,标签必须自动与树节点自动对齐,即像tier
树节点内的选项一样。
这个问题看起来非常类似
为(水平)tikz 树创建级别标签,但解决方案必须是至少用来forest
制作树。
答案1
我定义了两种新风格:
label tree
告诉 Forest 这棵树应该有标记的级别(如果提供了标签);level label=<label>
将当前级别的标签设置为<label>
。
然后
\begin{forest}
label tree,
...
[aaaa, level label=one [bbb, level label=two [eeeeeeeeeeee [fff, level label=four]]] [ccc [gg, level label=three] [hhh]] [ddddddddd [iii]]]
\end{forest}
生产
完整代码:
\documentclass[border=9pt]{standalone}
\usepackage[edges]{forest}
\forestset{%
label tree/.style={
for tree={tier/.option=level},
level label/.style={
before typesetting nodes={
for nodewalk={current,tempcounta/.option=level,group={root,tree breadth-first},ancestors}{if={>OR={level}{tempcounta}}{before drawing tree={label me=##1}}{}},
}
},
before drawing tree={
tikz+={\coordinate (a) at (current bounding box.north);},
},
},
label me/.style={tikz+={\node [anchor=base west] at (.parent |- a) {#1};}},
}
\begin{document}
\begin{forest}
forked edges,
label tree,
for tree={
grow=0,
s sep'=0pt,
edge+=thick,
anchor=base west,
font=\strut\footnotesize\sffamily,
},
[aaaa, level label=one [bbb, level label=two [eeeeeeeeeeee [fff, level label=four]]] [ccc [gg, level label=three] [hhh]] [ddddddddd [iii]]]
\end{forest}
\end{document}
答案2
这是一些代码的第一个版本,它执行类似操作。它根据级别为每个节点指定一个别名。(这个别名会被覆盖,但这并不重要,只要同一级别的所有节点都具有相同水平坐标的西锚点;对于扩展,可能希望使它们可区分。)这些节点用于指示级别。
\documentclass{article}
\usepackage[edges]{forest}
\newcommand\engnum[1]{\ifcase#1
zero
\or
one
\or
two
\or
three
\or
four
\or
five
\or
six
\or
seven
\or
eight
\or
nine
\fi}
\begin{document}
\begin{forest}
forked edges, for tree={grow=0, s sep=0pt, edge=thick,
anchor=base west, font=\strut\footnotesize\sffamily,
alias/.wrap pgfmath arg={l-#1}{level}}
[aaaa [bbb [eeeeeeeeeeee, tier=x, [fff]]] [ccc [gg, tier=x] [hhh, tier=x]] [ddddddddd [iii, tier=x]]]
\path ([yshift=0.5ex]current bounding box.north) coordinate (N);
% 0.5ex can be changed to increase/decreas the vertical distance between the
% level indicators and the tree
\foreach \X in {0,...,3}
{\node[anchor=south west,font=\strut\footnotesize\sffamily] at
(l-\X.west|-N){\engnum{\the\numexpr\X+1}};}
\end{forest}
\end{document}
有很多方法可以扩展这一点,如果有的话,我会添加哪种方法取决于您的输入。;-)
答案3
薛定谔猫的解决方案cfr
适用于 MWE,但我在更复杂的三元组中遇到了这些方法的问题。
幸运的是,我意识到一种更简单、更明显的方法是用幻影节点作为树的根,这样它的分支就显示为独立的树,例如:
[,phantom [A[B][C]][D[E][F]]]
现在可以使用来对齐两棵树的节点tier
,因为它们实际上只是同一棵树的一部分。
然后,为了制作标题标签,只需 (1) 添加幽灵根 (2) 添加标签作为最后一个分支[,phantom [...] [One[Two[Three[Four]]]]]
,(3) 更改此分支的样式(删除边缘等)和 (4) 最后,如果需要,将节点与对齐tier
:
\documentclass[tikz,border=10pt]{standalone}
\usepackage[edges]{forest}
\begin{document}
\begin{forest}
%
forked edges, % Tree style
for tree={grow=0, s sep=0pt,
edge= thick,
anchor=base west,
font=\strut\footnotesize\sffamily},
%
[,phantom % Paranormal root (BOO!)
%
[aaaa % Real branch
[bbb,tier=b,
[eeeeeeeeeeee, tier=c
[fff, tier=d]]]
[ccc
[gg, tier=c]
[hhh, tier=c]]
[ddddddddd
[iii, tier=c]]]
%
[One,for tree={color=gray,no edge} % Ethereal branch
[Two, tier=b
[Three, tier=c
[Four, tier=d]]]]
%
] % Closing poltergeist
%
\end{forest}
\end{document}