考虑 Gonzalo Medina 对问题的回答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
通常更有意义。)
我还做了一些其他微小的修改,您可能会(或可能不会)感兴趣。特别是,我改变了锚点,使它们不再依赖于方向。因此,您可以改变生长方向,而锚点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}