PSTricks and project management

Denis Girou Denis.Girou at idris.fr
Sat Apr 1 01:16:14 CEST 2000


-----------------------------------------------------------------------------
This is the PSTricks mailing list, devoted to discussions about computational
graphics in (La)TeX using the PSTricks package from Timothy van Zandt.
For help using this mailing list, see instructions at the end of message.
-----------------------------------------------------------------------------

>>>>> "Marc.Garriga" == Marc Garriga <marcg at fib.upc.es> writes:

    Marc.Garriga>     I have just started using PSTricks in LaTeX and I need to make a
    Marc.Garriga> Gantt diagram within PSTricks tools.

    Marc.Garriga>     The Gantt Diagram is for control the tasks of one project, so I need
    Marc.Garriga> a command that make me a box with one label, with and height, ...

    Marc.Garriga> ...

    Marc.Garriga> My only question is: I'm on the right way? or perhaps there is any other
    Marc.Garriga> way more easy?

  First, you may take a look at existing packages. I never use Gantt diagrams
and can make a mistake on what they are exactly, but I think you could find
something close at least in the TeXProject package from Stéphane Bressan and
Eitan Gurari. It is based on the (underestimate, in my opinion) (Al)DraTeX
package. You can look at TeXProject on
http://www.cis.ohio-state.edu/~gurari/systems.html
and CTAN/graphics/dratex/TeXProject.sty

  Nevertheless, it is clear that PSTricks is well suited for such kind of
diagrams. Personaly, if I had to develop such a package, I will follow the way 
shown below (in fact, it is the same way that you can find in the `pst-poly'
and `pst-osci' contributions, for instance). The main difference is that
I define a specifix environment for the chart and another macro used for each
entry.

  But this is only an one-evening exercice. And as I will never really use it, 
I do not want to go deeper, but I suppose that a lot of other parameters and
customizations would be useful. It will obviously be nice if somebody would be
interested to develop such a package. But, at least, it can show that in less
than 200 lines of code we can already have a powerful, flexible and with
rather satisfaying outputs solution.

D.G.

\documentclass[a4paper]{article}

\usepackage{lscape}
\usepackage{pstcol}
\usepackage{pst-grad}
\usepackage{pst-key}
\usepackage{multido}

\makeatletter

% "pspicture" environment or not?
\newif\ifPst at PstPicture
\define at key{psset}{PstPicture}[true]{%
\@nameuse{Pst at PstPicture#1}}

% Intervals to show?
\newif\ifPst at GanttChartShowIntervals
\define at key{psset}{ChartShowIntervals}[true]{%
\@nameuse{Pst at GanttChartShowIntervals#1}}

% Style for the tasks
\define at key{psset}{TaskStyle}{\def\psk at GanttTaskStyle{#1}}

% Name for unit interval
\define at key{psset}{ChartUnitIntervalName}{%
\def\psk at GanttChartUnitIntervalName{#1}}

% Name for basic unit
\define at key{psset}{ChartUnitBasicIntervalName}{%
\def\psk at GanttChartUnitBasicIntervalName{#1}}

% Unit interval for the tasks (7 for a week, 30 for a month, etc.)
% Warning: define it before "TaskUnitType"!
\define at key{psset}{TaskUnitIntervalValue}{%
\pst at cntg=#1\relax
\edef\psk at GanttTaskUnitIntervalValue{\the\pst at cntg}}

% Unit type for the tasks (UnitIntervalName or UnitBasicIntervalName)
\define at key{psset}{TaskUnitType}{%
\edef\psk at GanttTaskUnitValue{#1}%
% Validation of the parameter
\ifx\psk at GanttTaskUnitValue\psk at GanttChartUnitIntervalName
  \edef\psk at GanttTaskUnitValue{\psk at GanttTaskUnitIntervalValue}%
\else
  \ifx\psk at GanttTaskUnitValue\psk at GanttChartUnitBasicIntervalName
    \def\psk at GanttTaskUnitValue{1}%
  \else
    {\@pstrickserr{GanttTaskUnitType must be `\psk at GanttChartUnitIntervalName'
                   or `\psk at GanttChartUnitBasicIntervalName'
                  (and not `\psk at GanttTaskUnitValue')}\@eha}%
  \fi
\fi}

% Outside label for the tasks
\define at key{psset}{TaskOutsideLabel}{\def\psk at GanttTaskOutsideLabel{#1}}

% Inside label for the tasks
\define at key{psset}{TaskInsideLabel}{\def\psk at GanttTaskInsideLabel{#1}}

% Maximum outside size label for the tasks (in unit TaskUnitType !)
\define at key{psset}{TaskOutsideLabelMaxSize}{%
\pst at cntg=#1\relax
\edef\psk at GanttTaskOutsideLabelMaxSize{\the\pst at cntg}}

% Default values
% --------------
% pspicture environment, don't show intervals, default task style,
% unit for tasks is a week (so 7 days), no outside and inside labels
\setkeys{psset}{%
PstPicture=true,ChartShowIntervals=false,TaskStyle=TaskStyleDefault,
ChartUnitIntervalName=Week,ChartUnitBasicIntervalName=Day,
TaskUnitIntervalValue=7,TaskUnitType=Week,
TaskOutsideLabel=,TaskInsideLabel=,TaskOutsideLabelMaxSize=0}

\newpsstyle{TaskStyleDefault}{fillstyle=solid,fillcolor=yellow}

% The environment \PstGanttChart
% ------------------------------

% Syntax: \PstGanttChart[parameters]{Number of tasks}{Number of days}
\def\PstGanttChart{\@ifnextchar[\PstGanttChart at i{\PstGanttChart at i[]}}

\def\PstGanttChart at i[#1]#2#3{%
\begingroup
\setkeys{psset}{unit=0.1,#1}    % Affectation of local parameters
%
\ifPst at PstPicture               % "pspicture" environment
  \pst at cnta=\psk at GanttTaskOutsideLabelMaxSize
  \multiply\pst at cnta\psk at GanttTaskUnitValue
  %
  \pst at cntb=#2
  \multiply\pst at cntb by 5
  \advance\pst at cntb\@ne
  %
  \pst at cntc=#3
  \multiply\pst at cntc\psk at GanttTaskUnitValue
  \advance\pst at cntc\tw@
  %
  \ifPst at GanttChartShowIntervals
    \pspicture(-\pst at cnta,-\pst at cntb)(\pst at cntc,2)
  \else
    \pspicture(-\pst at cnta,-\pst at cntb)(\pst at cntc,0)
  \fi
\fi
\psframe(0,-\pst at cntb)(\pst at cntc,0)
%
\ifPst at GanttChartShowIntervals
  % We will show the intervals
  \pst at cnta=#3
  \multiply\pst at cnta\psk at GanttTaskUnitValue
  \divide\pst at cnta\psk at GanttTaskUnitIntervalValue
  \advance\pst at cnta\@ne
  %
  \pst at cntb=#2
  \multiply\pst at cntb by 5
  \advance\pst at cntb\@ne
  %
  \pst at dima=\psk at GanttTaskUnitIntervalValue pt
  \divide\pst at dima\tw@
  \advance\pst at dima\@ne pt
  \pst at dimtonum{\pst at dima}{\pst at tempa}
  %
  \multido{\iInterval=1+1,\iIntervalPos=1+\psk at GanttTaskUnitIntervalValue,
           \nIntervalPos=\pst at tempa+\psk at GanttTaskUnitIntervalValue.0}{\pst at cnta}{%
    \ifnum\iInterval=\pst at cnta
      \psline(\iIntervalPos,0)(\iIntervalPos,1.5)
      \psline[linestyle=dotted](\iIntervalPos,-\pst at cntb)(\iIntervalPos,0)
    \else
      \rput(\nIntervalPos,1){\psk at GanttChartUnitIntervalName\space\iInterval}
      \psline(\iIntervalPos,0)(\iIntervalPos,1.5)
      \psline[linestyle=dotted](\iIntervalPos,-\pst at cntb)(\iIntervalPos,0)
    \fi}
\fi}

\def\endPstGanttChart{%
\ifPst at PstPicture
  \endpspicture                 % End of "pspicture" environment
\fi
\endgroup}

% The macro \PstGanttTask
% -----------------------

\newcount\pst at GanttTaskCnt
\pst at GanttTaskCnt=\z@

% Syntax: \PstGanttTask[parameters]{Start}{Length}
\def\PstGanttTask{\@ifnextchar[\PstGanttTask at i{\PstGanttTask at i[]}}

\def\PstGanttTask at i[#1]#2#3{
\advance\pst at GanttTaskCnt\m at ne
\begingroup
\setkeys{psset}{#1}%            % Affectation of local parameters
% Frame
\pst at cnta=\psk at GanttTaskUnitValue
\multiply\pst at cnta by #2
\advance\pst at cnta\@ne
%
\pst at cntb=\psk at GanttTaskUnitValue
\multiply\pst at cntb by #3
\advance\pst at cntb\pst at cnta
%
\pst at cntc=\pst at GanttTaskCnt
\multiply\pst at cntc by 5
%
\pst at cntd=\pst at cntc
\advance\pst at cntd by 4
%
\psframe[style=\psk at GanttTaskStyle](\pst at cnta,\pst at cntc)(\pst at cntb,\pst at cntd)
% Inside label
\ifx\psk at GanttTaskInsideLabel\empty
\else
  \pst at dima=\pst at cnta pt
  \advance\pst at dima\pst at cntb pt
  \divide\pst at dima\tw@
  \pst at dimtonum{\pst at dima}{\pst at tempa}
  %
  \pst at dimb=\pst at cntc pt
  \advance\pst at dimb\pst at cntd pt
  \divide\pst at dimb\tw@
  \pst at dimtonum{\pst at dimb}{\pst at tempb}
  %
  \rput(\pst at tempa,\pst at tempb){\psk at GanttTaskInsideLabel}
\fi
% Outside label
\ifx\psk at GanttTaskOutsideLabel\empty
\else
  \pst at dimb=\pst at cntc pt
  \advance\pst at dimb\pst at cntd pt
  \divide\pst at dimb\tw@
  \pst at dimtonum{\pst at dimb}{\pst at tempb}
  \rput[r](-1.5,\pst at tempb){\psk at GanttTaskOutsideLabel}
\fi
\endgroup}

\makeatother

\begin{document}

\newpsstyle{Important}{fillstyle=solid,fillcolor=red}
\newpsstyle{NotImportant}{fillstyle=vlines}

\begin{PstGanttChart}{5}{7}
  \PstGanttTask{0}{3}
  \PstGanttTask{2}{1}
  \PstGanttTask[TaskStyle=Important,TaskInsideLabel=Important]{2}{5}
  \PstGanttTask[TaskStyle=NotImportant]{4}{2}
  \PstGanttTask{5}{2}
\end{PstGanttChart}

\begin{PstGanttChart}[yunit=2]{5}{7}
  \PstGanttTask{0}{3}
  \PstGanttTask{2}{1}
  \PstGanttTask[TaskStyle=Important,TaskInsideLabel=Important]{2}{5}
  \PstGanttTask[TaskStyle=NotImportant]{4}{2}
  \PstGanttTask{5}{2}
\end{PstGanttChart}

\begin{PstGanttChart}[unit=2,TaskOutsideLabelMaxSize=1,
                      ChartShowIntervals]{5}{7}
  \PstGanttTask[TaskOutsideLabel={Task 1}]{0}{3}
  \PstGanttTask[TaskOutsideLabel={Task 2},TaskUnitType=Day]
               {15}{3} % 3 days starting at day 15
  \PstGanttTask[TaskStyle=Important,TaskOutsideLabel={Task 3},
    TaskInsideLabel={\Large\textcolor{white}{\textbf{Important}}}]{2}{5}
  \PstGanttTask[TaskStyle=NotImportant,TaskOutsideLabel={Task 4}]{4}{2}
  \PstGanttTask[TaskOutsideLabel={Task 5}]{5}{2}
\end{PstGanttChart}

\begin{PstGanttChart}[yunit=2,ChartUnitIntervalName=Month,
                      TaskUnitIntervalValue=30,TaskUnitType=Month,
                      ChartShowIntervals]{3}{4}
  \PstGanttTask[TaskInsideLabel={Task 1}]{0}{1}
  \PstGanttTask[TaskInsideLabel={Task 2},TaskUnitType=Day]
               {24}{40} % 40 days starting at day 24
  \PstGanttTask[TaskInsideLabel={Task 3}]{2}{2}
\end{PstGanttChart}

\begin{PstGanttChart}[yunit=1.5,ChartUnitIntervalName=Year,
                      ChartUnitBasicIntervalName=Month,
                      TaskUnitIntervalValue=12,TaskUnitType=Year,
                      ChartShowIntervals]{4}{4}
  \PstGanttTask[TaskInsideLabel={Task 1}]{0}{1}
  \PstGanttTask[TaskInsideLabel={Task 2},TaskUnitType=Month]
               {6}{24} % 24 months starting at month 6
  \PstGanttTask[TaskInsideLabel={Task 3}]{2}{2}
  \PstGanttTask[TaskInsideLabel={Task 4}]{3}{1}
\end{PstGanttChart}

\definecolor{LightCyan}   {rgb}{0.88,1.,1.}
\definecolor{Orange}      {rgb}{1.,0.65,0.}
\definecolor{PaleGreen}   {rgb}{0.6,0.98,0.6}
\definecolor{Pink}        {rgb}{1.,0.75,0.8}

\psset{gradmidpoint=0,fillstyle=gradient,gradbegin=LightCyan,gradend=white}
\newpsstyle{TaskStyleA}{gradbegin=cyan,gradend=blue}
\newpsstyle{TaskStyleB}{gradbegin=red,gradend=Pink}
\newpsstyle{TaskStyleC}{gradbegin=yellow,gradend=Orange}
\newpsstyle{TaskStyleD}{gradbegin=green,gradend=PaleGreen}

\begin{landscape}
\begin{PstGanttChart}[yunit=2.5,xunit=3.5,ChartUnitIntervalName=Semaine,
                      ChartUnitBasicIntervalName=Jour,TaskUnitType=Jour,
                      TaskOutsideLabelMaxSize=14,ChartShowIntervals]{8}{43}
  \psset{gradangle=90,TaskStyle=TaskStyleA}
  \PstGanttTask[TaskOutsideLabel={\'Etude}]{0}{10}
  \PstGanttTask[TaskOutsideLabel={R\'edaction dossier}]{6}{7}
  \PstGanttTask[TaskOutsideLabel={Relecture et corrections}]{14}{2}
  \PstGanttTask[TaskOutsideLabel={Soumission},TaskStyle=TaskStyleB]{17}{1}
  \psset{TaskStyle=TaskStyleC}
  \PstGanttTask[TaskOutsideLabel={R\'ealisation}]{25}{14}
  \PstGanttTask[TaskOutsideLabel={Tests}]{35}{6}
  \PstGanttTask[TaskOutsideLabel={V\'erification}]{39}{3}
  \PstGanttTask[TaskOutsideLabel={Recette},TaskStyle=TaskStyleD]{42}{1}
\end{PstGanttChart}
\end{landscape}

\end{document}

-----------------------------------------------------------------------------
The list interface (subscription, information, access to the archives) is on:
http://www.tug.org/cgi-bin/lwgate/pstricks
Otherway to unsubscribe, send mail to pstricks-request at mail.tug.org
with a blank subject and in body the line unsubscribe <email-address>
-----------------------------------------------------------------------------



More information about the PSTricks mailing list