Рассмотрим ответ Гонсало Медины на вопросдеревья решений в TikZ. Для моего учебного процесса я немного изменил его:
\documentclass[tikz,multi,border=5pt]{standalone}
\usepackage{forest}
\tikzset{
EL/.style={%Edge Labels
midway,
#1,% <--- position: "EL=above" or "EL=below"
font=\scriptsize\sffamily,
text=teal,
text width=1.5cm,
align=center,
}
}
\begin{document}
%%%% modified version
\begin{forest}
for tree={
grow=east,
draw=teal,
circle,
line width=0.4pt,
parent anchor=east,
child anchor=west,
edge={draw=teal,very thin},
% edge label={\Huge\color{black}}, % <-- this seems to haven't any influence on tree
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) --
([xshift=-17mm].child anchor) -- % intermediate point
(.child anchor)\forestoption{edge label};
},
l sep=19mm, % <-- *l*: level distance
}
[,rectangle,
s sep=8mm, % <-- *s*: sibling distance
[,edge label={node[EL=below]{option1}}
[,edge label={node[EL=below]{a longer text goes here}}
]
[,edge label={node[EL=above]{text}}
]
]
[B,edge label={node[EL=above]{option2}}
[,edge label={node[EL=below]{a longer text goes here}}
]
[,edge label={node[EL=above]{text}}
]
]
]
\end{forest}
\end{document}
Почему дерево решений становится асимметричным относительно горизонтальной линии симметрии через узлы, если я добавляю некоторые тесты в узлы? Например, в узле B верхние ветви следующего уровня имеют меньшее расстояние от центральной горизонтальной линии через узел, чем нижние. Я проверил это с помощью леса 2.0.
решение1
Это решение. Документация довольно обманчива, поскольку не соответствует действительности, что значение имеет anchor
значение только тогда, когда у узла есть родственный узел.
[Однако, это не говорит о том, что утверждал мой предыдущий вариант ответа. Так что если вы это прочитали, значит, я был идиотом, и вам следует это проигнорировать.]
Значение по умолчанию — calign
это center
, которое выравнивает родительский элемент anchor
по средней точке между дочерними элементами anchor
. А значение по умолчанию — anchor
это base
.
Вот фотография:
Поэтому для нужного нам выравнивания необходимо либо изменить anchor
родительский и дочерний элементы, либо использовать нестандартное значение для calign
.
В первом случае мы могли бы сделать что-то вроде этого, задав anchor=center
для дерева:
или anchor=parent
(т.е. west
в этом случае):
или anchor=children
(т.е. east
) здесь:
Якорь children
всегда обращен к дочерним элементам узла (или туда, где будут находиться дочерние элементы); parent
обращен к родительскому элементу узла (или туда, где будут находиться родительские элементы).
В качестве альтернативы мы могли бы изменить calign
. Например calign=edge midpoint
. Однако это работает не совсем так, как я ожидал:
Я не могу точно определить, где в этом случае находятся дочерние якоря детей, но, похоже, они находятся там, куда TikZ мог бы пойти относительно того, откуда или куда вы направляетесь.
Но даже настройка parent anchor=east
и child anchor=west
для дерева не особо помогает:
Поэтому я бы изменил anchor
для дерева, как я делаю ниже, независимо от того, что еще кажется желательным. Кажется, это дает хорошие результаты в данном случае.
(Однако для некруглых узлов center
часто имеет смысл что-то другое, а не does.)
Я также сделал несколько других небольших изменений, которые могут быть вам интересны (или нет). В частности, я изменил якоря так, чтобы они не зависели от направления. Так что вы можете изменить направление роста, а якоря и должны parent
по child
-прежнему иметь смысл. Я также заставил пакет выяснить, должны ли этикетки по краям располагаться выше или ниже линий.
Но только
anchor=children,% work around alignment issue
действительно имеет какое-либо значение для результата.
\documentclass[tikz,multi,border=5pt]{standalone}
\usepackage{forest}
\begin{document}
% Zarko's modification of Gonzalo Medina's answer: http://tex.stackexchange.com/a/177254/
\tikzset{%
EL/.style={%
midway,
#1,
font=\scriptsize\sffamily,
text=teal,
text width=1.5cm,
align=center,
}
}
\begin{forest}
for tree={
draw=teal,
line width=0.4pt,
edge={draw=teal,very thin},
grow=east,
circle,
parent anchor=children,
child anchor=parent,
edge path'={
(!u.parent anchor) -- ([xshift=-17mm].child anchor) -- (.child anchor)
},
l sep=19mm,
anchor=children,% work around alignment issue
},
before typesetting nodes={%
where n=1{%
edge label/.wrap value={node[EL=below]{#1}}
}{%
edge label/.wrap value={node[EL=above]{#1}}
}
}
[, rectangle, s sep=8mm,
[, edge label={option1}
[, edge label={a longer text goes here}
]
[, edge label={text}
]
]
[B, edge label={option2}
[, edge label={a longer text goes here}
]
[, edge label={text}
]
]
]
\end{forest}
\end{document}
Код для демонстраций:
\documentclass[tikz,multi,border=5pt]{standalone}
\usepackage{forest}
\usetikzlibrary{calc}
\begin{document}
\begin{forest}
for tree={% default calign, anchor
grow=east,
draw
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.base) -- (.base);
\draw [densely dotted, red] (.base) -- ($(!1.base)!1/2!(!l.base)$) edge (!1.base) -- (!l.base);
}
[][]
]
]
\end{forest}
\begin{forest}
for tree={% default calign, anchor=center
grow=east,
draw,
anchor=center
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.center) -- (.center);
\draw [densely dotted, red] (.center) -- ($(!1.center)!1/2!(!l.center)$) edge (!1.center) -- (!l.center);
}
[][]
]
]
\end{forest}
\begin{forest}
for tree={% default calign, anchor=parent
grow=east,
draw,
anchor=parent
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.parent) -- (.parent);
\draw [densely dotted, red] (.parent) -- ($(!1.parent)!1/2!(!l.parent)$) edge (!1.parent) -- (!l.parent);
}
[][]
]
]
\end{forest}
\begin{forest}
for tree={% default calign, anchor=children
grow=east,
draw,
anchor=children
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.children) -- (.children);
\draw [densely dotted, red] (.children) -- ($(!1.children)!1/2!(!l.children)$) edge (!1.children) -- (!l.children);
}
[][]
]
]
\end{forest}
\begin{forest}
for tree={% calign=edge midpoint, default anchor
grow=east,
draw,
calign=edge midpoint,
parent anchor=east,
child anchor=west,
}
[
[B, tikz={%
\draw [densely dotted, blue] (!u.parent anchor) -- (.child anchor);
\draw [densely dotted, red] (.parent anchor) -- ($(!1.child anchor)!1/2!(!l.child anchor)$) edge (!1.child anchor) -- (!l.child anchor);
}
[][]
]
]
\end{forest}
\end{document}