如何突出显示 TikZ 树中的某些特定区域?
第一张图片显示了我的树,第二张图片显示了我期望的结果(但圆角灰色矩形应该位于节点和边缘的后面,在背景中,这样整个树仍然可见)。此外,在每个圆角灰色矩形的顶部(但仍在内部)应该可以输入简短的文本/名称。
希望你能帮我!
\documentclass[border=0.1cm]{standalone}
\usepackage[dvipsnames]{xcolor}
\usepackage[utf8x]{inputenc}
\usepackage{tikz}
\usetikzlibrary{trees}
\begin{document}
% Set the overall layout of the tree
\tikzstyle{level 1}=[level distance=5.5cm, sibling distance=3.5cm]
\tikzstyle{level 2}=[level distance=4.5cm, sibling distance=3cm]
\tikzstyle{level 3}=[level distance=4.5cm, sibling distance=4cm]
\tikzstyle{terminal} = [rectangle, rounded corners=0.1cm, fill=BrickRed!40]
\tikzstyle{other} = [rectangle, rounded corners=0.1cm,fill=MidnightBlue!40]
\begin{tikzpicture}[grow=right, sloped]
\node[other] {sf}
child {
node[other] {daeda}
child {
node[other] {aedae}
child {
node[terminal] {Zae}
edge from parent
node[above] {aeae}
}
child {
node[terminal] {ae}
edge from parent
node[above] {a}
node[below] {a}
}
edge from parent
node[above] {}
node[below] {ae}
}
child {
node[terminal] {ad}
edge from parent
node[above] {}
}
child {
node[terminal] {a}
edge from parent
node[above] {}
}
edge from parent
node[above] {}
};
\end{tikzpicture}
\end{document}
答案1
你的意思是:
对于上图,您需要添加另外两个 TikZ 库:backgrounds
和fit
命名节点,您需要突出显示它们:
\documentclass[border=5mm]{standalone}
\usepackage[dvipsnames]{xcolor}
\usepackage[utf8x]{inputenc}
\usepackage{tikz}
\usetikzlibrary{backgrounds,fit,trees}
\begin{document}
\begin{tikzpicture}[grow=right, sloped,
level 1/.style = {level distance=5.5cm, sibling distance=3.5cm},
level 2/.style = {level distance=4.5cm, sibling distance=3cm},
level 3/.style = {level distance=4.5cm, sibling distance=4cm},
%
terminal/.style = {rectangle, rounded corners=0.1cm, fill=BrickRed!40},
other/.style = {rectangle, rounded corners=0.1cm,fill=MidnightBlue!40},
%
highlight/.style = {minimum width=16mm,% fixed width
rounded corners, fill = gray!30,
inner ysep=2mm},
]
\node (sf) [other] {sf}
child {
node (daeda) [other] {daeda}
child {
node (aedae) [other] {aedae}
child {
node (zae) [terminal] {Zae}
edge from parent
node[above] {aeae}
}
child {
node[terminal] {ae}
edge from parent
node[above] {a}
node[below] {a}
}
edge from parent
node[above] {}
node[below] {ae}
}
child {
node[terminal] {ad}
edge from parent
node[above] {}
}
child {
node (a) [terminal] {a}
edge from parent
node[above] {}
}
edge from parent
node[above] {}
};
% highlights
\begin{scope}[on background layer]
\node[highlight,label=above:my label,
fit=(sf) (sf |- a.north) (sf |- zae.south)] {};
\node[highlight,fit=(daeda) (daeda |- a.north) (daeda |- zae.south)] {};
\node[highlight,fit=(aedae) (aedae |- a.north) (aedae |- zae.south)] {};
\node[highlight,fit=(zae) (zae |- a.north)] {};
\end{scope}
\end{tikzpicture}
\end{document}
答案2
这是使用功能强大的包绘制树的方法forest
。这种方法的好处是,一旦定义了样式,就可以非常简洁地指定树本身。
在这种情况下,实际的树仅使用
[sf, my box=box 1
[daeda, my box=box 2
[aedae, my edge label'=ae, my box=box 3
[Zae, my edge label=aeae]
[ae, my double edge labels={a}{a}, my box=box 4]
]
[ad]
[a]
]
]
绘制节点、适当设置样式、添加边缘标签并绘制带有标签的背景框。
这棵树的序言是
for tree={
if n children=0{terminal}{other},
grow=0,
l sep+=30pt,
s sep+=30pt,
},
highlight tree
它表示forest
终端节点应使用terminal
样式,其他节点应使用other
,树应向东生长,级别和兄弟节点之间的距离应增加 30pt。最后一行highlight tree
完成了大部分工作。这将调用一种样式来设置树的整体配置。
特别是,可以在适当的地方使用highlight tree
启用功能在该级别的节点后面绘制一个标记框。my box=<label for box>
此外,my edge label={<edge label above>}
my edge label'={<edge label below>}
还my double edge labels={<edge label above>}{<edge label below>}
可以更轻松地在树的边缘添加标签。
forest
有关将树转换为包使用的括号语法的简要介绍和说明,请参阅我的答案在这里。
完整代码:
\documentclass[tikz,border=10pt,dvipsnames]{standalone}
\usepackage{forest}
\usetikzlibrary{backgrounds,shadows}
\begin{document}
\tikzset{
terminal/.style = {rounded corners=0.1cm, inner color=BrickRed!35, outer color=BrickRed!45, draw=BrickRed, drop shadow},
other/.style = {rounded corners=0.1cm, inner color=MidnightBlue!35, outer color=MidnightBlue!45, draw=MidnightBlue, drop shadow},
auto edge label/.style={midway, anchor=center, sloped},
my box width/.store in=\myboxwidth,
my box width=4em,
highlight tree/.code={
\forestset{
my box/.style={
before drawing tree={
tikz+={
\scoped[on background layer]{
\fill [gray!25, rounded corners, draw=gray!50] () +(-.5*\myboxwidth,0) coordinate (c1) -- (tree top -| c1) -- +(\myboxwidth,0) |- (c1 |- tree bot) -- cycle;
}
\node [anchor=mid] at ([yshift=.5em]tree bot -| ) {##1};
},
},
},
before drawing tree={
tikz={%
\coordinate (tree top) at ([yshift=1em]current bounding box.north);
\coordinate (tree bot) at ([yshift=-2em]current bounding box.south);}
},
}
}
}
\forestset{
my edge label/.style={
edge label={node [auto edge label, above] {#1}},
},
my edge label'/.style={
edge label={node [auto edge label, below] {#1}},
},
my double edge labels/.style n args=2{
edge label={node [auto edge label, above] {#1} node [auto edge label, below] {#2}},
},
highlight tree/.style={/tikz/highlight tree},
}
\begin{forest}
for tree={
if n children=0{terminal}{other},
grow=0,
l sep+=30pt,
s sep+=30pt,
},
highlight tree
[sf, my box=box 1
[daeda, my box=box 2
[aedae, my edge label'=ae, my box=box 3
[Zae, my edge label=aeae]
[ae, my double edge labels={a}{a}, my box=box 4]
]
[ad]
[a]
]
]
\end{forest}
\end{document}