So I want to put a horizontal brace around a part of the tikzpicture.
Alternate approaches I found but don't seem to apply too well here:
- https://tex.stackexchange.com/a/1568/139666 (braces around
paragraphs, using matrix nodes) - https://tex.stackexchange.com/a/15336/139666 (braces around matrix
column/rows, using matrix nodes)
In both cases, there already is a node at the right-most (left-most) position,
allowing for easy calculation of the brace-endpoints via -|
or equivalent.
But there's not always such a node already; for example, when trying to put braces of part of a tree (see MWE).
I'm remotely aware that technically I could probably use calc
and compute minimal/maximal x
in custom code,
but I expect that there's a simpler way I don't know about.
\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}
I'd like to have a more sensible position of the braces, specifically:
- Don't get so close to the rectangles of the leafs by moving further away.
- No intersection with wide "internal" nodes, by moving the whole brace away.
- Braces should be vertical, but slightly sloped might look good, too.
Here's what it would look like with brace-end-points calculated by manually-chosen -|
and |-
:
So how do I get a vertical brace at a good position,
without doing manual work?
Or more specifically, assuming this is a good idea: How do I get an extreme corner (e.g. right-most and top-most) of a subset of nodes?
(Also: general suggestions and recommendations about my TeX and post style are very welcome!)
Best Answer
I would use one of the packages or libraries designed for drawing trees. Forest is my favourite because it means you don't have to figure out the positioning manually: the package automatically figures out how much space to allow for the nodes and places them accordingly. It is also very powerful and flexible, allowing substantial customisation and automation with very concise tree specifications.
Here's a version using
fit to
. To specify thecurl
's span, we pass a node walk as the argument. The label goes incurl label
.mirror curl
triggers mirroring.Or you can specify the start and end coordinates for the span:
Note that the
( -| )
coordinate specifications could be used with your original code, too. This is an easy way to make sure your curly brackets are aligned as you wish.If you have a subset of nodes,
a
,b
,c
, say, then(<widest node>.west |- <topmost node>.north)
will give the top left corner of a tight box just big enough to contain them,(<widest node>.east |- <bottommost node>.south)
will give the bottom right corner and so on.