有没有可以在 TikZ 中绘制状态树结构的库?

有没有可以在 TikZ 中绘制状态树结构的库?

State tree structure (STS)s 是一些特殊的图,属于state charts 家族。

典型STS示例如下:

在此处输入图片描述

分支机构的数量、状态标签和交叉或联合符号可以根据设计师的意图形成任意结构。

也许tikz-trees是一个近似值,但当我检查时,我觉得它总体上无法生成类似图形的东西。

有没有专门用于某些事物的图书馆TikZ?!

答案1

以下是定义 Forest 样式的版本,state tree用于格式化此类型的树。根据示例,假设如下:

  • 孩子们应该均匀分布;
  • 第一个和最后一个子节点应该与父节点等距;
  • 只应为第一个和最后一个孩子绘制边;
  • 节点的内容应该以数学模式排​​版。

如果其中一个或多个假设需要修改,则可能需要修改样式。

这是树的代码,它稍微改编自伊格纳西

\begin{forest}
  state tree,
  [x_0
    [x_1
      [x_{11}
        [x_{111}]
        [\dot{\cup}]
        [x_{112}]
      ]
      [\times]
      [x_{12}
        [x_{121}]
        [\dot{\cup}]
        [x_{122}]
      ]
    ]
    [\dot{\cup}]
    [x_2]
    [\dot{\cup}]
    [x_3
      [x_{31}]
      [\dot{\cup}]
      [x_{32}]
      [\dot{\cup}]
      [x_{33}]
    ]
  ]
\end{forest}

state tree设置样式。其余部分都是自动的,因此不需要等no edge

其结果如下:

状态树

完整代码:

\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
% ateb: addaswyd o ateb Ignasi: https://tex.stackexchange.com/a/351690/
\forestset{%
  state tree/.style={%
    for tree={
      math content,
      parent anchor=children,
      child anchor=parent,
      tier/.option=level,
      calign=center,
    },
    where={>On>{n children}{2}}{
      for nodewalk={
        filter={children}{>On=!On=!&{n}{1}{n'}{1}}
      }{no edge}
    }{},
    before computing xy={
      where={isodd(n_children)}{
        tempdima/.process={OOOw3+d{!n=1.s}{!n'=1.s}{n children}{(##2-##1)/(##3-1)}},
        tempdimb/.option={!n=1.s},
        for children={
          s/.process={RROw3+d{tempdima}{tempdimb}{n}{##2+(##1*(##3-1))}}
        },
      }{},
    },
  },
}
\begin{document}
\begin{forest}
  state tree,
  [x_0
    [x_1
      [x_{11}
        [x_{111}]
        [\dot{\cup}]
        [x_{112}]
      ]
      [\times]
      [x_{12}
        [x_{121}]
        [\dot{\cup}]
        [x_{122}]
      ]
    ]
    [\dot{\cup}]
    [x_2]
    [\dot{\cup}]
    [x_3
      [x_{31}]
      [\dot{\cup}]
      [x_{32}]
      [\dot{\cup}]
      [x_{33}]
    ]
  ]
\end{forest}
\end{document}

答案2

您也可以尝试forest,尽管我不知道如何正确分配一些孩子:

\documentclass [multi=forest, border=2mm]{standalone} 
\usepackage{forest}

\begin{document}
\begin{forest}
for tree={math content}
[x_0
    [x_1 
        [x_{11} 
            [x_{111}] 
            [\dot{\cup}, no edge] 
            [x_{112}]]
        [\times, no edge]
        [x_{12}
            [x_{121}]
            [\dot{\cup}, no edge]
            [x_{122}]]]
    [\dot{\cup}, no edge]
    [x_2, no edge]
    [\dot{\cup}, no edge]
    [x_3
        [x_{31}]
        [\dot{\cup}, no edge]
        [x_{32}, no edge]
        [\dot{\cup}, no edge]
        [x_{33}]]]
\end{forest}

\end{document}

在此处输入图片描述

更新:根据 JLDiaz 的建议,结果看起来更好,虽然仍然不完美,但更好了。

\documentclass [multi=forest, border=2mm]{standalone} 
\usepackage{forest}

\begin{document}
\begin{forest}
for tree={math content}
[x_0
    [x_1 
        [x_{11} 
            [x_{111}] 
            [\dot{\cup}, no edge] 
            [x_{112}]]
        [\null, no edge]  %<-------------
        [\times, no edge]
        [x_{12}
            [x_{121}]
            [\dot{\cup}, no edge]
            [x_{122}]]]
    [\null, no edge]        %<-------------
    [\dot{\cup}, no edge]
    [x_2, no edge]
    [\dot{\cup}, no edge]
    [x_3
        [x_{31}]
        [\dot{\cup}, no edge]
        [x_{32}, no edge]
        [\dot{\cup}, no edge]
        [x_{33}]]]
\end{forest}

\end{document}

在此处输入图片描述

答案3

第一次尝试如下。我不太擅长画树,所以可能有更好的方法。但是,关键点是将节点放置在子节点之间,这个calc库非常适合这个:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\def\rootname{root}
\newcommand{\stnode}[3]{\node at ($(#1)!0.5!(#2)$) { #3 }}
\newcommand{\stnodec}[3]{\node at ($(#1.center)!0.5!(#2.center)$) { #3 }}
\newcommand{\stnoderootc}[3]{\node at ($(\rootname-#1.center)!0.5!(\rootname-#2.center)$) { #3 }}

\begin{document}
    \begin{tikzpicture}
        [
            level 1/.style = {sibling distance = 3cm},
            level 2/.style = {sibling distance = 2cm}
        ]
        \node (root) { $x_0$ }
            child { node { $x_1$ } 
                child { node { $x_3$ } }
                child { node { $x_4$ } }
            }
            child { node { $x_2$ } 
                child { node { $x_5$ } }
                child { node { $x_6$ } }
            }
        ;
        place the annotation nodes between the children
        \stnode{root-1.center}{root-2.center}{$\times$};
        \stnodec{root-1-1}{root-1-2}{$\times$};
        \stnoderootc{2-1}{2-2}{$\times$};
    \end{tikzpicture}
\end{document}

您可以使用以下三个宏之一(\stnode\stnodecC输入)、\stnoderootc(自动根节点、中心))来放置注释节点。必须重新定义根名称以表示根节点的实际名称。为了获得最大的灵活性,只需使用\stnode

参数是#1:第一个节点,#2:第二个节点,#3:节点文本。

结果如下: 结果

显然,各个节点应该具有相同的 y 位置,如果不是这种情况,它仍然可以工作,但看起来很奇怪。

相关内容