Is this what you want?
Problem 1: Adding the pictures, like database Display Database Instance Relationship with TikZ, for example in the cells (stack-5-6) (stack-6-6)
with the name to make an arrow in future.
Cells (stack-5-6) (stack-6-6)
doesn't exist because you declared option nodes in empty cells=false
and no nodes are created in empty cells. But you can use some other nodes as reference to place your database symbol. As an example I've used (NTWorks|-RCPrun.south)
:
\node[database, minimum width=2cm, minimum height=2cm, anchor=south] (DB3) at (NTWorks|-RCPrun.south) {DB3};
Problem 2: Creating an arbitrary block of nodes with the border and shadow,
You almost did it with:
\begin{pgfonlayer}{background}
\node [background,
fit=(stack-2-1) (stack-4-1)(stack-4-5),draw, drop shadow,
] {};
\node [backgroundN,
fit=(stack-3-5) ] {};
\node [backgroundNN,draw, drop shadow,
fit=(stack-3-5) ] {};
\end{pgfonlayer}
The problem was \node [backgroundN, fit=(stack-3-5) ] {};
. This line introduced a wrong white border. Comment it out.
Some other points:
- I've changed
tikzstyle
to tikzset
. Please read Should \tikzset or \tikzstyle be used to define TikZ styles?
- In node
NTWorks
you used a tikzpicture
inside a tikzpicture
which is not recommended. I've adopted syntax from \widernode
to draw it.
- Distance between columns 5 and 6 has been enlarged with
&[3mm]
in first row. This adds 3mm
to column sep
. I've enlarged to better draw fitting
nodes.
- Right border of pink fitting box has been shifted to the right with
aux
coordinate. This way MSP Export
border doesn't overwrite background border.
- Data base symbol was taken from Thorsten Donig answer to Display Database Instance Relationship with TikZ
The complete code is:
\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds,shadows,positioning,fit,matrix,shapes.geometric, shapes.arrows} % add shadows #1
% a way to cut shadows in a cell #2
%https://tex.stackexchange.com/questions/129318/remove-drop-shadow-from-one-node
\makeatletter
\tikzset{no shadows/.code=\let\tikz@preactions\pgfutil@empty}
\makeatother
\tikzset{background/.style={rectangle, fill=red!10, inner sep=0.2cm},
backgroundN/.style={rectangle, fill=white, inner sep=0.3cm},
backgroundNN/.style={rectangle, fill=red!10, inner sep=0.2cm}}
\definecolor{mybluei}{RGB}{124,156,205}
\definecolor{myblueii}{RGB}{73,121,193}
\definecolor{mygreen}{RGB}{202,217,126}
\definecolor{mypink}{RGB}{233,198,235}
\newcommand\widernode[5][widebox]{
\node[
#1,
fit={(#2) (#3)},
label=center:{\sffamily\bfseries\color{black}#4}] (#5) {};
}
\begin{document}
\begin{tikzpicture}[node distance=2pt,outer sep=0pt, % just do nothing after modification
boxstyle/.style={
draw=white,
fill=#1,
rounded corners, drop shadow, %to get a shadow in below a node
font={\sffamily\bfseries\color{white}},
align=center,
minimum height=30pt
},
box/.style={
boxstyle=#1,
text width=2.5cm},
box/.default=mybluei,
title/.style={font={\sffamily\bfseries\color{black}}},
widebox/.style={draw=white,inner sep=0pt, rounded corners,fill=#1,drop shadow},
widebox/.default=mybluei,
mylabel/.style={font={\sffamily\bfseries\color{black}}},
database/.style={
cylinder,
cylinder uses custom fill,
cylinder body fill=yellow!50,
cylinder end fill=yellow!50,
shape border rotate=90,
aspect=0.25,
draw
}
]
\matrix (stack) [draw=black,% boxstyle=mybluei!40,%will overpaint blocks with background
column sep=10pt, row sep=10pt, inner sep=4mm,%
matrix of nodes,
nodes={box, outer sep=0pt, anchor=center, inner sep=3pt},%
nodes in empty cells=false,% #3
row 1/.style={nodes={fill=none,draw=none,minimum height=3mm}},
]
{
|[no shadows]| & & & & |[no shadows]| &[3mm] |[no shadows]| \\ % #5
RCP main & Authoring & Browsing & Publishing & Search&|[no shadows]| \\
Rich Text &|[no shadows]| &|[no shadows]| &{XML\\ Export/Import} & MSP Export&|[no shadows]| \\
Common & |[no shadows]| &|[no shadows]| & |[no shadows]| &|[no shadows]| &\node[rotate=10] {Hello};\\
|[box=mypink]| Jtidy & |[no shadows]| & |[no shadows]| &|[box=mygreen]| GEF & |[box=mygreen]| ICU4J & \\
|[no shadows]| & & & & |[no shadows]| &\\};
\widernode[]{stack-1-1}{stack-1-5}{EPF Composer}{EPF} %#5
\widernode{stack-3-2}{stack-3-3}{Library Management}{LMg}
\widernode{stack-4-2}{stack-4-3}{UMA}{UMA}
\widernode{stack-4-4}{stack-4-5}{Export/Import}{ExImp}
\widernode[widebox=mygreen]{stack-5-2}{stack-5-3}{EMF}{EMF}
\widernode[widebox=mygreen]{stack-6-1}{stack-6-5}{RCP Runtime}{RCPrun}
\node[widebox,
fit={(stack-2-6) (stack-3-6)},
label={[text width=2.5cm, align=center]center:{\sffamily\bfseries\color{black}Normal text works}}] (NTWorks) {};
% \widernode[widebox, text width=1.5cm, align=center]{stack-2-6}{stack-3-6}{Normal text works}{NTWorks}
%
\node [fit={(stack.south west)(stack.south east)},boxstyle=myblueii,draw=black,inner sep=0pt,below=3pt of stack.south,anchor=north,label={[mylabel]center:Java Runtime}] (JavaR) {};
%
%
% % smth to create an arbitrary block with a border and shadow
\begin{pgfonlayer}{background}
\coordinate (aux) at ([xshift=2mm]stack-4-5.east);
\node [background,
fit=(stack-2-1) (stack-4-1) (aux), draw, drop shadow,
] {};
% \node [backgroundN,
% fit=(stack-3-5) ] {};
\node [backgroundNN,draw, drop shadow,
fit=(stack-3-5) ] {};
\end{pgfonlayer}
\node[database, minimum width=2cm, minimum height=2cm, anchor=south] (DB3) at (NTWorks|-RCPrun.south) {DB3};
\node[single arrow, draw, shape border rotate=90, anchor=south, fill=mybluei] at ([yshift=1mm]DB3.north) {\phantom{bpf}};
\node[fit=(NTWorks) (DB3), draw, thick] {};
\end{tikzpicture}
\end{document}
Update: Making holes
I understand from your comment that your intention is to make holes
in your scheme to represent that some blocks are not part from a set. From my point of view, it's difficult to draw arbitrary holes and respect shadowing. I could manage to draw an internal shadow for a rectangular hole and I hope something similar could be applied to arbitrary holes but I think this should be another question.
What I've done has been to apply Paul Gaborit's shadowed
style adapted to default shadow style (first lines from section 66.3.1 Drop Shadows in pgfmanual.pdf).
shadowed/.style={postaction={draw=black!50, opacity=.5, line width=.5ex}}
and use this style to draw an internal shadow to certain rectangular node:
\begin{pgfonlayer}{background}
\coordinate (aux) at ([xshift=2mm]stack-4-5.east);
\node [background, fit=(stack-2-1) (stack-4-1) (aux),
draw, drop shadow] {};
%draw a white `background` around node
\node [fill=white, fit=(stack-3-5)] (hole) {};
%draw an internal shadow
\begin{scope}
\clip (hole.south west) rectangle (hole.north east);
\path[shadowed] (hole.south west) |- (hole.north east);
\end{scope}
\end{pgfonlayer}
The result looks like:
** 2nd Update: Non rectangular background
You don't need to use rectangular backgrounds because a drop shadow
can be also applied to any closed path. The difficult part is how to define the complex background. Next code show an example. I've still used the rectangular (although not drawn neither filled) background as reference to compoun a complex closed shape. Just changed code is provided:
\begin{pgfonlayer}{background}
\node [
fit=(stack-2-1) (stack-4-5),
] (BigGroup) {};
\draw[green, fill=green!30, very thick, drop shadow] (BigGroup.north west) -| ([shift={(-2mm,-3mm)}]stack-3-5.south west) -| (BigGroup.south east) -| ([shift={(-2mm,3mm)}]ExImp.north west)-|([xshift=-2mm]UMA.west|-BigGroup.south)-|cycle;
\end{pgfonlayer}
The result is:
Best Answer
You can use the following code as a starting point (a complete and improved version, as well as an explanation of the code, can be found below):
Here's now an improved version in which I am using the code from
Jake's answer
to Creating a node fitting the horizontal width of two other nodes. In this new version, some values that were hard-coded (in fact, mostly guessed) in the previous version are now automatically calculated.Explanation of the code
The first step is to notice that the diagram consists of just one basic shape: a rectangular node with rounded corners, a filling color, a color for the border, with text centered, and the text is white and in sans-serif font, so the thing to do is to define a style with this characteristics:
The next step is to position the nodes, and this can be done with the help of the
positioning
library; here's a portion of the diagram illustrating this:The next step is to place the "wider" nodes and it is here that Jake's answer is used; I defined a new command
\widernode
with four mandatory arguments (the first two are the nodes used to control the size (See the linked answer for details), the third one gives the label and the fourth one, the string used to name the node) and one optional argument (to control the attributes of the node):The above will require the
calc
andfit
libraries. Now we can automatically build the wider nodes using other nodes as reference:Next we add the frame for the upper part using layers, as in:
And the rest is now easy; just to add the lower node (Java Runtime) and the title.