封装森林:分叉边和分叉边的使用

封装森林:分叉边和分叉边的使用

在我回答问题时改善樹形圖表我错误地使用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 edgeforked 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>)但这次 TiZ 是相对于测量而不是追踪来自。因此,它不使用节点的边框锚点,而是使用节点的默认锚点(.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}

相关内容