7

I would like to recreate the following diagram in LaTeX:

enter image description here

Something that uses TikZ is likely to be good and I have seen TikZ-UML which is somewhat similar to what I want, but I would really value some guidance. I'm not sure how to go about creating a diagram like this in TikZ. Thank you for any ideas you may have.

3
  • 3
    It really isn't very reasonable to just post a complex graphic and expect people to create it for you. You are much more likely to get help if you post some code showing that you've had a go and ask for advice overcoming specific problems you run into. A MWE, even one which doesn't work very well, will give people something to work with.
    – cfr
    Jan 23, 2014 at 3:09
  • 2
    Oh, gosh. I wouldn't expect someone to create it for me! That wouldn't be fair. It's simply that the approaches to making a diagram like that I am aware of seem like a great deal of work and I want to see if there is some approach people could direct me to (like recommending an alternative to TikZ-UML). I just don't want to put a great deal of effort into something if another approach would do the same thing with far less effort. Is there a better way of asking the question?
    – d3pd
    Jan 23, 2014 at 3:14
  • No, I think you are fine with this comment. People will see that and give you starting points (as they have). Otherwise I would have suggested stating explicitly that you are looking for a start and not for somebody to do it all for you. The only reason for this is that it is not uncommon for people to post a picture and wait for a fully developed solution. Since that's not terribly fair, being clear about your (very reasonable) expectations encourages people to respond helpfully. I'm glad to see you now have at least one helpful starting point!
    – cfr
    Jan 23, 2014 at 14:51

2 Answers 2

13

This can give you a starting point:

\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{tikz}
\usetikzlibrary{positioning,fit,backgrounds,calc}

\pgfdeclarelayer{backgroundi}
\pgfdeclarelayer{backgroundii}
\pgfdeclarelayer{backgroundiii}
\pgfsetlayers{backgroundiii,backgroundii,backgroundi,main}

\begin{document}

\begin{tikzpicture}[node distance=0.3cm,
mynode/.style={
  draw,
  fill=white,
  text width=3cm,
  align=center,
  minimum height=20pt
},
>=latex
]

% The upper "Job" box
\node[mynode] (func) {function}; 
\node[mynode,below=of func] (argu) {arguments}; 
\node[mynode,below=of argu] (time) {timeout}; 
\node[mynode,below=of time] (resu) {result}; 
\node[mynode,below=of resu] (other) {other information};

% Auxiliary coordinates for the background frame for "Job"
\coordinate (ul) at ([xshift=-15pt,yshift=7pt]func.north west);
\coordinate (lr) at ([xshift=15pt,yshift=-7pt]other.south east);

% The background frame for "Job"
\begin{pgfonlayer}{backgroundi}
\node[draw,fill=gray!30,fit=(ul) (lr)] (frame) {}; 
\end{pgfonlayer}
\node[anchor=south west,draw,fill=gray!30] 
  at ([yshift=-.5\pgflinewidth]frame.north west) {Job};

% The lower "Job" box
\node[mynode,below=2cm of frame.south] (funcb) {function}; 
\node[mynode,below=of funcb] (argub) {arguments}; 
\node[mynode,below=of argub] (timeb) {timeout}; 
\node[mynode,below=of timeb] (resub) {result}; 
\node[mynode,below=of resub] (otherb) {other information};

% Auxiliary coordinates for the background frame for "Job"
\coordinate (ulb) at ([xshift=-15pt,yshift=7pt]funcb.north west);
\coordinate (lrb) at ([xshift=15pt,yshift=-7pt]otherb.south east);

% The background frame for "Job"
\begin{pgfonlayer}{backgroundi}
\node[draw,fill=gray!30,fit=(ulb) (lrb)] (frameb) {}; 
\end{pgfonlayer}
\node[anchor=south west,draw,fill=gray!30] 
  at ([yshift=-.5\pgflinewidth]frameb.north west) {Job};

% Auxiliary coordinates for the background frame for both "Job" boxes
\coordinate (ulc) at ([xshift=-15pt,yshift=18pt]frame.north west);
\coordinate (lrc) at ([xshift=15pt,yshift=-7pt]frameb.south east);

% The background frame for both "Job" boxes
\begin{pgfonlayer}{backgroundii}
\node[draw,fill=gray!50,fit=(ulc) (lrc)] (framec) {}; 
\end{pgfonlayer}
\node[anchor=south west,draw,fill=gray!50] 
  at ([yshift=-.5\pgflinewidth]framec.north west) {Job group};

% The midlle "init" box
\node[mynode,right=3.5cm of func] (init) {init}; 
\node[mynode,below=of init] (subm) {submit}; 
\node[mynode,below=of subm] (getR) {getResults}; 

% The "pool" box
\node[mynode,right=2cm of init] (processi) {process}; 
\node[mynode,below=of processi] (processii) {process}; 
\node[mynode,below=of processii] (processiii) {process}; 
\node[mynode,below=of processiii] (processiv) {process}; 

% Auxiliary coordinates for the background frame for "pool" box
\coordinate (uld) at ([xshift=-15pt,yshift=7pt]processi.north west);
\coordinate (lrd) at ([xshift=15pt,yshift=-7pt]processiv.south east);

% The background frame for "pool"
\begin{pgfonlayer}{backgroundi}
\node[draw,fill=gray!30,fit=(uld) (lrd)] (framed) {}; 
\end{pgfonlayer}
\node[anchor=south west,draw,fill=gray!30] 
  at ([yshift=-.5\pgflinewidth]framed.north west) {pool};

% Auxiliary coordinates for the background frame for both "init" and "pool" boxes
\coordinate (ule) at ([yshift=17pt,xshift=-15pt]init.north west|-framed.north);
\coordinate (lre) at ([xshift=15pt,yshift=-7pt]framed.south east);

% The background frame for "init" and "pool"
\begin{pgfonlayer}{backgroundii}
\node[draw,fill=gray!50,fit=(ule) (lre)] (framee) {}; 
\end{pgfonlayer}
\node[anchor=south west,draw,fill=gray!50] 
  at ([yshift=-.5\pgflinewidth]framee.north west) {ParallelJobProcessor};

% Auxiliary coordinates for the general background frame
\coordinate (ulf) at ([yshift=17pt,xshift=-15pt]framec.north west);
\coordinate (lrf) at ([xshift=15pt,yshift=-7pt]framee.south east|-framec.south);

% The general background frame
\begin{pgfonlayer}{backgroundiii}
\node[draw,fill=black!60,fit=(ulf) (lrf)] (framef) {}; 
\end{pgfonlayer}

% Some arrows
\begin{scope}[line width=6pt]
\draw[->] 
  (frame.east|-argu) -- (subm);
\draw[->] 
  (getR.west) -- +(-1.5cm,0) -| ([xshift=2cm]resub.east) -- (resub.east);
\draw[->]
  (init.east) -- (framed.west|-processi.west);
\draw[->]
  (subm.east) -- (framed.west|-processii.west);
\draw[->]
  (framed.west|-processiii.west) -- (getR.east);
\end{scope}
\end{tikzpicture}%

\end{document}

enter image description here

1
  • Wow! That was quick. The layers and the auxiliary coordinates are tricks I hadn't seen before. They make it relatively easy to position the frames around the nodes for the functions and so on. This is of great assistance. Thank you very much for your help! :D
    – d3pd
    Jan 23, 2014 at 4:29
2

The simplest way of doing this in TikZ will be to manually place the boxes by giving the coordinates and placing the nodes manually. This is the easiest and simplest but this approach has many disadvantages, like if you want to change it afterwards, then maybe you will have to change all coordinates. If this is the final image, and you are not going to make any changes, then you should use this approach.

1
  • 1
    Yes, I think you're right about the nodes approach being the simplest to understand. The difficulty of having to change a great many things in order to, say, reposition something in a conceptually simple way is mitigated quite a bit by the frames approach illustrated by Gonzalo Medina. Thanks for your thoughts.
    – d3pd
    Jan 23, 2014 at 4:33

You must log in to answer this question.

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