/****************************************************************************
- * RRDtool 1.2.6 Copyright by Tobi Oetiker, 1997-2005
+ * RRDtool 1.2.11 Copyright by Tobi Oetiker, 1997-2005
****************************************************************************
* rrd__graph.c produce graphs from data in rrdfiles
****************************************************************************/
#include "rrd_tool.h"
-#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
#include <io.h>
#include <fcntl.h>
#endif
0xE0505080, /* major grid */
0x000000FF, /* font */
0x802020FF, /* arrow */
- 0x202020FF /* axis */
-};
+ 0x202020FF, /* axis */
+ 0x000000FF /* frame */
+};
/* #define DEBUG */
conv_if(FONT,GRC_FONT)
conv_if(ARROW,GRC_ARROW)
conv_if(AXIS,GRC_AXIS)
+ conv_if(FRAME,GRC_FRAME)
return -1;
}
im->viewfactor = im->magfact / pow((double)im->base , viewdigits);
- pow((double)im->base , viewdigits);
-
if ( ((viewdigits+symbcenter) < sizeof(symbol)) &&
((viewdigits+symbcenter) >= 0) )
im->symbol = symbol[(int)viewdigits+symbcenter];
delt = im->maxval - im->minval;
adj = delt * 0.1;
fact = 2.0 * pow(10.0,
- floor(log10(max(fabs(im->minval), fabs(im->maxval)))) - 2);
+ floor(log10(max(fabs(im->minval), fabs(im->maxval))/im->magfact)) - 2);
if (delt < fact) {
adj = (fact - delt) * 0.55;
#ifdef DEBUG
-sensiblevalues[i] >=scaled_max)
im->maxval = -sensiblevalues[i]*(im->magfact);
}
- /* no sensiblevalues found. we switch to ALTYGRID mode */
- if (sensiblevalues[i] == 0){
- im->extra_flags |= ALTYGRID;
- }
}
} else {
/* adjust min and max to the grid definition if there is one */
double new_log10_range = factor * log10_range;
double new_ymax_log10 = log10(im->minval) + new_log10_range;
im->maxval = pow(10, new_ymax_log10);
- ytr(im, DNAN); /* reset precalc */
+ ytr(im,DNAN); /* reset precalc */
log10_range = log10(im->maxval) - log10(im->minval);
}
/* make sure first y=10^x gridline is located on
double yfrac = ypixfrac / im->ysize;
im->minval = pow(10, log10(im->minval) - yfrac * log10_range);
im->maxval = pow(10, log10(im->maxval) - yfrac * log10_range);
- ytr(im, DNAN); /* reset precalc */
+ ytr(im,DNAN); /* reset precalc */
}
} else {
/* Make sure we have an integer pixel distance between
double gridstep = im->ygrid_scale.gridstep;
double minor_y, minor_y_px, minor_y_px_frac;
im->maxval = im->minval + new_range;
- ytr(im, DNAN); /* reset precalc */
+ ytr(im,DNAN); /* reset precalc */
/* make sure first minor gridline is on integer pixel y coord */
minor_y = gridstep * floor(im->minval / gridstep);
while (minor_y < im->minval)
double range = im->maxval - im->minval;
im->minval = im->minval - yfrac * range;
im->maxval = im->maxval - yfrac * range;
- ytr(im, DNAN); /* reset precalc */
+ ytr(im,DNAN); /* reset precalc */
}
calc_horizontal_grid(im); /* recalc with changed im->maxval */
}
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))));
+ 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;
- fractionals = floor(log10(range));
- if(fractionals < 0) { /* small amplitude. */
- int len = decimals - fractionals + 1;
- if (im->unitslength < len) im->unitslength = len;
- sprintf(im->ygrid_scale.labfmt, "%%%d.%df", len, -fractionals + 1);
- } else {
- int len = decimals + 1;
- if (im->unitslength < len) im->unitslength = len;
- sprintf(im->ygrid_scale.labfmt, "%%%d.1f", len);
- }
- im->ygrid_scale.gridstep = pow((double)10, (double)fractionals);
+ 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 */
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++){
int sgrid = (int)( im->minval / im->ygrid_scale.gridstep - 1);
int egrid = (int)( im->maxval / im->ygrid_scale.gridstep + 1);
double MaxY;
- scaledstep = im->ygrid_scale.gridstep/im->magfact;
- MaxY = scaledstep*(double)im->viewfactor*(double)egrid;
+ scaledstep = im->ygrid_scale.gridstep/(double)im->magfact*(double)im->viewfactor;
+ MaxY = scaledstep*(double)egrid;
for (i = sgrid; i <= egrid; i++){
double Y0=ytr(im,im->ygrid_scale.gridstep*i);
if ( Y0 >= im->yorigin-im->ysize
&& Y0 <= im->yorigin){
if(i % im->ygrid_scale.labfact == 0){
- if (i==0 || im->symbol == ' ') {
- if(MaxY < 10) {
- if(im->extra_flags & ALTYGRID) {
- sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*im->viewfactor*i);
- }
- else {
- sprintf(graph_label,"%4.1f",scaledstep*im->viewfactor*i);
- }
- } else {
- sprintf(graph_label,"%4.0f",scaledstep*im->viewfactor*i);
- }
+ 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);
+ }
+ }
}else {
- if(MaxY < 10){
- sprintf(graph_label,"%4.1f %c",scaledstep*im->viewfactor*i, im->symbol);
- } else {
- sprintf(graph_label,"%4.0f %c",scaledstep*im->viewfactor*i, im->symbol);
- }
+ 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);
+ }
+ }
}
gfx_new_text ( im->canvas,
# 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,
+ 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_TOP,
+ im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_BOTTOM,
graph_label );
}
if ( im->gdes[i].gf != GF_PRINT &&
im->gdes[i].gf != GF_GPRINT &&
im->gdes[i].gf != GF_COMMENT) {
- int boxL, boxH, boxV;
+ int boxH, boxV;
- boxL = gfx_get_text_width(im->canvas, 0,
+ boxH = gfx_get_text_width(im->canvas, 0,
im->text_prop[TEXT_PROP_LEGEND].font,
im->text_prop[TEXT_PROP_LEGEND].size,
- im->tabwidth,"oo", 0);
- boxH = boxL / 1.9;
- boxV = boxH+1;
+ im->tabwidth,"o", 0) * 1.2;
+ boxV = boxH*1.1;
- /* make sure transparent colors show up all the same */
+ /* make sure transparent colors show up the same way as in the graph */
node = gfx_new_area(im->canvas,
- X0-1,Y0-boxV,
- X0-1,Y0+1,
- X0+boxL+0.5,Y0+1,
- im->graph_col[GRC_BACK]);
- gfx_add_point ( node, X0+boxL+0.5, Y0-boxV );
- node = gfx_new_area(im->canvas,
- X0-1,Y0-boxV,
- X0-1,Y0,
+ X0,Y0-boxV,
+ X0,Y0,
X0+boxH,Y0,
- im->graph_col[GRC_CANVAS]);
+ im->graph_col[GRC_BACK]);
gfx_add_point ( node, X0+boxH, Y0-boxV );
node = gfx_new_area(im->canvas,
- X0-1,Y0-boxV,
- X0-1,Y0,
+ X0,Y0-boxV,
+ X0,Y0,
X0+boxH,Y0,
im->gdes[i].col);
gfx_add_point ( node, X0+boxH, Y0-boxV );
node = gfx_new_line(im->canvas,
- X0-1,Y0-boxV,
- X0-1,Y0,
- 1,im->graph_col[GRC_FONT]);
+ X0,Y0-boxV,
+ X0,Y0,
+ 1.0,im->graph_col[GRC_FRAME]);
gfx_add_point(node,X0+boxH,Y0);
gfx_add_point(node,X0+boxH,Y0-boxV);
gfx_close_path(node);
im->ximg = im->xsize;
im->yimg = im->ysize;
im->yorigin = im->ysize;
+ ytr(im,DNAN);
return 0;
}
/* reserve space for main and/or pie */
im->yimg = Ymain + Yxlabel;
-
+
#ifdef WITH_PIECHART
if (im->yimg < Ypie) im->yimg = Ypie;
#endif
}
/* reserve space for padding below the graph */
im->yimg += Yspacing;
- ytr(im,DNAN);
-
+
/* Determine where to place the legends onto the image.
** Adjust im->yimg to match the space requirements.
*/
}
#endif
+ ytr(im,DNAN);
return 0;
}
node=gfx_new_area ( im->canvas,
0, 0,
- im->ximg, 0,
- im->ximg, im->yimg,
+ 0, im->yimg,
+ im->ximg, im->yimg,
im->graph_col[GRC_BACK]);
- gfx_add_point(node,0, im->yimg);
+ gfx_add_point(node,im->ximg, 0);
#ifdef WITH_PIECHART
if (piechart != 2) {
}
} else {
- double ybase0 = DNAN,ytop0=DNAN;
- for(ii=0;ii<im->xsize;ii++){
+ 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)){
+ int cntI=1;
+ int lastI=0;
+ while (cntI < idxI && foreY[lastI] == foreY[cntI] && foreY[lastI] == foreY[cntI+1]){cntI++;}
+ node = gfx_new_area(im->canvas,
+ backX[0],backY[0],
+ foreX[0],foreY[0],
+ foreX[cntI],foreY[cntI], im->gdes[i].col);
+ while (cntI < idxI) {
+ lastI = cntI;
+ cntI++;
+ while ( cntI < idxI && foreY[lastI] == foreY[cntI] && foreY[lastI] == foreY[cntI+1]){cntI++;}
+ gfx_add_point(node,foreX[cntI],foreY[cntI]);
+ }
+ gfx_add_point(node,backX[idxI],backY[idxI]);
+ while (idxI > 1){
+ lastI = idxI;
+ idxI--;
+ while ( idxI > 1 && backY[lastI] == backY[idxI] && backY[lastI] == backY[idxI-1]){idxI--;}
+ gfx_add_point(node,backX[idxI],backY[idxI]);
+ }
+ idxI=-1;
+ drawem = 0;
+ }
+ if (drawem != 0){
+ drawem = 0;
+ idxI=-1;
+ }
+ if (ii == im->xsize) break;
+
/* keep things simple for now, just draw these bars
do not try to build a big and complex area */
- double ybase,ytop;
+
+
if ( im->slopemode == 0 && ii==0){
continue;
}
if ( isnan(im->gdes[i].p_data[ii]) ) {
- ybase0 = DNAN;
+ drawem = 1;
continue;
}
ytop = ytr(im,im->gdes[i].p_data[ii]);
ybase = ytr(im,areazero);
}
if ( ybase == ytop ){
- ybase0 = DNAN;
+ drawem = 1;
continue;
}
/* every area has to be wound clock-wise,
ytop = ybase;
ybase = extra;
}
- if ( im->slopemode == 0){
- ybase0 = ybase;
- ytop0 = ytop;
- }
- if ( !isnan(ybase0) ){
- node = gfx_new_area(im->canvas,
- (double)ii-1.2+(double)im->xorigin,ybase0-0.2,
- (double)ii-1.2+(double)im->xorigin,ytop0+0.2,
- (double)ii+0.2+(double)im->xorigin,ytop+0.2,
- im->gdes[i].col
- );
- gfx_add_point(node,
- (double)ii+0.02+im->xorigin,ybase-0.2
- );
+ if ( im->slopemode == 0 ){
+ backY[++idxI] = ybase-0.2;
+ backX[idxI] = ii+im->xorigin-1;
+ foreY[idxI] = ytop+0.2;
+ foreX[idxI] = ii+im->xorigin-1;
}
- ybase0=ybase;
- ytop0=ytop;
- }
+ backY[++idxI] = ybase-0.2;
+ backX[idxI] = ii+im->xorigin;
+ foreY[idxI] = ytop+0.2;
+ foreX[idxI] = ii+im->xorigin;
+ }
+ /* close up any remaining area */
+ free(foreY);
+ free(foreX);
+ free(backY);
+ free(backX);
} /* else GF_LINE */
} /* if color != 0x0 */
/* make sure we do not run into trouble when stacking on NaN */
if (lastgdes && (im->gdes[i].stack)) {
im->gdes[i].p_data[ii] = lastgdes->p_data[ii];
} else {
- im->gdes[i].p_data[ii] = ytr(im,areazero);
+ im->gdes[i].p_data[ii] = areazero;
}
}
}
if (strcmp(im->graphfile,"-")==0) {
fo = im->graphhandle ? im->graphhandle : stdout;
-#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
/* Change translation mode for stdout to BINARY */
_setmode( _fileno( fo ), O_BINARY );
#endif
return (-1);
}
}
- gfx_render (im->canvas,im->ximg,im->yimg,0x0,fo);
+ gfx_render (im->canvas,im->ximg,im->yimg,0x00000000,fo);
if (strcmp(im->graphfile,"-") != 0)
fclose(fo);
return 0;
for(i=0;i<DIM(graph_col);i++)
im->graph_col[i]=graph_col[i];
-#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
{
char *windir;
char rrd_win_default_font[1000];
{"tabwidth", required_argument, 0, 'T'},
{"font-render-mode", required_argument, 0, 'R'},
{"font-smoothing-threshold", required_argument, 0, 'B'},
+ {"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;
case 'n':{
char prop[15];
double size = 1;
- char font[1024];
+ char font[1024] = "";
if(sscanf(optarg,
"%10[A-Z]:%lf:%1000s",
- prop,&size,font) == 3){
- int sindex;
+ prop,&size,font) >= 2){
+ int sindex,propidx;
if((sindex=text_prop_conv(prop)) != -1){
- im->text_prop[sindex].size=size;
- strcpy(im->text_prop[sindex].font,font);
- if (sindex==0) { /* the default */
- im->text_prop[TEXT_PROP_TITLE].size=size;
- strcpy(im->text_prop[TEXT_PROP_TITLE].font,font);
- im->text_prop[TEXT_PROP_AXIS].size=size;
- strcpy(im->text_prop[TEXT_PROP_AXIS].font,font);
- im->text_prop[TEXT_PROP_UNIT].size=size;
- strcpy(im->text_prop[TEXT_PROP_UNIT].font,font);
- im->text_prop[TEXT_PROP_LEGEND].size=size;
- strcpy(im->text_prop[TEXT_PROP_LEGEND].font,font);
- }
+ 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 (propidx==sindex && sindex != 0) break;
+ }
} else {
rrd_set_error("invalid fonttag '%s'",prop);
return;