I'm trying to make sort of a flow chart for a series of steps, but these steps are also grouped, and I'd like my diagram to reflect that. So I'm using the pgfonlayer/background environment to draw rectangles around these groups.
I found a similiar example that uses the fit
parameter to find the right dimensions.
That example works nicely except for the fact that groups do not have an equal width, so the rectangles don't look very nice:
That's the code for that (elicit is the first node "Wissenserhebung"):
\begin{pgfonlayer}{background}
\node [background, fit=(elicit)] {};
% others similiar
\end{pgfonlayer}
Then, I found another way to do it, with rectangles and lots of calculations:
[nice example][2]
\draw [background] ($(elicit.north west)-(0.2,-0.2)$) rectangle ($(matrix.east)!(elicit.south east)!(matrix.east)+(0.2,-0.2)$);
\draw [background] ($(elicit.north west)!(interpret.north west)!(elicit.north west)-(0.2,-0.2)$) rectangle ($(matrix.east)!(model.south east)!(matrix.east)+(0.2,-0.2)$);
\draw [background] ($(elicit.north west)!(representation.north west)!(elicit.north west)-(0.2,-0.2)$) rectangle ($(matrix.east)!(representation.south east)!(matrix.east)+(0.2,-0.2)$);
With that code, I get nice rectangles, but they don't seem to be nodes so I cannot attach text to them.
Is there a 'canonical' way of getting these rectangles with an equal width but fitting to the height of the nodes inside and able to get text attached?
I found posts about modifying bounding rectangles, but I'm not sure if or how that could help me here.
This is the full code (minus style definitions):
\begin{tikzpicture}
\matrix (matrix) [row sep=0.5cm,column sep=0.5cm] {
\node (elicit) [schritt] {Wissenserhebung}; & \\
\node (interpret) [schritt] {Interpretation}; & \\
& \node (model) [schritt] {Modellierung}; \\
\node (representation) [schritt] {Repräsentation}; & \\
\node (integration) [schritt] {Integration}; & \\
\node (maintenance) [schritt] {Wartung}; & \\
};
\path[->]
(elicit) edge (interpret)
(interpret) edge node[right] {\hspace{.35cm}\tiny Modellbasierter Ansatz} (model)
(interpret) edge node[right] {\tiny Rapid Prototyping} (representation)
(model) edge (representation)
(representation) edge (integration)
(integration) edge (maintenance);
\begin{pgfonlayer}{background}
% ugly, but nodes
%\node [background, fit=(elicit)] {};
%\node [background, fit=(interpret) (model)] {};
%\node [background, fit=(representation)] {};
% no nodes, but correct width
%\draw [background] ($(elicit.north west)-(0.2,-0.2)$) rectangle ($(matrix.east)!(elicit.south east)!(matrix.east)+(0.2,-0.2)$);
%\draw [background] ($(elicit.north west)!(interpret.north west)!(elicit.north west)-(0.2,-0.2)$) rectangle ($(matrix.east)!(model.south east)!(matrix.east)+(0.2,-0.2)$);
%\draw [background] ($(elicit.north west)!(representation.north west)!(elicit.north west)-(0.2,-0.2)$) rectangle ($(matrix.east)!(representation.south east)!(matrix.east)+(0.2,-0.2)$);
\end{pgfonlayer}
\end{tikzpicture}
Best Answer
You can use nodes with the
fit
library by adding coordinates to each of thefit
lists that lie on the left and right borders of the bounding box, but at the same vertical position as the nodes you want to highlight. You can do this with thecalc
library and its syntax($(A)!(C)!(B)$)
, which projects the point(C)
on the line from(A)
to(B)
.In the example below, I've used a script that takes a node name as an argument and returns three coordinates: The node itself, and its projection on the left and right borders of the bounding box. In order to make the new boxes all the same width, the bounding box needs to be "frozen", so one box doesn't influence the size of the next. You can do this by issuing
\path [use as bounding box] (current bounding box.north west) (current bounding box.south east)
before the first background box, which stops the updating of the bounding box.