所以我想在 tikzpicture 的一部分周围放置一个水平支架。
我发现了替代方法,但似乎在这里不太适用:
- https://tex.stackexchange.com/a/1568/139666(用矩阵节点括起段落)
- https://tex.stackexchange.com/a/15336/139666(使用矩阵节点括住矩阵的列/行)
在这两种情况下,最右边(最左边)位置已经有一个节点,从而可以通过或等效方法轻松计算括号端点-|
。
但并不总是存在这样的节点;例如,当尝试放置树的一部分的括号时(参见 MWE)。我隐约知道,从技术上讲,我可能可以在自定义代码中使用calc
和计算最小/最大值x
,但我希望有一种我不知道的更简单的方法。
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,positioning}
\begin{document}
\tikzstyle{edge} =[draw,thick,-latex]
\begin{tikzpicture}[node distance=0.8cm]
% Root trunk
\node (a1) at (0,0) {Sometimes};
\node[below=of a1] (a2) {One};
\path[edge] (a1) -- (a2);
\node[below=of a2] (a99) {Thing};
\path[edge] (a2) -- (a99);
% Right leaf
\node[below right=0.8cm and 0.5cm of a99] (r1) {Goes};
\path[edge] (a99) -- (r1);
\node[below=of r1] (r2) {On};
\path[edge] (r1) -- (r2);
\node[below=of r2] (r3) {And};
\path[edge] (r2) -- (r3);
\node[below=of r3,rectangle,draw] (r99) {On};
\path[edge] (r3) -- (r99);
% Left leaf
\node[below left=0.8cm and 0.5cm of a99] (l1) {Leads};
\path[edge] (a99) -- (l1);
\node[below=of l1,align=center] (l2) {In wide, verbose, even \\ multi-lined ways};
\path[edge] (l1) -- (l2);
\node[below=of l2,rectangle,draw] (l99) {To another};
\path[edge] (l2) -- (l99);
% Mapping to (sub)sections
\draw[decorate,decoration={brace,amplitude=10pt,mirror}]
(a1.north west) -- (a99.south west) node [midway,xshift=-0.4cm,left] {Section foo};
\draw[decorate,decoration={brace,amplitude=10pt,mirror}]
(l1.north west) -- (l99.south west) node [midway,xshift=-0.4cm,left] {Section bar};
\draw[decorate,decoration={brace,amplitude=10pt}]
(r1.north east) -- (r99.south east) node [midway,xshift=0.4cm,right] {Section baz};
\end{tikzpicture}
\end{document}
我希望牙套的位置更加合理,具体来说:
- 不要离叶子的矩形太近,要离得远一些。
- 通过移开整个支架,不会与宽的“内部”节点相交。
- 支架应垂直,但轻微地倾斜的看起来也不错。
-|
这是通过手动选择和计算出的括号端点的样子|-
:
那么,如何在不进行手动操作的情况下将垂直支架放置在合适的位置?或者更具体地说,假设这是一个好主意:如何获取节点子集的极角(例如最右边和最上面)?
(另外:非常欢迎对我的 TeX 和帖子风格的一般建议和推荐!)
答案1
我会使用专为绘制树而设计的软件包或库之一。Forest 是我的最爱,因为它意味着您不必手动确定定位:该软件包会自动计算出为节点留出多少空间并相应地放置它们。它也非常强大和灵活,允许大量定制和自动化,并且具有非常简洁的树规范。
这是使用 的版本fit to
。为了指定curl
的跨度,我们传递节点 walk 作为参数。标签进入curl label
。mirror curl
触发镜像。
\documentclass[border=10pt]{standalone}
\usepackage{forest}
\usetikzlibrary{decorations.pathreplacing,arrows.meta}
\begin{document}
\forestset{
declare toks={curl label}{},
declare toks={curl mirror}{},
mirror curl/.style={curl mirror=mirror},
curl/.style n args=5{
tikz+={
\node (n) [fit to=#1, inner sep=0pt] {};
\draw [decorate, decoration={brace, amplitude=10pt, #3}] (n.north #2) -- (n.south #2) node [midway, #4] {#5};
}
},
curl left/.style={
delay={
curl/.process={OOw2 {curl label}{curl mirror}{ {#1}{west}{##2}{left, xshift=-10pt}{##1}} }
},
},
curl right/.style={
delay={
curl/.process={OOw2 {curl label}{curl mirror}{ {#1}{east}{##2}{right, xshift=10pt}{##1}} }
},
},
}
\begin{forest}
for tree={
edge+={-Latex,thick},
align=center,
},
where n children=0{draw}{},
[Sometimes
[One
[Thing, curl left=cur, curl label=Section foo, mirror curl
[Leads, curl left=tree, curl label=Section bar, mirror curl
[{In wide, verbose, even\\multi-lined ways}
[To Another]
]
]
[Goes, curl right=tree, curl label=Section baz
[On
[And
[On]
]
]
]
]
]
]
\end{forest}
\end{document}
或者您可以指定跨度的起点和终点坐标:
\documentclass[border=10pt]{standalone}
\usepackage{forest}
\usetikzlibrary{decorations.pathreplacing,arrows.meta}
\begin{document}
\forestset{
declare toks={curl label}{},
declare toks={curl mirror}{},
mirror curl/.style={curl mirror=mirror},
curl/.style n args=5{
tikz+={
\draw [decorate, decoration={brace, amplitude=10pt, #3}] #1 -- #2 node [midway, #4] {#5};
}
},
curl left/.style args={from #1 to #2}{
delay={
curl/.process={OOw2 {curl label}{curl mirror}{ {#1}{#2}{##2}{left, xshift=-10pt}{##1}} }
},
},
curl right/.style args={from #1 to #2}{
delay={
curl/.process={OOw2 {curl label}{curl mirror}{ {#1}{#2}{##2}{right, xshift=10pt}{##1}} }
},
},
}
\begin{forest}
for tree={
edge+={-Latex,thick},
align=center,
},
where n children=0{draw}{},
[Sometimes
[One
[Thing, curl left=from (.south -| !r.west) to (!r.north west), curl label=Section foo
[Leads
[{In wide, verbose, even\\multi-lined ways}, curl left=from (!u.north -| .west) to (!1.south -| .west), curl label=Section bar, mirror curl
[To Another]
]
]
[Goes, curl right=from (.north east) to (.east |- !F.south), curl label=Section baz
[On
[And
[On]
]
]
]
]
]
]
\end{forest}
\end{document}
请注意,( -| )
坐标规范也可以用于您的原始代码。这是一种确保花括号按您希望的方式对齐的简单方法。
如果您有一个节点子集,,,,a
那么将给出一个足够大的b
紧密盒子的左上角以包含它们,将给出右下角等等。c
(<widest node>.west |- <topmost node>.north)
(<widest node>.east |- <bottommost node>.south)