![如何自动标记森林节点,并将标签作为前缀添加到节点内容中并仅添加一次?](https://linux22.com/image/477086/%E5%A6%82%E4%BD%95%E8%87%AA%E5%8A%A8%E6%A0%87%E8%AE%B0%E6%A3%AE%E6%9E%97%E8%8A%82%E7%82%B9%EF%BC%8C%E5%B9%B6%E5%B0%86%E6%A0%87%E7%AD%BE%E4%BD%9C%E4%B8%BA%E5%89%8D%E7%BC%80%E6%B7%BB%E5%8A%A0%E5%88%B0%E8%8A%82%E7%82%B9%E5%86%85%E5%AE%B9%E4%B8%AD%E5%B9%B6%E4%BB%85%E6%B7%BB%E5%8A%A0%E4%B8%80%E6%AC%A1%EF%BC%9F.png)
我试图弄清楚如何forest
在图中标记节点,例如这个问题自动。因此,这个想法是:
- 0级:节点内容以 为前缀
O.
,即,如果指定的内容为P0
,则该节点应以 的内容进行排版O. P0
; - 第一级:内容应该以 为前缀,
O.n
其中n
是子节点的编号,例如,如果第一级节点指定为P1
和P3
,则应将其排版为O.1 P1
和O.2 P3
; - 级别 2:内容应该以 为前缀,
O.n.m
其中n
是父级的子级编号,m
是节点的子级编号,例如,如果P1
有子级P2
,则后者应该显示为O.1.1 P2
,如果P3
有子级P4
,则后者应该排版为O.2.1 P4
。
0 级没有问题。我可以使用 来实现content={O. #1}
。我还可以构建相关标签并将其包含在 1 级和 2 级的节点中。但是,我无法弄清楚如何将其添加到每个节点的内容中一次。无论我做什么,我最终都会得到没有前缀、乱码或空前缀或正确前缀的多个副本。
我认为这是我所得到最接近的答案:
\documentclass[tikz, border=5pt]{standalone}
\usepackage{forest}
\usetikzlibrary{arrows.meta}
\begin{document}
\forestset{
tree node/.style = {align=center, inner sep=2pt, rounded corners = 2pt, text centered, font=\sffamily, rectangle, draw=black},
}
\begin{forest}
for tree={
parent anchor=south,
child anchor=north,
tree node,
l sep+=5pt,
edge path={
\noexpand\path [-{Stealth[]}, \forestoption{edge}, thick]
(!u.parent anchor) -- +(0,-5pt) -| (.child anchor)\forestoption{edge label};
},
},
set node label/.style={
content/.wrap 2 pgfmath args={O.##1 ##2}{n()}{content()},
},
set node super label/.style={
content/.wrap 3 pgfmath args={O.##1.##2 ##3}{n("!u")}{n()}{content()},
},
before typesetting nodes={
for tree={
where level=0{
content={O. #1},
}{
where level=1{
set node label,
}{
where level=2{
set node super label,
}{
},
},
},
},
}
[P0
[P1
[P2
]
]
[P3
[P4
]
]
]
;
\end{forest}
\end{document}
这正确地构建了前缀,但它将它们过于频繁地添加到节点中!
我也尝试过将原始内容存储在宏中,然后在的规范中使用它content
。但是,在这种情况下,我完全丢失了原始内容。
答案1
将所有where
s 替换为if
s。
where
定义为where/.style n args={3}{for tree={if={#1}{#2}{#3}}}
,因此它隐式包含一个for tree
循环。