
У меня есть вопрос по поводу 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
? Хотя я и сохранил это здесь, мне кажется, что это странная идея.