我使用以下代码绘制了特征图,但是我不希望所有子节点都是具体的,正如此代码所示。特别是,我需要指定一些子节点为抽象的
我该怎么做?此外,我如何制作分离分支(未填充角度)(因为在我的情况下并非所有子节点都是替代节点)?
我采用了代码形式这个帖子
\documentclass[border=10pt,tikz,multi]{standalone}
\usetikzlibrary{angles,shadows.blur,positioning,backgrounds}
\usepackage{forest}
\forestset{
declare count register=disjuncts from,
disjuncts from'=0,
declare count register=concrete from,
concrete from'=2,
concrete colour/.code={\colorlet{concretecol}{#1}},
abstract colour/.code={\colorlet{abstractcol}{#1}},
draw colour/.code={\colorlet{drawcol}{#1}},
concrete colour=gray,
abstract colour=white,
draw colour=black,
/tikz/mandatory/.style={circle, fill=drawcol, draw=drawcol},
/tikz/optional/.style={circle, draw=drawcol, fill=white},
/tikz/concrete/.style={fill=concretecol, draw=drawcol},
/tikz/abstract/.style={fill=abstractcol, draw=drawcol},
/tikz/or/.style={},
mandatory/.style={edge label={node [mandatory] {}}},
optional/.style={edge label={node [optional] {}}},
or/.style={for first={disjunct}},
disjunct/.style={
tikz+={\path (.parent) coordinate (A) -- (!u.children) coordinate (B) -- (!ul.parent) coordinate (C) pic [fill=drawcol] {angle};}
},
disjunction tree/.style={
where={isodd(n_children())}{
for n={int((n_children()+1)/2)}{calign with current},
}{
calign=midpoint,
},
before typesetting nodes={
for nodewalk={
filter/.wrap pgfmath arg={{level>=##1}{n_children()>1}}{(disjuncts_from)}
}{
or,
},
where={level()>=(concrete_from)}{
concrete,
}{
abstract,
},
tikz+={
[font=\sffamily]
\node (l) [anchor=north west, xshift=10pt] at (current bounding box.north east) {Legend};
\foreach \i/\j [remember=\i as \k (initially l)] in {mandatory/Mandatory,optional/Optional,or/Or,abstract/Abstract,concrete/Concrete}
{
\node (\i) [below=20pt of \k.north, anchor=north, text centered, \i, minimum width=5pt,] {};
\node (\j) [right=15pt of \i.center -| mandatory.west, anchor=west] {\j};
};
\draw [drawcol] (or.south west) coordinate (A) -- (or.north) coordinate (B) -- (or.south east) coordinate (C) pic [fill=drawcol, angle radius=5pt] {angle};
\foreach \i in {mandatory,optional} \draw [darkgray] (\i.north east) -- +(45:5pt);
\node (c) [below=0pt of Concrete.south] {};
\scoped[on background layer]{\node [draw, fill=white, blur shadow, fit=(l) (Mandatory) (Optional) (Or) (Abstract) (Concrete) (c), rounded corners] {};}
},
},
for tree={
parent anchor=children,
child anchor=parent,
l'+=10mm,
blur shadow,
rounded corners,
text height=2ex,
text depth=.5ex,
font=\sffamily,
},
},
}
\begin{document}
\begin{forest}% addaswyd o gôd Salim Bou: https://tex.stackexchange.com/a/335782/
disjunction tree,
disjuncts from'=1,
concrete from'=1,
concrete colour=blue!85!cyan!40,
abstract colour=blue!85!cyan!15,
draw colour=darkgray,
[Emergency Response System
[User interface, mandatory]
[Inform emergency, mandatory
[Inform Earthquake, abstract colour=blue!85!cyan!15]
[Inform flood]
]
[Display neighbourhood, mandatory
[Map
[Display danger zone]
[Display safe zone]
[Display path to safe zone]
]
[Textual direction]
]
[Shortcut calls, optional
[Cops]
[Ambulance]
[Fireman]
]
]
\end{forest}
\end{document}
答案1
我不熟悉forest
,所以只是将其视为一次尝试:
要将子节点标记为抽象,只需
abstract
向该节点添加选项,例如[Display danger zone, abstract]
。相应的代码变化:块
where={level()>=(concrete_from)}{ concrete, }{ abstract, },
从 内部 移到
before typesetting nodes={...}
内部for tree={...}
.现在
or
默认情况下只绘制角度而不填充。您可以使用or={list of <start/end> pairs}
指定填充的(子)角度。例如or={1/l}
表示从第一个子节点到最后一个子节点填充(子)角度,or={1/2, 4/5}
表示分别填充从第 1 个到第 2 个、第 4 个到第 5 个的(子)角度。相应的代码变化:
disjunct
调整了样式的定义。
\documentclass[border=10pt,tikz,multi]{standalone}
\usetikzlibrary{angles,shadows.blur,positioning,backgrounds}
\usepackage{forest}
\forestset{
declare count register=disjuncts from,
disjuncts from'=1,
declare count register=concrete from,
concrete from'=1,
concrete colour/.code={\colorlet{concretecol}{#1}},
abstract colour/.code={\colorlet{abstractcol}{#1}},
draw colour/.code={\colorlet{drawcol}{#1}},
concrete colour=blue!85!cyan!40,
abstract colour=blue!85!cyan!15,
draw colour=darkgray,
/tikz/mandatory/.style={circle, fill=drawcol, draw=drawcol},
/tikz/optional/.style={circle, draw=drawcol, fill=white},
/tikz/concrete/.style={fill=concretecol, draw=drawcol},
/tikz/abstract/.style={fill=abstractcol, draw=drawcol},
/tikz/or/.style={},
mandatory/.style={edge label={node [mandatory] {}}},
optional/.style={edge label={node [optional] {}}},
or/.style={for first={disjunct={#1}}},
disjunct/.style={
tikz+={
\path (.parent) coordinate (A) -- (!u.children) coordinate (B) -- (!ul.parent) coordinate (C) pic {angle};
\foreach \i/\j in {#1} {
\path (!u\i.parent) coordinate (A) -- (!u.children) coordinate (B) -- (!u\j.parent) coordinate (C) pic [fill=drawcol] {angle};
}
}
},
disjunction tree/.style={
where={isodd(n_children())}{
for n={int((n_children()+1)/2)}{calign with current},
}{
calign=midpoint,
},
before typesetting nodes={
for nodewalk={
filter/.wrap pgfmath arg=
{{level>=##1}{n_children()>1}}{(disjuncts_from)}
}{
or
},
% where={level()>=(concrete_from)}{
% concrete,
% }{
% abstract,
% },
tikz+={
[font=\sffamily]
\node (l) [anchor=north west, xshift=10pt] at (current bounding box.north east) {Legend};
\foreach \i/\j [remember=\i as \k (initially l)] in {mandatory/Mandatory,optional/Optional,or/Or,abstract/Abstract,concrete/Concrete}
{
\node (\i) [below=20pt of \k.north, anchor=north, text centered, \i, minimum width=5pt,] {};
\node (\j) [right=15pt of \i.center -| mandatory.west, anchor=west] {\j};
};
\draw [drawcol] (or.south west) coordinate (A) -- (or.north) coordinate (B) -- (or.south east) coordinate (C) pic [fill=drawcol, angle radius=5pt] {angle};
\foreach \i in {mandatory,optional} \draw [darkgray] (\i.north east) -- +(45:5pt);
\node (c) [below=0pt of Concrete.south] {};
\scoped[on background layer]{\node [draw, fill=white, blur shadow, fit=(l) (Mandatory) (Optional) (Or) (Abstract) (Concrete) (c), rounded corners] {};}
},
},
for tree={
parent anchor=children,
child anchor=parent,
l'+=10mm,
blur shadow,
rounded corners,
text height=2ex,
text depth=.5ex,
font=\sffamily,
where={level()>=concrete_from()}{
concrete,
}{
abstract,
},
},
},
}
\begin{document}
\begin{forest}% addaswyd o gôd Salim Bou: https://tex.stackexchange.com/a/335782/
disjunction tree,
[Emergency Response System
[User interface, mandatory]
[Inform emergency, mandatory,for children={abstract}
[Inform Earthquake]
[Inform flood]
]
[Display neighbourhood, mandatory,or={1/l} % 1 (the first) to ell (the last)
[Map,or={2/3}
[Display danger zone,abstract]
[Display safe zone]
[Display path to safe zone]
]
[Textual direction]
]
[Shortcut calls, optional,or={1/2,4/5}
[Cops]
[Ambulance]
[Fireman,abstract]
[Node]
[Node]
]
]
\end{forest}
\end{document}