使用 foreach 和 \newcommand 宏在 tikZ 中创建树

使用 foreach 和 \newcommand 宏在 tikZ 中创建树

在下面的两个例子中,我以两种不同的方式使用了相同的代码。为什么 TikZ 在使用宏时会对父节点感到困惑

\department{name dept}{list of subdepts}

代替

child[option]{name dept}
\subdepartment{list of subdepts} 

用于创建分支?

我已经尝试扩展命令但没有成功。

\documentclass[border=2pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{trees, calc}

\begin{document}
\begin{tikzpicture}[
%style every node
every node/.style={
 draw=black
},
%style management node
management/.style={
 anchor=south,
 text centered,
 text width=5cm
},
%style department node
department/.style={
 anchor=north,
 text width=2.5cm
},
%style subdepartment node
subdepartment/.style={
 grow=down,
 anchor=west,
 xshift=-1cm,
 text width=1.75cm,
 edge from parent path={(\tikzparentnode.191) |- (\tikzchildnode.west)}
},
%sibling distances
level 1/.style={sibling distance=3.5cm}
%level distances subdepartment node
%via macro
]

%macros
%level distances subdepartment node
\newcommand{\subdepartmentleveldistance}{0.75cm}

%
\newcommand{\department}[2]{
child{node [department] {#1}
%\subdepartment{#2}
child[subdepartment, level distance=\number * \subdepartmentleveldistance] foreach [count=\number from 1] \name in {#2} {node {\name}}
}
}

%
\newcommand{\subdepartment}[1]{
child[subdepartment, level distance=\number * \subdepartmentleveldistance] foreach [count=\number from 1] \name in {#1} {node {\name}}
}

%=====graphic

%works as intendet
\node[draw] at (0,1.5) {works as intended};
%management
\node[management] at (0,0) {Geschäftsführung}[edge from parent fork down]
%
%department and subdepartment via macro
%
child{node [department] {Einkauf}
\subdepartment{EK I, EK II}
}
%
child{node [department] {Konstruktion}
\subdepartment{KuE I, KuE II}
}
child{node [department] {Produktion}
\subdepartment{P I, P II, P III, P IV}
}
child{node [department] {Vertrieb}
\subdepartment{VK I, VK II}
}
;

%works not as intendet
\node[draw] at (10,1.5) {works not as intended seems to get confused about who the parent node is};
%management
\node[management] at (10,0) {Geschäftsführung}[edge from parent fork down]
%
%department and subdepartment via macro
\department{Einkauf}{EK I, EK II}
%
\department{Konstruktion}{KuE I, KuE II}
%
\department{Produktion}{P I, P II, P III, P IV}
%
\department{Vertrieb}{VK I, VK II}
;

\end{tikzpicture}
\end{document}

答案1

\department我用一种样式替换了你的宏ins dep。不要问我为什么一个不起作用而另一个起作用……我不知道!对不起。

\documentclass[border=7mm]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{trees, calc}

\begin{document}
  \begin{tikzpicture}[
  %style every node
  every node/.style={
   draw=black
  },
  %style management node
  management/.style={
   anchor=south,
   text centered,
   text width=5cm
  },
  %style department node
  department/.style={
   anchor=north,
   text width=2.5cm
  },
  %style subdepartment node
  subdepartment/.style={
   grow=down,
   anchor=west,
   xshift=-1cm,
   text width=1.75cm,
   edge from parent path={(\tikzparentnode.191) |- (\tikzchildnode.west)}
  },
  %sibling distances
  level 1/.style={sibling distance=3.5cm},
  %level distances subdepartment node
  %via macro
  ins dep/.style 2 args={insert path={
        node [department] {Einkauf}
      child[subdepartment, level distance=\number * \subdepartmentleveldistance] foreach [count=\number from 1] \name in {#2} {node {\name}}
    }}
  ]

  %macros
  %level distances subdepartment node
  \newcommand{\subdepartmentleveldistance}{0.75cm}

  %=====graphic

  %works now as intendet
  \node[draw] at (10,1.5) {works now as intendet};
  %management
  \node[management] at (10,0) {Geschäftsführung}[edge from parent fork down]
  %
  %department and subdepartment via macro
  child{[ins dep={Einkauf}{EK I, EK II}]}
  %
  child{[ins dep={Konstruktion}{KuE I, KuE II}]}
  %
  child{[ins dep={Produktion}{P I, P II, P III, P IV}]}
  %
  child{[ins dep={Vertrieb}{VK I, VK II}]}
  ;
  \end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

我不知道你的问题的答案,但是如果你对使用有点类似的解决方案感兴趣forest,这里有一种绘制树的方法,可以让你这样说,例如,

[, dept={some department}{some sub-department, some other sub-deparment, yet another sub-department}]

使用绘制树时使用的标准括号语法来绘制节点。设置有点复杂,但好处是可以简单地指定树。

\documentclass[border=5pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{forest}
\standaloneenv{forest}
\begin{document}
  \forestset{
    sub dept/.style={
      append={
        [#1,
          draw,
          child anchor=west,
          anchor=west,
          edge path={
            \noexpand\path [draw, \forestoption{edge}] (!u.parent anchor)  |- (.child anchor)\forestoption{edge label};
          },
          before computing xy={
            l=10pt,
          },
        ]
      },
    },
    dept/.style n args={2}{
      content/.wrap value={#1},
      append={
        [,
          inner sep=0pt,
          outer sep=0pt,
          child anchor=center,
          parent anchor=center,
          grow'=0,
          sub dept/.list={#2},
        ]
      },
    },
  }
  \begin{forest}
    for tree={
      draw,
      if level=0{
        align=center,
      }{
        align=left,
        if level=1{
          edge path={
            \noexpand\path [draw, \forestoption{edge}] (!u.parent anchor) -- +(0,-15pt) -| (.child anchor)\forestoption{edge label};
          },
        }{
          parent anchor=west,
          child anchor=west,
        },
      },
    }
    [Geschäftsführung
      [, dept={Einkauf}{EK I, EK II}
      ]
      [, dept={Konstruktion}{KuE I, KuE II}
      ]
      [, dept={Produktion}{P I, P II, P III, P IV}
      ]
      [, dept={Vertrieb}{VK I, VK II}
      ]
    ]
  \end{forest}
\end{document}

请注意,我不确定这是否充分利用了forest的功能。我想知道是否有更优雅的解决方案,但至少目前我找不到。

<code>森林</code> 树

相关内容