6

In the main part of the tikzpicture I'd like to simply create blocks. So I need somewhere in theirs' style definition to perform tracking of their common bounding rectangle. I've tried to access current bounding box, but it is obviously set to node's rectangle, thus, unfortunately, duplicating the path picture bounding box.

I'm going to use this box when creating another type of nodes (say, foo, which is to be implemented shortly). So, again, it should be accessible from inside foo's style definition. The goal is to make this calculations invisible from the user (drawer) perspective, though he will be restricted to declare nodes in two consecutive sections.

Is there a way to do this task in a somewhat more comfortable way than writing it with low-level commands, such as ifdim, etc.? What is preferred way of storing values, when drawing with TikZ? I guess, this is not by using \newcommand, which defines macros available at global scope. Up to now I've managed to store values using \pgfkeys but I stuck at getting the main picture's bounding box.

\documentclass[landscape]{article}

\usepackage{tikz}
\usetikzlibrary{scopes,chains,shapes.multipart,backgrounds,positioning,fit,calc}

\newcommand{\setup}{
    \tikzset{
        node distance=5mm and 3cm,
        block/.style={rectangle, %draw, thick,
            path picture={
                \draw[red, thick] (current bounding box.south west) rectangle (current bounding box.north east);
            }
        },
        %foo/.style={circle},
        every edge/.style={->, rounded corners, thick, draw,
            to path={
                let \p1=(\tikztostart.east),
                    \p2=($ (\tikztostart.east) + (1cm,0) $),
                    \p3=(\tikztotarget.west) in
                (\p1) -- (\p2) \ifdim\y2=\y3  -- \else |- \fi (\p3)
                \tikztonodes
            }
        }
    }
}

\begin{document}

\begin{tikzpicture}
    \setup

    % First section. This blocks will build up the bounding rectangle, which is to be used in the next section.
    \node[block=1] (A) {System A};
    \node[block=2] (B) [above right=of A] {System B};
    \node[block=3] (C) [right=of A] {System C};
    \node[block=4] (D) [below right=of A] {System D};

    % Second section. Positioning of this nodes depends on the resulting bounding rectangle of the previous section.
    %\node[foo] (o1) {circle 1};
    %\node[foo] (o2) {circle 2};

    \path
    (A) edge (B)
        edge (C)
        edge (D);
\end{tikzpicture}

\end{document}
1
  • \newcommand, which defines macros available at global scope: No, \newcommand defines macros in the local scope, not globally. You can also use \def\macroname{...} to store content. Apr 7, 2011 at 10:04

2 Answers 2

8

The fit library of TikZ can be used to create a surrounding rectangle or other shaped node of multiple nodes or coordinates.

% Preamble:
\usetikzlibrary{fit}
% ..
\node[inner sep=0pt,outer sep=0pt,fit=(a) (b) (c) (d) (e)] (bb) {};
% use `(bb.north west)` etc. to access the boundaries

What is prefered way of storing values, when drawing with TikZ?

You can use coordinate (<name>) inside a \path to save the current position. Alternative there is the \coordinate (<name>) at (<coordinate>); macro.

11
  • 2
    +1 on the preferred way. With TikZ you rarely have to work with dimensions and coordinates directly; you can use nodes and libraries for maximum flexibility. Apr 6, 2011 at 16:13
  • I agree with you. the fit library is the fine method here Apr 6, 2011 at 22:25
  • Before posting here, I've investigated pgfmanual. So I'm aware of the fit library. @Martins's code snippet allows to get boundary box, but - as far as I understand --- only after all nodes have been created. And this bounding box node should be created manually after defining blocks (in my case). But I want it to be implicitly calculated, and, more over, then used while creating another type of nodes. Apr 7, 2011 at 9:48
  • Using fit style I have to redefine node bb (inside block/.style) as \node[...,fit=(current bounding box) (bb)] (bb) {};. I am afraid of such recrusive redifinition, at least when doing this for the first time, when there's no such node bb by the moment. Apr 7, 2011 at 10:05
  • @Dmitry: The only nodes which must be already created for fit are the nodes use in the fit. You can define more nodes afterwards. You could try to use the every node key to recreate your bounding box node using fit every time a new node is created. Apr 7, 2011 at 10:06
-2

Well, I've played more with nodes and styles... The conclusion that inside path picture the current bounding box duplicates path picture bounding box was completely false. It stands what it should for. So, this code works (thanks to global definition of nodes):

block/.style={rectangle,
    path picture={
        \node[rectangle, fit=(current bounding box), inner sep=0pt, outer sep=0pt] (my bounding box) {};
    }
},

Unfortunately, I didn't manage to figure out, why in the example of the initial post each node gets surrounded by red border while that red border should increase in size with the creation of each new node.

2
  • 1
    -1 It seems unfair that you answered your own question using fit library suggestion given in an answer by Martin Scharrer and then accepted your answer. You also state that your own answer is incomplete. Perhaps your original question was unclear.
    – ipavlic
    Apr 26, 2011 at 8:49
  • @ipavlic: Though Martin's answer uses approach, which is also based on fit library, it doesn't solve the problem arised. So, I considered it to be superficial. Thanks for your critics. Apr 26, 2011 at 16:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .