![封装森林:分叉边和分叉边的使用](https://linux22.com/image/342355/%E5%B0%81%E8%A3%85%E6%A3%AE%E6%9E%97%EF%BC%9A%E5%88%86%E5%8F%89%E8%BE%B9%E5%92%8C%E5%88%86%E5%8F%89%E8%BE%B9%E7%9A%84%E4%BD%BF%E7%94%A8.png)
在我回答问题时改善樹形圖表我错误地使用forked edges
:
\documentclass[border=3mm]{standalone}
\usepackage[edges]{forest}
\begin{document}
\begin{forest}
for tree={
font=\footnotesize,
draw, semithick, rounded corners,
align = center,
inner sep = 3mm,
edge = {draw, semithick, -stealth},
grow = east,
forked edges, % <-- wrong, it should not be inside scope of "for tree"
l sep = 12mm% level distance
}
[Multimedia\\ RSs
[Multimedia\\ Content]
[Multimedia\\ Content]
]
\end{forest}
\end{document}
这使:
但是,用正确的forked edge
代替,forked edges
结果却是不可接受的:
如果我添加for tree
选项,它将被更正为第一个:
父锚点 = 东,子锚点 = 西,
或者如果我forked edges
在树外使用,例如:
...
\begin{forest}
forked edges,
for tree={
font=\footnotesize,
draw, semithick, rounded corners,
align = center,
inner sep = 3mm,
edge = {draw, semithick, -stealth},
grow = east,
l sep = 12mm% level distance
}
...
我想知道,为什么forked edge
和forked edges
会给出不同的结果?
还有一个问题:如果定义了边分支点,为什么它不在级别距离的中间,例如l sep=12mm
不管是否定义了父/子锚点?
我阅读了forest
文档,但没有发现任何可用的内容(也许我需要一遍又一遍地阅读它......并且还要查看代码)。
答案1
forked edge
以下是和forked edges
的定义forest-lib-edges.sty
。
\forestset{
declare dimen={fork sep}{0.5em},
forked edge/.style={
edge={rotate/.pgfmath=grow()},
edge path'={(!u.parent anchor) -- ++(\forestoption{fork sep},0) |- (.child anchor)},
},
forked edges/.style={
for tree={parent anchor=children},
for descendants={child anchor=parent,forked edge}
},
}
因此我们看到,这forked edges
不仅适用forked edge
于所有后代,而且还调整了parent anchor
树和child anchor
后代的。
我认为这forked edge
是不正确的。你确实不想要,forked edges
因为那样你就会有
for tree={
for tree={
...
这可能会导致问题。
但是,如果你使用时\forked edge
没有设置父/子锚点,那么 Forest 默认使用其(<node>)
自身和 Ti钾然后 Z 按照通常的方式选择一个边框锚点。但是,分叉路径的初始部分是相对于起点绘制的。起点也是,(<node>)
但这次 Ti钾Z 是相对于测量而不是追踪来自。因此,它不使用节点的边框锚点,而是使用节点的默认锚点(.center
默认情况下)。
因此,尽管路径从适当的边界锚点开始,但其初始段将其带向相对于锚点测量的位置.center
,而不是相对于边界锚点测量的位置。
以下是一个可视化效果:
路径从 开始,这是正确的,但从开始的(a.east)
点是从 测量的。这显示为红色。因此,路径的第一部分是显示为蓝色的部分,当然不是 。路径的其余部分则为绿色。++(.5em,0)
(a)
(a.center)
.5em
我们可以在边缘所处的默认增长方向上看到同样的情况rotate=-90
。
我不明白你的第二个问题。为什么要l sep
影响分支点?我想你是在问为什么你没有得到类似下面的结果。
这可以通过调整来实现fork sep
。
\begin{forest}
forked edges,
for tree={
font=\footnotesize,
draw,
semithick,
rounded corners,
align = center,
inner sep = 3mm,
edge = {semithick, -stealth},
grow = east,
l sep = 12mm,
fork sep=6mm,
}
[Multimedia\\ RSs
[Multimedia\\ Content]
[Multimedia\\ Content]
]
\end{forest}
但还要注意,这l sep
是父节点最近边界点与每个子节点最近边界点之间的最小距离。该距离最终可能是更大比指定的维度大。森林只是阻止它成为任何更小. (当然,除非后来对整棵树或更局部的树进行了改变。)
因此,您无法以这种方式保证中点。要做到这一点,您需要fork sep
稍后进行更改,因为树是打包的,因为我认为您需要在打包该级别节点的子树之前针对每个级别进行更改。(或者您必须在之后重新打包。)但我不确定这一点 - 它可能至少在很多情况下,在整棵树打包后执行此操作就足够了。(当然,您可能希望在计算 x 和 y 值之前执行此操作。)
\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage[edges]{forest}
\begin{document}
\begin{tikzpicture}
\node [draw] (a) at (0,0) {a};
\node [draw] (b) at (1,.25) {b};
\node [draw] (c) at (1,-.25) {c};
\foreach \i in {b,c}
{
\draw [rotate=0] (a) -- ++(.5em,0) |- (\i);
\draw [rotate=0, green] (a) ++(.5em,0) |- (\i);
\draw [rotate=0, blue] (a) -- ++(.5em,0);
}
\draw [red] (a.center) -- ++(.5em,0);
\end{tikzpicture}
\begin{tikzpicture}
\node [draw] (a) at (0,0) {a};
\node [draw] (b) at (-.25,-1) {b};
\node [draw] (c) at (.25,-1) {c};
\foreach \i in {b,c}
{
\draw [rotate=-90] (a) -- ++(.5em,0) |- (\i);
\draw [rotate=-90, green] (a) ++(.5em,0) |- (\i);
\draw [rotate=-90, blue] (a) -- ++(.5em,0);
}
\draw [rotate=-90, red] (a.center) -- ++(.5em,0);
\end{tikzpicture}
\begin{forest}
forked edges,
for tree={
font=\footnotesize,
draw,
semithick,
rounded corners,
align = center,
inner sep = 3mm,
edge = {semithick, -stealth},
grow = east,
l sep = 12mm,
fork sep=6mm,
}
[Multimedia\\ RSs
[Multimedia\\ Content]
[Multimedia\\ Content]
]
\end{forest}
\end{document}