Using the ANNOTATE= Option (gantte21)
/****************************************************************/
/* S A S S A M P L E L I B R A R Y */
/* */
/* NAME: GANTTE21 */
/* TITLE: Using the ANNOTATE= Option (gantte21) */
/* PRODUCT: OR */
/* SYSTEM: ALL */
/* KEYS: GANTT */
/* PROCS: CPM, SORT, GANTT */
/* DATA: */
/* */
/* SUPPORT: UPDATE: */
/* REF: Example 21 in the GANTT Chapter (PM User's Guide) */
/* MISC: Using the ANNOTATE= Option to */
/* a) Print Resource Requirements on a Gantt chart */
/* b) Plot Resource Usage and Resource Availability */
/* on a Gantt Chart */
/* */
/****************************************************************/
/* Activity-on-Arc representation of the project */
data widgres;
input task $ 1-12 days tail head engineer;
if engineer ^= . then engcost = engineer * 200;
datalines;
Approve Plan 5 1 2 2
Drawings 10 2 3 1
Study Market 5 2 4 1
Write Specs 5 2 3 2
Prototype 15 3 5 4
Mkt. Strat. 10 4 6 .
Materials 10 5 7 .
Facility 10 5 7 2
Init. Prod. 10 7 8 4
Evaluate 10 8 9 1
Test Market 15 6 9 .
Changes 5 9 10 2
Production 0 10 11 4
Marketing 0 6 12 .
Dummy 0 8 6 .
;
data widgrin;
input per date7. otype $ 11-18 engineer engcost;
format per date7.;
datalines;
. restype 1 2
. suplevel 1 .
01dec03 reslevel 3 40000
26dec03 reslevel 4 .
;
data holdata;
format hol date7.;
input hol date7. name $ 10-18;
datalines;
25dec03 Christmas
01jan04 New Year
;
options ls=80;
proc cpm date='01dec03'd interval=weekday
data=widgres holidata=holdata resin=widgrin
out=widgsch2 resout=widgrou2;
tailnode tail;
duration days;
headnode head;
holiday hol;
resource engineer engcost / period=per obstype=otype
rule=lst
delayanalysis;
id task;
run;
title2 'Resource Constrained Schedule: Rule = LST';
proc print data=widgsch2;
run;
* set up required pattern statements;
pattern1 c=green v=s; /* duration of a noncrit. activity */
pattern2 c=green v=e; /* slack time for a noncrit. act. */
pattern3 c=red v=s; /* duration of a critical activity */
pattern4 c=red v=e; /* slack time for a supercrit. act. */
pattern5 c=red v=r2; /* duration of a supercrit. act. */
pattern6 c=cyan v=s; /* actual duration of an activity */
pattern7 c=black v=x1; /* break due to a holiday */
pattern8 c=blue v=s; /* res. constrained dur of an act. */
title c=black h=1.75 'Gantt Example 21';
title2 c=black h=1.25 'Displaying Resource Requirements';
* set background to white and text to black;
goptions ctext=black cback=white;
* set graphics options;
goptions vpos=50 hpos=100 htext=1.01;
* begin annotate process;
* compile annotate macros;
%annomac;
* create annotate data set for first chart;
data anno1;
%dclanno; /* set length and type for annotate variables */
%system(2,2,4); /* define annotate reference system */
set widgsch2;
length lab $20;
length TEXT $ 37;
Y1 = _n_;
lab=' ';
if _n_=1 then do;
%label('01dec03'd,13,
'Format: Engineers per day, Total cost',*,0,0,1.2,brush,6);
end;
if engineer ^= . then do;
/* create a text label */
lab = put(engineer, 1.) || " Engineer";
if engineer > 1 then lab = trim(lab) || "s";
if days > 0 then lab = trim(lab) || ", " ||
put(engcost*days, dollar7.);
/* position the text label */
if y1 < 10 then do;
x1 = max(l_finish, s_finish) + 2;
%label(x1,y1,lab,black,0,0,1.0,brush, 6);
end;
else do;
x1 = e_start - 2;
%label(x1,y1,lab,black,0,0,1.0,brush, 4);
end;
end;
run;
* annotate the Gantt chart;
proc gantt graphics data=widgsch2 holidata=holdata annotate=anno1;
chart / pcompress holiday=(hol) interval=weekday increment=7
ref='1dec03'd to '21mar04'd by week
cref=blue lref=2
dur=days cmile=black caxis=black;
id task;
run;
* calculate scaling factor for cost curve;
data _null_;
set widgrou2 end=final;
retain maxcost;
if aengcost > maxcost then maxcost=aengcost;
if final then call symput('cscale',14/maxcost);
run;
* create annotate data set for second chart;
data anno2;
%dclanno; /* set length and type for annotate variables */
%system(2,2,4); /* define annotate reference system */
set widgrou2;
length lab $16;
length TEXT $27;
x1=_time_;
y1=15-aengcost*symget('cscale');
y2=15-rengineer;
lab=' ';
if _n_=1 then do;
/* print labels */
do i = 1 to 14 by 1;
lab=put( (15-i) / symget('cscale'), dollar7.);
%label('21mar04'd,i,lab,black,0,0,1.0,,4);
end;
do i = 0 to 4 by 1;
lab=put(i,1. );
%label('01dec03'd,15-i,lab,black,0,0,1.0,,6);
end;
%label('01dec03'd,10,
'Resource Usage: Engineers',*,0,0,1.2,,6);
%label('02jan04'd,4,
'Resource Availability: Cost',*,0,0,1.2,,6);
%move(x1,y1);
%push;
end;
else do;
/* draw cost availability curve */
%pop;
when='a';
%draw(x1,y1,black,1,2);
%push;
/* draw engineer usage barchart */
when='b';
if y2 <= 14 then do;
%bar(x1,15,x1+1,y2,blue,0,l1);
end;
end;
run;
title c=black h=1.75 'Gantt Example 21';
title2 c=black h=1.25
'Plotting Resource Usage and Resource Availability';
* annotate the Gantt chart;
proc gantt graphics data=widgsch2 holidata=holdata annotate=anno2;
chart / pcompress holiday=(hol) interval=weekday increment=7
mindate='1dec03'd maxdate='21mar04'd
ref='1dec03'd to '21mar04'd by week
cref=blue lref=2
dur=days cmile=black caxis=black;
id task;
run;