Изменить и смешать стили папок в пакете леса при создании деревьев

Изменить и смешать стили папок в пакете леса при создании деревьев

У меня есть вопрос по поводу forestпакета. Я хотел бы изменить следующее дерево, чтобы сэкономить немного вертикального пространства, изменив стиль папки на определенном уровне на чередующийся или растущий в другом направлении. К тому же я не знаю, почему первый уровень не выровнен вертикально.

Бонусный вопрос: Как возможно иметь чередующуюся структуру папок? Например

            A
            |-B
          C-|
or even   E-|-D

Мне бы хотелось иметь что-то вроде этого.

Желаемый результат

Вот мой MWE:

\documentclass[tikz,multi]{standalone}
\usepackage[edges]{forest}
\usetikzlibrary{arrows.meta,shadows}

\begin{document}
    \begin{forest}
      basic/.style = {draw, thin, drop shadow, font=\sffamily},
      my root/.style = {basic, rounded corners=2pt, fill=black!2},
      upper style/.style = {basic, rounded corners=6pt, fill=black!6, text width=10.5em},
      lower style/.style = {basic, rounded corners=0pt,fill=black!10, text width=9em},
      for tree={%
        parent anchor=south,
        child anchor=north,
        edge path={
          \noexpand\path [-{Stealth[]}, \forestoption{edge}, thin]
            (!u.parent anchor) -- +(0,-5pt) -| (.child anchor)\forestoption{edge label};
        },
        /tikz/>=LaTeX,
      },
      where level=0{%
        my root,
        %for 1={%
          for tree={%
            if={level()<3}{%
              upper style,
            }{%
              lower style,
            },
            if={level()<2}{%
              if={isodd(n_children())}{%
                calign=child edge,
                calign primary child/.wrap pgfmath arg={#1}{int((n_children()+1)/2)},
              }{%
                calign=edge midpoint,
              },
            }{%
              folder,
              grow'=0,
            },
          },
      }{},
      [Alphabet
        [First five letters, folder, grow'=0,
          [A, lower style,]
          [B, lower style,]
          [C, lower style,]
          [D, lower style,]
          [E, lower style, text width=12em]
        ]
        [Some header]
        [More letters
          [Two
            [F]
            [G]
          ]
          [Nine
            [H]
            [I]
            [J]
            [K]
            [L]
            [M]
            [N]
            [O]
            [And a longer box, text width=12em]
          ]
          [Some more stuff
            [to fill]
            [this tree]
          ]
        ]
      ]
    \end{forest}
\end{document}

Спасибо за ваше время!

решение1

Стиль folderна самом деле не разработан с учетом изменения направления роста, я не думаю. Следовательно, он требует некоторых ручных корректировок после факта. По крайней мере, я думаю, что самый простой способ — просто переместить соответствующее поддерево до того, как дерево будет нарисовано.

\documentclass[border=10pt]{standalone}
\usepackage[edges]{forest}
\usetikzlibrary{arrows.meta,shadows}
\begin{document}
\begin{forest}
  basic/.style = {draw, thin, drop shadow, font=\sffamily},
  upper style/.style = {basic, rounded corners=6pt, edge+={-Stealth, thin}, fill=black!6, text width=10.5em},
  lower style/.style = {basic, rounded corners=0pt, edge+={-, line width=.4pt}, fill=black!10, text width=9em},
  where level<=2{%
    upper style,
    edge path'={
      (!u.parent anchor) -- +(0,-5pt) -| (.child anchor)
    },
  }{%
    lower style,
  },
  where level<=1{%
    parent anchor=children,
    child anchor=parent,
    if={isodd(n_children())}{%
      calign=child edge,
      calign primary child/.process={
        O+nw+n{n children}{(#1+1)/2}
      },
    }{%
      calign=edge midpoint,
    },
  }{
    folder,
    grow'=0,
  },
  [Alphabet
    [First five letters, folder, grow'=0, for children={lower style},
      before drawing tree={
        tempdima/.option=!r2.max y,
        tempdima-/.option=max y,
        for tree={
          y+/.register=tempdima,
        },
      }
      [A]
      [B]
      [C]
      [D]
      [E, text width=12em]
    ]
    [Some header]
    [More letters
      [Two
        [F]
        [G]
      ]
      [Nine
        [H]
        [I]
        [J]
        [K]
        [L]
        [M]
        [N]
        [O]
        [And a longer box, text width=12em]
      ]
      [Some more stuff
        [to fill]
        [this tree]
      ]
    ]
  ]
\end{forest}
\end{document}

выровненный первый уровень

Дальнейшие желаемые элементы, я думаю, невозможны с Forest без изменения структуры дерева. То есть, вы можете подделать его, но вы не можете поместить некоторые дочерние элементы одним способом, а некоторые — другим, без ручного перемещения одного или другого набора, и в этом случае, вероятно, проще отказаться от Forest и использовать TiкZ — разместить все напрямую.

Если вы готовы изменить структуру дерева (что вы даже можете сделать автоматически, хотя я бы не стал заморачиваться, если только у вас не очень много узлов с таким шаблоном), вы можете использовать узел координат для изменения направления роста, то есть некоторые из дочерних узлов станут внуками своего текущего родителя, и у вас будет координата в качестве их родителя. Затем вам нужно будет вставить еще один набор из трех координат, сделав исходных дочерних узлов правнуками их исходного родителя. Я сомневаюсь, что это стоит дополнительного усложнения кода, но вот пример.

\begin{forest}
  basic/.style = {draw, thin, drop shadow, font=\sffamily},
  upper style/.style = {basic, rounded corners=6pt, edge+={-Stealth, thin}, fill=black!6, text width=10.5em},
  lower style/.style = {basic, rounded corners=0pt, edge+={-, line width=.4pt}, fill=black!10, text width=9em},
  where level<=2{%
    upper style,
    edge path'={
      (!u.parent anchor) -- +(0,-5pt) -| (.child anchor)
    },
  }{%
    lower style,
  },
  where level<=1{%
    parent anchor=children,
    child anchor=parent,
    if={isodd(n_children())}{%
      calign=child edge,
      calign primary child/.process={
        O+nw+n{n children}{(#1+1)/2}
      },
    }{%
      calign=edge midpoint,
    },
  }{
    folder,
    grow'=0,
  },
  [Alphabet
    [First five letters, folder, grow'=0, for children={lower style},
      before drawing tree={
        tempdima/.option=!r2.max y,
        tempdima-/.option=max y,
        for tree={
          y+/.register=tempdima,
        },
      }
      [A]
      [B]
      [C]
      [D]
      [E, text width=12em]
    ]
    [Some header]
    [More letters
      [Two
        [F]
        [G]
      ]
      [Nine
        [H]
        [I]
        [J]
        [K]
        [, coordinate, grow'=-90, for descendants={edge path'={(!u.parent anchor) |- (.child anchor)}}, before packing={calign primary child=2}
          [, coordinate
            [And a longer box, text width=12em]
          ]
          [, coordinate
            [N]
            [O]
          ]
          [, coordinate
            [L]
            [M]
          ]
        ]
      ]
      [Some more stuff
        [to fill]
        [this tree]
      ]
    ]
  ]
\end{forest}

реструктурированное дерево

Кстати, почему вы хотите, чтобы некоторые края были обычной ширины, а некоторые thin? Хотя я и сохранил это здесь, мне кажется, что это странная идея.

Связанный контент