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'm working on a diagram, and I'm exploring TikZ for doing it. I searched, and looks like there is no easy way of doing diagrams, like pgfplots for plotting.

So, I need to create some special node shape like this one:

artifact sample

However, when I try to set a fixed size for the rectangle in the tikzstyle the things get ugly. Moreover, I have no clue on how to set several rectangles in the same style. I tried moving them in the style with something like: \tikzstyle{rectangle(0,0,2,1), draw, rectangle(1,1,3,2),draw}, but obviously that doesn't work.

What I'm missing to define a style like the one in the picture?

share|improve this question
add comment

3 Answers

up vote 10 down vote accepted

Using the shadows library as follows. The idea is to use the preaction mecanism (the shadows library hides it behind the scene).

enter image description here

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shadows}
\begin{document}
\tikzset{%
  cascaded/.style = {%
    general shadow = {%
      shadow scale = 1,
      shadow xshift = -1ex,
      shadow yshift = 1ex,
      draw,
      thick,
      fill = white},
    general shadow = {%
      shadow scale = 1,
      shadow xshift = -.5ex,
      shadow yshift = .5ex,
      draw,
      thick,
      fill = white},
    fill = white, 
    draw,
    thick,
    minimum width = 1.5cm,
    minimum height = 2cm}}
\begin{tikzpicture}
  \node[cascaded,label=below:Text] {};
\end{tikzpicture}
\end{document}
share|improve this answer
    
After reading the manual this many times I can't believe I missed this library :) Nice to know ! –  percusse Jan 11 '12 at 16:37
    
You can direcly use double copy shadow option to shorten the code further. –  percusse Jan 11 '12 at 16:43
    
@percusse You're right, I missed that option :-) Nevertheless, it may be useful to know that one can cascade the shadows too (that is put as many {pre|post}actions as needed). –  cjorssen Jan 11 '12 at 16:53
    
This works really nice. However, if I have a long text. the label doesn't break like the text inside. How can I fix it? –  adn Jan 12 '12 at 2:14
2  
@adn You can put the label inside a \parbox: \node[cascaded,label=below:\parbox{3cm}{Some long long long text}] {};. –  cjorssen Jan 12 '12 at 9:18
add comment

The problem can be fixed by using a preaction/postaction style. These styles you can read about in the manual. Basically it takes the current path and does something to it.

What you then can do is:

\tikzset{add shifted/.style={%
    postaction={%
        transform canvas={%
            xshift=0.1cm,yshift=-0.1cm
        },draw,fill=white,#1%
    }%
}}

This will make a shifted drawing after (hence postaction), which is filled with white and drawn as specified.

You can also do it the other way around with preaction. I have here shown how it could be done with a couple of different techniques. Also you can toy with this and nodes, remember that nodes are also paths (rectangular paths if not specified).

\documentclass{article}
\usepackage{tikz}
\begin{document}
\tikzset{%
    my box/.style={draw,fill=white},
    % Shifted without need for correct middle coordinate
    add shifted/.style={%
        postaction={%
            transform canvas={%
                xshift=0.1cm,yshift=-0.1cm
            },my box,#1%
        }%
    },
    % Shifted with need for correct middle coordinate
    add left/.style={%
        preaction={%
            transform canvas={%
                xshift=-0.1cm,yshift=0.1cm
            },my box,#1%
        }%
    },
    add right/.style={%
        postaction={%
            transform canvas={%
                xshift=0.1cm,yshift=-0.1cm
            },my box,#1%
        }%
    },
    % Both left and right collected to one, with separate args.
    add lr/.style 2 args={add left={#1},add right={#2}},
    % A style which also adds text. (not so agile)
    add lr text/.style={add left,add right,postaction={%
            transform canvas={yshift=-0.5cm},
            path picture={%
                \node[anchor=south] at (path picture bounding box.south) {#1};%
            }%
        }%
    }
}
\begin{tikzpicture}
  \path[use as bounding box] (-0.5,-0.75) rectangle (8.5,2.5);
  \draw[my box,add shifted={add shifted=add shifted}] (0,0) rectangle ++(2,2);
  \node[below=6pt] at (1.25,0) {Text};
  \draw[my box,add lr={fill=brown}{fill=yellow}] (3,0) rectangle ++(2,2);
  \node[below] at (4,0) {Text};
  \draw[my box,add lr text=Text] (6,0) rectangle ++(2,2);
\end{tikzpicture}
\end{document}

Which will output as:

output

You can of course adapt to your needs.

Notice that you can keep tweaking your styles until you basically only need to alter one input.

share|improve this answer
add comment

If you have to draw only very few of these, then, a little bit of manual labor solves the problem.

\documentclass{article}
\usepackage{tikz}
\tikzset{
    cascaded1/.style={draw,fill=white,minimum height=1.5cm,ultra thick,minimum width=1cm},
    cascaded0/.style={fill=white,minimum height=1.4cm,minimum width=0.9cm}
}
\begin{document}
\begin{tikzpicture}

\foreach \x in {1,2,...,5}{
\pgfmathparse{int(mod(\x,2))}
\node[cascaded\pgfmathresult] (a\x) at (\x mm, -\x mm) {};
};
\node (text1) at([yshift=-5mm]a3.south) {\textsf{Text}};

\begin{scope}[xshift=2cm]
\foreach \x in {1,2,...,3}{
\node[cascaded1] (b\x) at (2*\x mm,-2*\x mm) {};
};
\node (text2) at([yshift=-4mm]b2.south) {\textsf{Text}};
\end{scope}
\end{tikzpicture}
\end{document}

The difference is the white filled nodes creating the void between rectangles in the example on the right or straightforward cascading. The boring part is the placement of text underneath but shouldn't be a problem.

enter image description here

Otherwise, you have to declare a new shape to use it as a node directly which requires some nontrivial coding. you can the use shadow library as shown in cjorssen's answer.

share|improve this answer
add comment

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.