Un diagramme de Gantt en TikZ

Il existe des paquets pour faire des diagrammes de Gantt en TikZ, mais ils font des trucs beaucoup trop compliqués pour ce que j’ai besoin de faire. Donc j’ai fait le mien avec de bêtes rectangles.

J’ai besoin de :

  • plusieurs work packages
  • délimiter les années
  • avoir plusieurs personnes en parallèles dans un même work package
  • pouvoir mettre des personnes à cheval sur plusieurs work packages

Voici le résultat :

Capture d’écran 2016-08-08 à 15.46.22

Les dimensions

Première chose à faire : régler les tailles. Ici on a :

  • la hauteur de chaque WP (on peut en définir plusieurs pour avoir des hauteurs différentes)
  • la hauteur des barres qui vont être utilisées pour les personnes
  • la largeur utilisée pour une année
  • l’écart entre deux personnes

\def\hauteur{2.6} %% hauteur d'un WP
\def\annee{3} %% largeur d'une annee
\def\taskH{.8} %% hauteur d'une personne
\def\ecart{.2} %% ecart entre deux personnes

On peut, à partir de là, demander à TikZ de calculer l’endroit où va se trouver le bord supérieur de chaque WP, mais pour aller vite j’ai défini des variables pour ça aussi. Dans cet exemple, je définis trois work packages.

\def\hauteurWPun{\hauteur*3} % hauteur du bord sup des WP
\def\hauteurWPdeux{\hauteur*2}
\def\hauteurWPtrois{\hauteur*1}

Le cadre autour

C’est très simple : il s’agit d’un rectangle avec des marques pour les années. J’aime bien avoir aussi une marque verticale pour les années.

%% Cadre
\foreach \y in {0, 1, 2, 3 } {
\draw (0, \y*\hauteur ) -- ( 6*\annee, \y*\hauteur );
}
\foreach \y in {1, 2, 3} {
\node at ( -.7, 3*\hauteur - \y*\hauteur+\hauteur/2 ) { $WP_\y$};
}
\foreach \x in {0, 6 } {
\draw (\x*\annee, 0 ) -- ( \x*\annee, 3*\hauteur );
\node at (\x*\annee, 3*\hauteur+.4 ) {
\pgfmathparse{\x*10}
\pgfmathprintnumber{\pgfmathresult}};
}
\foreach \x in {1.2, 2.4, 3.6, 4.8 } {
\draw [dashed] (\x*\annee, 0 ) -- ( \x*\annee, 3*\hauteur );
\node at (\x*\annee, 3*\hauteur+.4 ) {
\pgfmathparse{\x*10}
\pgfmathprintnumber{\pgfmathresult}};
}

Pour faire des WP de hauteurs différentes, on peut définir la position de chaque WP en fonction de celle qui le précède :

\def\hauteurWPquatre{\hauteur}
\def\hauteurWPtrois{\hauteur + \hauteurWPquatre}
\def\hauteurWPdeux{\hauteur + \taskH + \hauteurWPtrois}
\def\hauteurWPun{\hauteur + \hauteurWPdeux}
\def\hauteurWPzero{\hauteur + \hauteurWPun}

Les lignes horizontales sont donc tracées en fonction de ces hauteurs ainsi que les noms des WP :

\def\tableofhauteurs{0, \hauteurWPzero, \hauteurWPun, \hauteurWPdeux, \hauteurWPtrois, \hauteurWPquatre }
\foreach \y in \tableofhauteurs {
\draw (0, \y) -- ( 4*\annee, \y);
}
\foreach[count=\cnt from 0] \y in \tableofhauteurs {
\ifnum\cnt <5
\node at ( -.7, \y - \hauteur/2 ) { $WP_\cnt$};
\fi

Les gens dans les WP

Une personne est simplement représentée par un rectangle. On utilise les variables définies plus haut pour calculer les coordonnées du rectangle :

  • Pour les moments dans le temps, on multiplie la largeur d’une année \annee par le nombre de mois divisé par 10. Par exemple, une abscisse à la troisième année vaudra  3*1.2*\annee
  • Pour la hauteur, il faut calculer par rapport au bord supérieur du WP (rappelez-vous les variables \hauteurWPun, \hauteurWPdeux et \hauteurWPtrois), les personnes déjà placées dans ce WP (variable \taskH) et l’écart entre les personnes (variable \ecart)

Par exemple, pour une personne commençant année 0, terminant en fin d’année 2 (3*12 mois plus tard), tout en haut du WP1 :

\draw [fill=blue!30]( 0, \hauteurWPun - \ecart ) rectangle ( 3*1.2*\annee, \hauteurWPun - \ecart - \taskH) node[pos=.5] {PhD student 1};

Juste en-dessous de lui, commençant année 0 et terminant en fin d’année 0 (12 mois plus tard), et donc décalé de \écart + \taskH + \ecart par rapport au haut du WP1:

\draw [fill=blue!30]( 0, \hauteurWPun - \taskH - 2*\ecart ) rectangle (
1*1.2*\annee, \hauteurWPun - 2*\ecart - 2*\taskH) node[pos=.5] {post doc 1};

Le mec hachuré

Pour des raisons de présentation, j’ai utilisé une couleur par work package. Or, j’ai besoin de mettre un personne à cheval sur deux work packages. Je vous passe le calcul des coordonnées (il suffit d’utiliser \taskH/2), mais surtout, j’avais envie de le hachurer en utilisant les couleurs des deux work packages sur lesquels il est à cheval. Pour avoir les hachures kivonbien (largeur et écartement qui se voient bien), il faut définir un pattern :

\tikzset{
hatch distance/.store in=\hatchdistance,
hatch distance=10pt,
hatch thickness/.store in=\hatchthickness,
hatch thickness=4pt
}
\makeatletter
\pgfdeclarepatternformonly[\hatchdistance,\hatchthickness]{flexible hatch}
{\pgfqpoint{0pt}{0pt}}
{\pgfqpoint{\hatchdistance}{\hatchdistance}}
{\pgfpoint{\hatchdistance-1pt}{\hatchdistance-1pt}}%
{
\pgfsetcolor{\tikz@pattern@color}
\pgfsetlinewidth{\hatchthickness}
\pgfpathmoveto{\pgfqpoint{0pt}{0pt}}
\pgfpathlineto{\pgfqpoint{\hatchdistance}{\hatchdistance}}
\pgfusepath{stroke}
}
\makeatother

Encore une petite saleté pour hachurer : j’ai superposé deux rectangles, un bleu (celui avec \fill [color=blue!30]) et un hachuré vert (avec \draw [pattern=flexible hatch, pattern color=green!30 ]).

\fill [color=blue!30]( 3*1.2*\annee, \hauteurWPun - 3*\ecart-2*\taskH ) rectangle ( 5*1.2*\annee, \hauteurWPun - 2.2 - \taskH);
\draw [pattern=flexible hatch, pattern color=green!30 ]( 3*1.2*\annee, \hauteurWPun - 3*\ecart-2*\taskH ) rectangle ( 5*1.2*\annee, \hauteurWPun - 3*\ecart-2*\taskH - \taskH) node[pos=.5] {engineer};

Et voilà !

Un diagramme de Gantt en TikZ

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l’aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s