Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I wish to draw the flow like in the picture using the code below, however, I found it is very hard to locate the rectangles by using Coordinate. Is there any better way to do this?

enter image description here

Here is the code I have tried:

\documentclass{minimal}
\usepackage{tikz}
\usepackage{pgf}
\usetikzlibrary{arrows,automata} 
\usetikzlibrary{shapes}
\begin{document}


\begin{tikzpicture}
\draw (-4,-4) rectangle (4,4);
\draw (-0.5,0)  rectangle (-3,-3);
\draw (0.5,0)   rectangle (3,-3);
\draw (-1,0)    rectangle (-2,-1);

\end{tikzpicture}

\end{document}
share|improve this question
    
I’d work my way from the most inner to the most outer stuff, the fit library does help here. Instead of using rectangle paths, you’d be using rectangular nodes. –  Qrrbrbirlbel Feb 12 '13 at 14:00
    
Have a look at the TikZ-uml package too ensta-paristech.fr/~kielbasi/tikzuml/index.php?lang=en –  percusse Feb 12 '13 at 14:07
    
Thanks, however, I never used fit before,can you give me an example? –  sweetyBaby Feb 12 '13 at 14:07

1 Answer 1

up vote 7 down vote accepted

This answer makes use of the following TikZ libraries:

  • shapes.geometric for the diamond shapes
  • positioning for the relative positioning of nodes ( …=… of …)
  • fit for fitting nodes around other ones (fit=(…)(…) …)
  • calc for the positioning of the diamond nodes

The node f is on the same height as b and d. The node e is on the same height as the left diamond (dia1).

The right big rectangles enclosing e and f uses the coordinate dia1.north -| e to fit, so that it has the same height as the other big rectangle.

Should the “plussed” diamond on the bottom be horiztonally centered between the big rectangles use

\node[dia cross] at ([yshift=-.5cm]$(left.south east)!.5!(right.south west)$) (dia2) {};

for the placement (notice the anchors south east and south west).

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{
    shapes.geometric,
    positioning,
    fit,
    calc
}
\tikzset{
    dia/.style={
        shape=diamond,
        minimum size=2em,
    },
    dia cross/.style={
        dia,
%       path picture={
%           \draw (path picture bounding box.west) -- (path picture bounding box.east)
%                 (path picture bounding box.north) -- (path picture bounding box.south);
%       },
        append after command={
            \pgfextra
                \draw[shorten >=\pgflinewidth,shorten <=\pgflinewidth]
                                   (\tikzlastnode.west) -- (\tikzlastnode.east);
                \draw[shorten >=\pgflinewidth,shorten <=\pgflinewidth]
                                 (\tikzlastnode.north) -- (\tikzlastnode.south);
            \endpgfextra
        }

    }
}
\begin{document}
\begin{tikzpicture}[
    every node/.append style={draw,minimum width=3em,minimum height=1.5em},
    >=latex
]

%%% Left side
%% nodes with text
\node                (a) {a};
\node[below=.5 of a] (b) {b};

\node[right=of a]    (c) {c};
\node[below=.5 of c] (d) {d};

%% rectangles around nodes with text
\node[fit=(a)(b)] (ab) {};
\node[fit=(c)(d)] (cd) {};

%% top diamond
\node[dia] at ([yshift=.5cm]$(ab.north)!.5!(cd.north)$) (dia1) {};

%%% Right side
\node[right=2 of d] (f) {f};
\node[label={[inner sep=0pt,minimum height=2ex]above:h?}] at (f |- dia1) (e) {e};

% fake f to get the same spacing as on the left side (text with draw=gray)
\node[fit=(f),draw=none] (f') {}; 

%%% Big rectangles
\node[inner sep=1em,fit=(ab)(cd)(dia1)] (left) {};
\node[inner sep=1em,fit=(f')(dia1.north -| e)] (right) {};

%%% Diamond below
\node[dia cross] at ([yshift=-.5cm]$(left.south)!.5!(right.south)$) (dia2) {};

%%% Arrows
\foreach \pp/\pf/\pt in {--/a/b,
                         --/c/d,
                         --/e/f,
                         -|/dia1/ab,
                         -|/dia1/cd,
                         |-/left/dia2,
                         |-/right/dia2}
\draw[
    shorten >=\pgflinewidth,
    ->
] (\pf) \pp (\pt);
\end{tikzpicture}
\end{document}

Output

enter image description here

share|improve this answer
    
Thanks, however, it says "I can not find the file tizlibrary.\pgf@temp->shapes.geometric" when I run the code. Is it because I miss to install something? –  sweetyBaby Feb 12 '13 at 17:05
    
@sweetyBaby Apparently. Though shapes.geometric is a part of TikZ it should be available if TikZ is available. Do you have an updated installation? TikZ’ current version is 2.10. –  Qrrbrbirlbel Feb 12 '13 at 17:09
    
it is the latest one. And now a new problem occured when running the code, it says "package pdfkeys error: I don not know the key /tikz/path picture" –  sweetyBaby Feb 12 '13 at 17:24
    
@sweetyBaby Have you checked with \listfiles whether you have the right version? It does not seem to be the current version. –  Qrrbrbirlbel Feb 12 '13 at 17:46
    
Thanks, finally, I have updated, however, the code still can not run successfully, the error says "PDFTexify failed to create a pdf file ". is there any possible to draw the picture using tikz 2.0? –  sweetyBaby Feb 14 '13 at 1:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.