下面的 MWE 是机器生成的组织结构图。除了那些向多个主管汇报的员工外,它几乎可以正常工作。我不得不添加常规的 TikZ 节点并绘制箭头。它们的问题是当多个二级主管与一群垂直排列的员工重叠时。因此,xshift
我暂时无法找到自动化的方法(对于那些拥有粉红色主管的两个人)。自动化绿色主管的放置还算可以,但仍然不是 100% 可靠:它可以与粉红色主管重叠。
我无法将粉色节点设为连接箭头起源的白色节点的子节点,因为我不知道如何强制它们浮动到第二层,因此我在 Forest 生成后将它们添加为常规 TikZ 节点。因此它们不会受益于 Forest 提供的自动放置和压缩。
如果有办法将这些 TikZ 节点转换为森林节点,并告诉它们位于前两层,最好垂直交错,那将是一个理想的解决方案。如果这不可能,那么至少它们应该尝试占据第一层或第二层的所有空间。
那可能吗?
编辑:嗯,再想想,粉色的 2 级 boss 应该浮在第二级,而我可以让任何绿色的 2 级 boss 保持在第一级。这可能是指定要求最一致的方式。
\documentclass[border=10pt]{standalone}
\usepackage{forest}
\begin{document}
\begin{forest}
for tree={
draw=black, align=center, l sep=6ex, parent anchor=south, child anchor=north,
node options={font=\scriptsize, minimum width=14em, minimum height=10ex, rounded corners=1ex},
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) -- +(0,-4ex) -| (.child anchor)\forestoption{edge label};
},
where n children=0{
child anchor=west,
edge path={
\noexpand\path[\forestoption{edge}]
([xshift=-6em]!u.parent anchor) |- (.child anchor)\forestoption{edge label};
},
for parent={
parent anchor=south, l sep=-12em, grow'=east, calign=child edge%, draw=blue
} %,draw=red
}{}, base=b
}
[\textbf{DDDDDDDDDDDD}\\
SSSSSSSSS TTTTTTTTT\\MMMMMMMMMMM
,name=10005073
[\textbf{nnnnnnnnnnnnnnn}\\
dddddddddddddddddddd\\oooooooooooooooooooooooooooooooooooooooooo
,name=10005654
[\textbf{nnnnnnnnnnnn}\\
dddddddddddddddddd\\oooooooooooooooooooooooooooooooooooooooooooooooooo
,name=10005155
[,phantom, minimum height=1ex]
[\textbf{10003570}\\
ddddddddddddddddd\\oooooooooooooooooooooooooooooooooooooooooooooooooo
,name=10003570]
[\textbf{10003862}\\
dddddddddddddddddddddd\\oooooooooooooooooooooooooooooooooooooooooooooooooo
,name=10003862]
[\textbf{nnnnnnnnnnn}\\
ddddddddddddddddddddd\\oooooooooooooooooooooooooooooooooooooooooooooooooo
,name=10005556]
]
[\textbf{nnnnnnnnnn}\\
dddddddddddddd\\ooooooooooooooooooooooooooooooooooooooooooooo
,name=10003454[,phantom]]
[\textbf{nnnnnnnnnn}\\
ddddddddddddddd\\oooooooooooooooooooooooooooooooooooooooooooooooooo
,name=10003770[,phantom]]
[\textbf{nnnnnnnnnnn}\\
ddddddddddddddddd\\oooooooooooooooooooooooooooooooooooooooooooooooooo
,name=10004035[,phantom]]
]]
%
\tikzset{every node/.style={font=\footnotesize, align=center, draw=black!20, minimum width=14em, minimum height=10ex, rounded corners=1ex}}
\node[anchor=south,draw=black,fill=red!25](80000000) at ([xshift=-8em]10003570 |- 0,-4.5ex) {
\textbf{Boss Of 10003570}\\
VVVVVVV\\MMMMMMMMMMM
}[];
\draw[->,dashed,thick,black] (10003570) to (80000000);
\node[anchor=south,draw=black,fill=red!25](80000001) at ([xshift=8em]10003862 |- 0,-4.5ex) {
\textbf{Boss Of 10003862}\\
VVVVVVV\\MMMMMMMMMMM
}[];
\draw[->,dashed,thick,black] (10003862) to (80000001);
%
\end{forest}
\end{document}
答案1
我仍然不确定我是否理解了这个问题。不过,我对此很感兴趣,所以就说到这里。
此解决方案允许您将粉色老板指定为您喜欢的任何节点的子节点。您需要做的就是指定pink boss
相关节点。但是,这种节点的父节点应该是您希望排版为没有子节点的节点之一,因为将粉色老板设置为其子节点将强制执行该样式。终端节点的样式在样式的代码中重复,pink boss
但被推回到父节点。
你还需要知道forest
哪个是真正的、原始的 1 级节点。要与 0 级根进行对齐,你需要传递
before packing={calign with current},
这实际上正在被执行后粉色 Boss 被移动了,但移动过程本身被一些代码延迟了,你必须通过这些代码才能将粉色 Boss 移动到第 1 级:
before typesetting nodes={
repeat=\thepinkbosses{TeX={\stepcounter{countbosses}},insert before=pink boss \thecountbosses},
}
这将调用forest
对动态树的支持(当前手册中的第 3.3.8 节),以及其执行 TeX 代码和运行循环的能力。
至少应该包含一个粉色老板。如果情况并非如此,我认为您需要有条件地运行此代码的部分内容。
树绘制完成后,粉色凸台和其原来的父节点之间的连接会自动绘制。
代码需要两个计数器,用于跟踪粉色老板的数量以及粉色老板与其父母之间的关系。如果粉色老板有多个父母,则需要自己添加与其他父母的连接。如果您在同一文档中排版了多个树,则需要重置树之间的计数器。代码不会改变您的设置。它使用别名和进行父子配对,name
而不是更改这些设置。pink boss n
pink n
n
我以前从未在这段代码中做过几件事。它几乎肯定是脆弱的,肯定是不可靠的,而且可能不正确。你的脚步速度可能会有所不同。
买者自负...
\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
\standaloneenv{forest}
\begin{document}
\newcounter{pinkbosses}
\setcounter{pinkbosses}{0}
\newcounter{countbosses}
\setcounter{countbosses}{0}
\tikzset{
/forest,
pink boss/.style={
for parent={child anchor=north},
edge path={},
fill=red!25,
TeX={\stepcounter{pinkbosses}},
alias=pink boss \thepinkbosses,
for parent={
child anchor=west,
calign=child edge,
alias=pink \thepinkbosses,
edge path={
\noexpand\path[\forestoption{edge}]
([xshift=-6em]!u.parent anchor) |- (.child anchor)\forestoption{edge label};
},
},
},
}
\begin{forest}
for tree={
draw=black,
align=center,
l sep=6ex,
node options={font=\scriptsize, minimum width=14em, minimum height=10ex, rounded corners=1ex},
where n children=0{}{
parent anchor=south,
child anchor=north,
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) -- +(0,-4ex) -| (.child anchor)\forestoption{edge label};
},
},
where level=2{
for descendants={
where n children=0{
child anchor=west,
calign=child edge,
edge path={
\noexpand\path[\forestoption{edge}]
([xshift=-6em]!u.parent anchor) |- (.child anchor)\forestoption{edge label};
},
for parent={
parent anchor=south, l sep=-12em, grow'=east, calign=child edge,
},
}{},
},
}{},
base=b
}
[\textbf{DDDDDDDDDDDD}\\SSSSSSSSS TTTTTTTTT\\MMMMMMMMMMM, name=10005073
[\textbf{DUD}\\thing 2 here\\something here, name=10005654,
before packing={calign with current},
before typesetting nodes={
repeat=\thepinkbosses{TeX={\stepcounter{countbosses}},insert before=pink boss \thecountbosses},
}
[\textbf{thing 1 here}\\thing 2 here\\something here, name=10005155
[,phantom, minimum height=1ex
]
[\textbf{BOB}\\thing 2 here\\something here, name=10003570
[\textbf{BAB}\\VVVVVVV\\MMMMMMMMMMM, pink boss, alias=80000000
]
]
[\textbf{GOG}\\thing 2 here\\something here, name=10003862
[\textbf{GAG}\\VVVVVVV\\MMMMMMMMMMM, name=80000001, pink boss
]
]
[\textbf{BUB}\\thing 2 here\\something here, name=10005556
]
]
[\textbf{thing 1 here}\\thing 2 here\\something here, name=10003454
[,phantom
]
]
[\textbf{thing 1 here}\\thing 2 here\\something here, name=10003770
[,phantom
]
]
[\textbf{thing 1 here}\\thing 2 here\\something here, name=10004035
[,phantom
]
]
]
]
\foreach \i in {1,...,\thepinkbosses}
\draw[<-, dashed, black!30] (pink boss \i) -- (pink \i);
\end{forest}
\end{document}
编辑
这是对动态树进行更多实验的结果。这包括为绿色老板和粉色老板提供准备。在根节点和其主要子节点之间创建了一种“半级”。这包含一个空节点,该节点最终以幻影和绿色老板作为兄弟节点。
此版本中,大部分编码都移至样式设置,因此树本身所需的手动干预更少。现在树本身所需的唯一手动干预如下:
- 根的主子级必须具有样式
important node
; - 粉色的老板要有格调
pink boss
; - 环保老板要有风采
green boss
。
此外,如果需要排版多棵树,则应该在树之间重置所有计数器。
\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
\standaloneenv{forest}
\begin{document}
\newcounter{pinkbosses}
\setcounter{pinkbosses}{0}
\newcounter{countpinkbosses}
\setcounter{countpinkbosses}{0}
\newcounter{greenbosses}
\setcounter{greenbosses}{0}
\newcounter{countgreenbosses}
\setcounter{countgreenbosses}{0}
\tikzset{
/forest,
pink boss/.style={
edge path={},
fill=red!25,
TeX={\stepcounter{pinkbosses}},
alias=pink boss \thepinkbosses,
for parent={
child anchor=west,
calign=child edge,
alias=pink \thepinkbosses,
edge path={
\noexpand\path[\forestoption{edge}]
([xshift=-6em]!u.parent anchor) |- (.child anchor)\forestoption{edge label};
},
},
},
green boss/.style={
edge path={},
fill=green!25,
TeX={\stepcounter{greenbosses}},
alias=green boss \thegreenbosses,
for parent={
alias=green \thegreenbosses,
},
},
important/.style={
parent anchor=center,
child anchor=center,
},
important node/.style={
alias=important node,
before packing={calign with current},
before typesetting nodes={
repeat=\thepinkbosses{TeX={\stepcounter{countpinkbosses}}, insert before=pink boss \thecountpinkbosses},
},
},
}
\begin{forest}
for tree={
draw=black,
align=center,
l sep=6ex,
node options={font=\scriptsize, minimum width=14em, minimum height=10ex, rounded corners=1ex},
where n children=0{}{
parent anchor=south,
child anchor=north,
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) -- +(0,-4ex) -| (.child anchor)\forestoption{edge label};
},
},
where level=0{
l sep=0pt,
append={
[, important, append=important node,
before packing={calign with current},
]
},
append={
[, phantom, xshift=20ex,
]
},
before typesetting nodes={
repeat=\thegreenbosses{TeX={\stepcounter{countgreenbosses}},append=green boss \thecountgreenbosses},
}
}{},
where level=2{
for descendants={
where n children=0{
child anchor=west,
calign=child edge,
edge path={
\noexpand\path[\forestoption{edge}]
([xshift=-6em]!u.parent anchor) |- (.child anchor)\forestoption{edge label};
},
for parent={
parent anchor=south, l sep=-12em, grow'=east, calign=child edge,
},
}{},
},
}{},
base=b
}
[\textbf{DDDDDDDDDDDD}\\SSSSSSSSS TTTTTTTTT\\MMMMMMMMMMM, name=10005073
[\textbf{DUD}\\thing 2 here\\something here, name=10005654, important node
[\textbf{DAD}\\VVVVVVV\\MMMMMMMMMMM, name=80011942, green boss
]
[\textbf{thing 1 here}\\thing 2 here\\something here, name=10005155
[,phantom, minimum height=1ex
]
[\textbf{BOB}\\thing 2 here\\something here, name=10003570
[\textbf{BAB}\\VVVVVVV\\MMMMMMMMMMM, pink boss, alias=80000000
]
]
[\textbf{GOG}\\thing 2 here\\something here, name=10003862
[\textbf{GAG}\\VVVVVVV\\MMMMMMMMMMM, name=80000001, pink boss
]
]
[\textbf{BUB}\\thing 2 here\\something here, name=10005556
]
]
[\textbf{thing 1 here}\\thing 2 here\\something here, name=10003454
[,phantom
]
]
[\textbf{thing 1 here}\\thing 2 here\\something here, name=10003770
[,phantom
]
]
[\textbf{thing 1 here}\\thing 2 here\\something here, name=10004035
[\textbf{POP}\\thing 2 here\\something here, green boss
]
]
]
]
\foreach \i in {1,...,\thepinkbosses}
\draw[<-, dashed, black!30] (pink boss \i) -- (pink \i);
\foreach \i in {1,...,\thegreenbosses}
\draw[<-, dashed, black!30] (green boss \i) -- (green \i);
\end{forest}
\end{document}
又一次编辑
此版本使用幻像根节点。这意味着表观根位于第 1 级,而真实根当然位于第 0 级。因此,表观根可以有一个兄弟,因为真实根是树的实际根:
\documentclass[border=10pt,multi,tikz]{standalone}
\usepackage{forest}
\standaloneenv{forest}
\begin{document}
\newcounter{pinkbosses}
\setcounter{pinkbosses}{0}
\newcounter{countpinkbosses}
\setcounter{countpinkbosses}{0}
\tikzset{
/forest,
pink boss/.style={
edge path={},
fill=red!25,
TeX={\stepcounter{pinkbosses}},
alias=pink boss \thepinkbosses,
for parent={
child anchor=west,
calign=child edge,
alias=pink \thepinkbosses,
edge path={
\noexpand\path[\forestoption{edge}]
([xshift=-6em]!u.parent anchor) |- (.child anchor)\forestoption{edge label};
},
},
},
green boss/.style={
edge path={},
fill=green!25,
alias=green boss,
for parent={
alias=green parent,
},
},
important/.style={
parent anchor=center,
child anchor=center,
},
important node/.style={
alias=important node,
before packing={calign with current},
before typesetting nodes={
repeat=\thepinkbosses{TeX={\stepcounter{countpinkbosses}}, insert before=pink boss \thecountpinkbosses},
},
},
}
\begin{forest}
for tree={
draw=black,
align=center,
l sep=6ex,
node options={font=\scriptsize, minimum width=14em, minimum height=10ex, rounded corners=1ex},
where n children=0{}{
parent anchor=south,
child anchor=north,
edge path={
\noexpand\path[\forestoption{edge}]
(!u.parent anchor) -- +(0,-4ex) -| (.child anchor)\forestoption{edge label};
},
},
where level=1{
before typesetting nodes={
insert after=green boss,
},
}{},
where level=3{
for descendants={
where n children=0{
child anchor=west,
calign=child edge,
edge path={
\noexpand\path[\forestoption{edge}]
([xshift=-6em]!u.parent anchor) |- (.child anchor)\forestoption{edge label};
},
for parent={
parent anchor=south, l sep=-12em, grow'=east, calign=child edge,
},
}{},
},
}{},
base=b
}
[,phantom
[\textbf{LEVEL 1}
[\textbf{Thing 1}, important node
[\textbf{Green Thing}, green boss
]
[\textbf{Thing 2}
[,phantom, minimum height=1ex
]
[\textbf{Thing 3}
[\textbf{Pink Thing 1}, pink boss
]
]
[\textbf{Thing 4}
[\textbf{Pink Thing 2}, pink boss
]
]
[\textbf{Thing 5}
]
]
[\textbf{Thing 6}
[,phantom
]
]
[\textbf{Thing 7}
[,phantom
]
]
[\textbf{Thing 8}
[,phantom
]
]
]
]
]
\foreach \i in {1,...,\thepinkbosses}
\draw[<-, dashed, black!30] (pink boss \i) -- (pink \i);
\draw[<-, dashed, black!30] (green boss) -- (green parent);
\end{forest}
\end{document}