森林:局部重新排列“树枝”

森林:局部重新排列“树枝”
  • 这是森林:如何影响边的长度(使树更紧凑)
  • 主要问题是,如何重新排列分支“4.2”以节省垂直空间。理想情况下,将分支“4.2”垂直翻转(欢迎其他想法)。(参见绿色的注解)
  • 一个小的附加问题:我可以在本地(针对特定分支)增加与相邻分支的分离吗?(见红色的注解)

\documentclass{article}
\usepackage[edges]{forest}

\begin{document}

\begin{forest} 
  forked edges,
  l sep = 0, for children = {l*= 0.6},
  for tree = {
    align = center, % needed for "\\" in nodes.
    draw,
    font = \tiny,   
  },
  for descendants={
    grow' = 0,
    folder,
  },
  [0
    [1]
    [\ldots]
    [2
      [2.1]
      [2.2]
      [\ldots]
    ]
    [3
      [3.1]
      [3.2]       
    ]
    [4
      [4.1
        [4.1.1]
        [4.1.2]
        [4.1.3]
        [4.1.4]
        [4.1.5]         
      ]   
      [4.2
        [4.2.1]
        [4.2.2]
        [4.2.3]
        [4.2.4]
        [4.2.5]         
      ]       
    ]
  ]
\end{forest}

\end{document}

在此处输入图片描述

答案1

虽然这不是最漂亮的代码,但是它可以完成工作。

OP 的“绿色”问题可以通过将“4”设为分叉节点来解决。这样做的问题是实际的。第一次尝试可能是说根的所有后代都应该是文件夹节点,然后通过将分叉边缘设置为节点“4”来覆盖它。然而,这行不通,因为folderstyle 做了很多forked edge(s)不会覆盖的事情(事实上,通常很难覆盖)。因此,这个想法是使用一个复杂的 nodewalk,它设置folder为所有节点除了根节点及其第五个子节点(节点“4”)。我尝试通过定义(nodewalk)样式来使其(相对)简单且通用subtract

即使这样,也并非一切都完美无缺。节点“4”既是子节点又是具有分叉边的父节点,必须手动处理。这是因为 OP 将父节点与分叉边的子节点之间的默认距离设置得比默认值 ( l*=0.6) 短一些。这种缩短是有道理的,因为大多数分叉边子节点都是文件夹父节点,但需要针对节点“4”进行调整。

“红色”问题更容易解决。我们手动移动一些“s”坐标(在打包之后,但在计算 xy 之前)。(这在 Forest 的下一个版本中将更容易实现,它将包含用于在各个节点之间设置一些额外 s 空间的新键。)

\documentclass{article}
\usepackage[edges]{forest}

\forestset{
  for nodewalk={
    subtract/.style 2 args={
      save={@exceptions}{#2},
      Nodewalk/.process=__Rw {}{#1}{every step}{if in saved nodewalk={current}{@exceptions}{}{##1}}
    },
  }{},
}

\begin{document}

\begin{forest}
  for tree = {   % this applies to the entire tree
    align = center, % needed for "\\" in nodes.
    draw,
    font = \tiny,   
  },
  my forked nodes/.nodewalk style={current,5}, % for generality, if we decide to have more forked nodes
  for nodewalk={my forked nodes}{  % this applies to the parents of the forked edge nodes
    l sep = 0,
    for children = {
      l*= 0.6,
      forked edge
    },
  },
  for nodewalk={subtract={descendants}{my forked nodes}}{ % all other nodes are folder nodes
  %%% for nodewalk={   % in the absence of "subtract", this would work just as well
  %%%   for nodewalk'={1,descendantas},
  %%%   for nodewalk'={2,descendants},
  %%%   for nodewalk'={3,descendants},
  %%%   for nodewalk'={4,descendants},
  %%%   for nodewalk'={fake=5,descendants},
  %%% }{
    grow' = 0,
    folder,
  },
  % manual correction at the crossroads (node "4") of forked edge and folder ...
  for nodewalk={my forked nodes}{l*=1.47},
  % Increase the horizontal separation before "3" and "4"
  before computing xy={
    for nodewalk={4,next}{
      for current and following siblings={s+=0.5em}
    }
  },
  [0
    [1]
    [\ldots]
    [2
      [2.1]
      [2.2]
      [\ldots]
    ]
    [3
      [3.1]
      [3.2]       
    ]
    [4
      [4.1
        [4.1.1]
        [4.1.2]
        [4.1.3]
        [4.1.4]
        [4.1.5]         
      ]   
      [4.2
        [4.2.1]
        [4.2.2]
        [4.2.3]
        [4.2.4]
        [4.2.5]         
      ]       
    ]
  ]
\end{forest}

\end{document}

编译结果

相关内容