source: anr/gantt.l @ 36

Last change on this file since 36 was 36, checked in by coach, 14 years ago
  • Property svn:keywords set to Revision HeadURL Id
File size: 13.6 KB
Line 
1%{
2#define COLOR_Milestone  "gtcMilestone"
3#define COLOR_BOX_HEAVY "gtcBoxHeavy"
4#define COLOR_BOX_LIGHT "gtcBoxLight"
5
6#define PICT_TOPSEP   3
7#define PICT_BOTSEP   3
8#define PICT_LEFTSEP  3
9#define PICT_RIGHTSEP 3
10#define PICT_VSEP     2
11#define PICT_HSEP     2
12
13#define PICT_MONTHHEIGHT 5  // police height
14#define PICT_MONTHWIDTH  (10./3.)
15
16#define TASK_VSEP  2
17#define TASK_BGC0       "gtcTaskBG0"
18#define TASK_BGC1       "gtcTaskBG1"
19
20#define DELIVRABLE_VSEP   1
21#define DELIVRABLE_HEIGHT 3
22#define DELIVRABLE_LABELWIDTH  10
23#define DELIVRABLE_LABELHEIGHT DELIVRABLE_HEIGHT
24#define DELIVRABLE_TITLEWIDTH  35
25#define DELIVRABLE_TITLEHEIGHT DELIVRABLE_HEIGHT
26#define DELIVRABLE_BOXHEIGHT   (DELIVRABLE_HEIGHT)
27
28typedef struct _Tlivrable {
29    int tn,stn,dn,vn;  // task, sub-task, number
30    char v;            // 0, 1, 2, ..., F
31    char* title;
32    int   bm,em;   // mois de bebut et de fin
33    // these fields are filled by the program for data[tn][0][0][0]
34    double task_y;           // top of task
35    double task_dy;          // bot of task is task_y+task_dy
36    // these fields are filled by the program for data[tn][stn][dn][0]
37    struct _Tlivrable
38            **vers; // null termiated (vers[i] = &data[tn][stn][dn][i])
39    int    nbvers;     // nombre de vers
40    double height;     // height of livrable
41    // int del_bm,del_em;    // mois de bebut et de fin cummule
42    // these fields are filled by the program for all elements
43    int   nbTitleLines;
44    char* titleLines[5]; // null termiated
45} Tlivrable;
46
47#define T_MAX 10
48#define S_MAX 10
49#define D_MAX 10
50#define V_MAX 10
51Tlivrable* data[T_MAX][S_MAX][D_MAX][V_MAX];
52
53int milestones[100];
54
55char* gen_label_base(char* buf,Tlivrable*p)
56    { sprintf(buf,"D%d%d%d",p->tn,p->stn,p->dn); return buf; }
57char* gen_label_vers(char* buf,Tlivrable*p)
58    { if (p->nbvers<=1) sprintf(buf,""); else sprintf(buf,"V%c",p->v); return buf; }
59char* gen_label_full(char* buf,Tlivrable*p)
60    { char b[100],v[100]; gen_label_base(b,p); gen_label_vers(v,p);
61      sprintf(buf,"%s%s%s",b,*v?"-":"",v); return buf; }
62
63void print_put(double x,double y, const char* object)
64    { printf("\\put(%.2f,%.2f){%s}\n",x,y,object); }
65void print_hline(double x,double y, double len, const char* color)
66{
67    char object[1024];
68    if (color!=0) { printf("\\bgroup\\color{%s}\n",color); }
69    sprintf(object,"\\line(1,0){%.2f}",len);
70    print_put(x,y,object);
71    if (color!=0) { printf("\\egroup\n"); }
72}
73void print_vline(double x,double y, double len, const char* color)
74{
75    char object[1024];
76    if (color!=0) { printf("\\bgroup\\color{%s}\n",color); }
77    sprintf(object,"\\line(0,1){%.2f}",len);
78    print_put(x,y,object);
79    if (color!=0) { printf("\\egroup\n"); }
80}
81void print_box(
82    int filled, char* vers, // vers may be 0,
83    double x,double y, double dx, double dy,
84    const char* boxcolor,  // may be 0 (default COLOR_BOX_HEAVY)
85    const char* bgcolor,   // may be 0 (not set)
86    const char* textcolor //  may be 0 (black)
87){
88    double tn=.4;
89    char object[1024];
90    if ( boxcolor==0 ) boxcolor = COLOR_BOX_HEAVY;
91    if ( filled==1 ) {
92        sprintf(object,
93            "\\fcolorbox{black}{%s}{\\makebox(%.2f,%.2f){}}",
94                boxcolor,dx-2-tn,dy-2-tn);
95        print_put(x,y+1,object);
96    } else {
97        double tn2=tn/2;
98        double e=.1;
99        printf("\\bgroup\\color{%s}\n",boxcolor);
100        printf("\\linethickness{%.2fmm}\n",tn);
101        print_hline(x+tn2-e ,y,    dx     ,0);
102        print_hline(x+tn2-e ,y+dy, dx     ,0);
103        print_vline(x+tn-e  ,y+e,  dy-2*e ,0);
104        print_vline(x+dx-2*e,y+e,  dy-2*e ,0);
105        printf("\\egroup\n");
106    }
107    if (vers) {
108        sprintf(object,"\\begin{tiny}\\textbf{%s}\\end{tiny}",vers);
109        print_put(x+1,y+.5,object);
110    }
111}
112
113void gen_titleLines(Tlivrable*p)
114{
115    const char* macro="\\ganttlf";
116    char* pc = p->title;
117    char* pc2;
118
119    if (pc==0) return;
120   
121    while ( (pc2=strstr(pc,macro))!=0 ) {
122        char c = *pc2;
123        *pc2 = 0;
124        p->titleLines[p->nbTitleLines]=strdup(pc);
125        p->nbTitleLines+=1;
126        *pc2=c;
127        pc=pc2+strlen(macro);
128    }
129    p->titleLines[p->nbTitleLines]=strdup(pc);
130    p->nbTitleLines+=1;
131}
132%}
133
134%option noyywrap
135
136%%
137 int tn,stn,dn,v,bm,em; char* title;
138#.*\n   ;
139T=[0-9]+ { tn=atoi(yytext+2); }
140T=D[0-9]+ { tn=atoi(yytext+3); }
141S=[0-9]+ { stn=atoi(yytext+2); }
142D=[0-9]+ { dn=atoi(yytext+2); }
143V=V.     { v=yytext[3]; }
144V=       { v='F'; }
145ML=[0-9]+ {
146        int i;
147        for (i=0 ; milestones[i]!=0 ; i++);
148        milestones[i] = atoi(yytext+3);
149    }
150
151BM=[0-9]+ { bm=atoi(yytext+3); }
152EM=[0-9]+ { em=atoi(yytext+3); }
153TITLE=.*\n {
154        char* pc=yytext+6;
155        yytext[yyleng-1]=0;
156        while ( *pc==' ' || *pc=='\t' ) pc+=1;
157        title=strdup(pc);
158        Tlivrable* p= (Tlivrable*) calloc(sizeof(*p),1);
159        p->tn = tn;
160        p->stn = stn;
161        p->dn = dn;
162        p->v  = v;
163        p->title = title;
164        p->bm = bm;
165        p->em = em;
166        gen_titleLines(p);
167
168        for (v=0; data[tn][stn][dn][v]!=0 ; v++);
169        data[tn][stn][dn][v] = p;
170fprintf(stderr,"ADDED: %d %d %d %d\n",tn,stn,dn,v);
171//{int i,tn=0; fprintf(stderr,"CURR:t=%d:: ",tn); for (i=0; i<S_MAX ; i++) fprintf(stderr,"%d:%p ",i,data[tn][i][0][0]); fprintf(stderr,"\n"); }
172    }
173.|\n ;
174%%
175
176void prepare0()
177{
178int tn,stn,dn,v;
179int i0,i1,i;
180    for (tn=0 ; tn<T_MAX ; tn++)
181    for (stn=0; stn<S_MAX; stn++) {
182//fprintf(stderr,"AVANT:t=%d:%d:: ",tn,stn); for (i=0; i<D_MAX ; i++)
183//fprintf(stderr,"%d:%p ",i,data[tn][stn][i][0]); fprintf(stderr,"\n");
184        while (1) {
185            for (i0=0 ; i0<D_MAX ; i0++)
186                if (data[tn][stn][i0][0] == 0) break;
187            for (i1=i0+1 ; i1<D_MAX ; i1++)
188                if (data[tn][stn][i1][0] != 0) break;
189            if (i1>=D_MAX) break;
190            // shift
191            for (i=0 ; (i1+i)<D_MAX ; i++)
192                for (v=0;v<V_MAX;v+=1) {
193                    data[tn][stn][i0+i][v] = data[tn][stn][i1+i][v];
194                    data[tn][stn][i1+i][v] = 0;
195                }
196        }
197//fprintf(stderr,"AVANT:t=%d:%d:: ",tn,stn); for (i=0; i<D_MAX ; i++)
198//fprintf(stderr,"%d:%p ",i,data[tn][stn][i][0]); fprintf(stderr,"\n");
199    }
200}
201void prepare1()
202{
203int tn,stn,dn,v;
204int i0,i1,i;
205    for (tn=0 ; tn<T_MAX ; tn++) {
206//fprintf(stderr,"AVANT:t=%d:: ",tn,i0,i1); for (i=0; i<S_MAX ; i++) fprintf(stderr,"%d:%p ",i,data[tn][i][0][0]); fprintf(stderr,"\n");
207        while (1) {
208            for (i0=0 ; i0<S_MAX ; i0++)
209                if (data[tn][i0][0][0] == 0) break;
210            for (i1=i0+1 ; i1<S_MAX ; i1++)
211                if (data[tn][i1][0][0] != 0) break;
212//fprintf(stderr,"%d %d %d\n",tn,i0,i1);
213            if (i1>=S_MAX) break;
214            // shift
215            for (i=0 ; (i1+i)<S_MAX ; i++)
216                for (dn=0;dn<D_MAX;dn+=1)
217                    for (v=0;v<V_MAX;v+=1) {
218                        data[tn][i0+i][dn][v] = data[tn][i1+i][dn][v];
219                        data[tn][i1+i][dn][v] = 0;
220                    }
221        }
222//fprintf(stderr,"APRES:t=%d:: ",tn,i0,i1); for (i=0; i<S_MAX ; i++) fprintf(stderr,"%d:%p ",i,data[tn][i][0][0]); fprintf(stderr,"\n");
223    }
224}
225void prepare2()
226{
227int tn,stn,dn,vn;
228    for (tn=0 ; tn<T_MAX ; tn++)
229    for (stn=0; stn<S_MAX; stn++)
230    for (dn=0; dn<D_MAX; dn++) {
231        Tlivrable* p = data[tn][stn][dn][0];
232        if (p==0) continue;
233        p->nbvers=0 ;
234        for (vn=0 ; vn<V_MAX ; vn+=1)
235            if (data[tn][stn][dn][vn]!=0) p->nbvers+=1;
236        p->vers=(Tlivrable**)malloc(sizeof(*p->vers)*(p->nbvers+1));
237        for (vn=0 ; vn<p->nbvers ; vn+=1) {
238            p->vers[vn] = data[tn][stn][dn][vn];
239            data[tn][stn][dn][vn]->nbvers = p->nbvers;
240        }
241        p->vers[vn] = 0;
242        p->height = 1.0*DELIVRABLE_HEIGHT;
243        if (p->nbTitleLines>=1) {
244            double h=0;
245            h += p->vers[p->nbvers-1]->nbTitleLines*DELIVRABLE_TITLEHEIGHT;
246            h += (p->vers[p->nbvers-1]->nbTitleLines-1)*(DELIVRABLE_TITLEHEIGHT/5.);
247            if ( h>p->height) p->height=h;
248        }
249    }
250}
251
252double task_livrable_height(int tn)
253{
254int    stn,dn,nblivrables=0;
255double height=0;
256    for (stn=0 ; data[tn][stn][0][0]!=0 ; stn++)
257        for (dn=0 ; data[tn][stn][dn][0]!=0 ; dn++) {
258            nblivrables += 1;
259            height+=data[tn][stn][dn][0]->height;
260        }
261        height += DELIVRABLE_VSEP/2;
262        height += (nblivrables-1)*DELIVRABLE_VSEP;
263        height += DELIVRABLE_VSEP/2;
264    return height;
265}
266
267void  task_box(double pictwidth)
268{
269    int tn;
270    for ( tn=0 ; data[tn][0][0][0]!=0 ; tn++ ) {
271        const char* color= (tn%2)!=0 ? TASK_BGC1 : TASK_BGC0 ;
272        printf(
273            "\\put(%.2f,%.2f){\\fcolorbox{black}{%s}{\\makebox(%5.2f,%5.2f){}}}\n",
274            0.0,data[tn][0][0][0]->task_y,
275            color,
276            pictwidth,data[tn][0][0][0]->task_dy
277        );
278    }
279}
280
281void  month_grid(double x, double y, double dx, double dy)
282{
283    int i;
284    for (i=0 ;  i<=36 ; i+=1,x+=PICT_MONTHWIDTH) {
285        if ( (i%3)!=0 ) continue;
286        printf(
287            "\\put(%5.1f,%5.1f){\\line(0,1){%5.1f}}\\put(%5.1f,%5.1f){%d}\n",
288            x,y,dy-PICT_MONTHWIDTH-PICT_VSEP,
289            x-2,y+dy-PICT_MONTHHEIGHT,
290            i
291        );
292    }
293}
294
295void  print_milestones(double x, double y, double dx, double dy)
296{
297    int i;
298    double tn=.3;
299    //x=x-tn/2;
300    printf("\\bgroup\n");
301    printf("\\color{red}\n");
302    printf("\\linethickness{%.2fmm}\n",tn);
303    for (i=0 ;  milestones[i]!=0 ; i+=1) {
304        double xx= x + milestones[i]*PICT_MONTHWIDTH;
305        print_vline(xx,y,dy-PICT_MONTHWIDTH-PICT_VSEP,0);
306    }
307    printf("\\egroup\n");
308}
309
310double delivrable(
311    double label_x, double box_x, double title_x,
312    double y,
313    int tn, int stn, int dn)
314{
315    Tlivrable* top=data[tn][stn][dn][0];
316    Tlivrable* last=data[tn][stn][dn][top->nbvers-1];
317    char tmp[1000],label[1000],title[1000];
318    double y0;
319    int v;
320    double label_dx = DELIVRABLE_LABELWIDTH ;
321    double label_dy = DELIVRABLE_LABELHEIGHT ;
322    double boxx,box_dx;
323    double box_dy = DELIVRABLE_BOXHEIGHT ;
324    double title_dx = DELIVRABLE_LABELWIDTH ;
325    double title_dy = DELIVRABLE_TITLEHEIGHT ;
326   
327//print_hline(0,y,180,0);
328    gen_label_base(label,top);
329    // y -= DELIVRABLE_HEIGHT;
330    y -= top->height ;
331//print_hline(0,y,180,0);
332    printf("% Delivrable %s (tn=%d stn=%d dn=%d\n",label,tn,stn,dn);
333
334    // print label
335    //y0 = (DELIVRABLE_HEIGHT-DELIVRABLE_LABELHEIGHT)/2;
336    y0 = (top->height-DELIVRABLE_LABELHEIGHT)/2;
337    sprintf(tmp,"\\ganttlabelstyle{%s}",label);
338    print_put(label_x,y+y0,tmp);
339    // print title
340    if (last->nbTitleLines==1) {
341        y0  = (DELIVRABLE_HEIGHT-DELIVRABLE_TITLEHEIGHT)/2;
342        y0 += DELIVRABLE_TITLEHEIGHT/5. ;
343        sprintf(tmp,"\\gantttitlestyle{%s}",last->title);
344        print_put(title_x,y+y0,tmp);
345    } else if (last->nbTitleLines>1) {
346        int i;
347        // y0 = (DELIVRABLE_HEIGHT-DELIVRABLE_TITLEHEIGHT)/2;
348        y0=DELIVRABLE_TITLEHEIGHT/5.;
349        sprintf(tmp,"\\gantttitlestyle{\\shortstack[l]{%s",last->titleLines[0]);
350        for (i=1 ; i<last->nbTitleLines ; i+=1) {
351            strcat(tmp,"\\\\");
352            strcat(tmp,last->titleLines[i]);
353        }
354        strcat(tmp,"}}");
355        print_put(title_x,y+y0,tmp);
356    }
357       
358    // print box
359    //y0 = (DELIVRABLE_HEIGHT-DELIVRABLE_BOXHEIGHT)/2;
360    y0 = (top->height-DELIVRABLE_BOXHEIGHT)/2;
361    if ( last==top ) {
362        Tlivrable* l=top;
363        boxx = box_x + l->bm*PICT_MONTHWIDTH ;
364        box_dx  = (l->em - l->bm) * PICT_MONTHWIDTH;
365        print_box(1,0,boxx,y+y0,box_dx,box_dy,COLOR_BOX_LIGHT,0,0);
366        print_box(0,0,boxx,y+y0,box_dx,box_dy,0,0,0);
367    } else for (v=0 ; v<top->nbvers ; v+=1) {
368        Tlivrable* l=data[tn][stn][dn][v] ;
369        gen_label_vers(tmp,l);
370        boxx = box_x + l->bm*PICT_MONTHWIDTH ;
371        box_dx  = (l->em - l->bm) * PICT_MONTHWIDTH;
372        print_box(1,0,boxx,y+y0,box_dx,box_dy,COLOR_BOX_LIGHT,0,0);
373        print_box(0,tmp,boxx,y+y0,box_dx,box_dy,0,0,0);
374    }
375    y -= DELIVRABLE_VSEP;
376    return y;
377}
378
379void task_delivrable(double label_x, double box_x, double title_x, int tn)
380{
381int stn,dn;
382double y = data[tn][0][0][0]->task_y+data[tn][0][0][0]->task_dy;
383    //y += DELIVRABLE_VSEP/2. ;
384    for (stn=0 ; data[tn][stn][0][0]!=0 ; stn++)
385        for (dn=0 ; data[tn][stn][dn][0]!=0 ; dn++) {
386            y=delivrable(label_x,box_x,title_x,y,tn,stn,dn);
387        }
388}
389
390int main()
391{
392    int tn;
393    double pictwidth, pictheight;
394    double gantt_x,gantt_y;
395    double gantt_dx,gantt_dy;
396
397    double label_x,title_x;
398
399    yylex();
400    prepare0();
401    prepare1();
402    prepare2();
403
404    pictheight=0 ;
405    pictheight += PICT_BOTSEP ;
406    for ( tn=0 ; data[tn][0][0][0]!=0 ; tn++ );
407    for ( tn=tn-1 ; tn>=0 ; tn-- ) {
408        data[tn][0][0][0]->task_y = pictheight;
409        data[tn][0][0][0]->task_dy = task_livrable_height(tn);
410        pictheight += data[tn][0][0][0]->task_dy;
411        pictheight += TASK_VSEP;
412    }
413    pictheight += PICT_MONTHHEIGHT;
414    pictheight += PICT_TOPSEP ;
415    gantt_y  = PICT_BOTSEP ;
416    gantt_dy = pictheight-PICT_TOPSEP-PICT_BOTSEP ;
417
418    pictwidth=0;
419    pictwidth += PICT_LEFTSEP;
420    label_x    = pictwidth;
421    pictwidth += DELIVRABLE_LABELWIDTH;
422    pictwidth += PICT_HSEP;
423    gantt_x    = pictwidth ;
424    gantt_dx   = 36*PICT_MONTHWIDTH ;
425    pictwidth += gantt_dx ;
426    pictwidth += PICT_HSEP;
427    title_x    = pictwidth;
428    pictwidth += DELIVRABLE_TITLEWIDTH;
429    pictwidth += PICT_RIGHTSEP;
430   
431    printf("\\setlength{\\unitlength}{1.0mm}\n");
432    printf("\\begin{picture}(%.1f,%.1f)\n",pictwidth,pictheight);
433      task_box(pictwidth);
434      month_grid(gantt_x,gantt_y,gantt_dx,gantt_dy);
435      for ( tn=0 ; data[tn][0][0][0]!=0 ; tn++ ) {
436        task_delivrable(label_x,gantt_x,title_x,tn);
437      }
438
439    print_milestones(gantt_x,0,gantt_dx,gantt_dy+gantt_y);
440    printf("\\end{picture}\n");
441
442    return 0;
443}
Note: See TracBrowser for help on using the repository browser.