# Diagram with stacks

So this is what I would like to have (please don't mind my awful paint skills):

And this is what I got out of tikz:

Using this code:

\documentclass{article}

\usepackage[english]{babel}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}

\begin{document}

\tikzstyle{depot}=[circle, draw, fill=red]
\tikzstyle{station}=[circle, draw, fill=green]
\tikzstyle{customer}=[circle, draw, fill=yellow]
\tikzstyle{line}=[draw, -latex']

\begin{tikzpicture}[node distance=2cm]
\node[depot](s) {$s$};
\node[station, right of=s](p1) {$p_1$};
\node[rectangle, draw=black, right of=p1](c1) {\begin{tabular}{c} $c_1$\\\hline $d_1$\\\hline $d_2$ \\\hline $d_3$ \\\hline $\vdots$ \\\hline $d_{m(i)}$\end{tabular}};
\node[station, right of=c1](p2) {$p_2$};
\node[rectangle, draw=black, right of=p2](c2) {\begin{tabular}{c} $c_1$\\\hline $d_1$\\\hline $d_2$ \\\hline $d_3$ \\\hline $\vdots$ \\\hline $d_{m(i)}$\end{tabular}};
\node[depot, right of=c2](t) {$t$};
\draw[thick, ->] (s) -- node[yshift=.2cm] {$t_{sp_1}$} (p1);
\draw[thick, ->] (p1) -- node[yshift=.2cm] {$t_{p_1c_1}$} (c1);
\draw[thick, ->] (c1) -- node[yshift=.2cm] {$t_{c_1p_2}$} (p2);
\draw[thick, ->] (p2) -- node[yshift=.2cm] {$t_{p_2c_2}$} (c2);
\draw[thick, ->] (c2) -- node[yshift=.2cm] {$t_{c_2t}$} (t);
\end{tikzpicture}

\end{document}


As I'm new to tikz, I'm not sure how to resolve the remaining issues:

1. The horizontal lines in the table have white space on both sides, and the table is too wide.
2. The arrows should point at specific entries in the table, not just to the middle of the table.
3. The table colors (color of top cell must be different from remaining cells). Btw, I'm open minded towards a prettier color scheme and a cleaner overall look :).
4. If possible, the rounded table top, but that's just bonus.

Any suggestions are highly appreciated.

-
You might also want to take a look at the automata library. Chapter 19 of the manual, and also a bunch of examples. – Sean Allred Jul 5 '13 at 21:41
1. Use inner sep=0pt for the nodes with the table and \begin{tabular}{@{}c@{}}. 2. Instead of a tabular use the rectangle split shape. It provides west and east anchors for every entry. 3. Use rectangle split part fill={blue,blue!80!red} (for example). 4. Yes, that’s really a little bit harder but can be done with append after command or path picture and a node that is not drawn. 5. Don’t use yshift=.2cm for the nodes along the lines but above or auto (see manual). – Qrrbrbirlbel Jul 5 '13 at 21:41
By the way, both \tikzstyle and right of are deprecated. – Qrrbrbirlbel Jul 5 '13 at 21:48
I'm sorry to bother you but I just noticed that you still haven't accepted answers to your questions. Please consider revisiting your question, accepting the answer that you consider best solved your problem, by clicking the checkmark to its left. In case of doubt, please see How do you accept an answer?. – Gonzalo Medina Jul 7 '13 at 22:25
@Qrrbrbirlbel thnx for your answer. Why shouldn't I use yshift? The 'above' command leaves a lot of space in between the edge and its label. – Joris Kinable Jul 8 '13 at 8:36

Instead of tabulars, you can use a multipart rectangle (requires the shapes.multipart library (section 48.6 Shapes with Multiple Text Parts of the PGF manual)) for the stack-like shapes (this solves all your four requests); in the following code I also changed the old \tikzstyle for the newer \tikzset and changed the deprecated right of= syntax to right=of (with the positioning library):

\documentclass{article}
\usepackage[english]{babel}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,shapes.multipart,positioning}

\definecolor{mygreen}{RGB}{0,146,63}
\definecolor{myred}{RGB}{218,37,28}
\definecolor{myblue}{RGB}{0,146,221}
\definecolor{mygray}{RGB}{186,179,213}

\tikzset{
depot/.style={
circle,
draw,
fill=myred!80,
text width=12pt,
align=center},
station/.style={
circle,
draw,
fill=mygreen,
text width=0.75cm,
align=center},
customer/.style={circle, draw, fill=yellow},
line/.style={draw, -latex'},
myrect/.style={
rectangle split,
rectangle split parts=5,
draw,
anchor=center,
text width=0.8cm,
align=center,
rectangle split part fill={mygray!90}},
top/.style={
draw,
fill=myblue,
rounded corners,
text width=0.8cm,
text depth=1.5ex,
align=center
}
}

% centered version of \vdots
\makeatletter
\DeclareRobustCommand{\rvdots}{%
\vbox{
\baselineskip4\p@\lineskiplimit\z@
\kern-\p@
\hbox{.}\hbox{.}\hbox{.}
}}
\makeatother

\begin{document}

\begin{tikzpicture}[node distance=1.2cm]
\node[depot] (s) {$s$};
\node[station, right = of s] (p1) {$p_1$};
\node[top,above right= 1.8cm of p1] (t1) {$\mathstrut c_1$};
\node[myrect,below= -5pt of t1] (c1)
{$\mathstrut d_1$\nodepart{two}$\mathstrut d_2$
\nodepart{three}$\mathstrut d_3$\nodepart{four}$\rvdots$
\nodepart{five}$d_{m(i)}$};
\node[station, right = of c1] (p2) {$p_2$};
\node[top,above right= 1cm and 1.5cm of p2] (t2) {$\mathstrut c_1$};
\node[myrect, below= -5pt of t2] (c2)
{$\mathstrut d_1$\nodepart{two}$\mathstrut d_2$
\nodepart{three}$\mathstrut d_3$\nodepart{four}$\rvdots$
\nodepart{five}$d_{m(i)}$};
\node[depot, right = of c2](t) {$t$};

\draw[thick, ->] (s) -- node[above] {$t_{sp_1}$} (p1);
\draw[thick, ->] (p1) -- node[above,sloped] {$t_{p_1c_1}$} (c1.text west);
\draw[thick, ->] (c1.text east) -- node[above,sloped] {$t_{c_1p_2}$} (p2);
\draw[thick, ->] (p2) -- node[above,sloped] {$t_{p_2c_2}$} (c2.three west);
\draw[thick, ->] (c2.three east) -- node[above,sloped] {$t_{c_2t}$} (t);
\end{tikzpicture}

\end{document}


The trick to get rounded corners on top and sharp corners on bottom was to use a rectangular node with rounded corners for the top part, and then to superimpose appropriately a multipart rectangle with sharp corners for the remaining elements.

Instead of the standard \vdots I used the modified version \rvdots from the answer to How to vertically center the \vdots in this node?.

-
This looks awesome! Thank you very much for your help. I especially like the fact that you did not only post an answer, but also added some references to the manual, which makes it much easier for me to learn something new! – Joris Kinable Jul 8 '13 at 7:46
Your solution looks great, but I discovered a problem when using this picture on a non-white background. The command to hide the bottom part of a multipart rectangle creates a white block, thereby 'masking' the bottom part. When the background is simply one color, as is the case in my setting, the '\fill[white]' inside the \HideLast command definition may be replaced by the background's color. However, multi-colored backgrounds will be problematic. – Joris Kinable Jul 8 '13 at 9:28
@user1903852 you're right. I've updated my answer with a new approach. This time, no hiding is performed so there will be no problems with possible backgrounds. – Gonzalo Medina Jul 8 '13 at 15:00
Indeed, now its perfect :) Thank you very much. – Joris Kinable Jul 9 '13 at 19:11