summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: da4a47e)
raw | patch | inline | side by side (parent: da4a47e)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Tue, 10 Apr 2007 05:43:34 +0000 (05:43 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Tue, 10 Apr 2007 05:43:34 +0000 (05:43 +0000) |
git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.2/program@1032 a5681a0c-68f1-0310-ab6d-d61299d08faa
src/rrd_graph.c | patch | blob | history |
diff --git a/src/rrd_graph.c b/src/rrd_graph.c
index a23fb107472d8a678f538cdb429cf8f33523d6d5..47c187ad981db4c6ec19046dd95a5639f6220d1c 100644 (file)
--- a/src/rrd_graph.c
+++ b/src/rrd_graph.c
{180, 24*3600, TMT_HOUR,1, TMT_HOUR,6, TMT_HOUR,12, 0,"%a %H:%M"},
/*{300, 0, TMT_HOUR,3, TMT_HOUR,12, TMT_HOUR,12, 12*3600,"%a %p"}, this looks silly*/
{600, 0, TMT_HOUR,6, TMT_DAY,1, TMT_DAY,1, 24*3600,"%a"},
- {1200, 0, TMT_HOUR,6, TMT_DAY,1, TMT_DAY,1, 24*3600,"%d"},
+ {1200, 0, TMT_HOUR,6, TMT_DAY,1, TMT_DAY,1, 24*3600,"%d"},
{1800, 0, TMT_HOUR,12, TMT_DAY,1, TMT_DAY,2, 24*3600,"%a %d"},
{2400, 0, TMT_HOUR,12, TMT_DAY,1, TMT_DAY,2, 24*3600,"%a"},
{3600, 0, TMT_DAY,1, TMT_WEEK,1, TMT_WEEK,1, 7*24*3600,"Week %V"},
xtr(image_desc_t *im,time_t mytime){
static double pixie;
if (mytime==0){
- pixie = (double) im->xsize / (double)(im->end - im->start);
- return im->xorigin;
+ pixie = (double) im->xsize / (double)(im->end - im->start);
+ return im->xorigin;
}
return (int)((double)im->xorigin
- + pixie * ( mytime - im->start ) );
+ + pixie * ( mytime - im->start ) );
}
/* translate data values into y coordinates */
double yval;
if (isnan(value)){
if(!im->logarithmic)
- pixie = (double) im->ysize / (im->maxval - im->minval);
+ pixie = (double) im->ysize / (im->maxval - im->minval);
else
- pixie = (double) im->ysize / (log10(im->maxval) - log10(im->minval));
+ pixie = (double) im->ysize / (log10(im->maxval) - log10(im->minval));
yval = im->yorigin;
} else if(!im->logarithmic) {
yval = im->yorigin - pixie * (value - im->minval);
} else {
if (value < im->minval) {
- yval = im->yorigin;
+ yval = im->yorigin;
} else {
- yval = im->yorigin - pixie * (log10(value) - log10(im->minval));
+ yval = im->yorigin - pixie * (log10(value) - log10(im->minval));
}
}
/* make sure we don't return anything too unreasonable. GD lib can
conv_if(AXIS,GRC_AXIS)
conv_if(FRAME,GRC_FRAME)
- return -1;
+ return -1;
}
enum text_prop_en text_prop_conv(char *string){
int
im_free(image_desc_t *im)
{
- unsigned long i,ii;
+ unsigned long i,ii;
if (im == NULL) return 0;
for(i=0;i<(unsigned)im->gdes_c;i++){
if (im->gdes[i].data_first){
- /* careful here, because a single pointer can occur several times */
- free (im->gdes[i].data);
- if (im->gdes[i].ds_namv){
- for (ii=0;ii<im->gdes[i].ds_cnt;ii++)
- free(im->gdes[i].ds_namv[ii]);
- free(im->gdes[i].ds_namv);
- }
+ /* careful here, because a single pointer can occur several times */
+ free (im->gdes[i].data);
+ if (im->gdes[i].ds_namv){
+ for (ii=0;ii<im->gdes[i].ds_cnt;ii++)
+ free(im->gdes[i].ds_namv[ii]);
+ free(im->gdes[i].ds_namv);
+ }
}
free (im->gdes[i].p_data);
free (im->gdes[i].rpnp);
/* find SI magnitude symbol for the given number*/
void
auto_scale(
- image_desc_t *im, /* image description */
- double *value,
- char **symb_ptr,
- double *magfact
- )
+ image_desc_t *im, /* image description */
+ double *value,
+ char **symb_ptr,
+ double *magfact
+ )
{
-
+
char *symbol[] = {"a", /* 10e-18 Atto */
- "f", /* 10e-15 Femto */
- "p", /* 10e-12 Pico */
- "n", /* 10e-9 Nano */
- "u", /* 10e-6 Micro */
- "m", /* 10e-3 Milli */
- " ", /* Base */
- "k", /* 10e3 Kilo */
- "M", /* 10e6 Mega */
- "G", /* 10e9 Giga */
- "T", /* 10e12 Tera */
- "P", /* 10e15 Peta */
- "E"};/* 10e18 Exa */
+ "f", /* 10e-15 Femto */
+ "p", /* 10e-12 Pico */
+ "n", /* 10e-9 Nano */
+ "u", /* 10e-6 Micro */
+ "m", /* 10e-3 Milli */
+ " ", /* Base */
+ "k", /* 10e3 Kilo */
+ "M", /* 10e6 Mega */
+ "G", /* 10e9 Giga */
+ "T", /* 10e12 Tera */
+ "P", /* 10e15 Peta */
+ "E"};/* 10e18 Exa */
int symbcenter = 6;
int sindex;
if (*value == 0.0 || isnan(*value) ) {
- sindex = 0;
- *magfact = 1.0;
+ sindex = 0;
+ *magfact = 1.0;
} else {
- sindex = floor(log(fabs(*value))/log((double)im->base));
- *magfact = pow((double)im->base, (double)sindex);
- (*value) /= (*magfact);
+ sindex = floor(log(fabs(*value))/log((double)im->base));
+ *magfact = pow((double)im->base, (double)sindex);
+ (*value) /= (*magfact);
}
if ( sindex <= symbcenter && sindex >= -symbcenter) {
- (*symb_ptr) = symbol[sindex+symbcenter];
+ (*symb_ptr) = symbol[sindex+symbcenter];
}
else {
- (*symb_ptr) = "?";
+ (*symb_ptr) = "?";
}
}
static char si_symbol[] = {
- 'a', /* 10e-18 Atto */
- 'f', /* 10e-15 Femto */
- 'p', /* 10e-12 Pico */
- 'n', /* 10e-9 Nano */
- 'u', /* 10e-6 Micro */
- 'm', /* 10e-3 Milli */
- ' ', /* Base */
- 'k', /* 10e3 Kilo */
- 'M', /* 10e6 Mega */
- 'G', /* 10e9 Giga */
- 'T', /* 10e12 Tera */
- 'P', /* 10e15 Peta */
- 'E', /* 10e18 Exa */
+ 'a', /* 10e-18 Atto */
+ 'f', /* 10e-15 Femto */
+ 'p', /* 10e-12 Pico */
+ 'n', /* 10e-9 Nano */
+ 'u', /* 10e-6 Micro */
+ 'm', /* 10e-3 Milli */
+ ' ', /* Base */
+ 'k', /* 10e3 Kilo */
+ 'M', /* 10e6 Mega */
+ 'G', /* 10e9 Giga */
+ 'T', /* 10e12 Tera */
+ 'P', /* 10e15 Peta */
+ 'E', /* 10e18 Exa */
};
static const int si_symbcenter = 6;
digits = floor( log( max( fabs(im->minval),fabs(im->maxval)))/log((double)im->base));
if (im->unitsexponent != 9999) {
- /* unitsexponent = 9, 6, 3, 0, -3, -6, -9, etc */
+ /* unitsexponent = 9, 6, 3, 0, -3, -6, -9, etc */
viewdigits = floor(im->unitsexponent / 3);
} else {
- viewdigits = digits;
+ viewdigits = digits;
}
im->magfact = pow((double)im->base , digits);
im->viewfactor = im->magfact / pow((double)im->base , viewdigits);
if ( ((viewdigits+si_symbcenter) < sizeof(si_symbol)) &&
- ((viewdigits+si_symbcenter) >= 0) )
+ ((viewdigits+si_symbcenter) >= 0) )
im->symbol = si_symbol[(int)viewdigits+si_symbcenter];
else
- im->symbol = '?';
+ im->symbol = '?';
}
/* move min and max values around to become sensible */
expand_range(image_desc_t *im)
{
double sensiblevalues[] ={1000.0,900.0,800.0,750.0,700.0,
- 600.0,500.0,400.0,300.0,250.0,
- 200.0,125.0,100.0,90.0,80.0,
- 75.0,70.0,60.0,50.0,40.0,30.0,
- 25.0,20.0,10.0,9.0,8.0,
- 7.0,6.0,5.0,4.0,3.5,3.0,
- 2.5,2.0,1.8,1.5,1.2,1.0,
- 0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1,0.0,-1};
+ 600.0,500.0,400.0,300.0,250.0,
+ 200.0,125.0,100.0,90.0,80.0,
+ 75.0,70.0,60.0,50.0,40.0,30.0,
+ 25.0,20.0,10.0,9.0,8.0,
+ 7.0,6.0,5.0,4.0,3.5,3.0,
+ 2.5,2.0,1.8,1.5,1.2,1.0,
+ 0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1,0.0,-1};
double scaled_min,scaled_max;
double adj;
#ifdef DEBUG
printf("Min: %6.2f Max: %6.2f MagFactor: %6.2f\n",
- im->minval,im->maxval,im->magfact);
+ im->minval,im->maxval,im->magfact);
#endif
if (isnan(im->ygridstep)){
- if(im->extra_flags & ALTAUTOSCALE) {
- /* measure the amplitude of the function. Make sure that
- graph boundaries are slightly higher then max/min vals
- so we can see amplitude on the graph */
- double delt, fact;
-
- delt = im->maxval - im->minval;
- adj = delt * 0.1;
- fact = 2.0 * pow(10.0,
- floor(log10(max(fabs(im->minval), fabs(im->maxval))/im->magfact)) - 2);
- if (delt < fact) {
- adj = (fact - delt) * 0.55;
+ if(im->extra_flags & ALTAUTOSCALE) {
+ /* measure the amplitude of the function. Make sure that
+ graph boundaries are slightly higher then max/min vals
+ so we can see amplitude on the graph */
+ double delt, fact;
+
+ delt = im->maxval - im->minval;
+ adj = delt * 0.1;
+ fact = 2.0 * pow(10.0,
+ floor(log10(max(fabs(im->minval), fabs(im->maxval))/im->magfact)) - 2);
+ if (delt < fact) {
+ adj = (fact - delt) * 0.55;
#ifdef DEBUG
- printf("Min: %6.2f Max: %6.2f delt: %6.2f fact: %6.2f adj: %6.2f\n", im->minval, im->maxval, delt, fact, adj);
+ printf("Min: %6.2f Max: %6.2f delt: %6.2f fact: %6.2f adj: %6.2f\n", im->minval, im->maxval, delt, fact, adj);
#endif
- }
- im->minval -= adj;
- im->maxval += adj;
- }
- else if(im->extra_flags & ALTAUTOSCALE_MAX) {
- /* measure the amplitude of the function. Make sure that
- graph boundaries are slightly higher than max vals
- so we can see amplitude on the graph */
- adj = (im->maxval - im->minval) * 0.1;
- im->maxval += adj;
- }
- else {
- scaled_min = im->minval / im->magfact;
- scaled_max = im->maxval / im->magfact;
-
- for (i=1; sensiblevalues[i] > 0; i++){
- if (sensiblevalues[i-1]>=scaled_min &&
- sensiblevalues[i]<=scaled_min)
- im->minval = sensiblevalues[i]*(im->magfact);
-
- if (-sensiblevalues[i-1]<=scaled_min &&
- -sensiblevalues[i]>=scaled_min)
- im->minval = -sensiblevalues[i-1]*(im->magfact);
-
- if (sensiblevalues[i-1] >= scaled_max &&
- sensiblevalues[i] <= scaled_max)
- im->maxval = sensiblevalues[i-1]*(im->magfact);
-
- if (-sensiblevalues[i-1]<=scaled_max &&
- -sensiblevalues[i] >=scaled_max)
- im->maxval = -sensiblevalues[i]*(im->magfact);
- }
- }
+ }
+ im->minval -= adj;
+ im->maxval += adj;
+ }
+ else if(im->extra_flags & ALTAUTOSCALE_MAX) {
+ /* measure the amplitude of the function. Make sure that
+ graph boundaries are slightly higher than max vals
+ so we can see amplitude on the graph */
+ adj = (im->maxval - im->minval) * 0.1;
+ im->maxval += adj;
+ }
+ else {
+ scaled_min = im->minval / im->magfact;
+ scaled_max = im->maxval / im->magfact;
+
+ for (i=1; sensiblevalues[i] > 0; i++){
+ if (sensiblevalues[i-1]>=scaled_min &&
+ sensiblevalues[i]<=scaled_min)
+ im->minval = sensiblevalues[i]*(im->magfact);
+
+ if (-sensiblevalues[i-1]<=scaled_min &&
+ -sensiblevalues[i]>=scaled_min)
+ im->minval = -sensiblevalues[i-1]*(im->magfact);
+
+ if (sensiblevalues[i-1] >= scaled_max &&
+ sensiblevalues[i] <= scaled_max)
+ im->maxval = sensiblevalues[i-1]*(im->magfact);
+
+ if (-sensiblevalues[i-1]<=scaled_max &&
+ -sensiblevalues[i] >=scaled_max)
+ im->maxval = -sensiblevalues[i]*(im->magfact);
+ }
+ }
} else {
- /* adjust min and max to the grid definition if there is one */
- im->minval = (double)im->ylabfact * im->ygridstep *
- floor(im->minval / ((double)im->ylabfact * im->ygridstep));
- im->maxval = (double)im->ylabfact * im->ygridstep *
- ceil(im->maxval /( (double)im->ylabfact * im->ygridstep));
+ /* adjust min and max to the grid definition if there is one */
+ im->minval = (double)im->ylabfact * im->ygridstep *
+ floor(im->minval / ((double)im->ylabfact * im->ygridstep));
+ im->maxval = (double)im->ylabfact * im->ygridstep *
+ ceil(im->maxval /( (double)im->ylabfact * im->ygridstep));
}
#ifdef DEBUG
fprintf(stderr,"SCALED Min: %6.2f Max: %6.2f Factor: %6.2f\n",
- im->minval,im->maxval,im->magfact);
+ im->minval,im->maxval,im->magfact);
#endif
}
yb = ya * 10;
if (yb <= im->maxval) {
/* we have at least 2 y=10^x gridlines.
- Make sure distance between them in pixels
- are an integer by expanding im->maxval */
+ Make sure distance between them in pixels
+ are an integer by expanding im->maxval */
double y_pixel_delta = ytr(im, ya) - ytr(im, yb);
double factor = y_pixel_delta / floor(y_pixel_delta);
double new_log10_range = factor * log10_range;
#endif
#ifdef DEBUG_REDUCE
printf("Reducing %lu rows with factor %i time %lu to %lu, step %lu\n",
- row_cnt,reduce_factor,*start,*end,cur_step);
+ row_cnt,reduce_factor,*start,*end,cur_step);
for (col=0;col<row_cnt;col++) {
printf("time %10lu: ",*start+(col+1)*cur_step);
for (i=0;i<*ds_cnt;i++)
- printf(" %8.2e",srcptr[*ds_cnt*col+i]);
+ printf(" %8.2e",srcptr[*ds_cnt*col+i]);
printf("\n");
}
#endif
printf("row_cnt before: %lu\n",row_cnt);
#endif
if (start_offset) {
- (*start) = (*start)-start_offset;
- skiprows=reduce_factor-start_offset/cur_step;
- srcptr+=skiprows* *ds_cnt;
+ (*start) = (*start)-start_offset;
+ skiprows=reduce_factor-start_offset/cur_step;
+ srcptr+=skiprows* *ds_cnt;
for (col=0;col<(*ds_cnt);col++) *dstptr++ = DNAN;
- row_cnt-=skiprows;
+ row_cnt-=skiprows;
}
#ifdef DEBUG_REDUCE
printf("row_cnt between: %lu\n",row_cnt);
** used, the amount is end_offset/cur_step
*/
if (end_offset) {
- (*end) = (*end)-end_offset+(*step);
- skiprows = end_offset/cur_step;
- row_cnt-=skiprows;
+ (*end) = (*end)-end_offset+(*step);
+ skiprows = end_offset/cur_step;
+ row_cnt-=skiprows;
}
#ifdef DEBUG_REDUCE
printf("row_cnt after: %lu\n",row_cnt);
/* if this gets triggered, something is REALLY WRONG ... we die immediately */
if (row_cnt%reduce_factor) {
- printf("SANITY CHECK: %lu rows cannot be reduced by %i \n",
- row_cnt,reduce_factor);
- printf("BUG in reduce_data()\n");
- exit(1);
+ printf("SANITY CHECK: %lu rows cannot be reduced by %i \n",
+ row_cnt,reduce_factor);
+ printf("BUG in reduce_data()\n");
+ exit(1);
}
/* Now combine reduce_factor intervals at a time
*/
for (dst_row=0;(long int)row_cnt>=reduce_factor;dst_row++) {
- for (col=0;col<(*ds_cnt);col++) {
- rrd_value_t newval=DNAN;
- unsigned long validval=0;
-
- for (i=0;i<reduce_factor;i++) {
- if (isnan(srcptr[i*(*ds_cnt)+col])) {
- continue;
- }
- validval++;
- if (isnan(newval)) newval = srcptr[i*(*ds_cnt)+col];
- else {
- switch (cf) {
- case CF_HWPREDICT:
- case CF_DEVSEASONAL:
- case CF_DEVPREDICT:
- case CF_SEASONAL:
- case CF_AVERAGE:
- newval += srcptr[i*(*ds_cnt)+col];
- break;
- case CF_MINIMUM:
- newval = min (newval,srcptr[i*(*ds_cnt)+col]);
- break;
- case CF_FAILURES:
- /* an interval contains a failure if any subintervals contained a failure */
- case CF_MAXIMUM:
- newval = max (newval,srcptr[i*(*ds_cnt)+col]);
- break;
- case CF_LAST:
- newval = srcptr[i*(*ds_cnt)+col];
- break;
- }
- }
- }
- if (validval == 0){newval = DNAN;} else{
- switch (cf) {
- case CF_HWPREDICT:
- case CF_DEVSEASONAL:
- case CF_DEVPREDICT:
- case CF_SEASONAL:
- case CF_AVERAGE:
- newval /= validval;
- break;
- case CF_MINIMUM:
- case CF_FAILURES:
- case CF_MAXIMUM:
- case CF_LAST:
- break;
- }
- }
- *dstptr++=newval;
- }
- srcptr+=(*ds_cnt)*reduce_factor;
- row_cnt-=reduce_factor;
+ for (col=0;col<(*ds_cnt);col++) {
+ rrd_value_t newval=DNAN;
+ unsigned long validval=0;
+
+ for (i=0;i<reduce_factor;i++) {
+ if (isnan(srcptr[i*(*ds_cnt)+col])) {
+ continue;
+ }
+ validval++;
+ if (isnan(newval)) newval = srcptr[i*(*ds_cnt)+col];
+ else {
+ switch (cf) {
+ case CF_HWPREDICT:
+ case CF_DEVSEASONAL:
+ case CF_DEVPREDICT:
+ case CF_SEASONAL:
+ case CF_AVERAGE:
+ newval += srcptr[i*(*ds_cnt)+col];
+ break;
+ case CF_MINIMUM:
+ newval = min (newval,srcptr[i*(*ds_cnt)+col]);
+ break;
+ case CF_FAILURES:
+ /* an interval contains a failure if any subintervals contained a failure */
+ case CF_MAXIMUM:
+ newval = max (newval,srcptr[i*(*ds_cnt)+col]);
+ break;
+ case CF_LAST:
+ newval = srcptr[i*(*ds_cnt)+col];
+ break;
+ }
+ }
+ }
+ if (validval == 0){newval = DNAN;} else{
+ switch (cf) {
+ case CF_HWPREDICT:
+ case CF_DEVSEASONAL:
+ case CF_DEVPREDICT:
+ case CF_SEASONAL:
+ case CF_AVERAGE:
+ newval /= validval;
+ break;
+ case CF_MINIMUM:
+ case CF_FAILURES:
+ case CF_MAXIMUM:
+ case CF_LAST:
+ break;
+ }
+ }
+ *dstptr++=newval;
+ }
+ srcptr+=(*ds_cnt)*reduce_factor;
+ row_cnt-=reduce_factor;
}
/* If we had to alter the endtime, we didn't have enough
** source rows to fill the last row. Fill it with NaN.
row_cnt = ((*end)-(*start))/ *step;
srcptr = *data;
printf("Done reducing. Currently %lu rows, time %lu to %lu, step %lu\n",
- row_cnt,*start,*end,*step);
+ row_cnt,*start,*end,*step);
for (col=0;col<row_cnt;col++) {
printf("time %10lu: ",*start+(col+1)*(*step));
for (i=0;i<*ds_cnt;i++)
- printf(" %8.2e",srcptr[*ds_cnt*col+i]);
+ printf(" %8.2e",srcptr[*ds_cnt*col+i]);
printf("\n");
}
#endif
data_fetch(image_desc_t *im )
{
int i,ii;
- int skip;
+ int skip;
/* pull the data from the rrd files ... */
for (i=0;i< (int)im->gdes_c;i++){
- /* only GF_DEF elements fetch data */
- if (im->gdes[i].gf != GF_DEF)
- continue;
-
- skip=0;
- /* do we have it already ?*/
- for (ii=0;ii<i;ii++) {
- if (im->gdes[ii].gf != GF_DEF)
- continue;
- if ((strcmp(im->gdes[i].rrd, im->gdes[ii].rrd) == 0)
- && (im->gdes[i].cf == im->gdes[ii].cf)
- && (im->gdes[i].cf_reduce == im->gdes[ii].cf_reduce)
- && (im->gdes[i].start_orig == im->gdes[ii].start_orig)
- && (im->gdes[i].end_orig == im->gdes[ii].end_orig)
- && (im->gdes[i].step_orig == im->gdes[ii].step_orig)) {
- /* OK, the data is already there.
- ** Just copy the header portion
- */
- im->gdes[i].start = im->gdes[ii].start;
- im->gdes[i].end = im->gdes[ii].end;
- im->gdes[i].step = im->gdes[ii].step;
- im->gdes[i].ds_cnt = im->gdes[ii].ds_cnt;
- im->gdes[i].ds_namv = im->gdes[ii].ds_namv;
- im->gdes[i].data = im->gdes[ii].data;
- im->gdes[i].data_first = 0;
- skip=1;
- }
- if (skip)
- break;
- }
- if (! skip) {
- unsigned long ft_step = im->gdes[i].step ; /* ft_step will record what we got from fetch */
-
- if((rrd_fetch_fn(im->gdes[i].rrd,
- im->gdes[i].cf,
- &im->gdes[i].start,
- &im->gdes[i].end,
- &ft_step,
- &im->gdes[i].ds_cnt,
- &im->gdes[i].ds_namv,
- &im->gdes[i].data)) == -1){
- return -1;
- }
- im->gdes[i].data_first = 1;
-
- if (ft_step < im->gdes[i].step) {
- reduce_data(im->gdes[i].cf_reduce,
- ft_step,
- &im->gdes[i].start,
- &im->gdes[i].end,
- &im->gdes[i].step,
- &im->gdes[i].ds_cnt,
- &im->gdes[i].data);
- } else {
- im->gdes[i].step = ft_step;
- }
- }
-
+ /* only GF_DEF elements fetch data */
+ if (im->gdes[i].gf != GF_DEF)
+ continue;
+
+ skip=0;
+ /* do we have it already ?*/
+ for (ii=0;ii<i;ii++) {
+ if (im->gdes[ii].gf != GF_DEF)
+ continue;
+ if ((strcmp(im->gdes[i].rrd, im->gdes[ii].rrd) == 0)
+ && (im->gdes[i].cf == im->gdes[ii].cf)
+ && (im->gdes[i].cf_reduce == im->gdes[ii].cf_reduce)
+ && (im->gdes[i].start_orig == im->gdes[ii].start_orig)
+ && (im->gdes[i].end_orig == im->gdes[ii].end_orig)
+ && (im->gdes[i].step_orig == im->gdes[ii].step_orig)) {
+ /* OK, the data is already there.
+ ** Just copy the header portion
+ */
+ im->gdes[i].start = im->gdes[ii].start;
+ im->gdes[i].end = im->gdes[ii].end;
+ im->gdes[i].step = im->gdes[ii].step;
+ im->gdes[i].ds_cnt = im->gdes[ii].ds_cnt;
+ im->gdes[i].ds_namv = im->gdes[ii].ds_namv;
+ im->gdes[i].data = im->gdes[ii].data;
+ im->gdes[i].data_first = 0;
+ skip=1;
+ }
+ if (skip)
+ break;
+ }
+ if (! skip) {
+ unsigned long ft_step = im->gdes[i].step ; /* ft_step will record what we got from fetch */
+
+ if((rrd_fetch_fn(im->gdes[i].rrd,
+ im->gdes[i].cf,
+ &im->gdes[i].start,
+ &im->gdes[i].end,
+ &ft_step,
+ &im->gdes[i].ds_cnt,
+ &im->gdes[i].ds_namv,
+ &im->gdes[i].data)) == -1){
+ return -1;
+ }
+ im->gdes[i].data_first = 1;
+
+ if (ft_step < im->gdes[i].step) {
+ reduce_data(im->gdes[i].cf_reduce,
+ ft_step,
+ &im->gdes[i].start,
+ &im->gdes[i].end,
+ &im->gdes[i].step,
+ &im->gdes[i].ds_cnt,
+ &im->gdes[i].data);
+ } else {
+ im->gdes[i].step = ft_step;
+ }
+ }
+
/* lets see if the required data source is really there */
- for(ii=0;ii<(int)im->gdes[i].ds_cnt;ii++){
- if(strcmp(im->gdes[i].ds_namv[ii],im->gdes[i].ds_nam) == 0){
- im->gdes[i].ds=ii; }
- }
- if (im->gdes[i].ds== -1){
- rrd_set_error("No DS called '%s' in '%s'",
- im->gdes[i].ds_nam,im->gdes[i].rrd);
- return -1;
- }
-
+ for(ii=0;ii<(int)im->gdes[i].ds_cnt;ii++){
+ if(strcmp(im->gdes[i].ds_namv[ii],im->gdes[i].ds_nam) == 0){
+ im->gdes[i].ds=ii; }
+ }
+ if (im->gdes[i].ds== -1){
+ rrd_set_error("No DS called '%s' in '%s'",
+ im->gdes[i].ds_nam,im->gdes[i].rrd);
+ return -1;
+ }
+
}
return 0;
}
find_var(image_desc_t *im, char *key){
long ii;
for(ii=0;ii<im->gdes_c-1;ii++){
- if((im->gdes[ii].gf == GF_DEF
- || im->gdes[ii].gf == GF_VDEF
- || im->gdes[ii].gf == GF_CDEF)
- && (strcmp(im->gdes[ii].vname,key) == 0)){
- return ii;
- }
- }
+ if((im->gdes[ii].gf == GF_DEF
+ || im->gdes[ii].gf == GF_VDEF
+ || im->gdes[ii].gf == GF_CDEF)
+ && (strcmp(im->gdes[ii].vname,key) == 0)){
+ return ii;
+ }
+ }
return -1;
}
long rest;
int i;
for (i=0;num[i+1]!=0;i++){
- do {
- rest=num[i] % num[i+1];
- num[i]=num[i+1]; num[i+1]=rest;
- } while (rest!=0);
- num[i+1] = num[i];
+ do {
+ rest=num[i] % num[i+1];
+ num[i]=num[i+1]; num[i+1]=rest;
+ } while (rest!=0);
+ num[i+1] = num[i];
}
/* return i==0?num[i]:num[i-1]; */
return num[i];
rpnstack_init(&rpnstack);
for (gdi=0;gdi<im->gdes_c;gdi++){
- /* Look for GF_VDEF and GF_CDEF in the same loop,
- * so CDEFs can use VDEFs and vice versa
- */
- switch (im->gdes[gdi].gf) {
- case GF_XPORT:
- break;
- case GF_SHIFT: {
- graph_desc_t *vdp = &im->gdes[im->gdes[gdi].vidx];
-
- /* remove current shift */
- vdp->start -= vdp->shift;
- vdp->end -= vdp->shift;
-
- /* vdef */
- if (im->gdes[gdi].shidx >= 0)
- vdp->shift = im->gdes[im->gdes[gdi].shidx].vf.val;
- /* constant */
- else
- vdp->shift = im->gdes[gdi].shval;
-
- /* normalize shift to multiple of consolidated step */
- vdp->shift = (vdp->shift / (long)vdp->step) * (long)vdp->step;
-
- /* apply shift */
- vdp->start += vdp->shift;
- vdp->end += vdp->shift;
- break;
- }
- case GF_VDEF:
- /* A VDEF has no DS. This also signals other parts
- * of rrdtool that this is a VDEF value, not a CDEF.
- */
- im->gdes[gdi].ds_cnt = 0;
- if (vdef_calc(im,gdi)) {
- rrd_set_error("Error processing VDEF '%s'"
- ,im->gdes[gdi].vname
- );
- rpnstack_free(&rpnstack);
- return -1;
- }
- break;
- case GF_CDEF:
- im->gdes[gdi].ds_cnt = 1;
- im->gdes[gdi].ds = 0;
- im->gdes[gdi].data_first = 1;
- im->gdes[gdi].start = 0;
- im->gdes[gdi].end = 0;
- steparray=NULL;
- stepcnt = 0;
- dataidx=-1;
-
- /* Find the variables in the expression.
- * - VDEF variables are substituted by their values
- * and the opcode is changed into OP_NUMBER.
- * - CDEF variables are analized for their step size,
- * the lowest common denominator of all the step
- * sizes of the data sources involved is calculated
- * and the resulting number is the step size for the
- * resulting data source.
- */
- for(rpi=0;im->gdes[gdi].rpnp[rpi].op != OP_END;rpi++){
- if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE ||
- im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER){
- long ptr = im->gdes[gdi].rpnp[rpi].ptr;
- if (im->gdes[ptr].ds_cnt == 0) { /* this is a VDEF data source */
+ /* Look for GF_VDEF and GF_CDEF in the same loop,
+ * so CDEFs can use VDEFs and vice versa
+ */
+ switch (im->gdes[gdi].gf) {
+ case GF_XPORT:
+ break;
+ case GF_SHIFT: {
+ graph_desc_t *vdp = &im->gdes[im->gdes[gdi].vidx];
+
+ /* remove current shift */
+ vdp->start -= vdp->shift;
+ vdp->end -= vdp->shift;
+
+ /* vdef */
+ if (im->gdes[gdi].shidx >= 0)
+ vdp->shift = im->gdes[im->gdes[gdi].shidx].vf.val;
+ /* constant */
+ else
+ vdp->shift = im->gdes[gdi].shval;
+
+ /* normalize shift to multiple of consolidated step */
+ vdp->shift = (vdp->shift / (long)vdp->step) * (long)vdp->step;
+
+ /* apply shift */
+ vdp->start += vdp->shift;
+ vdp->end += vdp->shift;
+ break;
+ }
+ case GF_VDEF:
+ /* A VDEF has no DS. This also signals other parts
+ * of rrdtool that this is a VDEF value, not a CDEF.
+ */
+ im->gdes[gdi].ds_cnt = 0;
+ if (vdef_calc(im,gdi)) {
+ rrd_set_error("Error processing VDEF '%s'"
+ ,im->gdes[gdi].vname
+ );
+ rpnstack_free(&rpnstack);
+ return -1;
+ }
+ break;
+ case GF_CDEF:
+ im->gdes[gdi].ds_cnt = 1;
+ im->gdes[gdi].ds = 0;
+ im->gdes[gdi].data_first = 1;
+ im->gdes[gdi].start = 0;
+ im->gdes[gdi].end = 0;
+ steparray=NULL;
+ stepcnt = 0;
+ dataidx=-1;
+
+ /* Find the variables in the expression.
+ * - VDEF variables are substituted by their values
+ * and the opcode is changed into OP_NUMBER.
+ * - CDEF variables are analized for their step size,
+ * the lowest common denominator of all the step
+ * sizes of the data sources involved is calculated
+ * and the resulting number is the step size for the
+ * resulting data source.
+ */
+ for(rpi=0;im->gdes[gdi].rpnp[rpi].op != OP_END;rpi++){
+ if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE ||
+ im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER){
+ long ptr = im->gdes[gdi].rpnp[rpi].ptr;
+ if (im->gdes[ptr].ds_cnt == 0) { /* this is a VDEF data source */
#if 0
- printf("DEBUG: inside CDEF '%s' processing VDEF '%s'\n",
- im->gdes[gdi].vname,
- im->gdes[ptr].vname);
- printf("DEBUG: value from vdef is %f\n",im->gdes[ptr].vf.val);
+ printf("DEBUG: inside CDEF '%s' processing VDEF '%s'\n",
+ im->gdes[gdi].vname,
+ im->gdes[ptr].vname);
+ printf("DEBUG: value from vdef is %f\n",im->gdes[ptr].vf.val);
#endif
- im->gdes[gdi].rpnp[rpi].val = im->gdes[ptr].vf.val;
- im->gdes[gdi].rpnp[rpi].op = OP_NUMBER;
- } else { /* normal variables and PREF(variables) */
-
- /* add one entry to the array that keeps track of the step sizes of the
- * data sources going into the CDEF. */
- if ((steparray =
- rrd_realloc(steparray,
- (++stepcnt+1)*sizeof(*steparray)))==NULL){
- rrd_set_error("realloc steparray");
- rpnstack_free(&rpnstack);
- return -1;
- };
-
- steparray[stepcnt-1] = im->gdes[ptr].step;
-
- /* adjust start and end of cdef (gdi) so
- * that it runs from the latest start point
- * to the earliest endpoint of any of the
- * rras involved (ptr)
- */
-
- if(im->gdes[gdi].start < im->gdes[ptr].start)
- im->gdes[gdi].start = im->gdes[ptr].start;
-
- if(im->gdes[gdi].end == 0 ||
- im->gdes[gdi].end > im->gdes[ptr].end)
- im->gdes[gdi].end = im->gdes[ptr].end;
-
- /* store pointer to the first element of
- * the rra providing data for variable,
- * further save step size and data source
- * count of this rra
- */
+ im->gdes[gdi].rpnp[rpi].val = im->gdes[ptr].vf.val;
+ im->gdes[gdi].rpnp[rpi].op = OP_NUMBER;
+ } else { /* normal variables and PREF(variables) */
+
+ /* add one entry to the array that keeps track of the step sizes of the
+ * data sources going into the CDEF. */
+ if ((steparray =
+ rrd_realloc(steparray,
+ (++stepcnt+1)*sizeof(*steparray)))==NULL){
+ rrd_set_error("realloc steparray");
+ rpnstack_free(&rpnstack);
+ return -1;
+ };
+
+ steparray[stepcnt-1] = im->gdes[ptr].step;
+
+ /* adjust start and end of cdef (gdi) so
+ * that it runs from the latest start point
+ * to the earliest endpoint of any of the
+ * rras involved (ptr)
+ */
+
+ if(im->gdes[gdi].start < im->gdes[ptr].start)
+ im->gdes[gdi].start = im->gdes[ptr].start;
+
+ if(im->gdes[gdi].end == 0 ||
+ im->gdes[gdi].end > im->gdes[ptr].end)
+ im->gdes[gdi].end = im->gdes[ptr].end;
+
+ /* store pointer to the first element of
+ * the rra providing data for variable,
+ * further save step size and data source
+ * count of this rra
+ */
im->gdes[gdi].rpnp[rpi].data = im->gdes[ptr].data + im->gdes[ptr].ds;
- im->gdes[gdi].rpnp[rpi].step = im->gdes[ptr].step;
- im->gdes[gdi].rpnp[rpi].ds_cnt = im->gdes[ptr].ds_cnt;
+ im->gdes[gdi].rpnp[rpi].step = im->gdes[ptr].step;
+ im->gdes[gdi].rpnp[rpi].ds_cnt = im->gdes[ptr].ds_cnt;
- /* backoff the *.data ptr; this is done so
- * rpncalc() function doesn't have to treat
- * the first case differently
- */
- } /* if ds_cnt != 0 */
- } /* if OP_VARIABLE */
- } /* loop through all rpi */
+ /* backoff the *.data ptr; this is done so
+ * rpncalc() function doesn't have to treat
+ * the first case differently
+ */
+ } /* if ds_cnt != 0 */
+ } /* if OP_VARIABLE */
+ } /* loop through all rpi */
/* move the data pointers to the correct period */
for(rpi=0;im->gdes[gdi].rpnp[rpi].op != OP_END;rpi++){
- if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE ||
- im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER){
- long ptr = im->gdes[gdi].rpnp[rpi].ptr;
- long diff = im->gdes[gdi].start - im->gdes[ptr].start;
+ if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE ||
+ im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER){
+ long ptr = im->gdes[gdi].rpnp[rpi].ptr;
+ long diff = im->gdes[gdi].start - im->gdes[ptr].start;
if(diff > 0)
- im->gdes[gdi].rpnp[rpi].data += (diff / im->gdes[ptr].step) * im->gdes[ptr].ds_cnt;
+ im->gdes[gdi].rpnp[rpi].data += (diff / im->gdes[ptr].step) * im->gdes[ptr].ds_cnt;
}
}
- if(steparray == NULL){
- rrd_set_error("rpn expressions without DEF"
- " or CDEF variables are not supported");
- rpnstack_free(&rpnstack);
- return -1;
- }
- steparray[stepcnt]=0;
- /* Now find the resulting step. All steps in all
- * used RRAs have to be visited
- */
- im->gdes[gdi].step = lcd(steparray);
- free(steparray);
- if((im->gdes[gdi].data = malloc((
- (im->gdes[gdi].end-im->gdes[gdi].start)
- / im->gdes[gdi].step)
- * sizeof(double)))==NULL){
- rrd_set_error("malloc im->gdes[gdi].data");
- rpnstack_free(&rpnstack);
- return -1;
- }
-
- /* Step through the new cdef results array and
- * calculate the values
- */
- for (now = im->gdes[gdi].start + im->gdes[gdi].step;
- now<=im->gdes[gdi].end;
- now += im->gdes[gdi].step)
- {
- rpnp_t *rpnp = im -> gdes[gdi].rpnp;
-
- /* 3rd arg of rpn_calc is for OP_VARIABLE lookups;
- * in this case we are advancing by timesteps;
- * we use the fact that time_t is a synonym for long
- */
- if (rpn_calc(rpnp,&rpnstack,(long) now,
- im->gdes[gdi].data,++dataidx) == -1) {
- /* rpn_calc sets the error string */
- rpnstack_free(&rpnstack);
- return -1;
- }
- } /* enumerate over time steps within a CDEF */
- break;
- default:
- continue;
- }
+ if(steparray == NULL){
+ rrd_set_error("rpn expressions without DEF"
+ " or CDEF variables are not supported");
+ rpnstack_free(&rpnstack);
+ return -1;
+ }
+ steparray[stepcnt]=0;
+ /* Now find the resulting step. All steps in all
+ * used RRAs have to be visited
+ */
+ im->gdes[gdi].step = lcd(steparray);
+ free(steparray);
+ if((im->gdes[gdi].data = malloc((
+ (im->gdes[gdi].end-im->gdes[gdi].start)
+ / im->gdes[gdi].step)
+ * sizeof(double)))==NULL){
+ rrd_set_error("malloc im->gdes[gdi].data");
+ rpnstack_free(&rpnstack);
+ return -1;
+ }
+
+ /* Step through the new cdef results array and
+ * calculate the values
+ */
+ for (now = im->gdes[gdi].start + im->gdes[gdi].step;
+ now<=im->gdes[gdi].end;
+ now += im->gdes[gdi].step)
+ {
+ rpnp_t *rpnp = im -> gdes[gdi].rpnp;
+
+ /* 3rd arg of rpn_calc is for OP_VARIABLE lookups;
+ * in this case we are advancing by timesteps;
+ * we use the fact that time_t is a synonym for long
+ */
+ if (rpn_calc(rpnp,&rpnstack,(long) now,
+ im->gdes[gdi].data,++dataidx) == -1) {
+ /* rpn_calc sets the error string */
+ rpnstack_free(&rpnstack);
+ return -1;
+ }
+ } /* enumerate over time steps within a CDEF */
+ break;
+ default:
+ continue;
+ }
} /* enumerate over CDEFs */
rpnstack_free(&rpnstack);
return 0;
data_proc( image_desc_t *im ){
long i,ii;
double pixstep = (double)(im->end-im->start)
- /(double)im->xsize; /* how much time
- passes in one pixel */
+ /(double)im->xsize; /* how much time
+ passes in one pixel */
double paintval;
double minval=DNAN,maxval=DNAN;
/* memory for the processed data */
for(i=0;i<im->gdes_c;i++) {
- if((im->gdes[i].gf==GF_LINE) ||
- (im->gdes[i].gf==GF_AREA) ||
- (im->gdes[i].gf==GF_TICK)) {
- if((im->gdes[i].p_data = malloc((im->xsize +1)
- * sizeof(rrd_value_t)))==NULL){
- rrd_set_error("malloc data_proc");
- return -1;
- }
- }
- }
-
- for (i=0;i<im->xsize;i++) { /* for each pixel */
- long vidx;
- gr_time = im->start+pixstep*i; /* time of the current step */
- paintval=0.0;
-
- for (ii=0;ii<im->gdes_c;ii++) {
- double value;
- switch (im->gdes[ii].gf) {
- case GF_LINE:
- case GF_AREA:
- case GF_TICK:
- if (!im->gdes[ii].stack)
- paintval = 0.0;
- value = im->gdes[ii].yrule;
- if (isnan(value) || (im->gdes[ii].gf == GF_TICK)) {
- /* The time of the data doesn't necessarily match
- ** the time of the graph. Beware.
- */
- vidx = im->gdes[ii].vidx;
- if (im->gdes[vidx].gf == GF_VDEF) {
- value = im->gdes[vidx].vf.val;
- } else if (((long int)gr_time >= (long int)im->gdes[vidx].start) &&
- ((long int)gr_time <= (long int)im->gdes[vidx].end) ) {
- value = im->gdes[vidx].data[
- (unsigned long) floor(
- (double)(gr_time - im->gdes[vidx].start)
- / im->gdes[vidx].step)
- * im->gdes[vidx].ds_cnt
- + im->gdes[vidx].ds
- ];
- } else {
- value = DNAN;
- }
- };
-
- if (! isnan(value)) {
- paintval += value;
- im->gdes[ii].p_data[i] = paintval;
- /* GF_TICK: the data values are not
- ** relevant for min and max
- */
- if (finite(paintval) && im->gdes[ii].gf != GF_TICK ) {
- if ((isnan(minval) || paintval < minval ) &&
- ! (im->logarithmic && paintval <= 0.0))
- minval = paintval;
- if (isnan(maxval) || paintval > maxval)
- maxval = paintval;
- }
- } else {
- im->gdes[ii].p_data[i] = DNAN;
- }
- break;
- case GF_STACK:
+ if((im->gdes[i].gf==GF_LINE) ||
+ (im->gdes[i].gf==GF_AREA) ||
+ (im->gdes[i].gf==GF_TICK)) {
+ if((im->gdes[i].p_data = malloc((im->xsize +1)
+ * sizeof(rrd_value_t)))==NULL){
+ rrd_set_error("malloc data_proc");
+ return -1;
+ }
+ }
+ }
+
+ for (i=0;i<im->xsize;i++) { /* for each pixel */
+ long vidx;
+ gr_time = im->start+pixstep*i; /* time of the current step */
+ paintval=0.0;
+
+ for (ii=0;ii<im->gdes_c;ii++) {
+ double value;
+ switch (im->gdes[ii].gf) {
+ case GF_LINE:
+ case GF_AREA:
+ case GF_TICK:
+ if (!im->gdes[ii].stack)
+ paintval = 0.0;
+ value = im->gdes[ii].yrule;
+ if (isnan(value) || (im->gdes[ii].gf == GF_TICK)) {
+ /* The time of the data doesn't necessarily match
+ ** the time of the graph. Beware.
+ */
+ vidx = im->gdes[ii].vidx;
+ if (im->gdes[vidx].gf == GF_VDEF) {
+ value = im->gdes[vidx].vf.val;
+ } else if (((long int)gr_time >= (long int)im->gdes[vidx].start) &&
+ ((long int)gr_time <= (long int)im->gdes[vidx].end) ) {
+ value = im->gdes[vidx].data[
+ (unsigned long) floor(
+ (double)(gr_time - im->gdes[vidx].start)
+ / im->gdes[vidx].step)
+ * im->gdes[vidx].ds_cnt
+ + im->gdes[vidx].ds
+ ];
+ } else {
+ value = DNAN;
+ }
+ };
+
+ if (! isnan(value)) {
+ paintval += value;
+ im->gdes[ii].p_data[i] = paintval;
+ /* GF_TICK: the data values are not
+ ** relevant for min and max
+ */
+ if (finite(paintval) && im->gdes[ii].gf != GF_TICK ) {
+ if ((isnan(minval) || paintval < minval ) &&
+ ! (im->logarithmic && paintval <= 0.0))
+ minval = paintval;
+ if (isnan(maxval) || paintval > maxval)
+ maxval = paintval;
+ }
+ } else {
+ im->gdes[ii].p_data[i] = DNAN;
+ }
+ break;
+ case GF_STACK:
rrd_set_error("STACK should already be turned into LINE or AREA here");
return -1;
break;
- default:
- break;
- }
- }
+ default:
+ break;
+ }
+ }
}
/* if min or max have not been asigned a value this is because
lets set these to dummy values then ... */
if (im->logarithmic) {
- if (isnan(minval)) minval = 0.2;
- if (isnan(maxval)) maxval = 5.1;
+ if (isnan(minval)) minval = 0.2;
+ if (isnan(maxval)) maxval = 5.1;
}
else {
- if (isnan(minval)) minval = 0.0;
- if (isnan(maxval)) maxval = 1.0;
+ if (isnan(minval)) minval = 0.0;
+ if (isnan(maxval)) maxval = 1.0;
}
/* adjust min and max values */
if (isnan(im->minval)
- /* don't adjust low-end with log scale */ /* why not? */
- || ((!im->rigid) && im->minval > minval)
- ) {
- if (im->logarithmic)
- im->minval = minval * 0.5;
- else
- im->minval = minval;
+ /* don't adjust low-end with log scale */ /* why not? */
+ || ((!im->rigid) && im->minval > minval)
+ ) {
+ if (im->logarithmic)
+ im->minval = minval * 0.5;
+ else
+ im->minval = minval;
}
if (isnan(im->maxval)
- || (!im->rigid && im->maxval < maxval)
- ) {
- if (im->logarithmic)
- im->maxval = maxval * 2.0;
- else
- im->maxval = maxval;
+ || (!im->rigid && im->maxval < maxval)
+ ) {
+ if (im->logarithmic)
+ im->maxval = maxval * 2.0;
+ else
+ im->maxval = maxval;
}
/* make sure min is smaller than max */
if (im->minval > im->maxval) {
/* make sure min and max are not equal */
if (im->minval == im->maxval) {
- im->maxval *= 1.01;
- if (! im->logarithmic) {
- im->minval *= 0.99;
- }
- /* make sure min and max are not both zero */
- if (im->maxval == 0.0) {
- im->maxval = 1.0;
- }
+ im->maxval *= 1.01;
+ if (! im->logarithmic) {
+ im->minval *= 0.99;
+ }
+ /* make sure min and max are not both zero */
+ if (im->maxval == 0.0) {
+ im->maxval = 1.0;
+ }
}
return 0;
}
localtime_r(&start, &tm);
switch(baseint){
case TMT_SECOND:
- tm.tm_sec -= tm.tm_sec % basestep; break;
+ tm.tm_sec -= tm.tm_sec % basestep; break;
case TMT_MINUTE:
- tm.tm_sec=0;
- tm.tm_min -= tm.tm_min % basestep;
- break;
+ tm.tm_sec=0;
+ tm.tm_min -= tm.tm_min % basestep;
+ break;
case TMT_HOUR:
- tm.tm_sec=0;
- tm.tm_min = 0;
- tm.tm_hour -= tm.tm_hour % basestep; break;
+ tm.tm_sec=0;
+ tm.tm_min = 0;
+ tm.tm_hour -= tm.tm_hour % basestep; break;
case TMT_DAY:
- /* we do NOT look at the basestep for this ... */
- tm.tm_sec=0;
- tm.tm_min = 0;
- tm.tm_hour = 0; break;
+ /* we do NOT look at the basestep for this ... */
+ tm.tm_sec=0;
+ tm.tm_min = 0;
+ tm.tm_hour = 0; break;
case TMT_WEEK:
- /* we do NOT look at the basestep for this ... */
- tm.tm_sec=0;
- tm.tm_min = 0;
- tm.tm_hour = 0;
- tm.tm_mday -= tm.tm_wday -1; /* -1 because we want the monday */
- if (tm.tm_wday==0) tm.tm_mday -= 7; /* we want the *previous* monday */
- break;
+ /* we do NOT look at the basestep for this ... */
+ tm.tm_sec=0;
+ tm.tm_min = 0;
+ tm.tm_hour = 0;
+ tm.tm_mday -= tm.tm_wday -1; /* -1 because we want the monday */
+ if (tm.tm_wday==0) tm.tm_mday -= 7; /* we want the *previous* monday */
+ break;
case TMT_MONTH:
- tm.tm_sec=0;
- tm.tm_min = 0;
- tm.tm_hour = 0;
- tm.tm_mday = 1;
- tm.tm_mon -= tm.tm_mon % basestep; break;
+ tm.tm_sec=0;
+ tm.tm_min = 0;
+ tm.tm_hour = 0;
+ tm.tm_mday = 1;
+ tm.tm_mon -= tm.tm_mon % basestep; break;
case TMT_YEAR:
- tm.tm_sec=0;
- tm.tm_min = 0;
- tm.tm_hour = 0;
- tm.tm_mday = 1;
- tm.tm_mon = 0;
- tm.tm_year -= (tm.tm_year+1900) % basestep;
-
+ tm.tm_sec=0;
+ tm.tm_min = 0;
+ tm.tm_hour = 0;
+ tm.tm_mday = 1;
+ tm.tm_mon = 0;
+ tm.tm_year -= (tm.tm_year+1900) % basestep;
+
}
return mktime(&tm);
}
time_t madetime;
localtime_r(¤t, &tm);
do {
- switch(baseint){
- case TMT_SECOND:
- tm.tm_sec += basestep; break;
- case TMT_MINUTE:
- tm.tm_min += basestep; break;
- case TMT_HOUR:
- tm.tm_hour += basestep; break;
- case TMT_DAY:
- tm.tm_mday += basestep; break;
- case TMT_WEEK:
- tm.tm_mday += 7*basestep; break;
- case TMT_MONTH:
- tm.tm_mon += basestep; break;
- case TMT_YEAR:
- tm.tm_year += basestep;
- }
- madetime = mktime(&tm);
+ switch(baseint){
+ case TMT_SECOND:
+ tm.tm_sec += basestep; break;
+ case TMT_MINUTE:
+ tm.tm_min += basestep; break;
+ case TMT_HOUR:
+ tm.tm_hour += basestep; break;
+ case TMT_DAY:
+ tm.tm_mday += basestep; break;
+ case TMT_WEEK:
+ tm.tm_mday += 7*basestep; break;
+ case TMT_MONTH:
+ tm.tm_mon += basestep; break;
+ case TMT_YEAR:
+ tm.tm_year += basestep;
+ }
+ madetime = mktime(&tm);
} while (madetime == -1); /* this is necessary to skip impssible times
- like the daylight saving time skips */
+ like the daylight saving time skips */
return madetime;
-
+
}
struct tm tmvdef;
int graphelement = 0;
long vidx;
- int max_ii;
+ int max_ii;
double magfact = -1;
char *si_symb = "";
char *percent_s;
localtime_r(&now,&tmvdef);
if (im->imginfo) prlines++;
for(i=0;i<im->gdes_c;i++){
- switch(im->gdes[i].gf){
- case GF_PRINT:
- prlines++;
- if(((*prdata) = rrd_realloc((*prdata),prlines*sizeof(char *)))==NULL){
- rrd_set_error("realloc prdata");
- return 0;
- }
- case GF_GPRINT:
- /* PRINT and GPRINT can now print VDEF generated values.
- * There's no need to do any calculations on them as these
- * calculations were already made.
- */
- vidx = im->gdes[i].vidx;
- if (im->gdes[vidx].gf==GF_VDEF) { /* simply use vals */
- printval = im->gdes[vidx].vf.val;
- localtime_r(&im->gdes[vidx].vf.when,&tmvdef);
- } else { /* need to calculate max,min,avg etcetera */
- max_ii =((im->gdes[vidx].end
- - im->gdes[vidx].start)
- / im->gdes[vidx].step
- * im->gdes[vidx].ds_cnt);
- printval = DNAN;
- validsteps = 0;
- for( ii=im->gdes[vidx].ds;
- ii < max_ii;
- ii+=im->gdes[vidx].ds_cnt){
- if (! finite(im->gdes[vidx].data[ii]))
- continue;
- if (isnan(printval)){
- printval = im->gdes[vidx].data[ii];
- validsteps++;
- continue;
- }
-
- switch (im->gdes[i].cf){
- case CF_HWPREDICT:
- case CF_DEVPREDICT:
- case CF_DEVSEASONAL:
- case CF_SEASONAL:
- case CF_AVERAGE:
- validsteps++;
- printval += im->gdes[vidx].data[ii];
- break;
- case CF_MINIMUM:
- printval = min( printval, im->gdes[vidx].data[ii]);
- break;
- case CF_FAILURES:
- case CF_MAXIMUM:
- printval = max( printval, im->gdes[vidx].data[ii]);
- break;
- case CF_LAST:
- printval = im->gdes[vidx].data[ii];
- }
- }
- if (im->gdes[i].cf==CF_AVERAGE || im->gdes[i].cf > CF_LAST) {
- if (validsteps > 1) {
- printval = (printval / validsteps);
- }
- }
- } /* prepare printval */
-
- if ((percent_s = strstr(im->gdes[i].format,"%S")) != NULL) {
- /* Magfact is set to -1 upon entry to print_calc. If it
- * is still less than 0, then we need to run auto_scale.
- * Otherwise, put the value into the correct units. If
- * the value is 0, then do not set the symbol or magnification
- * so next the calculation will be performed again. */
- if (magfact < 0.0) {
- auto_scale(im,&printval,&si_symb,&magfact);
- if (printval == 0.0)
- magfact = -1.0;
- } else {
- printval /= magfact;
- }
- *(++percent_s) = 's';
- } else if (strstr(im->gdes[i].format,"%s") != NULL) {
- auto_scale(im,&printval,&si_symb,&magfact);
- }
+ vidx = im->gdes[i].vidx;
+ switch(im->gdes[i].gf){
+ case GF_PRINT:
+ prlines++;
+ if(((*prdata) = rrd_realloc((*prdata),prlines*sizeof(char *)))==NULL){
+ rrd_set_error("realloc prdata");
+ return 0;
+ }
+ case GF_GPRINT:
+ /* PRINT and GPRINT can now print VDEF generated values.
+ * There's no need to do any calculations on them as these
+ * calculations were already made.
+ */
+ if (im->gdes[vidx].gf==GF_VDEF) { /* simply use vals */
+ printval = im->gdes[vidx].vf.val;
+ localtime_r(&im->gdes[vidx].vf.when,&tmvdef);
+ } else { /* need to calculate max,min,avg etcetera */
+ max_ii =((im->gdes[vidx].end
+ - im->gdes[vidx].start)
+ / im->gdes[vidx].step
+ * im->gdes[vidx].ds_cnt);
+ printval = DNAN;
+ validsteps = 0;
+ for( ii=im->gdes[vidx].ds;
+ ii < max_ii;
+ ii+=im->gdes[vidx].ds_cnt){
+ if (! finite(im->gdes[vidx].data[ii]))
+ continue;
+ if (isnan(printval)){
+ printval = im->gdes[vidx].data[ii];
+ validsteps++;
+ continue;
+ }
+
+ switch (im->gdes[i].cf){
+ case CF_HWPREDICT:
+ case CF_DEVPREDICT:
+ case CF_DEVSEASONAL:
+ case CF_SEASONAL:
+ case CF_AVERAGE:
+ validsteps++;
+ printval += im->gdes[vidx].data[ii];
+ break;
+ case CF_MINIMUM:
+ printval = min( printval, im->gdes[vidx].data[ii]);
+ break;
+ case CF_FAILURES:
+ case CF_MAXIMUM:
+ printval = max( printval, im->gdes[vidx].data[ii]);
+ break;
+ case CF_LAST:
+ printval = im->gdes[vidx].data[ii];
+ }
+ }
+ if (im->gdes[i].cf==CF_AVERAGE || im->gdes[i].cf > CF_LAST) {
+ if (validsteps > 1) {
+ printval = (printval / validsteps);
+ }
+ }
+ } /* prepare printval */
+
+ if ((percent_s = strstr(im->gdes[i].format,"%S")) != NULL) {
+ /* Magfact is set to -1 upon entry to print_calc. If it
+ * is still less than 0, then we need to run auto_scale.
+ * Otherwise, put the value into the correct units. If
+ * the value is 0, then do not set the symbol or magnification
+ * so next the calculation will be performed again. */
+ if (magfact < 0.0) {
+ auto_scale(im,&printval,&si_symb,&magfact);
+ if (printval == 0.0)
+ magfact = -1.0;
+ } else {
+ printval /= magfact;
+ }
+ *(++percent_s) = 's';
+ } else if (strstr(im->gdes[i].format,"%s") != NULL) {
+ auto_scale(im,&printval,&si_symb,&magfact);
+ }
if (im->gdes[i].gf == GF_PRINT){
- (*prdata)[prlines-2] = malloc((FMT_LEG_LEN+2)*sizeof(char));
- (*prdata)[prlines-1] = NULL;
+ (*prdata)[prlines-2] = malloc((FMT_LEG_LEN+2)*sizeof(char));
+ (*prdata)[prlines-1] = NULL;
if (im->gdes[i].strftm){
- strftime((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,&tmvdef);
+ strftime((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,&tmvdef);
} else {
- if (bad_format(im->gdes[i].format)) {
- rrd_set_error("bad format for PRINT in '%s'", im->gdes[i].format);
- return -1;
- }
+ if (bad_format(im->gdes[i].format)) {
+ rrd_set_error("bad format for PRINT in '%s'", im->gdes[i].format);
+ return -1;
+ }
#ifdef HAVE_SNPRINTF
- snprintf((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,printval,si_symb);
+ snprintf((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,printval,si_symb);
#else
- sprintf((*prdata)[prlines-2],im->gdes[i].format,printval,si_symb);
+ sprintf((*prdata)[prlines-2],im->gdes[i].format,printval,si_symb);
#endif
}
} else {
- /* GF_GPRINT */
+ /* GF_GPRINT */
if (im->gdes[i].strftm){
- strftime(im->gdes[i].legend,FMT_LEG_LEN,im->gdes[i].format,&tmvdef);
+ strftime(im->gdes[i].legend,FMT_LEG_LEN,im->gdes[i].format,&tmvdef);
} else {
- if (bad_format(im->gdes[i].format)) {
- rrd_set_error("bad format for GPRINT in '%s'", im->gdes[i].format);
- return -1;
- }
+ if (bad_format(im->gdes[i].format)) {
+ rrd_set_error("bad format for GPRINT in '%s'", im->gdes[i].format);
+ return -1;
+ }
#ifdef HAVE_SNPRINTF
- snprintf(im->gdes[i].legend,FMT_LEG_LEN-2,im->gdes[i].format,printval,si_symb);
+ snprintf(im->gdes[i].legend,FMT_LEG_LEN-2,im->gdes[i].format,printval,si_symb);
#else
- sprintf(im->gdes[i].legend,im->gdes[i].format,printval,si_symb);
+ sprintf(im->gdes[i].legend,im->gdes[i].format,printval,si_symb);
#endif
}
- graphelement = 1;
- }
- break;
- case GF_LINE:
- case GF_AREA:
- case GF_TICK:
- graphelement = 1;
- break;
- case GF_HRULE:
+ graphelement = 1;
+ }
+ break;
+ case GF_LINE:
+ case GF_AREA:
+ case GF_TICK:
+ graphelement = 1;
+ break;
+ case GF_HRULE:
if(isnan(im->gdes[i].yrule)) { /* we must set this here or the legend printer can not decide to print the legend */
im->gdes[i].yrule=im->gdes[vidx].vf.val;
};
- graphelement = 1;
- break;
- case GF_VRULE:
+ graphelement = 1;
+ break;
+ case GF_VRULE:
if(im->gdes[i].xrule == 0) { /* again ... the legend printer needs it*/
im->gdes[i].xrule = im->gdes[vidx].vf.when;
};
- graphelement = 1;
- break;
+ graphelement = 1;
+ break;
case GF_COMMENT:
- case GF_DEF:
- case GF_CDEF:
- case GF_VDEF:
+ case GF_DEF:
+ case GF_CDEF:
+ case GF_VDEF:
#ifdef WITH_PIECHART
- case GF_PART:
+ case GF_PART:
#endif
- case GF_SHIFT:
- case GF_XPORT:
- break;
- case GF_STACK:
+ case GF_SHIFT:
+ case GF_XPORT:
+ break;
+ case GF_STACK:
rrd_set_error("STACK should already be turned into LINE or AREA here");
return -1;
break;
- }
+ }
}
return graphelement;
}
}
for(i=0;i<im->gdes_c;i++){
- fill_last = fill;
+ fill_last = fill;
/* hid legends for rules which are not displayed */
- if(!(im->extra_flags & FORCE_RULES_LEGEND)) {
- if (im->gdes[i].gf == GF_HRULE &&
- (im->gdes[i].yrule < im->minval || im->gdes[i].yrule > im->maxval))
- im->gdes[i].legend[0] = '\0';
-
- if (im->gdes[i].gf == GF_VRULE &&
- (im->gdes[i].xrule < im->start || im->gdes[i].xrule > im->end))
- im->gdes[i].legend[0] = '\0';
- }
-
- leg_cc = strlen(im->gdes[i].legend);
-
- /* is there a controle code ant the end of the legend string ? */
- /* and it is not a tab \\t */
- if (leg_cc >= 2 && im->gdes[i].legend[leg_cc-2] == '\\' && im->gdes[i].legend[leg_cc-1] != 't') {
- prt_fctn = im->gdes[i].legend[leg_cc-1];
- leg_cc -= 2;
- im->gdes[i].legend[leg_cc] = '\0';
- } else {
- prt_fctn = '\0';
- }
- /* only valid control codes */
+ if(!(im->extra_flags & FORCE_RULES_LEGEND)) {
+ if (im->gdes[i].gf == GF_HRULE &&
+ (im->gdes[i].yrule < im->minval || im->gdes[i].yrule > im->maxval))
+ im->gdes[i].legend[0] = '\0';
+
+ if (im->gdes[i].gf == GF_VRULE &&
+ (im->gdes[i].xrule < im->start || im->gdes[i].xrule > im->end))
+ im->gdes[i].legend[0] = '\0';
+ }
+
+ leg_cc = strlen(im->gdes[i].legend);
+
+ /* is there a controle code ant the end of the legend string ? */
+ /* and it is not a tab \\t */
+ if (leg_cc >= 2 && im->gdes[i].legend[leg_cc-2] == '\\' && im->gdes[i].legend[leg_cc-1] != 't') {
+ prt_fctn = im->gdes[i].legend[leg_cc-1];
+ leg_cc -= 2;
+ im->gdes[i].legend[leg_cc] = '\0';
+ } else {
+ prt_fctn = '\0';
+ }
+ /* only valid control codes */
if (prt_fctn != 'l' &&
- prt_fctn != 'n' && /* a synonym for l */
- prt_fctn != 'r' &&
- prt_fctn != 'j' &&
- prt_fctn != 'c' &&
- prt_fctn != 's' &&
+ prt_fctn != 'n' && /* a synonym for l */
+ prt_fctn != 'r' &&
+ prt_fctn != 'j' &&
+ prt_fctn != 'c' &&
+ prt_fctn != 's' &&
prt_fctn != 't' &&
prt_fctn != '\0' &&
prt_fctn != 'g' ) {
- free(legspace);
- rrd_set_error("Unknown control code at the end of '%s\\%c'",im->gdes[i].legend,prt_fctn);
- return -1;
+ free(legspace);
+ rrd_set_error("Unknown control code at the end of '%s\\%c'",im->gdes[i].legend,prt_fctn);
+ return -1;
- }
+ }
/* remove exess space */
if ( prt_fctn == 'n' ){
}
while (prt_fctn=='g' &&
- leg_cc > 0 &&
- im->gdes[i].legend[leg_cc-1]==' '){
- leg_cc--;
- im->gdes[i].legend[leg_cc]='\0';
- }
- if (leg_cc != 0 ){
- legspace[i]=(prt_fctn=='g' ? 0 : interleg);
-
- if (fill > 0){
- /* no interleg space if string ends in \g */
- fill += legspace[i];
- }
- fill += gfx_get_text_width(im->canvas, fill+border,
- im->text_prop[TEXT_PROP_LEGEND].font,
- im->text_prop[TEXT_PROP_LEGEND].size,
- im->tabwidth,
- im->gdes[i].legend, 0);
- leg_c++;
- } else {
- legspace[i]=0;
- }
+ leg_cc > 0 &&
+ im->gdes[i].legend[leg_cc-1]==' '){
+ leg_cc--;
+ im->gdes[i].legend[leg_cc]='\0';
+ }
+ if (leg_cc != 0 ){
+ legspace[i]=(prt_fctn=='g' ? 0 : interleg);
+
+ if (fill > 0){
+ /* no interleg space if string ends in \g */
+ fill += legspace[i];
+ }
+ fill += gfx_get_text_width(im->canvas, fill+border,
+ im->text_prop[TEXT_PROP_LEGEND].font,
+ im->text_prop[TEXT_PROP_LEGEND].size,
+ im->tabwidth,
+ im->gdes[i].legend, 0);
+ leg_c++;
+ } else {
+ legspace[i]=0;
+ }
/* who said there was a special tag ... ?*/
- if (prt_fctn=='g') {
- prt_fctn = '\0';
- }
- if (prt_fctn == '\0') {
- if (i == im->gdes_c -1 ) prt_fctn ='l';
-
- /* is it time to place the legends ? */
- if (fill > im->ximg - 2*border){
- if (leg_c > 1) {
- /* go back one */
- i--;
- fill = fill_last;
- leg_c--;
- prt_fctn = 'j';
- } else {
- prt_fctn = 'l';
- }
-
- }
- }
-
-
- if (prt_fctn != '\0'){
- leg_x = border;
- if (leg_c >= 2 && prt_fctn == 'j') {
- glue = (im->ximg - fill - 2* border) / (leg_c-1);
- } else {
- glue = 0;
- }
- if (prt_fctn =='c') leg_x = (im->ximg - fill) / 2.0;
- if (prt_fctn =='r') leg_x = im->ximg - fill - border;
-
- for(ii=mark;ii<=i;ii++){
- if(im->gdes[ii].legend[0]=='\0')
- continue; /* skip empty legends */
- im->gdes[ii].leg_x = leg_x;
- im->gdes[ii].leg_y = leg_y;
- leg_x +=
- gfx_get_text_width(im->canvas, leg_x,
- im->text_prop[TEXT_PROP_LEGEND].font,
- im->text_prop[TEXT_PROP_LEGEND].size,
- im->tabwidth,
- im->gdes[ii].legend, 0)
- + legspace[ii]
- + glue;
- }
+ if (prt_fctn=='g') {
+ prt_fctn = '\0';
+ }
+ if (prt_fctn == '\0') {
+ if (i == im->gdes_c -1 ) prt_fctn ='l';
+
+ /* is it time to place the legends ? */
+ if (fill > im->ximg - 2*border){
+ if (leg_c > 1) {
+ /* go back one */
+ i--;
+ fill = fill_last;
+ leg_c--;
+ prt_fctn = 'j';
+ } else {
+ prt_fctn = 'l';
+ }
+
+ }
+ }
+
+
+ if (prt_fctn != '\0'){
+ leg_x = border;
+ if (leg_c >= 2 && prt_fctn == 'j') {
+ glue = (im->ximg - fill - 2* border) / (leg_c-1);
+ } else {
+ glue = 0;
+ }
+ if (prt_fctn =='c') leg_x = (im->ximg - fill) / 2.0;
+ if (prt_fctn =='r') leg_x = im->ximg - fill - border;
+
+ for(ii=mark;ii<=i;ii++){
+ if(im->gdes[ii].legend[0]=='\0')
+ continue; /* skip empty legends */
+ im->gdes[ii].leg_x = leg_x;
+ im->gdes[ii].leg_y = leg_y;
+ leg_x +=
+ gfx_get_text_width(im->canvas, leg_x,
+ im->text_prop[TEXT_PROP_LEGEND].font,
+ im->text_prop[TEXT_PROP_LEGEND].size,
+ im->tabwidth,
+ im->gdes[ii].legend, 0)
+ + legspace[ii]
+ + glue;
+ }
leg_y_prev = leg_y;
/* only add y space if there was text on the line */
if (leg_x > border || prt_fctn == 's')
- leg_y += im->text_prop[TEXT_PROP_LEGEND].size*1.8;
- if (prt_fctn == 's')
- leg_y -= im->text_prop[TEXT_PROP_LEGEND].size;
- fill = 0;
- leg_c = 0;
- mark = ii;
- }
+ leg_y += im->text_prop[TEXT_PROP_LEGEND].size*1.8;
+ if (prt_fctn == 's')
+ leg_y -= im->text_prop[TEXT_PROP_LEGEND].size;
+ fill = 0;
+ leg_c = 0;
+ mark = ii;
+ }
}
im->yimg = leg_y_prev;
/* if we did place some legends we have to add vertical space */
if (leg_y != im->yimg){
- im->yimg += im->text_prop[TEXT_PROP_LEGEND].size*1.8;
+ im->yimg += im->text_prop[TEXT_PROP_LEGEND].size*1.8;
}
free(legspace);
}
range = im->maxval - im->minval;
scaledrange = range / im->magfact;
- /* does the scale of this graph make it impossible to put lines
- on it? If so, give up. */
- if (isnan(scaledrange)) {
- return 0;
- }
+ /* does the scale of this graph make it impossible to put lines
+ on it? If so, give up. */
+ if (isnan(scaledrange)) {
+ return 0;
+ }
/* find grid spaceing */
pixel=1;
if(isnan(im->ygridstep)){
- if(im->extra_flags & ALTYGRID) {
- /* find the value with max number of digits. Get number of digits */
- decimals = ceil(log10(max(fabs(im->maxval), fabs(im->minval))*im->viewfactor/im->magfact));
- if(decimals <= 0) /* everything is small. make place for zero */
- decimals = 1;
-
- im->ygrid_scale.gridstep = pow((double)10, floor(log10(range*im->viewfactor/im->magfact)))/im->viewfactor*im->magfact;
-
- if(im->ygrid_scale.gridstep == 0) /* range is one -> 0.1 is reasonable scale */
- im->ygrid_scale.gridstep = 0.1;
- /* should have at least 5 lines but no more then 15 */
- if(range/im->ygrid_scale.gridstep < 5)
+ if(im->extra_flags & ALTYGRID) {
+ /* find the value with max number of digits. Get number of digits */
+ decimals = ceil(log10(max(fabs(im->maxval), fabs(im->minval))*im->viewfactor/im->magfact));
+ if(decimals <= 0) /* everything is small. make place for zero */
+ decimals = 1;
+
+ im->ygrid_scale.gridstep = pow((double)10, floor(log10(range*im->viewfactor/im->magfact)))/im->viewfactor*im->magfact;
+
+ if(im->ygrid_scale.gridstep == 0) /* range is one -> 0.1 is reasonable scale */
+ im->ygrid_scale.gridstep = 0.1;
+ /* should have at least 5 lines but no more then 15 */
+ if(range/im->ygrid_scale.gridstep < 5)
im->ygrid_scale.gridstep /= 10;
- if(range/im->ygrid_scale.gridstep > 15)
+ if(range/im->ygrid_scale.gridstep > 15)
im->ygrid_scale.gridstep *= 10;
- if(range/im->ygrid_scale.gridstep > 5) {
- im->ygrid_scale.labfact = 1;
- if(range/im->ygrid_scale.gridstep > 8)
- im->ygrid_scale.labfact = 2;
- }
- else {
- im->ygrid_scale.gridstep /= 5;
- im->ygrid_scale.labfact = 5;
- }
- fractionals = floor(log10(im->ygrid_scale.gridstep*(double)im->ygrid_scale.labfact*im->viewfactor/im->magfact));
- if(fractionals < 0) { /* small amplitude. */
- int len = decimals - fractionals + 1;
- if (im->unitslength < len+2) im->unitslength = len+2;
- sprintf(im->ygrid_scale.labfmt, "%%%d.%df%s", len, -fractionals,(im->symbol != ' ' ? " %c" : ""));
- } else {
- int len = decimals + 1;
- if (im->unitslength < len+2) im->unitslength = len+2;
- sprintf(im->ygrid_scale.labfmt, "%%%d.0f%s", len, ( im->symbol != ' ' ? " %c" : "" ));
- }
- }
- else {
- for(i=0;ylab[i].grid > 0;i++){
- pixel = im->ysize / (scaledrange / ylab[i].grid);
- gridind = i;
- if (pixel > 7)
+ if(range/im->ygrid_scale.gridstep > 5) {
+ im->ygrid_scale.labfact = 1;
+ if(range/im->ygrid_scale.gridstep > 8)
+ im->ygrid_scale.labfact = 2;
+ }
+ else {
+ im->ygrid_scale.gridstep /= 5;
+ im->ygrid_scale.labfact = 5;
+ }
+ fractionals = floor(log10(im->ygrid_scale.gridstep*(double)im->ygrid_scale.labfact*im->viewfactor/im->magfact));
+ if(fractionals < 0) { /* small amplitude. */
+ int len = decimals - fractionals + 1;
+ if (im->unitslength < len+2) im->unitslength = len+2;
+ sprintf(im->ygrid_scale.labfmt, "%%%d.%df%s", len, -fractionals,(im->symbol != ' ' ? " %c" : ""));
+ } else {
+ int len = decimals + 1;
+ if (im->unitslength < len+2) im->unitslength = len+2;
+ sprintf(im->ygrid_scale.labfmt, "%%%d.0f%s", len, ( im->symbol != ' ' ? " %c" : "" ));
+ }
+ }
+ else {
+ for(i=0;ylab[i].grid > 0;i++){
+ pixel = im->ysize / (scaledrange / ylab[i].grid);
+ gridind = i;
+ if (pixel > 7)
break;
- }
-
- for(i=0; i<4;i++) {
- if (pixel * ylab[gridind].lfac[i] >= 2.5 * im->text_prop[TEXT_PROP_AXIS].size) {
- im->ygrid_scale.labfact = ylab[gridind].lfac[i];
- break;
+ }
+
+ for(i=0; i<4;i++) {
+ if (pixel * ylab[gridind].lfac[i] >= 2.5 * im->text_prop[TEXT_PROP_AXIS].size) {
+ im->ygrid_scale.labfact = ylab[gridind].lfac[i];
+ break;
}
- }
-
- im->ygrid_scale.gridstep = ylab[gridind].grid * im->magfact;
- }
+ }
+
+ im->ygrid_scale.gridstep = ylab[gridind].grid * im->magfact;
+ }
} else {
- im->ygrid_scale.gridstep = im->ygridstep;
- im->ygrid_scale.labfact = im->ylabfact;
+ im->ygrid_scale.gridstep = im->ygridstep;
+ im->ygrid_scale.labfact = im->ylabfact;
}
return 1;
}
double Y0=ytr(im,im->ygrid_scale.gridstep*i);
double YN=ytr(im,im->ygrid_scale.gridstep*(i+1));
if ( Y0 >= im->yorigin-im->ysize
- && Y0 <= im->yorigin){
- /* Make sure at least 2 grid labels are shown, even if it doesn't agree
- with the chosen settings. Add a label if required by settings, or if
- there is only one label so far and the next grid line is out of bounds. */
- if(i % im->ygrid_scale.labfact == 0 || ( nlabels==1 && (YN < im->yorigin-im->ysize || YN > im->yorigin) )){
- if (im->symbol == ' ') {
- if(im->extra_flags & ALTYGRID) {
- sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*(double)i);
+ && Y0 <= im->yorigin){
+ /* Make sure at least 2 grid labels are shown, even if it doesn't agree
+ with the chosen settings. Add a label if required by settings, or if
+ there is only one label so far and the next grid line is out of bounds. */
+ if(i % im->ygrid_scale.labfact == 0 || ( nlabels==1 && (YN < im->yorigin-im->ysize || YN > im->yorigin) )){
+ if (im->symbol == ' ') {
+ if(im->extra_flags & ALTYGRID) {
+ sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*(double)i);
} else {
if(MaxY < 10) {
- sprintf(graph_label,"%4.1f",scaledstep*(double)i);
- } else {
- sprintf(graph_label,"%4.0f",scaledstep*(double)i);
- }
+ sprintf(graph_label,"%4.1f",scaledstep*(double)i);
+ } else {
+ sprintf(graph_label,"%4.0f",scaledstep*(double)i);
+ }
}
- }else {
- char sisym = ( i == 0 ? ' ' : im->symbol);
- if(im->extra_flags & ALTYGRID) {
- sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*(double)i,sisym);
+ }else {
+ char sisym = ( i == 0 ? ' ' : im->symbol);
+ if(im->extra_flags & ALTYGRID) {
+ sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*(double)i,sisym);
} else {
- if(MaxY < 10){
- sprintf(graph_label,"%4.1f %c",scaledstep*(double)i, sisym);
- } else {
- sprintf(graph_label,"%4.0f %c",scaledstep*(double)i, sisym);
- }
+ if(MaxY < 10){
+ sprintf(graph_label,"%4.1f %c",scaledstep*(double)i, sisym);
+ } else {
+ sprintf(graph_label,"%4.0f %c",scaledstep*(double)i, sisym);
+ }
}
- }
- nlabels++;
-
- gfx_new_text ( im->canvas,
- X0-im->text_prop[TEXT_PROP_AXIS].size, Y0,
- im->graph_col[GRC_FONT],
- im->text_prop[TEXT_PROP_AXIS].font,
- im->text_prop[TEXT_PROP_AXIS].size,
- im->tabwidth, 0.0, GFX_H_RIGHT, GFX_V_CENTER,
- graph_label );
- gfx_new_dashed_line ( im->canvas,
- X0-2,Y0,
- X1+2,Y0,
- MGRIDWIDTH, im->graph_col[GRC_MGRID],
- im->grid_dash_on, im->grid_dash_off);
-
- } else if (!(im->extra_flags & NOMINOR)) {
- gfx_new_dashed_line ( im->canvas,
- X0-1,Y0,
- X1+1,Y0,
- GRIDWIDTH, im->graph_col[GRC_GRID],
- im->grid_dash_on, im->grid_dash_off);
-
- }
- }
+ }
+ nlabels++;
+
+ gfx_new_text ( im->canvas,
+ X0-im->text_prop[TEXT_PROP_AXIS].size, Y0,
+ im->graph_col[GRC_FONT],
+ im->text_prop[TEXT_PROP_AXIS].font,
+ im->text_prop[TEXT_PROP_AXIS].size,
+ im->tabwidth, 0.0, GFX_H_RIGHT, GFX_V_CENTER,
+ graph_label );
+ gfx_new_dashed_line ( im->canvas,
+ X0-2,Y0,
+ X1+2,Y0,
+ MGRIDWIDTH, im->graph_col[GRC_MGRID],
+ im->grid_dash_on, im->grid_dash_off);
+
+ } else if (!(im->extra_flags & NOMINOR)) {
+ gfx_new_dashed_line ( im->canvas,
+ X0-1,Y0,
+ X1+1,Y0,
+ GRIDWIDTH, im->graph_col[GRC_GRID],
+ im->grid_dash_on, im->grid_dash_off);
+
+ }
+ }
}
return 1;
}
iexp = floor(log(fabs(x)) / log(10));
mnt = x / pow(10.0, iexp);
if(mnt >= 10.0) {
- iexp++;
- mnt = x / pow(10.0, iexp);
+ iexp++;
+ mnt = x / pow(10.0, iexp);
}
*e = iexp;
return mnt;
horizontal_log_grid(image_desc_t *im)
{
double yloglab[][10] = {
- {1.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 5.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 2.0, 5.0, 7.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0},
- {1.0, 2.0, 4.0, 6.0, 8.0, 10., 0.0, 0.0, 0.0, 0.0},
- {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.},
- {0,0,0,0,0, 0,0,0,0,0} /* last line */ };
+ {1.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 5.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 2.0, 5.0, 7.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0},
+ {1.0, 2.0, 4.0, 6.0, 8.0, 10., 0.0, 0.0, 0.0, 0.0},
+ {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.},
+ {0,0,0,0,0, 0,0,0,0,0} /* last line */ };
int i, j, val_exp, min_exp;
- double nex; /* number of decades in data */
- double logscale; /* scale in logarithmic space */
- int exfrac = 1; /* decade spacing */
- int mid = -1; /* row in yloglab for major grid */
- double mspac; /* smallest major grid spacing (pixels) */
- int flab; /* first value in yloglab to use */
+ double nex; /* number of decades in data */
+ double logscale; /* scale in logarithmic space */
+ int exfrac = 1; /* decade spacing */
+ int mid = -1; /* row in yloglab for major grid */
+ double mspac; /* smallest major grid spacing (pixels) */
+ int flab; /* first value in yloglab to use */
double value, tmp, pre_value;
double X0,X1,Y0;
char graph_label[100];
/* major spacing for data with high dynamic range */
while(logscale * exfrac < 3 * im->text_prop[TEXT_PROP_LEGEND].size) {
- if(exfrac == 1) exfrac = 3;
- else exfrac += 3;
+ if(exfrac == 1) exfrac = 3;
+ else exfrac += 3;
}
/* major spacing for less dynamic data */
do {
- /* search best row in yloglab */
- mid++;
- for(i = 0; yloglab[mid][i + 1] < 10.0; i++);
- mspac = logscale * log10(10.0 / yloglab[mid][i]);
+ /* search best row in yloglab */
+ mid++;
+ for(i = 0; yloglab[mid][i + 1] < 10.0; i++);
+ mspac = logscale * log10(10.0 / yloglab[mid][i]);
} while(mspac > 2 * im->text_prop[TEXT_PROP_LEGEND].size && yloglab[mid][0] > 0);
if(mid) mid--;
/* find first value in yloglab */
for(flab = 0; yloglab[mid][flab] < 10 && frexp10(im->minval, &tmp) > yloglab[mid][flab] ; flab++);
if(yloglab[mid][flab] == 10.0) {
- tmp += 1.0;
- flab = 0;
+ tmp += 1.0;
+ flab = 0;
}
val_exp = tmp;
if(val_exp % exfrac) val_exp += abs(-val_exp % exfrac);
pre_value = DNAN;
while(1) {
- value = yloglab[mid][flab] * pow(10.0, val_exp);
+ value = yloglab[mid][flab] * pow(10.0, val_exp);
if ( AlmostEqual2sComplement(value,pre_value,4) ) break; /* it seems we are not converging */
pre_value = value;
- Y0 = ytr(im, value);
- if(Y0 <= im->yorigin - im->ysize) break;
-
- /* major grid line */
- gfx_new_dashed_line ( im->canvas,
- X0-2,Y0,
- X1+2,Y0,
- MGRIDWIDTH, im->graph_col[GRC_MGRID],
- im->grid_dash_on, im->grid_dash_off);
-
- /* label */
- if (im->extra_flags & FORCE_UNITS_SI) {
- int scale;
- double pvalue;
- char symbol;
-
- scale = floor(val_exp / 3.0);
- if( value >= 1.0 ) pvalue = pow(10.0, val_exp % 3);
- else pvalue = pow(10.0, ((val_exp + 1) % 3) + 2);
- pvalue *= yloglab[mid][flab];
-
- if ( ((scale+si_symbcenter) < (int)sizeof(si_symbol)) &&
- ((scale+si_symbcenter) >= 0) )
- symbol = si_symbol[scale+si_symbcenter];
- else
- symbol = '?';
-
- sprintf(graph_label,"%3.0f %c", pvalue, symbol);
+ Y0 = ytr(im, value);
+ if(Y0 <= im->yorigin - im->ysize) break;
+
+ /* major grid line */
+ gfx_new_dashed_line ( im->canvas,
+ X0-2,Y0,
+ X1+2,Y0,
+ MGRIDWIDTH, im->graph_col[GRC_MGRID],
+ im->grid_dash_on, im->grid_dash_off);
+
+ /* label */
+ if (im->extra_flags & FORCE_UNITS_SI) {
+ int scale;
+ double pvalue;
+ char symbol;
+
+ scale = floor(val_exp / 3.0);
+ if( value >= 1.0 ) pvalue = pow(10.0, val_exp % 3);
+ else pvalue = pow(10.0, ((val_exp + 1) % 3) + 2);
+ pvalue *= yloglab[mid][flab];
+
+ if ( ((scale+si_symbcenter) < (int)sizeof(si_symbol)) &&
+ ((scale+si_symbcenter) >= 0) )
+ symbol = si_symbol[scale+si_symbcenter];
+ else
+ symbol = '?';
+
+ sprintf(graph_label,"%3.0f %c", pvalue, symbol);
} else
- sprintf(graph_label,"%3.0e", value);
- gfx_new_text ( im->canvas,
- X0-im->text_prop[TEXT_PROP_AXIS].size, Y0,
- im->graph_col[GRC_FONT],
- im->text_prop[TEXT_PROP_AXIS].font,
- im->text_prop[TEXT_PROP_AXIS].size,
- im->tabwidth,0.0, GFX_H_RIGHT, GFX_V_CENTER,
- graph_label );
-
- /* minor grid */
- if(mid < 4 && exfrac == 1) {
- /* find first and last minor line behind current major line
- * i is the first line and j tha last */
- if(flab == 0) {
- min_exp = val_exp - 1;
- for(i = 1; yloglab[mid][i] < 10.0; i++);
- i = yloglab[mid][i - 1] + 1;
- j = 10;
- }
- else {
- min_exp = val_exp;
- i = yloglab[mid][flab - 1] + 1;
- j = yloglab[mid][flab];
- }
-
- /* draw minor lines below current major line */
- for(; i < j; i++) {
-
- value = i * pow(10.0, min_exp);
- if(value < im->minval) continue;
-
- Y0 = ytr(im, value);
- if(Y0 <= im->yorigin - im->ysize) break;
-
- /* draw lines */
- gfx_new_dashed_line ( im->canvas,
- X0-1,Y0,
- X1+1,Y0,
- GRIDWIDTH, im->graph_col[GRC_GRID],
- im->grid_dash_on, im->grid_dash_off);
- }
- }
- else if(exfrac > 1) {
- for(i = val_exp - exfrac / 3 * 2; i < val_exp; i += exfrac / 3) {
- value = pow(10.0, i);
- if(value < im->minval) continue;
-
- Y0 = ytr(im, value);
- if(Y0 <= im->yorigin - im->ysize) break;
-
- /* draw lines */
- gfx_new_dashed_line ( im->canvas,
- X0-1,Y0,
- X1+1,Y0,
- GRIDWIDTH, im->graph_col[GRC_GRID],
- im->grid_dash_on, im->grid_dash_off);
- }
- }
-
- /* next decade */
- if(yloglab[mid][++flab] == 10.0) {
- flab = 0;
- val_exp += exfrac;
- }
+ sprintf(graph_label,"%3.0e", value);
+ gfx_new_text ( im->canvas,
+ X0-im->text_prop[TEXT_PROP_AXIS].size, Y0,
+ im->graph_col[GRC_FONT],
+ im->text_prop[TEXT_PROP_AXIS].font,
+ im->text_prop[TEXT_PROP_AXIS].size,
+ im->tabwidth,0.0, GFX_H_RIGHT, GFX_V_CENTER,
+ graph_label );
+
+ /* minor grid */
+ if(mid < 4 && exfrac == 1) {
+ /* find first and last minor line behind current major line
+ * i is the first line and j tha last */
+ if(flab == 0) {
+ min_exp = val_exp - 1;
+ for(i = 1; yloglab[mid][i] < 10.0; i++);
+ i = yloglab[mid][i - 1] + 1;
+ j = 10;
+ }
+ else {
+ min_exp = val_exp;
+ i = yloglab[mid][flab - 1] + 1;
+ j = yloglab[mid][flab];
+ }
+
+ /* draw minor lines below current major line */
+ for(; i < j; i++) {
+
+ value = i * pow(10.0, min_exp);
+ if(value < im->minval) continue;
+
+ Y0 = ytr(im, value);
+ if(Y0 <= im->yorigin - im->ysize) break;
+
+ /* draw lines */
+ gfx_new_dashed_line ( im->canvas,
+ X0-1,Y0,
+ X1+1,Y0,
+ GRIDWIDTH, im->graph_col[GRC_GRID],
+ im->grid_dash_on, im->grid_dash_off);
+ }
+ }
+ else if(exfrac > 1) {
+ for(i = val_exp - exfrac / 3 * 2; i < val_exp; i += exfrac / 3) {
+ value = pow(10.0, i);
+ if(value < im->minval) continue;
+
+ Y0 = ytr(im, value);
+ if(Y0 <= im->yorigin - im->ysize) break;
+
+ /* draw lines */
+ gfx_new_dashed_line ( im->canvas,
+ X0-1,Y0,
+ X1+1,Y0,
+ GRIDWIDTH, im->graph_col[GRC_GRID],
+ im->grid_dash_on, im->grid_dash_off);
+ }
+ }
+
+ /* next decade */
+ if(yloglab[mid][++flab] == 10.0) {
+ flab = 0;
+ val_exp += exfrac;
+ }
}
/* draw minor lines after highest major line */
if(mid < 4 && exfrac == 1) {
- /* find first and last minor line below current major line
- * i is the first line and j tha last */
- if(flab == 0) {
- min_exp = val_exp - 1;
- for(i = 1; yloglab[mid][i] < 10.0; i++);
- i = yloglab[mid][i - 1] + 1;
- j = 10;
- }
- else {
- min_exp = val_exp;
- i = yloglab[mid][flab - 1] + 1;
- j = yloglab[mid][flab];
- }
-
- /* draw minor lines below current major line */
- for(; i < j; i++) {
-
- value = i * pow(10.0, min_exp);
- if(value < im->minval) continue;
-
- Y0 = ytr(im, value);
- if(Y0 <= im->yorigin - im->ysize) break;
-
- /* draw lines */
- gfx_new_dashed_line ( im->canvas,
- X0-1,Y0,
- X1+1,Y0,
- GRIDWIDTH, im->graph_col[GRC_GRID],
- im->grid_dash_on, im->grid_dash_off);
- }
+ /* find first and last minor line below current major line
+ * i is the first line and j tha last */
+ if(flab == 0) {
+ min_exp = val_exp - 1;
+ for(i = 1; yloglab[mid][i] < 10.0; i++);
+ i = yloglab[mid][i - 1] + 1;
+ j = 10;
+ }
+ else {
+ min_exp = val_exp;
+ i = yloglab[mid][flab - 1] + 1;
+ j = yloglab[mid][flab];
+ }
+
+ /* draw minor lines below current major line */
+ for(; i < j; i++) {
+
+ value = i * pow(10.0, min_exp);
+ if(value < im->minval) continue;
+
+ Y0 = ytr(im, value);
+ if(Y0 <= im->yorigin - im->ysize) break;
+
+ /* draw lines */
+ gfx_new_dashed_line ( im->canvas,
+ X0-1,Y0,
+ X1+1,Y0,
+ GRIDWIDTH, im->graph_col[GRC_GRID],
+ im->grid_dash_on, im->grid_dash_off);
+ }
}
/* fancy minor gridlines */
else if(exfrac > 1) {
- for(i = val_exp - exfrac / 3 * 2; i < val_exp; i += exfrac / 3) {
- value = pow(10.0, i);
- if(value < im->minval) continue;
-
- Y0 = ytr(im, value);
- if(Y0 <= im->yorigin - im->ysize) break;
-
- /* draw lines */
- gfx_new_dashed_line ( im->canvas,
- X0-1,Y0,
- X1+1,Y0,
- GRIDWIDTH, im->graph_col[GRC_GRID],
- im->grid_dash_on, im->grid_dash_off);
- }
+ for(i = val_exp - exfrac / 3 * 2; i < val_exp; i += exfrac / 3) {
+ value = pow(10.0, i);
+ if(value < im->minval) continue;
+
+ Y0 = ytr(im, value);
+ if(Y0 <= im->yorigin - im->ysize) break;
+
+ /* draw lines */
+ gfx_new_dashed_line ( im->canvas,
+ X0-1,Y0,
+ X1+1,Y0,
+ GRIDWIDTH, im->graph_col[GRC_GRID],
+ im->grid_dash_on, im->grid_dash_off);
+ }
}
return 1;
vertical_grid(
image_desc_t *im )
{
- int xlab_sel; /* which sort of label and grid ? */
+ int xlab_sel; /* which sort of label and grid ? */
time_t ti, tilab, timajor;
long factor;
char graph_label[100];
if(im->xlab_user.minsec == -1){
- factor=(im->end - im->start)/im->xsize;
- xlab_sel=0;
- while ( xlab[xlab_sel+1].minsec != -1
- && xlab[xlab_sel+1].minsec <= factor) { xlab_sel++; } /* pick the last one */
- while ( xlab[xlab_sel-1].minsec == xlab[xlab_sel].minsec
- && xlab[xlab_sel].length > (im->end - im->start)) { xlab_sel--; } /* go back to the smallest size */
- im->xlab_user.gridtm = xlab[xlab_sel].gridtm;
- im->xlab_user.gridst = xlab[xlab_sel].gridst;
- im->xlab_user.mgridtm = xlab[xlab_sel].mgridtm;
- im->xlab_user.mgridst = xlab[xlab_sel].mgridst;
- im->xlab_user.labtm = xlab[xlab_sel].labtm;
- im->xlab_user.labst = xlab[xlab_sel].labst;
- im->xlab_user.precis = xlab[xlab_sel].precis;
- im->xlab_user.stst = xlab[xlab_sel].stst;
+ factor=(im->end - im->start)/im->xsize;
+ xlab_sel=0;
+ while ( xlab[xlab_sel+1].minsec != -1
+ && xlab[xlab_sel+1].minsec <= factor) { xlab_sel++; } /* pick the last one */
+ while ( xlab[xlab_sel-1].minsec == xlab[xlab_sel].minsec
+ && xlab[xlab_sel].length > (im->end - im->start)) { xlab_sel--; } /* go back to the smallest size */
+ im->xlab_user.gridtm = xlab[xlab_sel].gridtm;
+ im->xlab_user.gridst = xlab[xlab_sel].gridst;
+ im->xlab_user.mgridtm = xlab[xlab_sel].mgridtm;
+ im->xlab_user.mgridst = xlab[xlab_sel].mgridst;
+ im->xlab_user.labtm = xlab[xlab_sel].labtm;
+ im->xlab_user.labst = xlab[xlab_sel].labst;
+ im->xlab_user.precis = xlab[xlab_sel].precis;
+ im->xlab_user.stst = xlab[xlab_sel].stst;
}
/* y coords are the same for every line ... */
/* paint the major grid */
for(ti = find_first_time(im->start,
- im->xlab_user.mgridtm,
- im->xlab_user.mgridst);
- ti < im->end;
- ti = find_next_time(ti,im->xlab_user.mgridtm,im->xlab_user.mgridst)
- ){
- /* are we inside the graph ? */
- if (ti < im->start || ti > im->end) continue;
+ im->xlab_user.mgridtm,
+ im->xlab_user.mgridst);
+ ti < im->end;
+ ti = find_next_time(ti,im->xlab_user.mgridtm,im->xlab_user.mgridst)
+ ){
+ /* are we inside the graph ? */
+ if (ti < im->start || ti > im->end) continue;
X0 = xtr(im,ti);
gfx_new_dashed_line(im->canvas,X0,Y0+3, X0,Y1-2,MGRIDWIDTH,
- im->graph_col[GRC_MGRID],
- im->grid_dash_on, im->grid_dash_off);
+ im->graph_col[GRC_MGRID],
+ im->grid_dash_on, im->grid_dash_off);
}
/* paint the labels below the graph */
for(ti = find_first_time(im->start - im->xlab_user.precis/2,
- im->xlab_user.labtm,
- im->xlab_user.labst);
- ti <= im->end - im->xlab_user.precis/2;
- ti = find_next_time(ti,im->xlab_user.labtm,im->xlab_user.labst)
- ){
+ im->xlab_user.labtm,
+ im->xlab_user.labst);
+ ti <= im->end - im->xlab_user.precis/2;
+ ti = find_next_time(ti,im->xlab_user.labtm,im->xlab_user.labst)
+ ){
tilab= ti + im->xlab_user.precis/2; /* correct time for the label */
- /* are we inside the graph ? */
- if (tilab < im->start || tilab > im->end) continue;
+ /* are we inside the graph ? */
+ if (tilab < im->start || tilab > im->end) continue;
#if HAVE_STRFTIME
- localtime_r(&tilab, &tm);
- strftime(graph_label,99,im->xlab_user.stst, &tm);
+ localtime_r(&tilab, &tm);
+ strftime(graph_label,99,im->xlab_user.stst, &tm);
#else
# error "your libc has no strftime I guess we'll abort the exercise here."
#endif
gfx_new_text ( im->canvas,
- xtr(im,tilab), Y0+im->text_prop[TEXT_PROP_AXIS].size*1.4+5,
- im->graph_col[GRC_FONT],
- im->text_prop[TEXT_PROP_AXIS].font,
- im->text_prop[TEXT_PROP_AXIS].size,
- im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_BOTTOM,
- graph_label );
+ xtr(im,tilab), Y0+im->text_prop[TEXT_PROP_AXIS].size*1.4+5,
+ im->graph_col[GRC_FONT],
+ im->text_prop[TEXT_PROP_AXIS].font,
+ im->text_prop[TEXT_PROP_AXIS].size,
+ im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_BOTTOM,
+ graph_label );
}
void
axis_paint(
image_desc_t *im
- )
+ )
{
/* draw x and y axis */
/* gfx_new_line ( im->canvas, im->xorigin+im->xsize,im->yorigin,
- im->xorigin+im->xsize,im->yorigin-im->ysize,
- GRIDWIDTH, im->graph_col[GRC_AXIS]);
+ im->xorigin+im->xsize,im->yorigin-im->ysize,
+ GRIDWIDTH, im->graph_col[GRC_AXIS]);
gfx_new_line ( im->canvas, im->xorigin,im->yorigin-im->ysize,
- im->xorigin+im->xsize,im->yorigin-im->ysize,
- GRIDWIDTH, im->graph_col[GRC_AXIS]); */
+ im->xorigin+im->xsize,im->yorigin-im->ysize,
+ GRIDWIDTH, im->graph_col[GRC_AXIS]); */
gfx_new_line ( im->canvas, im->xorigin-4,im->yorigin,
- im->xorigin+im->xsize+4,im->yorigin,
- MGRIDWIDTH, im->graph_col[GRC_AXIS]);
+ im->xorigin+im->xsize+4,im->yorigin,
+ MGRIDWIDTH, im->graph_col[GRC_AXIS]);
gfx_new_line ( im->canvas, im->xorigin,im->yorigin+4,
- im->xorigin,im->yorigin-im->ysize-4,
- MGRIDWIDTH, im->graph_col[GRC_AXIS]);
+ im->xorigin,im->yorigin-im->ysize-4,
+ MGRIDWIDTH, im->graph_col[GRC_AXIS]);
/* arrow for X and Y axis direction */
gfx_new_area ( im->canvas,
- im->xorigin+im->xsize+2, im->yorigin-2,
- im->xorigin+im->xsize+2, im->yorigin+3,
- im->xorigin+im->xsize+7, im->yorigin+0.5, /* LINEOFFSET */
- im->graph_col[GRC_ARROW]);
+ im->xorigin+im->xsize+2, im->yorigin-2,
+ im->xorigin+im->xsize+2, im->yorigin+3,
+ im->xorigin+im->xsize+7, im->yorigin+0.5, /* LINEOFFSET */
+ im->graph_col[GRC_ARROW]);
gfx_new_area ( im->canvas,
- im->xorigin-2, im->yorigin-im->ysize-2,
- im->xorigin+3, im->yorigin-im->ysize-2,
- im->xorigin+0.5, im->yorigin-im->ysize-7, /* LINEOFFSET */
- im->graph_col[GRC_ARROW]);
+ im->xorigin-2, im->yorigin-im->ysize-2,
+ im->xorigin+3, im->yorigin-im->ysize-2,
+ im->xorigin+0.5, im->yorigin-im->ysize-7, /* LINEOFFSET */
+ im->graph_col[GRC_ARROW]);
}
vertical_grid(im);
if (im->draw_y_grid == 1){
- if(im->logarithmic){
- res = horizontal_log_grid(im);
- } else {
- res = draw_horizontal_grid(im);
- }
-
- /* dont draw horizontal grid if there is no min and max val */
- if (! res ) {
- char *nodata = "No Data found";
- gfx_new_text(im->canvas,im->ximg/2, (2*im->yorigin-im->ysize) / 2,
- im->graph_col[GRC_FONT],
- im->text_prop[TEXT_PROP_AXIS].font,
- im->text_prop[TEXT_PROP_AXIS].size,
- im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_CENTER,
- nodata );
- }
+ if(im->logarithmic){
+ res = horizontal_log_grid(im);
+ } else {
+ res = draw_horizontal_grid(im);
+ }
+
+ /* dont draw horizontal grid if there is no min and max val */
+ if (! res ) {
+ char *nodata = "No Data found";
+ gfx_new_text(im->canvas,im->ximg/2, (2*im->yorigin-im->ysize) / 2,
+ im->graph_col[GRC_FONT],
+ im->text_prop[TEXT_PROP_AXIS].font,
+ im->text_prop[TEXT_PROP_AXIS].size,
+ im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_CENTER,
+ nodata );
+ }
}
/* yaxis unit description */
/* graph title */
gfx_new_text( im->canvas,
- im->ximg/2, im->text_prop[TEXT_PROP_TITLE].size*1.3+4,
- im->graph_col[GRC_FONT],
- im->text_prop[TEXT_PROP_TITLE].font,
- im->text_prop[TEXT_PROP_TITLE].size, im->tabwidth, 0.0,
- GFX_H_CENTER, GFX_V_CENTER,
- im->title);
+ im->ximg/2, im->text_prop[TEXT_PROP_TITLE].size*1.3+4,
+ im->graph_col[GRC_FONT],
+ im->text_prop[TEXT_PROP_TITLE].font,
+ im->text_prop[TEXT_PROP_TITLE].size, im->tabwidth, 0.0,
+ GFX_H_CENTER, GFX_V_CENTER,
+ im->title);
/* rrdtool 'logo' */
gfx_new_text( im->canvas,
- im->ximg-7, 7,
- ( im->graph_col[GRC_FONT] & 0xffffff00 ) | 0x00000044,
- im->text_prop[TEXT_PROP_AXIS].font,
- 5.5, im->tabwidth, 270,
- GFX_H_RIGHT, GFX_V_TOP,
- "RRDTOOL / TOBI OETIKER");
+ im->ximg-7, 7,
+ ( im->graph_col[GRC_FONT] & 0xffffff00 ) | 0x00000044,
+ im->text_prop[TEXT_PROP_AXIS].font,
+ 5.5, im->tabwidth, 270,
+ GFX_H_RIGHT, GFX_V_TOP,
+ "RRDTOOL / TOBI OETIKER");
/* graph watermark */
if(im->watermark[0] != '\0') {
gfx_new_text( im->canvas,
im->ximg/2, im->yimg-6,
- ( im->graph_col[GRC_FONT] & 0xffffff00 ) | 0x00000044,
- im->text_prop[TEXT_PROP_AXIS].font,
- 5.5, im->tabwidth, 0,
- GFX_H_CENTER, GFX_V_BOTTOM,
- im->watermark);
+ ( im->graph_col[GRC_FONT] & 0xffffff00 ) | 0x00000044,
+ im->text_prop[TEXT_PROP_AXIS].font,
+ 5.5, im->tabwidth, 0,
+ GFX_H_CENTER, GFX_V_BOTTOM,
+ im->watermark);
}
/* graph labels */
X0 = im->gdes[i].leg_x;
Y0 = im->gdes[i].leg_y;
gfx_new_text ( im->canvas, X0, Y0,
- im->graph_col[GRC_FONT],
- im->text_prop[TEXT_PROP_LEGEND].font,
- im->text_prop[TEXT_PROP_LEGEND].size,
- im->tabwidth,0.0, GFX_H_LEFT, GFX_V_BOTTOM,
- im->gdes[i].legend );
- /* The legend for GRAPH items starts with "M " to have
+ im->graph_col[GRC_FONT],
+ im->text_prop[TEXT_PROP_LEGEND].font,
+ im->text_prop[TEXT_PROP_LEGEND].size,
+ im->tabwidth,0.0, GFX_H_LEFT, GFX_V_BOTTOM,
+ im->gdes[i].legend );
+ /* The legend for GRAPH items starts with "M " to have
enough space for the box */
- if ( im->gdes[i].gf != GF_PRINT &&
- im->gdes[i].gf != GF_GPRINT &&
+ if ( im->gdes[i].gf != GF_PRINT &&
+ im->gdes[i].gf != GF_GPRINT &&
im->gdes[i].gf != GF_COMMENT) {
int boxH, boxV;
boxV = boxH*1.1;
/* make sure transparent colors show up the same way as in the graph */
- node = gfx_new_area(im->canvas,
+ node = gfx_new_area(im->canvas,
X0,Y0-boxV,
X0,Y0,
X0+boxH,Y0,
int lazy_check(image_desc_t *im){
FILE *fd = NULL;
- int size = 1;
+ int size = 1;
struct stat imgstat;
if (im->lazy == 0) return 0; /* no lazy option */
/* one pixel in the existing graph is more then what we would
change here ... */
if (time(NULL) - imgstat.st_mtime >
- (im->end - im->start) / im->xsize)
+ (im->end - im->start) / im->xsize)
return 0;
if ((fd = fopen(im->graphfile,"rb")) == NULL)
return 0; /* the file does not exist */
switch (im->canvas->imgformat) {
case IF_PNG:
- size = PngSize(fd,&(im->ximg),&(im->yimg));
- break;
+ size = PngSize(fd,&(im->ximg),&(im->yimg));
+ break;
default:
- size = 1;
+ size = 1;
}
fclose(fd);
return size;
#ifdef WITH_PIECHART
void
pie_part(image_desc_t *im, gfx_color_t color,
- double PieCenterX, double PieCenterY, double Radius,
- double startangle, double endangle)
+ double PieCenterX, double PieCenterY, double Radius,
+ double startangle, double endangle)
{
gfx_node_t *node;
double angle;
double step=M_PI/50; /* Number of iterations for the circle;
- ** 10 is definitely too low, more than
- ** 50 seems to be overkill
- */
+ ** 10 is definitely too low, more than
+ ** 50 seems to be overkill
+ */
/* Strange but true: we have to work clockwise or else
** anti aliasing nor transparency don't work.
/* Hidden feature: Radius decreases each full circle */
angle=startangle;
while (angle>=2*M_PI) {
- angle -= 2*M_PI;
- Radius *= 0.8;
+ angle -= 2*M_PI;
+ Radius *= 0.8;
}
node=gfx_new_area(im->canvas,
- PieCenterX+sin(startangle)*Radius,
- PieCenterY-cos(startangle)*Radius,
- PieCenterX,
- PieCenterY,
- PieCenterX+sin(endangle)*Radius,
- PieCenterY-cos(endangle)*Radius,
- color);
+ PieCenterX+sin(startangle)*Radius,
+ PieCenterY-cos(startangle)*Radius,
+ PieCenterX,
+ PieCenterY,
+ PieCenterX+sin(endangle)*Radius,
+ PieCenterY-cos(endangle)*Radius,
+ color);
for (angle=endangle;angle-startangle>=step;angle-=step) {
- gfx_add_point(node,
- PieCenterX+sin(angle)*Radius,
- PieCenterY-cos(angle)*Radius );
+ gfx_add_point(node,
+ PieCenterX+sin(angle)*Radius,
+ PieCenterY-cos(angle)*Radius );
}
}
** | watermark |
** +---------------------------------------------+
*/
- int Xvertical=0,
- Ytitle =0,
- Xylabel =0,
- Xmain =0, Ymain =0,
+ int Xvertical=0,
+ Ytitle =0,
+ Xylabel =0,
+ Xmain =0, Ymain =0,
#ifdef WITH_PIECHART
- Xpie =0, Ypie =0,
+ Xpie =0, Ypie =0,
#endif
- Yxlabel =0,
+ Yxlabel =0,
#if 0
- Xlegend =0, Ylegend =0,
+ Xlegend =0, Ylegend =0,
#endif
Xspacing =15, Yspacing =15,
Ywatermark =4;
if (im->extra_flags & ONLY_GRAPH) {
- im->xorigin =0;
- im->ximg = im->xsize;
+ im->xorigin =0;
+ im->ximg = im->xsize;
im->yimg = im->ysize;
im->yorigin = im->ysize;
ytr(im,DNAN);
- return 0;
+ return 0;
}
if (im->ylegend[0] != '\0' ) {
if (im->title[0] != '\0') {
- /* The title is placed "inbetween" two text lines so it
- ** automatically has some vertical spacing. The horizontal
- ** spacing is added here, on each side.
- */
- /* don't care for the with of the title
- Xtitle = gfx_get_text_width(im->canvas, 0,
- im->text_prop[TEXT_PROP_TITLE].font,
- im->text_prop[TEXT_PROP_TITLE].size,
- im->tabwidth,
- im->title, 0) + 2*Xspacing; */
- Ytitle = im->text_prop[TEXT_PROP_TITLE].size*2.6+10;
+ /* The title is placed "inbetween" two text lines so it
+ ** automatically has some vertical spacing. The horizontal
+ ** spacing is added here, on each side.
+ */
+ /* don't care for the with of the title
+ Xtitle = gfx_get_text_width(im->canvas, 0,
+ im->text_prop[TEXT_PROP_TITLE].font,
+ im->text_prop[TEXT_PROP_TITLE].size,
+ im->tabwidth,
+ im->title, 0) + 2*Xspacing; */
+ Ytitle = im->text_prop[TEXT_PROP_TITLE].size*2.6+10;
}
if (elements) {
- Xmain=im->xsize;
- Ymain=im->ysize;
- if (im->draw_x_grid) {
- Yxlabel=im->text_prop[TEXT_PROP_AXIS].size *2.5;
- }
- if (im->draw_y_grid || im->forceleftspace ) {
- Xylabel=gfx_get_text_width(im->canvas, 0,
- im->text_prop[TEXT_PROP_AXIS].font,
- im->text_prop[TEXT_PROP_AXIS].size,
- im->tabwidth,
- "0", 0) * im->unitslength;
- }
+ Xmain=im->xsize;
+ Ymain=im->ysize;
+ if (im->draw_x_grid) {
+ Yxlabel=im->text_prop[TEXT_PROP_AXIS].size *2.5;
+ }
+ if (im->draw_y_grid || im->forceleftspace ) {
+ Xylabel=gfx_get_text_width(im->canvas, 0,
+ im->text_prop[TEXT_PROP_AXIS].font,
+ im->text_prop[TEXT_PROP_AXIS].size,
+ im->tabwidth,
+ "0", 0) * im->unitslength;
+ }
}
#ifdef WITH_PIECHART
if (piechart) {
- im->piesize=im->xsize<im->ysize?im->xsize:im->ysize;
- Xpie=im->piesize;
- Ypie=im->piesize;
+ im->piesize=im->xsize<im->ysize?im->xsize:im->ysize;
+ Xpie=im->piesize;
+ Ypie=im->piesize;
}
#endif
if (Xtitle > im->ximg) im->ximg = Xtitle; */
if (Xvertical) { /* unit description */
- im->ximg += Xvertical;
- im->xorigin += Xvertical;
+ im->ximg += Xvertical;
+ im->xorigin += Xvertical;
}
xtr(im,0);
/* reserve space for the title *or* some padding above the graph */
if (Ytitle) {
- im->yimg += Ytitle;
- im->yorigin += Ytitle;
+ im->yimg += Ytitle;
+ im->yorigin += Ytitle;
} else {
- im->yimg += 1.5*Yspacing;
- im->yorigin += 1.5*Yspacing;
+ im->yimg += 1.5*Yspacing;
+ im->yorigin += 1.5*Yspacing;
}
/* reserve space for padding below the graph */
im->yimg += Yspacing;
** Adjust im->yimg to match the space requirements.
*/
if(leg_place(im)==-1)
- return -1;
-
+ return -1;
+
if (im->watermark[0] != '\0') {
im->yimg += Ywatermark;
}
#if 0
if (Xlegend > im->ximg) {
- im->ximg = Xlegend;
- /* reposition Pie */
+ im->ximg = Xlegend;
+ /* reposition Pie */
}
#endif
** padding.
*/
if (elements) {
- im->pie_x = im->ximg - Xspacing - Xpie/2;
+ im->pie_x = im->ximg - Xspacing - Xpie/2;
im->pie_y = im->yorigin-Ymain+Ypie/2;
} else {
- im->pie_x = im->ximg/2;
+ im->pie_x = im->ximg/2;
im->pie_y = im->yorigin-Ypie/2;
}
#endif
node=gfx_new_area ( im->canvas,
0, 0,
0, im->yimg,
- im->ximg, im->yimg,
+ im->ximg, im->yimg,
im->graph_col[GRC_BACK]);
gfx_add_point(node,im->ximg, 0);
if (!isnan(im->gdes[i].p_data[ii]) &&
im->gdes[i].p_data[ii] != 0.0)
{
- if (im -> gdes[i].yrule > 0 ) {
- gfx_new_line(im->canvas,
+ if (im -> gdes[i].yrule > 0 ) {
+ gfx_new_line(im->canvas,
im -> xorigin + ii, im->yorigin,
- im -> xorigin + ii, im->yorigin - im -> gdes[i].yrule * im -> ysize,
- 1.0,
- im -> gdes[i].col );
+ im -> xorigin + ii, im->yorigin - im -> gdes[i].yrule * im -> ysize,
+ 1.0,
+ im -> gdes[i].col );
} else if ( im -> gdes[i].yrule < 0 ) {
- gfx_new_line(im->canvas,
+ gfx_new_line(im->canvas,
im -> xorigin + ii, im->yorigin - im -> ysize,
- im -> xorigin + ii, im->yorigin - ( 1 - im -> gdes[i].yrule ) * im -> ysize,
- 1.0,
- im -> gdes[i].col );
-
+ im -> xorigin + ii, im->yorigin - ( 1 - im -> gdes[i].yrule ) * im -> ysize,
+ 1.0,
+ im -> gdes[i].col );
+
}
}
}
/* *******************************************************
a ___. (a,t)
- | | ___
+ | | ___
____| | | |
| |___|
-------|--t-1--t--------------------------------
double last_y=0.0;
node = NULL;
for(ii=1;ii<im->xsize;ii++){
- if (isnan(im->gdes[i].p_data[ii]) || (im->slopemode==1 && isnan(im->gdes[i].p_data[ii-1]))){
- node = NULL;
- continue;
- }
+ if (isnan(im->gdes[i].p_data[ii]) || (im->slopemode==1 && isnan(im->gdes[i].p_data[ii-1]))){
+ node = NULL;
+ continue;
+ }
if ( node == NULL ) {
- last_y = ytr(im,im->gdes[i].p_data[ii]);
- if ( im->slopemode == 0 ){
+ last_y = ytr(im,im->gdes[i].p_data[ii]);
+ if ( im->slopemode == 0 ){
node = gfx_new_line(im->canvas,
ii-1+im->xorigin,last_y,
ii+im->xorigin,last_y,
im->gdes[i].linewidth,
im->gdes[i].col);
- } else {
+ } else {
node = gfx_new_line(im->canvas,
ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii-1]),
ii+im->xorigin,last_y,
im->gdes[i].linewidth,
im->gdes[i].col);
- }
+ }
} else {
double new_y = ytr(im,im->gdes[i].p_data[ii]);
- if ( im->slopemode==0 && ! AlmostEqual2sComplement(new_y,last_y,4)){
+ if ( im->slopemode==0 && ! AlmostEqual2sComplement(new_y,last_y,4)){
gfx_add_point(node,ii-1+im->xorigin,new_y);
- };
+ };
last_y = new_y;
gfx_add_point(node,ii+im->xorigin,new_y);
};
}
} else {
- int idxI=-1;
- double *foreY=malloc(sizeof(double)*im->xsize*2);
- double *foreX=malloc(sizeof(double)*im->xsize*2);
- double *backY=malloc(sizeof(double)*im->xsize*2);
- double *backX=malloc(sizeof(double)*im->xsize*2);
- int drawem = 0;
+ int idxI=-1;
+ double *foreY=malloc(sizeof(double)*im->xsize*2);
+ double *foreX=malloc(sizeof(double)*im->xsize*2);
+ double *backY=malloc(sizeof(double)*im->xsize*2);
+ double *backX=malloc(sizeof(double)*im->xsize*2);
+ int drawem = 0;
for(ii=0;ii<=im->xsize;ii++){
- double ybase,ytop;
- if ( idxI > 0 && ( drawem != 0 || ii==im->xsize)){
+ double ybase,ytop;
+ if ( idxI > 0 && ( drawem != 0 || ii==im->xsize)){
int cntI=1;
int lastI=0;
while (cntI < idxI && AlmostEqual2sComplement(foreY[lastI],foreY[cntI],4) && AlmostEqual2sComplement(foreY[lastI],foreY[cntI+1],4)){cntI++;}
}
if (ii == im->xsize) break;
- /* keep things simple for now, just draw these bars
- do not try to build a big and complex area */
-
-
- if ( im->slopemode == 0 && ii==0){
- continue;
- }
- if ( isnan(im->gdes[i].p_data[ii]) ) {
- drawem = 1;
- continue;
- }
+ /* keep things simple for now, just draw these bars
+ do not try to build a big and complex area */
+
+
+ if ( im->slopemode == 0 && ii==0){
+ continue;
+ }
+ if ( isnan(im->gdes[i].p_data[ii]) ) {
+ drawem = 1;
+ continue;
+ }
ytop = ytr(im,im->gdes[i].p_data[ii]);
- if ( lastgdes && im->gdes[i].stack ) {
+ if ( lastgdes && im->gdes[i].stack ) {
ybase = ytr(im,lastgdes->p_data[ii]);
} else {
ybase = ytr(im,areazero);
}
if ( ybase == ytop ){
- drawem = 1;
- continue;
- }
- /* every area has to be wound clock-wise,
- so we have to make sur base remains base */
- if (ybase > ytop){
- double extra = ytop;
- ytop = ybase;
- ybase = extra;
- }
+ drawem = 1;
+ continue;
+ }
+ /* every area has to be wound clock-wise,
+ so we have to make sur base remains base */
+ if (ybase > ytop){
+ double extra = ytop;
+ ytop = ybase;
+ ybase = extra;
+ }
if ( im->slopemode == 0 ){
backY[++idxI] = ybase-0.2;
backX[idxI] = ii+im->xorigin-1;
#ifdef WITH_PIECHART
case GF_PART:
if(isnan(im->gdes[i].yrule)) /* fetch variable */
- im->gdes[i].yrule = im->gdes[im->gdes[i].vidx].vf.val;
+ im->gdes[i].yrule = im->gdes[im->gdes[i].vidx].vf.val;
- if (finite(im->gdes[i].yrule)) { /* even the fetched var can be NaN */
- pie_part(im,im->gdes[i].col,
- im->pie_x,im->pie_y,im->piesize*0.4,
- M_PI*2.0*PieStart/100.0,
- M_PI*2.0*(PieStart+im->gdes[i].yrule)/100.0);
- PieStart += im->gdes[i].yrule;
+ if (finite(im->gdes[i].yrule)) { /* even the fetched var can be NaN */
+ pie_part(im,im->gdes[i].col,
+ im->pie_x,im->pie_y,im->piesize*0.4,
+ M_PI*2.0*PieStart/100.0,
+ M_PI*2.0*(PieStart+im->gdes[i].yrule)/100.0);
+ PieStart += im->gdes[i].yrule;
}
break;
#endif
rrd_set_error("STACK should already be turned into LINE or AREA here");
return -1;
break;
-
+
} /* switch */
}
#ifdef WITH_PIECHART
im->gdes_c++;
if ((im->gdes = (graph_desc_t *) rrd_realloc(im->gdes, (im->gdes_c)
- * sizeof(graph_desc_t)))==NULL){
- rrd_set_error("realloc graph_descs");
- return -1;
+ * sizeof(graph_desc_t)))==NULL){
+ rrd_set_error("realloc graph_descs");
+ return -1;
}
{
int inp,outp=0;
for (inp=0;
- inp < len &&
- input[inp] != ':' &&
- input[inp] != '\0';
- inp++){
+ inp < len &&
+ input[inp] != ':' &&
+ input[inp] != '\0';
+ inp++){
if (input[inp] == '\\' &&
- input[inp+1] != '\0' &&
- (input[inp+1] == '\\' ||
- input[inp+1] == ':')){
- output[outp++] = input[++inp];
+ input[inp+1] != '\0' &&
+ (input[inp+1] == '\\' ||
+ input[inp+1] == ':')){
+ output[outp++] = input[++inp];
}
else {
- output[outp++] = input[inp];
+ output[outp++] = input[inp];
}
}
output[outp] = '\0';
@@ -3025,30 +3025,30 @@ rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize, FILE *s
rrd_graph_options(argc,argv,&im);
if (rrd_test_error()) {
- im_free(&im);
- return -1;
+ im_free(&im);
+ return -1;
}
if (strlen(argv[optind])>=MAXPATH) {
- rrd_set_error("filename (including path) too long");
- im_free(&im);
- return -1;
+ rrd_set_error("filename (including path) too long");
+ im_free(&im);
+ return -1;
}
strncpy(im.graphfile,argv[optind],MAXPATH-1);
im.graphfile[MAXPATH-1]='\0';
rrd_graph_script(argc,argv,&im,1);
if (rrd_test_error()) {
- im_free(&im);
- return -1;
+ im_free(&im);
+ return -1;
}
/* Everything is now read and the actual work can start */
(*prdata)=NULL;
if (graph_paint(&im,prdata)==-1){
- im_free(&im);
- return -1;
+ im_free(&im);
+ return -1;
}
/* The image is generated and needs to be output.
@@ -3060,26 +3060,26 @@ rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize, FILE *s
*ymin=im.minval;
*ymax=im.maxval;
if (im.imginfo) {
- char *filename;
- if (!(*prdata)) {
- /* maybe prdata is not allocated yet ... lets do it now */
- if ((*prdata = calloc(2,sizeof(char *)))==NULL) {
- rrd_set_error("malloc imginfo");
- return -1;
- };
- }
- if(((*prdata)[0] = malloc((strlen(im.imginfo)+200+strlen(im.graphfile))*sizeof(char)))
- ==NULL){
- rrd_set_error("malloc imginfo");
- return -1;
- }
- filename=im.graphfile+strlen(im.graphfile);
- while(filename > im.graphfile) {
- if (*(filename-1)=='/' || *(filename-1)=='\\' ) break;
- filename--;
- }
-
- sprintf((*prdata)[0],im.imginfo,filename,(long)(im.canvas->zoom*im.ximg),(long)(im.canvas->zoom*im.yimg));
+ char *filename;
+ if (!(*prdata)) {
+ /* maybe prdata is not allocated yet ... lets do it now */
+ if ((*prdata = calloc(2,sizeof(char *)))==NULL) {
+ rrd_set_error("malloc imginfo");
+ return -1;
+ };
+ }
+ if(((*prdata)[0] = malloc((strlen(im.imginfo)+200+strlen(im.graphfile))*sizeof(char)))
+ ==NULL){
+ rrd_set_error("malloc imginfo");
+ return -1;
+ }
+ filename=im.graphfile+strlen(im.graphfile);
+ while(filename > im.graphfile) {
+ if (*(filename-1)=='/' || *(filename-1)=='\\' ) break;
+ filename--;
+ }
+
+ sprintf((*prdata)[0],im.imginfo,filename,(long)(im.canvas->zoom*im.ximg),(long)(im.canvas->zoom*im.yimg));
}
im_free(&im);
return 0;
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
{
char *windir;
- char rrd_win_default_font[1000];
+ char rrd_win_default_font[1000];
windir = getenv("windir");
/* %windir% is something like D:\windows or C:\winnt */
if (windir != NULL) {
strncpy(rrd_win_default_font,windir,500);
rrd_win_default_font[500] = '\0';
strcat(rrd_win_default_font,"\\fonts\\");
- strcat(rrd_win_default_font,RRD_DEFAULT_FONT);
+ strcat(rrd_win_default_font,RRD_DEFAULT_FONT);
for(i=0;i<DIM(text_prop);i++){
strncpy(text_prop[i].font,rrd_win_default_font,sizeof(text_prop[i].font)-1);
text_prop[i].font[sizeof(text_prop[i].font)-1] = '\0';
deffont = getenv("RRD_DEFAULT_FONT");
if (deffont != NULL) {
for(i=0;i<DIM(text_prop);i++){
- strncpy(text_prop[i].font,deffont,sizeof(text_prop[i].font)-1);
- text_prop[i].font[sizeof(text_prop[i].font)-1] = '\0';
- }
+ strncpy(text_prop[i].font,deffont,sizeof(text_prop[i].font)-1);
+ text_prop[i].font[sizeof(text_prop[i].font)-1] = '\0';
+ }
}
}
for(i=0;i<DIM(text_prop);i++){
void
rrd_graph_options(int argc, char *argv[],image_desc_t *im)
{
- int stroff;
- char *parsetime_error = NULL;
- char scan_gtm[12],scan_mtm[12],scan_ltm[12],col_nam[12];
- time_t start_tmp=0,end_tmp=0;
- long long_tmp;
- struct rrd_time_value start_tv, end_tv;
+ int stroff;
+ char *parsetime_error = NULL;
+ char scan_gtm[12],scan_mtm[12],scan_ltm[12],col_nam[12];
+ time_t start_tmp=0,end_tmp=0;
+ long long_tmp;
+ struct rrd_time_value start_tv, end_tv;
gfx_color_t color;
optind = 0; opterr = 0; /* initialize getopt */
#define LONGOPT_UNITS_SI 255
while (1){
- static struct option long_options[] =
- {
- {"start", required_argument, 0, 's'},
- {"end", required_argument, 0, 'e'},
- {"x-grid", required_argument, 0, 'x'},
- {"y-grid", required_argument, 0, 'y'},
- {"vertical-label",required_argument,0,'v'},
- {"width", required_argument, 0, 'w'},
- {"height", required_argument, 0, 'h'},
- {"interlaced", no_argument, 0, 'i'},
- {"upper-limit",required_argument, 0, 'u'},
- {"lower-limit",required_argument, 0, 'l'},
- {"rigid", no_argument, 0, 'r'},
- {"base", required_argument, 0, 'b'},
- {"logarithmic",no_argument, 0, 'o'},
- {"color", required_argument, 0, 'c'},
+ static struct option long_options[] =
+ {
+ {"start", required_argument, 0, 's'},
+ {"end", required_argument, 0, 'e'},
+ {"x-grid", required_argument, 0, 'x'},
+ {"y-grid", required_argument, 0, 'y'},
+ {"vertical-label",required_argument,0,'v'},
+ {"width", required_argument, 0, 'w'},
+ {"height", required_argument, 0, 'h'},
+ {"interlaced", no_argument, 0, 'i'},
+ {"upper-limit",required_argument, 0, 'u'},
+ {"lower-limit",required_argument, 0, 'l'},
+ {"rigid", no_argument, 0, 'r'},
+ {"base", required_argument, 0, 'b'},
+ {"logarithmic",no_argument, 0, 'o'},
+ {"color", required_argument, 0, 'c'},
{"font", required_argument, 0, 'n'},
- {"title", required_argument, 0, 't'},
- {"imginfo", required_argument, 0, 'f'},
- {"imgformat", required_argument, 0, 'a'},
- {"lazy", no_argument, 0, 'z'},
+ {"title", required_argument, 0, 't'},
+ {"imginfo", required_argument, 0, 'f'},
+ {"imgformat", required_argument, 0, 'a'},
+ {"lazy", no_argument, 0, 'z'},
{"zoom", required_argument, 0, 'm'},
- {"no-legend", no_argument, 0, 'g'},
- {"force-rules-legend",no_argument,0, 'F'},
+ {"no-legend", no_argument, 0, 'g'},
+ {"force-rules-legend",no_argument,0, 'F'},
{"only-graph", no_argument, 0, 'j'},
- {"alt-y-grid", no_argument, 0, 'Y'},
+ {"alt-y-grid", no_argument, 0, 'Y'},
{"no-minor", no_argument, 0, 'I'},
- {"slope-mode", no_argument, 0, 'E'},
- {"alt-autoscale", no_argument, 0, 'A'},
- {"alt-autoscale-max", no_argument, 0, 'M'},
+ {"slope-mode", no_argument, 0, 'E'},
+ {"alt-autoscale", no_argument, 0, 'A'},
+ {"alt-autoscale-max", no_argument, 0, 'M'},
{"no-gridfit", no_argument, 0, 'N'},
- {"units-exponent",required_argument, 0, 'X'},
- {"units-length",required_argument, 0, 'L'},
+ {"units-exponent",required_argument, 0, 'X'},
+ {"units-length",required_argument, 0, 'L'},
{"units", required_argument, 0, LONGOPT_UNITS_SI },
- {"step", required_argument, 0, 'S'},
+ {"step", required_argument, 0, 'S'},
{"tabwidth", required_argument, 0, 'T'},
- {"font-render-mode", required_argument, 0, 'R'},
- {"font-smoothing-threshold", required_argument, 0, 'B'},
- {"watermark", required_argument, 0, 'W'},
- {"alt-y-mrtg", no_argument, 0, 1000}, /* this has no effect it is just here to save old apps from crashing when they use it */
- {0,0,0,0}};
- int option_index = 0;
- int opt;
+ {"font-render-mode", required_argument, 0, 'R'},
+ {"font-smoothing-threshold", required_argument, 0, 'B'},
+ {"watermark", required_argument, 0, 'W'},
+ {"alt-y-mrtg", no_argument, 0, 1000}, /* this has no effect it is just here to save old apps from crashing when they use it */
+ {0,0,0,0}};
+ int option_index = 0;
+ int opt;
int col_start,col_end;
- opt = getopt_long(argc, argv,
- "s:e:x:y:v:w:h:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:",
- long_options, &option_index);
+ opt = getopt_long(argc, argv,
+ "s:e:x:y:v:w:h:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:",
+ long_options, &option_index);
- if (opt == EOF)
- break;
-
- switch(opt) {
+ if (opt == EOF)
+ break;
+
+ switch(opt) {
case 'I':
im->extra_flags |= NOMINOR;
break;
- case 'Y':
- im->extra_flags |= ALTYGRID;
- break;
- case 'A':
- im->extra_flags |= ALTAUTOSCALE;
- break;
- case 'M':
- im->extra_flags |= ALTAUTOSCALE_MAX;
- break;
+ case 'Y':
+ im->extra_flags |= ALTYGRID;
+ break;
+ case 'A':
+ im->extra_flags |= ALTAUTOSCALE;
+ break;
+ case 'M':
+ im->extra_flags |= ALTAUTOSCALE_MAX;
+ break;
case 'j':
im->extra_flags |= ONLY_GRAPH;
break;
- case 'g':
- im->extra_flags |= NOLEGEND;
- break;
- case 'F':
- im->extra_flags |= FORCE_RULES_LEGEND;
- break;
- case LONGOPT_UNITS_SI:
- if(im->extra_flags & FORCE_UNITS) {
- rrd_set_error("--units can only be used once!");
- return;
- }
- if(strcmp(optarg,"si")==0)
- im->extra_flags |= FORCE_UNITS_SI;
- else {
- rrd_set_error("invalid argument for --units: %s", optarg );
- return;
- }
- break;
- case 'X':
- im->unitsexponent = atoi(optarg);
- break;
- case 'L':
- im->unitslength = atoi(optarg);
+ case 'g':
+ im->extra_flags |= NOLEGEND;
+ break;
+ case 'F':
+ im->extra_flags |= FORCE_RULES_LEGEND;
+ break;
+ case LONGOPT_UNITS_SI:
+ if(im->extra_flags & FORCE_UNITS) {
+ rrd_set_error("--units can only be used once!");
+ return;
+ }
+ if(strcmp(optarg,"si")==0)
+ im->extra_flags |= FORCE_UNITS_SI;
+ else {
+ rrd_set_error("invalid argument for --units: %s", optarg );
+ return;
+ }
+ break;
+ case 'X':
+ im->unitsexponent = atoi(optarg);
+ break;
+ case 'L':
+ im->unitslength = atoi(optarg);
im->forceleftspace = 1;
- break;
- case 'T':
- im->tabwidth = atof(optarg);
- break;
- case 'S':
- im->step = atoi(optarg);
- break;
- case 'N':
- im->gridfit = 0;
- break;
- case 's':
- if ((parsetime_error = parsetime(optarg, &start_tv))) {
- rrd_set_error( "start time: %s", parsetime_error );
- return;
- }
- break;
- case 'e':
- if ((parsetime_error = parsetime(optarg, &end_tv))) {
- rrd_set_error( "end time: %s", parsetime_error );
- return;
- }
- break;
- case 'x':
- if(strcmp(optarg,"none") == 0){
- im->draw_x_grid=0;
- break;
- };
-
- if(sscanf(optarg,
- "%10[A-Z]:%ld:%10[A-Z]:%ld:%10[A-Z]:%ld:%ld:%n",
- scan_gtm,
- &im->xlab_user.gridst,
- scan_mtm,
- &im->xlab_user.mgridst,
- scan_ltm,
- &im->xlab_user.labst,
- &im->xlab_user.precis,
- &stroff) == 7 && stroff != 0){
+ break;
+ case 'T':
+ im->tabwidth = atof(optarg);
+ break;
+ case 'S':
+ im->step = atoi(optarg);
+ break;
+ case 'N':
+ im->gridfit = 0;
+ break;
+ case 's':
+ if ((parsetime_error = parsetime(optarg, &start_tv))) {
+ rrd_set_error( "start time: %s", parsetime_error );
+ return;
+ }
+ break;
+ case 'e':
+ if ((parsetime_error = parsetime(optarg, &end_tv))) {
+ rrd_set_error( "end time: %s", parsetime_error );
+ return;
+ }
+ break;
+ case 'x':
+ if(strcmp(optarg,"none") == 0){
+ im->draw_x_grid=0;
+ break;
+ };
+
+ if(sscanf(optarg,
+ "%10[A-Z]:%ld:%10[A-Z]:%ld:%10[A-Z]:%ld:%ld:%n",
+ scan_gtm,
+ &im->xlab_user.gridst,
+ scan_mtm,
+ &im->xlab_user.mgridst,
+ scan_ltm,
+ &im->xlab_user.labst,
+ &im->xlab_user.precis,
+ &stroff) == 7 && stroff != 0){
strncpy(im->xlab_form, optarg+stroff, sizeof(im->xlab_form) - 1);
- im->xlab_form[sizeof(im->xlab_form)-1] = '\0';
- if((int)(im->xlab_user.gridtm = tmt_conv(scan_gtm)) == -1){
- rrd_set_error("unknown keyword %s",scan_gtm);
- return;
- } else if ((int)(im->xlab_user.mgridtm = tmt_conv(scan_mtm)) == -1){
- rrd_set_error("unknown keyword %s",scan_mtm);
- return;
- } else if ((int)(im->xlab_user.labtm = tmt_conv(scan_ltm)) == -1){
- rrd_set_error("unknown keyword %s",scan_ltm);
- return;
- }
- im->xlab_user.minsec = 1;
- im->xlab_user.stst = im->xlab_form;
- } else {
- rrd_set_error("invalid x-grid format");
- return;
- }
- break;
- case 'y':
-
- if(strcmp(optarg,"none") == 0){
- im->draw_y_grid=0;
- break;
- };
-
- if(sscanf(optarg,
- "%lf:%d",
- &im->ygridstep,
- &im->ylabfact) == 2) {
- if(im->ygridstep<=0){
- rrd_set_error("grid step must be > 0");
- return;
- } else if (im->ylabfact < 1){
- rrd_set_error("label factor must be > 0");
- return;
- }
- } else {
- rrd_set_error("invalid y-grid format");
- return;
- }
- break;
- case 'v':
- strncpy(im->ylegend,optarg,150);
- im->ylegend[150]='\0';
- break;
- case 'u':
- im->maxval = atof(optarg);
- break;
- case 'l':
- im->minval = atof(optarg);
- break;
- case 'b':
- im->base = atol(optarg);
- if(im->base != 1024 && im->base != 1000 ){
- rrd_set_error("the only sensible value for base apart from 1000 is 1024");
- return;
- }
- break;
- case 'w':
- long_tmp = atol(optarg);
- if (long_tmp < 10) {
- rrd_set_error("width below 10 pixels");
- return;
- }
- im->xsize = long_tmp;
- break;
- case 'h':
- long_tmp = atol(optarg);
- if (long_tmp < 10) {
- rrd_set_error("height below 10 pixels");
- return;
- }
- im->ysize = long_tmp;
- break;
- case 'i':
- im->canvas->interlaced = 1;
- break;
- case 'r':
- im->rigid = 1;
- break;
- case 'f':
- im->imginfo = optarg;
- break;
- case 'a':
- if((int)(im->canvas->imgformat = if_conv(optarg)) == -1) {
- rrd_set_error("unsupported graphics format '%s'",optarg);
- return;
- }
- break;
- case 'z':
- im->lazy = 1;
- break;
- case 'E':
- im->slopemode = 1;
- break;
-
- case 'o':
- im->logarithmic = 1;
- break;
+ im->xlab_form[sizeof(im->xlab_form)-1] = '\0';
+ if((int)(im->xlab_user.gridtm = tmt_conv(scan_gtm)) == -1){
+ rrd_set_error("unknown keyword %s",scan_gtm);
+ return;
+ } else if ((int)(im->xlab_user.mgridtm = tmt_conv(scan_mtm)) == -1){
+ rrd_set_error("unknown keyword %s",scan_mtm);
+ return;
+ } else if ((int)(im->xlab_user.labtm = tmt_conv(scan_ltm)) == -1){
+ rrd_set_error("unknown keyword %s",scan_ltm);
+ return;
+ }
+ im->xlab_user.minsec = 1;
+ im->xlab_user.stst = im->xlab_form;
+ } else {
+ rrd_set_error("invalid x-grid format");
+ return;
+ }
+ break;
+ case 'y':
+
+ if(strcmp(optarg,"none") == 0){
+ im->draw_y_grid=0;
+ break;
+ };
+
+ if(sscanf(optarg,
+ "%lf:%d",
+ &im->ygridstep,
+ &im->ylabfact) == 2) {
+ if(im->ygridstep<=0){
+ rrd_set_error("grid step must be > 0");
+ return;
+ } else if (im->ylabfact < 1){
+ rrd_set_error("label factor must be > 0");
+ return;
+ }
+ } else {
+ rrd_set_error("invalid y-grid format");
+ return;
+ }
+ break;
+ case 'v':
+ strncpy(im->ylegend,optarg,150);
+ im->ylegend[150]='\0';
+ break;
+ case 'u':
+ im->maxval = atof(optarg);
+ break;
+ case 'l':
+ im->minval = atof(optarg);
+ break;
+ case 'b':
+ im->base = atol(optarg);
+ if(im->base != 1024 && im->base != 1000 ){
+ rrd_set_error("the only sensible value for base apart from 1000 is 1024");
+ return;
+ }
+ break;
+ case 'w':
+ long_tmp = atol(optarg);
+ if (long_tmp < 10) {
+ rrd_set_error("width below 10 pixels");
+ return;
+ }
+ im->xsize = long_tmp;
+ break;
+ case 'h':
+ long_tmp = atol(optarg);
+ if (long_tmp < 10) {
+ rrd_set_error("height below 10 pixels");
+ return;
+ }
+ im->ysize = long_tmp;
+ break;
+ case 'i':
+ im->canvas->interlaced = 1;
+ break;
+ case 'r':
+ im->rigid = 1;
+ break;
+ case 'f':
+ im->imginfo = optarg;
+ break;
+ case 'a':
+ if((int)(im->canvas->imgformat = if_conv(optarg)) == -1) {
+ rrd_set_error("unsupported graphics format '%s'",optarg);
+ return;
+ }
+ break;
+ case 'z':
+ im->lazy = 1;
+ break;
+ case 'E':
+ im->slopemode = 1;
+ break;
+
+ case 'o':
+ im->logarithmic = 1;
+ break;
case 'c':
if(sscanf(optarg,
"%10[A-Z]#%n%8lx%n",
col_nam,&col_start,&color,&col_end) == 2){
int ci;
- int col_len = col_end - col_start;
- switch (col_len){
- case 3:
- color = (
- ((color & 0xF00) * 0x110000) |
- ((color & 0x0F0) * 0x011000) |
- ((color & 0x00F) * 0x001100) |
- 0x000000FF
- );
- break;
- case 4:
- color = (
- ((color & 0xF000) * 0x11000) |
- ((color & 0x0F00) * 0x01100) |
- ((color & 0x00F0) * 0x00110) |
- ((color & 0x000F) * 0x00011)
- );
- break;
- case 6:
- color = (color << 8) + 0xff /* shift left by 8 */;
- break;
- case 8:
- break;
- default:
- rrd_set_error("the color format is #RRGGBB[AA]");
- return;
- }
+ int col_len = col_end - col_start;
+ switch (col_len){
+ case 3:
+ color = (
+ ((color & 0xF00) * 0x110000) |
+ ((color & 0x0F0) * 0x011000) |
+ ((color & 0x00F) * 0x001100) |
+ 0x000000FF
+ );
+ break;
+ case 4:
+ color = (
+ ((color & 0xF000) * 0x11000) |
+ ((color & 0x0F00) * 0x01100) |
+ ((color & 0x00F0) * 0x00110) |
+ ((color & 0x000F) * 0x00011)
+ );
+ break;
+ case 6:
+ color = (color << 8) + 0xff /* shift left by 8 */;
+ break;
+ case 8:
+ break;
+ default:
+ rrd_set_error("the color format is #RRGGBB[AA]");
+ return;
+ }
if((ci=grc_conv(col_nam)) != -1){
im->graph_col[ci]=color;
} else {
rrd_set_error("invalid color name '%s'",col_nam);
- return;
+ return;
}
} else {
rrd_set_error("invalid color def format");
}
break;
case 'n':{
- char prop[15];
- double size = 1;
- char font[1024] = "";
-
- if(sscanf(optarg,
- "%10[A-Z]:%lf:%1000s",
- prop,&size,font) >= 2){
- int sindex,propidx;
- if((sindex=text_prop_conv(prop)) != -1){
- for (propidx=sindex;propidx<TEXT_PROP_LAST;propidx++){
- if (size > 0){
- im->text_prop[propidx].size=size;
+ char prop[15];
+ double size = 1;
+ char font[1024] = "";
+
+ if(sscanf(optarg,
+ "%10[A-Z]:%lf:%1000s",
+ prop,&size,font) >= 2){
+ int sindex,propidx;
+ if((sindex=text_prop_conv(prop)) != -1){
+ for (propidx=sindex;propidx<TEXT_PROP_LAST;propidx++){
+ if (size > 0){
+ im->text_prop[propidx].size=size;
}
- if (strlen(font) > 0){
- strcpy(im->text_prop[propidx].font,font);
+ if (strlen(font) > 0){
+ strcpy(im->text_prop[propidx].font,font);
}
if (propidx==sindex && sindex != 0) break;
}
- } else {
- rrd_set_error("invalid fonttag '%s'",prop);
- return;
- }
- } else {
- rrd_set_error("invalid text property format");
- return;
- }
- break;
- }
+ } else {
+ rrd_set_error("invalid fonttag '%s'",prop);
+ return;
+ }
+ } else {
+ rrd_set_error("invalid text property format");
+ return;
+ }
+ break;
+ }
case 'm':
- im->canvas->zoom = atof(optarg);
- if (im->canvas->zoom <= 0.0) {
- rrd_set_error("zoom factor must be > 0");
- return;
- }
+ im->canvas->zoom = atof(optarg);
+ if (im->canvas->zoom <= 0.0) {
+ rrd_set_error("zoom factor must be > 0");
+ return;
+ }
break;
- case 't':
- strncpy(im->title,optarg,150);
- im->title[150]='\0';
- break;
-
- case 'R':
- if ( strcmp( optarg, "normal" ) == 0 )
- im->canvas->aa_type = AA_NORMAL;
- else if ( strcmp( optarg, "light" ) == 0 )
- im->canvas->aa_type = AA_LIGHT;
- else if ( strcmp( optarg, "mono" ) == 0 )
- im->canvas->aa_type = AA_NONE;
- else
- {
- rrd_set_error("unknown font-render-mode '%s'", optarg );
- return;
- }
- break;
-
- case 'B':
- im->canvas->font_aa_threshold = atof(optarg);
- break;
+ case 't':
+ strncpy(im->title,optarg,150);
+ im->title[150]='\0';
+ break;
+
+ case 'R':
+ if ( strcmp( optarg, "normal" ) == 0 )
+ im->canvas->aa_type = AA_NORMAL;
+ else if ( strcmp( optarg, "light" ) == 0 )
+ im->canvas->aa_type = AA_LIGHT;
+ else if ( strcmp( optarg, "mono" ) == 0 )
+ im->canvas->aa_type = AA_NONE;
+ else
+ {
+ rrd_set_error("unknown font-render-mode '%s'", optarg );
+ return;
+ }
+ break;
+
+ case 'B':
+ im->canvas->font_aa_threshold = atof(optarg);
+ break;
case 'W':
strncpy(im->watermark,optarg,100);
im->watermark[99]='\0';
break;
- case '?':
+ case '?':
if (optopt != 0)
rrd_set_error("unknown option '%c'", optopt);
else
rrd_set_error("unknown option '%s'",argv[optind-1]);
return;
- }
+ }
}
if (optind >= argc) {
}
if (im->logarithmic == 1 && im->minval <= 0){
- rrd_set_error("for a logarithmic yaxis you must specify a lower-limit > 0");
- return;
+ rrd_set_error("for a logarithmic yaxis you must specify a lower-limit > 0");
+ return;
}
if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
- /* error string is set in parsetime.c */
- return;
+ /* error string is set in parsetime.c */
+ return;
}
if (start_tmp < 3600*24*365*10){
- rrd_set_error("the first entry to fetch should be after 1980 (%ld)",start_tmp);
- return;
+ rrd_set_error("the first entry to fetch should be after 1980 (%ld)",start_tmp);
+ return;
}
if (end_tmp < start_tmp) {
- rrd_set_error("start (%ld) should be less than end (%ld)",
- start_tmp, end_tmp);
- return;
+ rrd_set_error("start (%ld) should be less than end (%ld)",
+ start_tmp, end_tmp);
+ return;
}
im->start = start_tmp;
color=strstr(var,"#");
if (color==NULL) {
- if (optional==0) {
- rrd_set_error("Found no color in %s",err);
- return 0;
- }
- return 0;
+ if (optional==0) {
+ rrd_set_error("Found no color in %s",err);
+ return 0;
+ }
+ return 0;
} else {
- int n=0;
- char *rest;
- gfx_color_t col;
-
- rest=strstr(color,":");
- if (rest!=NULL)
- n=rest-color;
- else
- n=strlen(color);
-
- switch (n) {
- case 7:
- sscanf(color,"#%6lx%n",&col,&n);
+ int n=0;
+ char *rest;
+ gfx_color_t col;
+
+ rest=strstr(color,":");
+ if (rest!=NULL)
+ n=rest-color;
+ else
+ n=strlen(color);
+
+ switch (n) {
+ case 7:
+ sscanf(color,"#%6lx%n",&col,&n);
col = (col << 8) + 0xff /* shift left by 8 */;
- if (n!=7) rrd_set_error("Color problem in %s",err);
- break;
- case 9:
- sscanf(color,"#%8lx%n",&col,&n);
- if (n==9) break;
- default:
- rrd_set_error("Color problem in %s",err);
- }
- if (rrd_test_error()) return 0;
- gdp->col = col;
- return n;
+ if (n!=7) rrd_set_error("Color problem in %s",err);
+ break;
+ case 9:
+ sscanf(color,"#%8lx%n",&col,&n);
+ if (n==9) break;
+ default:
+ rrd_set_error("Color problem in %s",err);
+ }
+ if (rrd_test_error()) return 0;
+ gdp->col = col;
+ return n;
}
}
if (*ptr == 's' || *ptr == 'S' || *ptr == '%') ptr++;
/* %c is allowed (but use only with vdef!) */
- else if (*ptr == 'c') {
- ptr++;
- n=1;
- }
+ else if (*ptr == 'c') {
+ ptr++;
+ n=1;
+ }
/* or else '% 6.2lf' and such are allowed */
else {
/* A VDEF currently is either "func" or "param,func"
* so the parsing is rather simple. Change if needed.
*/
- double param;
- char func[30];
- int n;
+ double param;
+ char func[30];
+ int n;
n=0;
sscanf(str,"%le,%29[A-Z]%n",¶m,func,&n);
if (n== (int)strlen(str)) { /* matched */
- ;
+ ;
} else {
- n=0;
- sscanf(str,"%29[A-Z]%n",func,&n);
- if (n== (int)strlen(str)) { /* matched */
- param=DNAN;
- } else {
- rrd_set_error("Unknown function string '%s' in VDEF '%s'"
- ,str
- ,gdes->vname
- );
- return -1;
- }
- }
- if (!strcmp("PERCENT",func)) gdes->vf.op = VDEF_PERCENT;
- else if (!strcmp("MAXIMUM",func)) gdes->vf.op = VDEF_MAXIMUM;
- else if (!strcmp("AVERAGE",func)) gdes->vf.op = VDEF_AVERAGE;
- else if (!strcmp("MINIMUM",func)) gdes->vf.op = VDEF_MINIMUM;
- else if (!strcmp("TOTAL", func)) gdes->vf.op = VDEF_TOTAL;
- else if (!strcmp("FIRST", func)) gdes->vf.op = VDEF_FIRST;
- else if (!strcmp("LAST", func)) gdes->vf.op = VDEF_LAST;
+ n=0;
+ sscanf(str,"%29[A-Z]%n",func,&n);
+ if (n== (int)strlen(str)) { /* matched */
+ param=DNAN;
+ } else {
+ rrd_set_error("Unknown function string '%s' in VDEF '%s'"
+ ,str
+ ,gdes->vname
+ );
+ return -1;
+ }
+ }
+ if (!strcmp("PERCENT",func)) gdes->vf.op = VDEF_PERCENT;
+ else if (!strcmp("MAXIMUM",func)) gdes->vf.op = VDEF_MAXIMUM;
+ else if (!strcmp("AVERAGE",func)) gdes->vf.op = VDEF_AVERAGE;
+ else if (!strcmp("MINIMUM",func)) gdes->vf.op = VDEF_MINIMUM;
+ else if (!strcmp("TOTAL", func)) gdes->vf.op = VDEF_TOTAL;
+ else if (!strcmp("FIRST", func)) gdes->vf.op = VDEF_FIRST;
+ else if (!strcmp("LAST", func)) gdes->vf.op = VDEF_LAST;
else if (!strcmp("LSLSLOPE", func)) gdes->vf.op = VDEF_LSLSLOPE;
else if (!strcmp("LSLINT", func)) gdes->vf.op = VDEF_LSLINT;
else if (!strcmp("LSLCORREL",func)) gdes->vf.op = VDEF_LSLCORREL;
else {
- rrd_set_error("Unknown function '%s' in VDEF '%s'\n"
- ,func
- ,gdes->vname
- );
- return -1;
+ rrd_set_error("Unknown function '%s' in VDEF '%s'\n"
+ ,func
+ ,gdes->vname
+ );
+ return -1;
};
switch (gdes->vf.op) {
- case VDEF_PERCENT:
- if (isnan(param)) { /* no parameter given */
- rrd_set_error("Function '%s' needs parameter in VDEF '%s'\n"
- ,func
- ,gdes->vname
- );
- return -1;
- };
- if (param>=0.0 && param<=100.0) {
- gdes->vf.param = param;
- gdes->vf.val = DNAN; /* undefined */
- gdes->vf.when = 0; /* undefined */
- } else {
- rrd_set_error("Parameter '%f' out of range in VDEF '%s'\n"
- ,param
- ,gdes->vname
- );
- return -1;
- };
- break;
- case VDEF_MAXIMUM:
- case VDEF_AVERAGE:
- case VDEF_MINIMUM:
- case VDEF_TOTAL:
- case VDEF_FIRST:
- case VDEF_LAST:
- case VDEF_LSLSLOPE:
- case VDEF_LSLINT:
- case VDEF_LSLCORREL:
- if (isnan(param)) {
- gdes->vf.param = DNAN;
- gdes->vf.val = DNAN;
- gdes->vf.when = 0;
- } else {
- rrd_set_error("Function '%s' needs no parameter in VDEF '%s'\n"
- ,func
- ,gdes->vname
- );
- return -1;
- };
- break;
+ case VDEF_PERCENT:
+ if (isnan(param)) { /* no parameter given */
+ rrd_set_error("Function '%s' needs parameter in VDEF '%s'\n"
+ ,func
+ ,gdes->vname
+ );
+ return -1;
+ };
+ if (param>=0.0 && param<=100.0) {
+ gdes->vf.param = param;
+ gdes->vf.val = DNAN; /* undefined */
+ gdes->vf.when = 0; /* undefined */
+ } else {
+ rrd_set_error("Parameter '%f' out of range in VDEF '%s'\n"
+ ,param
+ ,gdes->vname
+ );
+ return -1;
+ };
+ break;
+ case VDEF_MAXIMUM:
+ case VDEF_AVERAGE:
+ case VDEF_MINIMUM:
+ case VDEF_TOTAL:
+ case VDEF_FIRST:
+ case VDEF_LAST:
+ case VDEF_LSLSLOPE:
+ case VDEF_LSLINT:
+ case VDEF_LSLCORREL:
+ if (isnan(param)) {
+ gdes->vf.param = DNAN;
+ gdes->vf.val = DNAN;
+ gdes->vf.when = 0;
+ } else {
+ rrd_set_error("Function '%s' needs no parameter in VDEF '%s'\n"
+ ,func
+ ,gdes->vname
+ );
+ return -1;
+ };
+ break;
};
return 0;
}
image_desc_t *im;
int gdi;
{
- graph_desc_t *src,*dst;
- rrd_value_t *data;
- long step,steps;
+ graph_desc_t *src,*dst;
+ rrd_value_t *data;
+ long step,steps;
dst = &im->gdes[gdi];
src = &im->gdes[dst->vidx];
#endif
switch (dst->vf.op) {
- case VDEF_PERCENT: {
- rrd_value_t * array;
- int field;
-
-
- if ((array = malloc(steps*sizeof(double)))==NULL) {
- rrd_set_error("malloc VDEV_PERCENT");
- return -1;
- }
- for (step=0;step < steps; step++) {
- array[step]=data[step*src->ds_cnt];
- }
- qsort(array,step,sizeof(double),vdef_percent_compar);
-
- field = (steps-1)*dst->vf.param/100;
- dst->vf.val = array[field];
- dst->vf.when = 0; /* no time component */
- free(array);
+ case VDEF_PERCENT: {
+ rrd_value_t * array;
+ int field;
+
+
+ if ((array = malloc(steps*sizeof(double)))==NULL) {
+ rrd_set_error("malloc VDEV_PERCENT");
+ return -1;
+ }
+ for (step=0;step < steps; step++) {
+ array[step]=data[step*src->ds_cnt];
+ }
+ qsort(array,step,sizeof(double),vdef_percent_compar);
+
+ field = (steps-1)*dst->vf.param/100;
+ dst->vf.val = array[field];
+ dst->vf.when = 0; /* no time component */
+ free(array);
#if 0
for(step=0;step<steps;step++)
printf("DEBUG: %3li:%10.2f %c\n",step,array[step],step==field?'*':' ');
#endif
- }
- break;
- case VDEF_MAXIMUM:
- step=0;
- while (step != steps && isnan(data[step*src->ds_cnt])) step++;
- if (step == steps) {
- dst->vf.val = DNAN;
- dst->vf.when = 0;
- } else {
- dst->vf.val = data[step*src->ds_cnt];
- dst->vf.when = src->start + (step+1)*src->step;
- }
- while (step != steps) {
- if (finite(data[step*src->ds_cnt])) {
- if (data[step*src->ds_cnt] > dst->vf.val) {
- dst->vf.val = data[step*src->ds_cnt];
- dst->vf.when = src->start + (step+1)*src->step;
- }
- }
- step++;
- }
- break;
- case VDEF_TOTAL:
- case VDEF_AVERAGE: {
- int cnt=0;
- double sum=0.0;
- for (step=0;step<steps;step++) {
- if (finite(data[step*src->ds_cnt])) {
- sum += data[step*src->ds_cnt];
- cnt ++;
- };
- }
- if (cnt) {
- if (dst->vf.op == VDEF_TOTAL) {
- dst->vf.val = sum*src->step;
- dst->vf.when = 0; /* no time component */
- } else {
- dst->vf.val = sum/cnt;
- dst->vf.when = 0; /* no time component */
- };
- } else {
- dst->vf.val = DNAN;
- dst->vf.when = 0;
- }
- }
- break;
- case VDEF_MINIMUM:
- step=0;
- while (step != steps && isnan(data[step*src->ds_cnt])) step++;
- if (step == steps) {
- dst->vf.val = DNAN;
- dst->vf.when = 0;
- } else {
- dst->vf.val = data[step*src->ds_cnt];
- dst->vf.when = src->start + (step+1)*src->step;
- }
- while (step != steps) {
- if (finite(data[step*src->ds_cnt])) {
- if (data[step*src->ds_cnt] < dst->vf.val) {
- dst->vf.val = data[step*src->ds_cnt];
- dst->vf.when = src->start + (step+1)*src->step;
- }
- }
- step++;
- }
- break;
- case VDEF_FIRST:
- /* The time value returned here is one step before the
- * actual time value. This is the start of the first
- * non-NaN interval.
- */
- step=0;
- while (step != steps && isnan(data[step*src->ds_cnt])) step++;
- if (step == steps) { /* all entries were NaN */
- dst->vf.val = DNAN;
- dst->vf.when = 0;
- } else {
- dst->vf.val = data[step*src->ds_cnt];
- dst->vf.when = src->start + step*src->step;
- }
- break;
- case VDEF_LAST:
- /* The time value returned here is the
- * actual time value. This is the end of the last
- * non-NaN interval.
- */
- step=steps-1;
- while (step >= 0 && isnan(data[step*src->ds_cnt])) step--;
- if (step < 0) { /* all entries were NaN */
- dst->vf.val = DNAN;
- dst->vf.when = 0;
- } else {
- dst->vf.val = data[step*src->ds_cnt];
- dst->vf.when = src->start + (step+1)*src->step;
- }
- break;
- case VDEF_LSLSLOPE:
- case VDEF_LSLINT:
- case VDEF_LSLCORREL:{
- /* Bestfit line by linear least squares method */
-
- int cnt=0;
- double SUMx, SUMy, SUMxy, SUMxx, SUMyy, slope, y_intercept, correl ;
- SUMx = 0; SUMy = 0; SUMxy = 0; SUMxx = 0; SUMyy = 0;
-
- for (step=0;step<steps;step++) {
- if (finite(data[step*src->ds_cnt])) {
- cnt++;
- SUMx += step;
- SUMxx += step * step;
- SUMxy += step * data[step*src->ds_cnt];
- SUMy += data[step*src->ds_cnt];
- SUMyy += data[step*src->ds_cnt]*data[step*src->ds_cnt];
- };
- }
-
- slope = ( SUMx*SUMy - cnt*SUMxy ) / ( SUMx*SUMx - cnt*SUMxx );
- y_intercept = ( SUMy - slope*SUMx ) / cnt;
- correl = (SUMxy - (SUMx*SUMy)/cnt) / sqrt((SUMxx - (SUMx*SUMx)/cnt)*(SUMyy - (SUMy*SUMy)/cnt));
-
- if (cnt) {
- if (dst->vf.op == VDEF_LSLSLOPE) {
- dst->vf.val = slope;
- dst->vf.when = 0;
- } else if (dst->vf.op == VDEF_LSLINT) {
- dst->vf.val = y_intercept;
- dst->vf.when = 0;
- } else if (dst->vf.op == VDEF_LSLCORREL) {
- dst->vf.val = correl;
- dst->vf.when = 0;
- };
-
- } else {
- dst->vf.val = DNAN;
- dst->vf.when = 0;
- }
- }
- break;
+ }
+ break;
+ case VDEF_MAXIMUM:
+ step=0;
+ while (step != steps && isnan(data[step*src->ds_cnt])) step++;
+ if (step == steps) {
+ dst->vf.val = DNAN;
+ dst->vf.when = 0;
+ } else {
+ dst->vf.val = data[step*src->ds_cnt];
+ dst->vf.when = src->start + (step+1)*src->step;
+ }
+ while (step != steps) {
+ if (finite(data[step*src->ds_cnt])) {
+ if (data[step*src->ds_cnt] > dst->vf.val) {
+ dst->vf.val = data[step*src->ds_cnt];
+ dst->vf.when = src->start + (step+1)*src->step;
+ }
+ }
+ step++;
+ }
+ break;
+ case VDEF_TOTAL:
+ case VDEF_AVERAGE: {
+ int cnt=0;
+ double sum=0.0;
+ for (step=0;step<steps;step++) {
+ if (finite(data[step*src->ds_cnt])) {
+ sum += data[step*src->ds_cnt];
+ cnt ++;
+ };
+ }
+ if (cnt) {
+ if (dst->vf.op == VDEF_TOTAL) {
+ dst->vf.val = sum*src->step;
+ dst->vf.when = 0; /* no time component */
+ } else {
+ dst->vf.val = sum/cnt;
+ dst->vf.when = 0; /* no time component */
+ };
+ } else {
+ dst->vf.val = DNAN;
+ dst->vf.when = 0;
+ }
+ }
+ break;
+ case VDEF_MINIMUM:
+ step=0;
+ while (step != steps && isnan(data[step*src->ds_cnt])) step++;
+ if (step == steps) {
+ dst->vf.val = DNAN;
+ dst->vf.when = 0;
+ } else {
+ dst->vf.val = data[step*src->ds_cnt];
+ dst->vf.when = src->start + (step+1)*src->step;
+ }
+ while (step != steps) {
+ if (finite(data[step*src->ds_cnt])) {
+ if (data[step*src->ds_cnt] < dst->vf.val) {
+ dst->vf.val = data[step*src->ds_cnt];
+ dst->vf.when = src->start + (step+1)*src->step;
+ }
+ }
+ step++;
+ }
+ break;
+ case VDEF_FIRST:
+ /* The time value returned here is one step before the
+ * actual time value. This is the start of the first
+ * non-NaN interval.
+ */
+ step=0;
+ while (step != steps && isnan(data[step*src->ds_cnt])) step++;
+ if (step == steps) { /* all entries were NaN */
+ dst->vf.val = DNAN;
+ dst->vf.when = 0;
+ } else {
+ dst->vf.val = data[step*src->ds_cnt];
+ dst->vf.when = src->start + step*src->step;
+ }
+ break;
+ case VDEF_LAST:
+ /* The time value returned here is the
+ * actual time value. This is the end of the last
+ * non-NaN interval.
+ */
+ step=steps-1;
+ while (step >= 0 && isnan(data[step*src->ds_cnt])) step--;
+ if (step < 0) { /* all entries were NaN */
+ dst->vf.val = DNAN;
+ dst->vf.when = 0;
+ } else {
+ dst->vf.val = data[step*src->ds_cnt];
+ dst->vf.when = src->start + (step+1)*src->step;
+ }
+ break;
+ case VDEF_LSLSLOPE:
+ case VDEF_LSLINT:
+ case VDEF_LSLCORREL:{
+ /* Bestfit line by linear least squares method */
+
+ int cnt=0;
+ double SUMx, SUMy, SUMxy, SUMxx, SUMyy, slope, y_intercept, correl ;
+ SUMx = 0; SUMy = 0; SUMxy = 0; SUMxx = 0; SUMyy = 0;
+
+ for (step=0;step<steps;step++) {
+ if (finite(data[step*src->ds_cnt])) {
+ cnt++;
+ SUMx += step;
+ SUMxx += step * step;
+ SUMxy += step * data[step*src->ds_cnt];
+ SUMy += data[step*src->ds_cnt];
+ SUMyy += data[step*src->ds_cnt]*data[step*src->ds_cnt];
+ };
+ }
+
+ slope = ( SUMx*SUMy - cnt*SUMxy ) / ( SUMx*SUMx - cnt*SUMxx );
+ y_intercept = ( SUMy - slope*SUMx ) / cnt;
+ correl = (SUMxy - (SUMx*SUMy)/cnt) / sqrt((SUMxx - (SUMx*SUMx)/cnt)*(SUMyy - (SUMy*SUMy)/cnt));
+
+ if (cnt) {
+ if (dst->vf.op == VDEF_LSLSLOPE) {
+ dst->vf.val = slope;
+ dst->vf.when = 0;
+ } else if (dst->vf.op == VDEF_LSLINT) {
+ dst->vf.val = y_intercept;
+ dst->vf.when = 0;
+ } else if (dst->vf.op == VDEF_LSLCORREL) {
+ dst->vf.val = correl;
+ dst->vf.when = 0;
+ };
+
+ } else {
+ dst->vf.val = DNAN;
+ dst->vf.when = 0;
+ }
+ }
+ break;
}
return 0;
}