我正在尝试绘制下面的图表,但我还没有找到任何解决方案来将“选项 1”和“选项 2”连接到公共子节点“C”。
我已尽力使用森林包,结果得到以下 MWE:
\documentclass{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage[edges]{forest}
\usetikzlibrary{arrows.meta, shapes.geometric, calc, shadows}
\begin{document}
\begin{forest}
warn/.append style = {
% rectangle,
font = \sffamily\footnotesize\bfseries,
% rounded corners = 2pt,
% inner color = hsoorange,
% outer color = hsoorange
},
box/.append style = {
rectangle,
font = \sffamily\footnotesize\bfseries,
draw = black,
align = center,
inner color = green,
outer color = green,
},
special/.append style = {
rectangle,
font = \sffamily\footnotesize\bfseries,
draw = black,
align = center,
inner color = orange,
outer color = orange,
},
for tree = {
font = \sffamily\footnotesize,
l sep = 0.6em,
s sep = 0.3em,
minimum width = 4.0em,
line width = 1pt,
child anchor = north,
parent anchor = south,
edge path={
\noexpand\path[color=black,
% rounded corners=5pt,
>={Stealth[length=10pt]},
line width = 1pt,
-,
\forestoption{edge}
]
(!u.parent anchor) -- +(0,-9pt) -| (.child anchor)\forestoption{edge label};
},
},
forked edges,
[Title, box
[Option 1, box
[A, box
[, edge=dotted,
[cool, warn, edge=dotted]]
]
[B, box
[, edge=dotted
[not cool, warn, edge=dotted]]
]
[C, special]
]
[Option 2, box
[X, box
[, edge=dotted
[ok!, warn, edge=dotted]]
]
[Y, box
[1, box]
[2, box]
[3, box]
[4, box]
]
[Z, box]
]
]
\end{forest}
\end{document}
然而,我没能常见的子节点“C”,并且指向最后一级评论的边是中断而且不连续,看起来不太好看。
请问,有人可以使用森林、树木或本地 tikz 为我提供解决方案吗?
亲切的问候
答案1
这是对 Alan Munn 的答案的修改,旨在纠正假边缘的轻微错位,并采用略有不同的方法来处理底部的三个节点。
这是错位的特写。请注意,线条没有完全对齐,箭头与 C 的相邻部分接触的地方有些奇怪。
我没有增加l
,而是使用coordinate
s 将三个节点移至较低级别。我这样做是因为我认为它可以将线周围的间距改善到OK!
。此节点的创建方式不同。我们不是将其创建为 X 的子节点,而是将其父节点创建为 Y 的子节点并省略边。
我们使用条件样式来格式化树,在一系列测试的基础上添加coordinate
、、dotted
和。我们还使用布尔值来让 C 更容易理解edge=line
。此布尔选项必须在环境之外声明 - 不能在该环境内声明。也就是说,声明它是可以的,但它不能正常工作,所以没有多大意义。special
box
forest
我还稍微增加了级别之间的距离,以避免箭头看起来被压扁。显然,您可以根据需要进行调整。
% addaswyd o ateb Alun Munn: https://tex.stackexchange.com/a/693202/ i MWE George: https://tex.stackexchange.com/q/693152/
\documentclass[border=10pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage[edges]{forest}
\usetikzlibrary{arrows.meta}
\tikzset{line/.style={draw,-Stealth}}
\forestset{declare boolean={my special}{0}}% declare a custom boolean option and set it to false by default
\begin{document}
\begin{forest}
warn/.append style = {
font = \sffamily\footnotesize\bfseries,
},
box/.append style = {
rectangle,
font = \sffamily\footnotesize\bfseries,
draw = black,
align = center,
inner color = green,
outer color = green,
},
special/.append style = {
rectangle,
font = \sffamily\footnotesize\bfseries,
draw = black,
align = center,
inner color = orange,
outer color = orange,
child anchor = 140,% set the anchor specially so we get symmetric points for the two connections from Option 1 and Option 2
tikz+={% add in a fake edge from the node named 2's parent anchor to this node's 40 anchor
\draw [every edge, line] (2.parent anchor) -- ++(0pt,-\forestoption{fork sep}) -| (.40);
}
},
for tree = {
font = \sffamily\footnotesize,
l sep' = 0.6em,
s sep' = 0.3em,
minimum width = 4.0em,
line width = 1pt,
child anchor = north,
parent anchor = south,
tier/.option=level,
l sep*=2,
},
forked edges,
box,
before typesetting nodes={%
for descendants={%
if={> O_= O_= | {content}{}{!u.content}{}}
{% if either the node or its parent has no content
edge=dotted,
if n children=0 {% if the node is a terminus
edge=line
} {% if it isn't a terminus
coordinate
}
}{% if both the node and its parent have some conent
edge=line,
if={> {O} {my special} }%
{% if the option 'my special' is set for the node
special
}{% if that option isn't set
box
}
}
},
}
[Title
[Option 1
[A
[
[cool, warn]
]
]
[B, calign with current edge
[
[not cool, warn]
]
]
[C, my special
]
]
[Option 2, name=2
[X]
[Y
[1]
[
[ok!, warn]
]
[2]
[3]
[4]
]
[Z]
]
]
\end{forest}
\end{document}
答案2
由于这不再是一棵树,因此需要一些手动干预。基本思想是创建一个没有边的节点,然后手动绘制分支。我使用该ext.paths.ortho
库绘制了等效的分叉路径。您的路径代码没有达到您的要求,因此我添加了另一种添加箭头的方法,改编自这里
\documentclass[border=10pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage[edges]{forest}
\usetikzlibrary{arrows.meta, shapes.geometric, calc, shadows,ext.paths.ortho}
\tikzset{line/.style={draw,-Stealth}}
\begin{document}
\begin{forest}
warn/.append style = {
% rectangle,
font = \sffamily\footnotesize\bfseries,
% rounded corners = 2pt,
% inner color = hsoorange,
% outer color = hsoorange
},
box/.append style = {
rectangle,
font = \sffamily\footnotesize\bfseries,
draw = black,
align = center,
inner color = green,
outer color = green,
},
special/.append style = {
rectangle,
font = \sffamily\footnotesize\bfseries,
draw = black,
align = center,
inner color = orange,
outer color = orange,
},
for tree = {
font = \sffamily\footnotesize,
l sep = 0.6em,
s sep = 0.3em,
minimum width = 4.0em,
line width = 1pt,
child anchor = north,
parent anchor = south,
edge=line,
},forked edges,
[Title, box
[Option 1, box
[A, box,tier=A
[cool, warn, edge=dotted,l=.75in]
]
[B, box,name=B
[not cool, warn, edge=dotted,l=.75in]
]
]
[C,special,no edge,tier=A,name=C,
]
[Option 2, box
[X, box,name=X,
[ok!, warn, no edge,l=.75in,name=OK]
]
[Y, box
[1, box]
[2, box]
[3, box]
[4, box]
]
[Z, box]
]
]
\draw[-Stealth] (B.north) r-ud[ud distance=5.6pt] (C.130);
\draw[-Stealth] (X.north) r-ud[ud distance=5.6pt] (C.50);
\draw[-Stealth,dotted] (X.south) -- (OK.north);
\end{forest}
\end{document}
答案3
我不知道forest
包,所以我建议一个简单的代码tikz
:
\documentclass[border=.5cm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% \draw[gray!20] (-10,-4) grid (10,4);
\filldraw[draw=black,fill=green] (-2,3) rectangle (2,4) node[pos=.5] (t) {\large Title};
\filldraw[draw=black,fill=green] (-8,1) rectangle (-5,2) node[pos=.5] (o1) {\large Option1};
\filldraw[draw=black,fill=green] (5,1) rectangle (8,2) node[pos=.5] (o2) {\large Option2};
\draw[-latex] (0,3)--(0,2.5)--(-6.5,2.5)--(-6.5,2);
\draw[-latex] (0,3)--(0,2.5)--(6.5,2.5)--(6.5,2);
\draw (-6.5,1)--(-6.5,.5);
\draw (-10,.5)--(-2.25,.5);
\draw (10,.5)--(-1.25,.5);
\draw[-latex] (-1.25,.5)--(-1.25,0);
\draw[-latex] (-2.25,.5)--(-2.25,0);
\draw[-latex] (-6.5,.5)--(-6.5,0);
\draw[-latex] (-10,.5)--(-10,0);
\filldraw[draw=black,fill=orange] (-2.75,-1) rectangle (-.75,0) node[pos=.5] () {\large C};
\filldraw[draw=black,fill=green] (-11,-1) rectangle (-9.,0) node[pos=.5] () {\large A};
\filldraw[draw=black,fill=green] (-7.5,-1) rectangle (-5.5,0) node[pos=.5] () {\large B};
\draw (6.5,1)--(6.5,.5);
\draw[-latex] (10,.5)--(10,0);
\filldraw[draw=black,fill=green] (2,-1) rectangle (4,0) node[pos=.5] () {\large X};
\filldraw[draw=black,fill=green] (5.5,-1) rectangle (7.5,0) node[pos=.5] () {\large Y};
\filldraw[draw=black,fill=green] (9,-1) rectangle (11,0) node[pos=.5] () {\large Z};
\draw[-latex] (6.5,.5)--(6.5,0);
\draw[-latex] (3,.5)--(3,0);
\draw (2,-2)--(7.4,-2);
\draw (6.5,-1)--(6.5,-2);
\draw[-latex] (2,-2)--(2,-2.4);
\filldraw[draw=black,fill=green] (1.4,-3.6) rectangle (2.6,-2.4) node[pos=.5] () {\large 1};
\draw[-latex] (3.8,-2)--(3.8,-2.4);
\filldraw[draw=black,fill=green] (3.2,-3.6) rectangle (4.4,-2.4) node[pos=.5] () {\large 2};
\draw[-latex] (5.6,-2)--(5.6,-2.4);
\filldraw[draw=black,fill=green] (5,-3.6) rectangle (6.2,-2.4) node[pos=.5] () {\large 3};
\draw[-latex] (7.4,-2)--(7.4,-2.4);
\filldraw[draw=black,fill=green] (6.8,-3.6) rectangle (8,-2.4) node[pos=.5] () {\large 4};
\draw[dashed] (-10,-1)--(-10,-5);
\draw[gray,line width=3pt] (-10.5,-5)--(-9.5,-5) node[pos=.5,below] () {\bfseries cool};
\draw[dashed] (-6.5,-1)--(-6.5,-5);
\draw[gray,line width=3pt] (-7,-5)--(-6,-5) node[pos=.5,below] () {\bfseries not cool};
\draw[dashed] (3,-1)--(3,-5);
\draw[gray,line width=3pt] (2.5,-5)--(3.5,-5) node[pos=.5,below] () {\bfseries OK!};
\end{tikzpicture}
\end{document}
输出: