LaTeX 特性图

LaTeX 特性图

我使用以下代码绘制了特征图,但是我不希望所有子节点都是具体的,正如此代码所示。特别是,我需要指定一些子节点为抽象的

我该怎么做?此外,我如何制作分离分支(未填充角度)(因为在我的情况下并非所有子节点都是替代节点)?

我采用了代码形式这个帖子

\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}

在此处输入图片描述

相关内容