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 have this code that generates the process gantt chart:

\usetikzlibrary{shadows,arrows,positioning}
\begin{tikzpicture}[scale=0.75, transform shape]
      \tikzset{every node/.style={minimum height=2em},
        proc/.style={draw=black, fill=blue!15, drop shadow},
      }

      \node [draw, proc, minimum width=3em] (p2) {P2};
      \node [draw, proc, minimum width=3em, right=0em of p2.east, anchor=west] (p3) {P3};
      \node [draw, proc, minimum width=24em, right=0em of p3.east, anchor=west] (p1) {P1};


      \node [below=of p2.west] {0}  edge [draw] (p2.west);
      \node [below=of p2.east] {3} edge [draw] (p2.east);
      \node [below=of p3.east] {6} edge [draw] (p3.east);
      \node [below=of p1.east] {30} edge [draw] (p1.east);
      \end{tikzpicture}

The output:

Process Gantt Chart

I can see a pattern over here and I can imagine passing the parameters (e.g. p2/3,p3/3,p1/24) to some command that uses some kind of for loop to automatically generate the code. Unfortunately, my TikZ/LaTeX skills are way below that. Can anyone help me get started with automating this?

share|improve this question
3  
Are you aware of the pgfgantt package? –  Marc van Dongen Feb 16 '12 at 8:29
    
I'm not actually looking for a gantt chart. Thanks for that tip, by the way. That might come in handy. The fig I'm trying to create is a simpler timing diagram. –  recluze Feb 16 '12 at 9:53
    
Perhaps this doesn't quite fit, but for timing diagrams there is tikz-timing. –  qubyte Feb 17 '12 at 10:51
    
@recluze: if any of the answers given below do what you need, please consider accepting them. Else, please tell us why they don't. –  romeovs Feb 17 '12 at 20:27
add comment

2 Answers

up vote 4 down vote accepted

Try this:

\newcommand{\gantt}[1]{

    \newcounter{ganttnum}
    \setcounter{ganttnum}{0}

     \foreach \i/\j in {#1}{
         \draw (\theganttnum em,0)node [proc, minimum width=\j em, anchor=south west] (\i) {\i};
         \draw (\theganttnum em,0) -- ++(0,-0.5) node[below]{\theganttnum};
         \addtocounter{ganttnum}{\j}
     }
     \draw (\theganttnum em,0) -- ++(0,-0.5) node[below]{\theganttnum};
}

\begin{tikzpicture}[scale=0.75,transform shape]
    \gantt{P2/3,P3/3,P1/24}
\end{tikzpicture}

\begin{tikzpicture}[scale=0.75,transform shape]
    \gantt{A1/3,A2/10,A3/14,A5/3,A4/3}
\end{tikzpicture}

It creates a newcommand that takes 1 parameter, which should be a comma seperated list of the form P1/3,P2/5,P3/12. Every item has two parts: the node name (before / and the width of the node after the /).

gantt, third try

This allows you to add an arbitrary number of nodes, with arbitrary names and widths.

A bit of explanation to the code:

Tikz' \foreach can take multiples for looping over eg. A/1, B/2, ... this comes in handy to keep the names and widths of the nodes togheter while looping over them.

I first let a counter gantt be set to 0. Each step in the loop adds the width of the node that gets added in that step be added to this counter, so the counter can be used to determine where the next node should be.

share|improve this answer
    
Thanks for this but the problem is that Ps are hard-coded. I want them to be "flexible". –  recluze Feb 16 '12 at 9:47
    
@recluze: Okay, modified the code for more flexibility. lthoug this doesn't allow for a different number of nodes. I'll look into the for loop thing and post something up quick. –  romeovs Feb 16 '12 at 11:27
    
@recluze the new code should do it. –  romeovs Feb 16 '12 at 11:41
    
That works perfectly. Exactly what I was looking for. The key was to use absolute placement, I think instead of right keys. –  recluze Feb 18 '12 at 3:23
    
@romeovs \newcounter{ganttnum} inside the macro is not very good ! –  Alain Matthes May 8 '12 at 15:00
show 1 more comment

You can start with this code

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shadows,arrows,positioning}

\begin{document}
\begin{tikzpicture}[scale=0.75, transform shape]
      \tikzset{every node/.style={minimum height=2em},
        proc/.style={draw=black, fill=blue!15, drop shadow},
      }

\node [draw, proc, minimum width=3em] (p2) {P2};

\foreach \i/\j/\k in {3/2/3,1/3/24}
      \node [draw, proc, minimum width=\k em, right=0em of p\j.east, anchor=west] (p\i) {P\i};


\node [below=of p2.west] {0}  edge [draw] (p2.west);
\foreach \i/\j in {2/3,3/6,1/30}
      \node [below=of p\i.east] {\j} edge [draw] (p\i.east);
\end{tikzpicture}
\end{document}

An updated version. Same loop will draw nodes and labels and a counter will take care of initial position of nodes. Once loop finishes, 0 mark is drawn.

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shadows,arrows,positioning}

\begin{document}
\begin{tikzpicture}[scale=0.75, transform shape]
      \tikzset{every node/.style={minimum height=2em},
        proc/.style={draw=black, fill=blue!15, drop shadow},
      }

\newcounter{pos}
\setcounter{pos}{0}

\foreach \process/\width in {2/3,3/3,1/24}
{
   \node [draw, proc, minimum width=\width em,  anchor=west] (p\process) at (\thepos em,0) {P\process};
    \addtocounter{pos}{\width}
    \node [below=of p\process.east] {\thepos} edge [draw] (p\process.east);
}
\node [below=of p2.west] {0} edge [draw] (p2.west);

\end{tikzpicture}

\end{document}
share|improve this answer
    
Thanks for the for loop. That helps a lot. I don't see why I have to pass both 3/2/3,1/3/24 and 2/3,3/6,1/30. Shouldn't it be possible to somehow calculate the second set of values from the first? –  recluze Feb 16 '12 at 10:04
    
@recluze I've updated the answer with a version which calculates values. It uses absolutes positions but I don't know to do it better now. –  Ignasi Feb 17 '12 at 10:02
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.