2
graphs.c - produces graphs used by the Webalizer
4
Copyright (C) 1997-2011 Bradford L. Barrett
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version, and provided that the above
10
copyright and permission notice is included with all distributed
11
copies of this or derived software.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27
#include <sys/types.h>
35
/* need socket header? */
36
#ifdef HAVE_SYS_SOCKET_H
37
#include <sys/socket.h>
40
#include "webalizer.h"
45
/* Some systems don't define this */
47
#define PI 3.14159265358979323846
50
#define HITCOLOR hit_or_green /* graph color - hits */
51
#define FILECOLOR file_or_blue /* files */
52
#define SITECOLOR site_or_orange /* sites */
53
#define KBYTECOLOR kbyte_or_red /* KBytes */
54
#define IKBYTECOLOR ikbyte_or_blue /* In KBytes */
55
#define OKBYTECOLOR okbyte_or_green /* Out KBytes */
56
#define PAGECOLOR page_or_cyan /* Files */
57
#define VISITCOLOR visit_or_yellow /* Visits */
59
/* shortcuts to convert ASCII hex color for gdImageColorAllocate() */
61
#define getred(s) (ashex2int((s[0] == '#')?s+1:s))
62
/* returns the red base-10 integer value from a html color */
64
#define getgreen(s) (ashex2int((s[0] == '#')?s+3:s+2))
65
/* returns the green base-10 integer value from a html color */
67
#define getblue(s) (ashex2int((s[0] == '#')?s+5:s+4))
68
/* returns the blue base-10 integer value from a html color */
70
#define CX 156 /* center x (for pie) */
71
#define CY 150 /* center y (chart) */
72
#define XRAD 240 /* X-axis radius */
73
#define YRAD 200 /* Y-axis radius */
75
/* forward reference internal routines */
77
void init_graph(char *, int, int);
78
struct pie_data *calc_arc(float, float);
79
int ashex2int(char *);
81
/* common public declarations */
83
char *numchar[] = { " 0"," 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9","10",
84
"11","12","13","14","15","16","17","18","19","20",
85
"21","22","23","24","25","26","27","28","29","30","31"};
87
gdImagePtr im; /* image buffer */
88
FILE *out; /* output file for PNG */
89
struct stat out_stat; /* stat struct for PNG */
90
char maxvaltxt[32]; /* graph values */
91
float percent; /* percent storage */
92
u_int64_t julday; /* julday value */
94
struct pie_data { int x; int y; /* line x,y */
95
int mx; int my; }; /* midpoint x,y */
97
int black, white, grey, dkgrey, kbyte_or_red,
98
ikbyte_or_blue, okbyte_or_green,
99
file_or_blue, site_or_orange, hit_or_green,
100
page_or_cyan, visit_or_yellow, blue;
102
/*****************************************************************/
104
/* YEAR_GRAPH6x - Year graph from array of hist_rec structs */
106
/*****************************************************************/
108
int year_graph6x(char *fname, char *title, struct hist_rec data[HISTSIZE])
111
/* local variables */
119
/* initalize the graph */
120
init_graph(title,512,256); /* init as 512 x 256 */
122
gdImageLine(im, 305,25,305,233,black); /* draw section lines */
123
gdImageLine(im, 304,25,304,233,white);
124
gdImageLine(im, 305,130,490,130,black);
125
gdImageLine(im, 305,129,490,129,white);
130
y1=210/(graph_lines+1);
131
for (i=0;i<graph_lines;i++)
132
gdImageLine(im,21,((i+1)*y1)+25,303,((i+1)*y1)+25,dkgrey);
133
y1=105/(graph_lines+1);
134
for (i=0;i<graph_lines;i++)
135
gdImageLine(im,306,((i+1)*y1)+25,489,((i+1)*y1)+25,dkgrey);
136
for (i=0;i<graph_lines;i++)
137
gdImageLine(im,306,((i+1)*y1)+130,489,((i+1)*y1)+130,dkgrey);
140
/* color coded legends? */
144
i = (strlen(msg_h_xfer)*6);
147
gdImageString(im,gdFontSmall,491-i,237,
148
(unsigned char *)msg_h_xfer,dkgrey);
149
gdImageString(im,gdFontSmall,490-i,236,
150
(unsigned char *)msg_h_xfer,KBYTECOLOR);
154
j = (strlen(msg_h_ixfer)*6);
155
k = (strlen(msg_h_oxfer)*6);
156
gdImageString(im,gdFontSmall,491-i-j-k-24,237,
157
(unsigned char *)msg_h_xfer,dkgrey);
158
gdImageString(im,gdFontSmall,490-i-j-k-24,236,
159
(unsigned char *)msg_h_xfer,KBYTECOLOR);
160
gdImageString(im,gdFontSmall,491-k-j-21,237,"/",dkgrey);
161
gdImageString(im,gdFontSmall,490-k-j-21,236,"/",black);
162
gdImageString(im,gdFontSmall,491-k-j-12,237,
163
(unsigned char *)msg_h_ixfer,dkgrey);
164
gdImageString(im,gdFontSmall,490-k-j-12,236,
165
(unsigned char *)msg_h_ixfer,IKBYTECOLOR);
166
gdImageString(im,gdFontSmall,491-k-9,237,"/",dkgrey);
167
gdImageString(im,gdFontSmall,490-k-9,236,"/",black);
168
gdImageString(im,gdFontSmall,491-k,237,
169
(unsigned char *)msg_h_oxfer,dkgrey);
170
gdImageString(im,gdFontSmall,490-k,236,
171
(unsigned char *)msg_h_oxfer,OKBYTECOLOR);
173
/* Sites/Visits Legend */
174
i = (strlen(msg_h_visits)*6);
175
j = (strlen(msg_h_sites)*6);
176
gdImageString(im,gdFontSmall,491-i-j-12,11,
177
(unsigned char *)msg_h_visits,dkgrey);
178
gdImageString(im,gdFontSmall,490-i-j-12,10,
179
(unsigned char *)msg_h_visits,VISITCOLOR);
180
gdImageString(im,gdFontSmall,491-j-9,11,(unsigned char *)"/",dkgrey);
181
gdImageString(im,gdFontSmall,490-j-9,10,(unsigned char *)"/",black);
182
gdImageString(im,gdFontSmall,491-j,11,
183
(unsigned char *)msg_h_sites,dkgrey);
184
gdImageString(im,gdFontSmall,490-j,10,
185
(unsigned char *)msg_h_sites,SITECOLOR);
187
/* Hits/Files/Pages Legend */
188
i = (strlen(msg_h_pages)*6);
189
j = (strlen(msg_h_files)*6);
190
gdImageStringUp(im,gdFontSmall,6,231,
191
(unsigned char *)msg_h_pages,dkgrey);
192
gdImageStringUp(im,gdFontSmall,5,230,
193
(unsigned char *)msg_h_pages,PAGECOLOR);
194
gdImageStringUp(im,gdFontSmall,6,231-i-3,(unsigned char *)"/",dkgrey);
195
gdImageStringUp(im,gdFontSmall,5,230-i-3,(unsigned char *)"/",black);
196
gdImageStringUp(im,gdFontSmall,6,231-i-12,
197
(unsigned char *)msg_h_files,dkgrey);
198
gdImageStringUp(im,gdFontSmall,5,230-i-12,
199
(unsigned char *)msg_h_files,FILECOLOR);
200
gdImageStringUp(im,gdFontSmall,6,231-i-j-15,(unsigned char *)"/",dkgrey);
201
gdImageStringUp(im,gdFontSmall,5,230-i-j-15,(unsigned char *)"/",black);
202
gdImageStringUp(im,gdFontSmall,6,231-i-j-24,
203
(unsigned char *)msg_h_hits,dkgrey);
204
gdImageStringUp(im,gdFontSmall,5,230-i-j-24,
205
(unsigned char *)msg_h_hits,HITCOLOR);
208
/* Now draw data areas */
209
s_mth = HISTSIZE-graph_mths;
210
cs = 280.0/graph_mths; cw = cs/2;
211
co = (48/graph_mths<1)?1:48/graph_mths;
215
for (i=s_mth;i<HISTSIZE;i++)
219
gdImageString(im,gdFontSmall,ci+((i-s_mth)*cs)+(((cw+co+co)-18)/2)+1,
220
236,(unsigned char *)Q_(s_month[data[i].month-1]),black);
222
else if (graph_mths<36)
224
gdImageChar(im,gdFontSmall,ci+((i-s_mth)*cs)+(((cw+co+co)-6)/2)+1,
225
236,Q_(s_month[data[i].month-1])[0],
226
(data[i].month==1)?blue:black);
230
if (s_year!=data[i].year) /* year change only */
232
if (data[i].month==1 && (i-s_mth)!=0)
233
gdImageChar(im,gdFontSmall, ci+((i-s_mth)*cs)-3,236,'|',blue);
234
j=(12-data[i].month+1)*cs;
235
if ((HISTSIZE-i)*cs < j) j=(HISTSIZE-i)*cs;
238
/* format the year string */
239
sprintf(maxvaltxt, "%04d", data[i].year);
240
gdImageString(im,gdFontSmall,ci+((i-s_mth)*cs)+(j/2)-12,
241
236, (unsigned char *)maxvaltxt, black);
247
if (data[i].hit > maxval) maxval = data[i].hit;
248
if (data[i].files > maxval) maxval = data[i].files;
249
if (data[i].page > maxval) maxval = data[i].page;
251
if (maxval <= 0) maxval = 1;
252
sprintf(maxvaltxt, "%llu", maxval);
253
gdImageStringUp(im,gdFontSmall,6,26+(strlen(maxvaltxt)*6),
254
(unsigned char *)maxvaltxt,black);
257
for (i=s_mth; i<HISTSIZE; i++)
259
percent = ((float)data[i].hit / (float)maxval);
260
if (percent <= 0.0) continue;
261
x1 = ci + ((i-s_mth)*cs);
263
y1 = 232 - (percent * 203);
264
gdImageFilledRectangle(im, x1, y1, x2, 232, HITCOLOR);
265
if (cw>2) gdImageRectangle(im, x1, y1, x2, 232, black);
269
for (i=s_mth; i<HISTSIZE; i++)
271
percent = ((float)data[i].files / (float)maxval);
272
if (percent <= 0.0) continue;
273
x1 = ci + co + ((i-s_mth)*cs);
275
y1 = 232 - (percent * 203);
276
gdImageFilledRectangle(im, x1, y1, x2, 232, FILECOLOR);
277
if (cw>2) gdImageRectangle(im, x1, y1, x2, 232, black);
281
for (i=s_mth; i<HISTSIZE; i++)
283
percent = ((float)data[i].page / (float)maxval);
284
if (percent <= 0.0) continue;
285
x1 = ci + co + co + ((i-s_mth)*cs);
287
y1 = 232 - (percent * 203);
288
gdImageFilledRectangle(im, x1, y1, x2, 232, PAGECOLOR);
289
if (cw>2) gdImageRectangle(im, x1, y1, x2, 232, black);
293
for (i=s_mth; i<HISTSIZE; i++)
295
if (data[i].site > maxval) maxval = data[i].site;
296
if (data[i].visit > maxval) maxval = data[i].visit;
298
if (maxval <= 0) maxval = 1;
299
sprintf(maxvaltxt, "%llu", maxval);
300
gdImageStringUp(im, gdFontSmall,493,26+(strlen(maxvaltxt)*6),
301
(unsigned char *)maxvaltxt, black);
303
cs = 180.0/graph_mths; cw = cs/2;
304
co = (48/graph_mths<1)?1:48/graph_mths;
305
ci = 308+((cw-co)/2);
308
for (i=s_mth; i<HISTSIZE; i++)
310
percent = ((float)data[i].visit / (float)maxval);
311
if (percent <= 0.0) continue;
312
x1 = ci + ((i-s_mth)*cs);
314
y1 = 127 - (percent * 98);
315
gdImageFilledRectangle(im, x1, y1, x2, 127, VISITCOLOR);
316
if (cw>2) gdImageRectangle(im, x1, y1, x2, 127, black);
320
for (i=s_mth; i<HISTSIZE; i++)
322
percent = ((float)data[i].site / (float)maxval);
323
if (percent <= 0.0) continue;
324
x1 = ci + co + ((i-s_mth)*cs);
326
y1 = 127 - (percent * 98);
327
gdImageFilledRectangle(im, x1, y1, x2, 127, SITECOLOR);
328
if (cw>2) gdImageRectangle(im, x1, y1, x2, 127, black);
332
for (i=s_mth; i<HISTSIZE; i++){
333
if (data[i].xfer > fmaxval) fmaxval = data[i].xfer;
336
if (data[i].ixfer > fmaxval) fmaxval = data[i].ixfer;
337
if (data[i].oxfer > fmaxval) fmaxval = data[i].oxfer;
340
if (fmaxval <= 0.0) fmaxval = 1.0;
341
sprintf(maxvaltxt, "%.0f", fmaxval);
342
gdImageStringUp(im, gdFontSmall,493,130+(strlen(maxvaltxt)*6),
343
(unsigned char *)maxvaltxt,black);
345
cs = 180.0/graph_mths;
348
co = (48/graph_mths<1)?1:48/graph_mths;
350
ci = 308+((cw-co)/2);
354
co = (36/graph_mths<1)?1:36/graph_mths;
356
ci = 308+((cw-2*co)/2);
360
for (i=s_mth; i<HISTSIZE; i++)
362
percent = ((float)data[i].xfer / (float)fmaxval);
363
if (percent <= 0.0) continue;
364
x1 = ci + ((i-s_mth)*cs);
366
y1 = 232 - (percent * 98);
367
gdImageFilledRectangle(im, x1, y1, x2, 232, KBYTECOLOR);
368
if (cw>2) gdImageRectangle(im, x1, y1, x2, 232, black);
374
for (i=s_mth; i<HISTSIZE; i++)
376
percent = ((float)data[i].ixfer / (float)fmaxval);
377
if (percent <= 0.0) continue;
378
x1 = ci + co + ((i-s_mth)*cs);
380
y1 = 232 - (percent * 98);
381
gdImageFilledRectangle(im, x1, y1, x2, 232, IKBYTECOLOR);
382
if (cw>2) gdImageRectangle(im, x1, y1, x2, 232, black);
386
for (i=s_mth; i<HISTSIZE; i++)
388
percent = ((float)data[i].oxfer / (float)fmaxval);
389
if (percent <= 0.0) continue;
390
x1 = ci + co + co + ((i-s_mth)*cs);
392
y1 = 232 - (percent * 98);
393
gdImageFilledRectangle(im, x1, y1, x2, 232, OKBYTECOLOR);
394
if (cw>2) gdImageRectangle(im, x1, y1, x2, 232, black);
399
if ( !(lstat(fname, &out_stat)) )
401
/* check if the file a symlink */
402
if ( S_ISLNK(out_stat.st_mode) )
405
fprintf(stderr,"%s %s (symlink)\n",msg_no_open,fname);
411
if ((out = fopen(fname, "wb")) != NULL)
416
/* deallocate memory */
422
/*****************************************************************/
424
/* MONTH_GRAPH6 - Month graph with six data sets */
426
/*****************************************************************/
430
int month_graph6( char *fname, /* filename */
431
char *title, /* graph title */
432
int month, /* graph month */
433
int year, /* graph year */
434
u_int64_t data1[31], /* data1 (hits) */
435
u_int64_t data2[31], /* data2 (files) */
436
u_int64_t data3[31], /* data3 (sites) */
437
double data4[31], /* data4 (kbytes) */
438
double data5[31], /* data4 (kbytes) */
439
double data6[31], /* data4 (kbytes) */
440
u_int64_t data7[31], /* data5 (views) */
441
u_int64_t data8[31]) /* data6 (visits) */
444
/* local variables */
449
/* calc julian date for month */
450
julday = (jdate(1, month,year) % 7);
452
/* initalize the graph */
453
init_graph(title,512,400);
455
gdImageLine(im, 21, 180, 490, 180, black); /* draw section lines */
456
gdImageLine(im, 21, 179, 490, 179, white);
457
gdImageLine(im, 21, 280, 490, 280, black);
458
gdImageLine(im, 21, 279, 490, 279, white);
463
y1=154/(graph_lines+1);
464
for (i=0;i<graph_lines;i++)
465
gdImageLine(im,21,((i+1)*y1)+25,489,((i+1)*y1)+25,dkgrey);
466
y1=100/(graph_lines+1);
467
for (i=0;i<graph_lines;i++)
468
gdImageLine(im,21,((i+1)*y1)+180,489,((i+1)*y1)+180,dkgrey);
469
for (i=0;i<graph_lines;i++)
470
gdImageLine(im,21,((i+1)*y1)+280,489,((i+1)*y1)+280,dkgrey);
476
if ((julday % 7 == 6) || (julday % 7 == 0))
477
gdImageString(im,gdFontSmall,25+(i*15),382,
478
(unsigned char *)numchar[i+1],HITCOLOR);
480
gdImageString(im,gdFontSmall,25+(i*15),382,
481
(unsigned char *)numchar[i+1],black);
488
if (data1[i] > maxval) maxval = data1[i]; /* get max val */
489
if (data2[i] > maxval) maxval = data2[i];
490
if (data7[i] > maxval) maxval = data7[i];
492
if (maxval <= 0) maxval = 1;
493
sprintf(maxvaltxt, "%llu", maxval);
494
gdImageStringUp(im, gdFontSmall,8,26+(strlen(maxvaltxt)*6),
495
(unsigned char *)maxvaltxt,black);
497
if (graph_legend) /* Print color coded legends? */
500
gdImageStringUp(im,gdFontSmall,494,376,
501
(unsigned char *)msg_h_xfer,dkgrey);
502
gdImageStringUp(im,gdFontSmall,493,375,
503
(unsigned char *)msg_h_xfer,KBYTECOLOR);
506
i=(strlen(msg_h_xfer)*6);
507
j=(strlen(msg_h_ixfer)*6);
508
gdImageStringUp(im,gdFontSmall,494,376-i-3,"/",dkgrey);
509
gdImageStringUp(im,gdFontSmall,493,375-i-3,"/",black);
510
gdImageStringUp(im,gdFontSmall,494,376-i-12,
511
(unsigned char *)msg_h_ixfer,dkgrey);
512
gdImageStringUp(im,gdFontSmall,493,375-i-12,
513
(unsigned char *)msg_h_ixfer,IKBYTECOLOR);
514
gdImageStringUp(im,gdFontSmall,494,376-i-j-15,"/",dkgrey);
515
gdImageStringUp(im,gdFontSmall,493,375-i-j-15,"/",black);
516
gdImageStringUp(im,gdFontSmall,494,376-i-j-24,
517
(unsigned char *)msg_h_oxfer,dkgrey);
518
gdImageStringUp(im,gdFontSmall,493,375-i-j-24,
519
(unsigned char *)msg_h_oxfer,OKBYTECOLOR);
522
/* Sites/Visits Legend */
523
i = (strlen(msg_h_sites)*6);
524
gdImageStringUp(im,gdFontSmall,494,256,
525
(unsigned char *)msg_h_sites,dkgrey);
526
gdImageStringUp(im,gdFontSmall,493,255,
527
(unsigned char *)msg_h_sites,SITECOLOR);
528
gdImageStringUp(im,gdFontSmall,494,256-i-3,(unsigned char *)"/",dkgrey);
529
gdImageStringUp(im,gdFontSmall,493,255-i-3,(unsigned char *)"/",black);
530
gdImageStringUp(im,gdFontSmall,494,256-i-12,
531
(unsigned char *)msg_h_visits,dkgrey);
532
gdImageStringUp(im,gdFontSmall,493,255-i-12,
533
(unsigned char *)msg_h_visits,VISITCOLOR);
535
/* Pages/Files/Hits Legend */
536
s = ( i=(strlen(msg_h_pages)*6) )+
537
( j=(strlen(msg_h_files)*6) )+
538
( strlen(msg_h_hits)*6 )+ 52;
539
gdImageStringUp(im,gdFontSmall,494,s,
540
(unsigned char *)msg_h_pages,dkgrey);
541
gdImageStringUp(im,gdFontSmall,493,s-1,
542
(unsigned char *)msg_h_pages,PAGECOLOR);
543
gdImageStringUp(im,gdFontSmall,494,s-i-3,(unsigned char *)"/",dkgrey);
544
gdImageStringUp(im,gdFontSmall,493,s-i-4,(unsigned char *)"/",black);
545
gdImageStringUp(im,gdFontSmall,494,s-i-12,
546
(unsigned char *)msg_h_files,dkgrey);
547
gdImageStringUp(im,gdFontSmall,493,s-i-13,
548
(unsigned char *)msg_h_files,FILECOLOR);
549
gdImageStringUp(im,gdFontSmall,494,s-i-j-15,(unsigned char *)"/",dkgrey);
550
gdImageStringUp(im,gdFontSmall,493,s-i-j-16,(unsigned char *)"/",black);
551
gdImageStringUp(im,gdFontSmall,494,s-i-j-24,
552
(unsigned char *)msg_h_hits,dkgrey);
553
gdImageStringUp(im,gdFontSmall,493,s-i-j-25,
554
(unsigned char *)msg_h_hits,HITCOLOR);
560
percent = ((float)data1[i] / (float)maxval);
561
if (percent <= 0.0) continue;
564
y1 = 176 - (percent * 147);
565
gdImageFilledRectangle(im, x1, y1, x2, 176, HITCOLOR);
566
gdImageRectangle(im, x1, y1, x2, 176, black);
572
percent = ((float)data2[i] / (float)maxval);
573
if (percent <= 0.0) continue;
576
y1 = 176 - (percent * 147);
577
gdImageFilledRectangle(im, x1, y1, x2, 176, FILECOLOR);
578
gdImageRectangle(im, x1, y1, x2, 176, black);
584
if (data7[i]==0) continue;
585
percent = ((float)data7[i] / (float)maxval);
586
if (percent <= 0.0) continue;
589
y1 = 176 - (percent * 147);
590
gdImageFilledRectangle(im, x1, y1, x2, 176, PAGECOLOR);
591
gdImageRectangle(im, x1, y1, x2, 176, black);
598
if (data3[i]>maxval) maxval = data3[i];
599
if (data8[i]>maxval) maxval = data8[i];
601
if (maxval <= 0) maxval = 1;
602
sprintf(maxvaltxt, "%llu", maxval);
603
gdImageStringUp(im, gdFontSmall,8,180+(strlen(maxvaltxt)*6),
604
(unsigned char *)maxvaltxt, black);
609
percent = ((float)data8[i] / (float)maxval);
610
if (percent <= 0.0) continue;
613
y1 = 276 - (percent * 92);
614
gdImageFilledRectangle(im, x1, y1, x2, 276, VISITCOLOR);
615
gdImageRectangle(im, x1, y1, x2, 276, black);
621
percent = ((float)data3[i] / (float)maxval);
622
if (percent <= 0.0) continue;
625
y1 = 276 - (percent * 92);
626
gdImageFilledRectangle(im, x1, y1, x2, 276, SITECOLOR);
627
gdImageRectangle(im, x1, y1, x2, 276, black);
632
for (i=0; i<31; i++){
633
if (data4[i]>fmaxval) fmaxval = data4[i];
636
if (data5[i]>fmaxval) fmaxval = data5[i];
637
if (data6[i]>fmaxval) fmaxval = data6[i];
640
if (fmaxval <= 0.0) fmaxval = 1.0;
641
sprintf(maxvaltxt, "%.0f", fmaxval/1024);
642
gdImageStringUp(im, gdFontSmall,8,280+(strlen(maxvaltxt)*6),
643
(unsigned char *)maxvaltxt, black);
648
percent = data4[i] / fmaxval;
649
if (percent <= 0.0) continue;
660
y1 = 375 - ( percent * 91 );
661
gdImageFilledRectangle(im, x1, y1, x2, 375, KBYTECOLOR);
662
gdImageRectangle(im, x1, y1, x2, 375, black);
670
percent = data5[i] / fmaxval;
671
if (percent <= 0.0) continue;
674
y1 = 375 - ( percent * 91 );
675
gdImageFilledRectangle(im, x1, y1, x2, 375, IKBYTECOLOR);
676
gdImageRectangle(im, x1, y1, x2, 375, black);
682
percent = data6[i] / fmaxval;
683
if (percent <= 0.0) continue;
686
y1 = 375 - ( percent * 91 );
687
gdImageFilledRectangle(im, x1, y1, x2, 375, OKBYTECOLOR);
688
gdImageRectangle(im, x1, y1, x2, 375, black);
693
if ( !(lstat(fname, &out_stat)) )
695
/* check if the file a symlink */
696
if ( S_ISLNK(out_stat.st_mode) )
699
fprintf(stderr,"%s %s (symlink)\n",msg_no_open,fname);
705
if ((out = fopen(fname, "wb")) != NULL)
710
/* deallocate memory */
716
/*****************************************************************/
718
/* DAY_GRAPH3 - Day graph with three data sets */
720
/*****************************************************************/
722
int day_graph3( char *fname,
729
/* local variables */
733
/* initalize the graph */
734
init_graph(title,512,256);
739
y1=210/(graph_lines+1);
740
for (i=0;i<graph_lines;i++)
741
gdImageLine(im,21,((i+1)*y1)+25,489,((i+1)*y1)+25,dkgrey);
747
gdImageString(im,gdFontSmall,33+(i*19),238,
748
(unsigned char *)numchar[i],black);
749
if (data1[i] > maxval) maxval = data1[i]; /* get max val */
750
if (data2[i] > maxval) maxval = data2[i];
751
if (data3[i] > maxval) maxval = data3[i];
753
if (maxval <= 0) maxval = 1;
754
sprintf(maxvaltxt, "%llu", maxval);
755
gdImageStringUp(im, gdFontSmall, 8, 26+(strlen(maxvaltxt)*6),
756
(unsigned char *)maxvaltxt, black);
758
if (graph_legend) /* print color coded legends? */
760
/* Pages/Files/Hits Legend */
761
s = ( i=(strlen(msg_h_pages)*6) )+
762
( j=(strlen(msg_h_files)*6) )+
763
( strlen(msg_h_hits)*6 )+ 52;
764
gdImageStringUp(im,gdFontSmall,494,s,
765
(unsigned char *)msg_h_pages,dkgrey);
766
gdImageStringUp(im,gdFontSmall,493,s-1,
767
(unsigned char *)msg_h_pages,PAGECOLOR);
768
gdImageStringUp(im,gdFontSmall,494,s-i-3,(unsigned char *)"/",dkgrey);
769
gdImageStringUp(im,gdFontSmall,493,s-i-4,(unsigned char *)"/",black);
770
gdImageStringUp(im,gdFontSmall,494,s-i-12,
771
(unsigned char *)msg_h_files,dkgrey);
772
gdImageStringUp(im,gdFontSmall,493,s-i-13,
773
(unsigned char *)msg_h_files,FILECOLOR);
774
gdImageStringUp(im,gdFontSmall,494,s-i-j-15,(unsigned char *)"/",dkgrey);
775
gdImageStringUp(im,gdFontSmall,493,s-i-j-16,(unsigned char *)"/",black);
776
gdImageStringUp(im,gdFontSmall,494,s-i-j-24,
777
(unsigned char *)msg_h_hits,dkgrey);
778
gdImageStringUp(im,gdFontSmall,493,s-i-j-25,
779
(unsigned char *)msg_h_hits,HITCOLOR);
785
percent = ((float)data1[i] / (float)maxval); /* percent of 100% */
786
if (percent <= 0.0) continue;
789
y1 = 232 - (percent * 203);
790
gdImageFilledRectangle(im, x1, y1, x2, 232, HITCOLOR);
791
gdImageRectangle(im, x1, y1, x2, 232, black);
797
percent = ((float)data2[i] / (float)maxval); /* percent of 100% */
798
if (percent <= 0.0) continue;
801
y1 = 232 - (percent * 203);
802
gdImageFilledRectangle(im, x1, y1, x2, 232, FILECOLOR);
803
gdImageRectangle(im, x1, y1, x2, 232, black);
809
percent = ((float)data3[i] / (float)maxval); /* percent of 100% */
810
if (percent <= 0.0) continue;
813
y1 = 232 - (percent * 203);
814
gdImageFilledRectangle(im, x1, y1, x2, 232, PAGECOLOR);
815
gdImageRectangle(im, x1, y1, x2, 232, black);
819
if ( !(lstat(fname, &out_stat)) )
821
/* check if the file a symlink */
822
if ( S_ISLNK(out_stat.st_mode) )
825
fprintf(stderr,"%s %s (symlink)\n",msg_no_open,fname);
831
if ((out = fopen(fname, "wb")) != NULL)
836
/* deallocate memory */
842
/*****************************************************************/
844
/* PIE_CHART - draw a pie chart (10 data items max) */
846
/*****************************************************************/
848
int pie_chart(char *fname, char *title, u_int64_t t_val,
849
u_int64_t data1[], char *legend[])
851
int i,x,percent,y=47;
853
int purple_or_pie1, ltgreen_or_pie2, ltpurple_or_pie3, brown_or_pie4;
857
struct pie_data gdata;
859
/* init graph and colors */
860
init_graph(title,512,300);
861
r=getred(pie_color1); g=getgreen(pie_color1); b=getblue(pie_color1);
862
purple_or_pie1 = gdImageColorAllocate(im, r, g, b);
863
r=getred(pie_color2); g=getgreen(pie_color2); b=getblue(pie_color2);
864
ltgreen_or_pie2 = gdImageColorAllocate(im, r, g, b);
865
r=getred(pie_color3); g=getgreen(pie_color3); b=getblue(pie_color3);
866
ltpurple_or_pie3= gdImageColorAllocate(im, r, g, b);
867
r=getred(pie_color4); g=getgreen(pie_color4); b=getblue(pie_color4);
868
brown_or_pie4 = gdImageColorAllocate(im, r, g, b);
870
/* do the circle... */
871
gdImageArc(im, CX, CY, XRAD, YRAD, 0, 360, black);
872
gdImageArc(im, CX, CY+10, XRAD-2, YRAD-2, 2, 178, black);
873
gdImageFillToBorder(im, CX, CY+(YRAD/2)+1, black, black);
876
gdata=*calc_arc(0.0,0.0);
877
gdImageLine(im,CX,CY,gdata.x,gdata.y,black); /* inital line */
879
for (i=0;i<10;i++) /* run through data array */
881
if ((data1[i]!=0)&&(s_arc<1.0)) /* make sure valid slice */
883
percent=(((double)data1[i]/t_val)+0.005)*100.0;
884
if (percent<1) break;
886
if (s_arc+((double)percent/100.0)>=1.0)
888
gdata=*calc_arc(s_arc,1.0);
893
gdata=*calc_arc(s_arc,s_arc+((double)percent/100.0));
894
s_arc+=(double)percent/100.0;
897
gdImageLine(im, CX, CY, gdata.x, gdata.y, black);
898
gdImageFill(im, gdata.mx, gdata.my, i+5);
900
snprintf(buffer,sizeof(buffer),"%s (%d%%)",legend[i], percent);
901
x=480-(strlen(buffer)*7);
902
gdImageString(im,gdFontMediumBold, x+1, y+1,
903
(unsigned char *)buffer, black);
904
gdImageString(im,gdFontMediumBold, x, y,
905
(unsigned char *)buffer, i+5);
910
if (s_arc < 1.0) /* anything left over? */
912
gdata=*calc_arc(s_arc,1.0);
914
gdImageFill(im, gdata.mx, gdata.my, white);
915
snprintf(buffer,sizeof(buffer),"%s (%d%%)",
916
msg_h_other,100-(int)(s_arc*100));
917
x=480-(strlen(buffer)*7);
918
gdImageString(im,gdFontMediumBold, x+1, y+1,
919
(unsigned char *)buffer, black);
920
gdImageString(im,gdFontMediumBold, x, y,
921
(unsigned char *)buffer, white);
925
if ( !(lstat(fname, &out_stat)) )
927
/* check if the file a symlink */
928
if ( S_ISLNK(out_stat.st_mode) )
931
fprintf(stderr,"%s %s (symlink)\n",msg_no_open,fname);
937
if ((out = fopen(fname, "wb")) != NULL)
942
/* deallocate memory */
948
/*****************************************************************/
950
/* CALC_ARC - generate x,y coordinates for pie chart */
952
/*****************************************************************/
954
struct pie_data *calc_arc(float min, float max)
956
static struct pie_data data;
959
/* Calculate max line */
961
data.x=cos(d*(2*PI))*((XRAD-2)/2)+CX;
962
data.y=sin(d*(2*PI))*((YRAD-2)/2)+CY;
963
/* Now get mid-point */
965
data.mx=cos(d*(2*PI))*(XRAD/3)+CX;
966
data.my=sin(d*(2*PI))*(YRAD/3)+CY;
970
/*****************************************************************/
972
/* INIT_GRAPH - initalize graph and draw borders */
974
/*****************************************************************/
976
void init_graph(char *title, int xsize, int ysize)
980
im = gdImageCreate(xsize,ysize);
982
/* allocate color maps, background color first (grey) */
983
grey = gdImageColorAllocate(im, 192, 192, 192);
984
dkgrey = gdImageColorAllocate(im, 128, 128, 128);
985
black = gdImageColorAllocate(im, 0, 0, 0);
986
white = gdImageColorAllocate(im, 255, 255, 255);
987
blue = gdImageColorAllocate(im, 0, 0, 255);
988
r=getred(hit_color); g=getgreen(hit_color); b=getblue(hit_color);
989
hit_or_green = gdImageColorAllocate(im, r, g, b);
990
r=getred(site_color); g=getgreen(site_color); b=getblue(site_color);
991
site_or_orange = gdImageColorAllocate(im, r, g, b);
992
r=getred(file_color); g=getgreen(file_color); b=getblue(file_color);
993
file_or_blue = gdImageColorAllocate(im, r, g, b);
994
r=getred(kbyte_color); g=getgreen(kbyte_color); b=getblue(kbyte_color);
995
kbyte_or_red = gdImageColorAllocate(im, r, g, b);
996
r=getred(ikbyte_color); g=getgreen(ikbyte_color); b=getblue(ikbyte_color);
997
ikbyte_or_blue = gdImageColorAllocate(im, r, g, b);
998
r=getred(okbyte_color); g=getgreen(okbyte_color); b=getblue(okbyte_color);
999
okbyte_or_green = gdImageColorAllocate(im, r, g, b);
1000
r=getred(page_color); g=getgreen(page_color); b=getblue(page_color);
1001
page_or_cyan = gdImageColorAllocate(im, r, g, b);
1002
r=getred(visit_color); g=getgreen(visit_color); b=getblue(visit_color);
1003
visit_or_yellow = gdImageColorAllocate(im, r, g, b);
1005
/* black outside border */
1006
gdImageRectangle(im, 0, 0, xsize-1, ysize-1, black);
1008
/* do shadow effect (bevel) border */
1011
gdImageLine(im, i, i, xsize-i-2, i, white);
1012
gdImageLine(im, i, i, i, ysize-i-2, white);
1013
gdImageLine(im, i+1, ysize-i-1, xsize-i-1, ysize-i-1, dkgrey);
1014
gdImageLine(im, xsize-i-1, i+1, xsize-i-1, ysize-i-1, dkgrey);
1017
/* generic inside shadow box */
1018
gdImageRectangle(im, 20, 25, xsize-21, ysize-21, black);
1019
gdImageRectangle(im, 19, 24, xsize-22, ysize-22, white);
1021
/* display the graph title */
1022
gdImageString(im, gdFontMediumBold, 20, 8,
1023
(unsigned char *)title, blue);
1028
#ifdef HAVE_LIBGD_TTF
1030
* Simple wrapper of gdImageString() for TrueType fonts
1032
* To support Japanese (and other multi-byte characters), GD 1.7
1033
* or later that supports kanji(JISX208) TTF has been required.
1034
* So, we must use TrueType fonts instead of gd built-in
1037
* Original of function written by <yasu@on.cs.keio.ac.jp>.
1038
* And modified by Tatsuki Sugiura <sugi@nemui.org>
1041
static void gdImageStringWrapper(gdImagePtr im, gdFontPtr f,
1043
unsigned char *s, int color, double rad)
1045
double ptsize = 11.0;
1047
extern char *ttf_file;
1049
if (ttf_file == NULL || strcmp(ttf_file, "") == 0) {
1050
if (fabs(rad) < PI/4.0)
1051
gdImageString(im, f, x, y, s, color);
1053
gdImageStringUp(im, f, x, y, s, color);
1055
if (f == gdFontSmall)
1058
gdImageStringFT(im, brect, color, ttf_file, ptsize, rad,
1059
x + (int)(ptsize*sin(rad)),
1060
y + (int)(ptsize*cos(rad)), s);
1064
#define gdImageString(im, f, x, y, s, color) \
1065
gdImageStringWrapper(im, f, x, y, s, color, 0.0)
1066
#define gdImageStringUp(im, f, x, y, s, color) \
1067
gdImageStringWrapper(im, f, x, y, s, color, PI/2.0)
1068
#endif /* HAVE_LIBGD_TTF */
1070
/****************************************************************/
1072
/* ASHEX2INT - ASCII HEX TO INT CONVERTER */
1074
/****************************************************************/
1076
int ashex2int(char *str)
1078
/* returns base-10 integer value from a 2 ASCII hex number */
1079
return from_hex(str[1])+(from_hex(str[0])*16);