/****************************************************************************
- * RRDtool 1.2rc5 Copyright by Tobi Oetiker, 1997-2005
+ * RRDtool 1.2.0 Copyright by Tobi Oetiker, 1997-2005
****************************************************************************
* rrd__graph.c produce graphs from data in rrdfiles
****************************************************************************/
#endif
text_prop_t text_prop[] = {
- { 9.0, RRD_DEFAULT_FONT }, /* default */
- { 11.0, RRD_DEFAULT_FONT }, /* title */
- { 8.0, RRD_DEFAULT_FONT }, /* axis */
- { 9.0, RRD_DEFAULT_FONT }, /* unit */
- { 9.0, RRD_DEFAULT_FONT } /* legend */
+ { 8.0, RRD_DEFAULT_FONT }, /* default */
+ { 9.0, RRD_DEFAULT_FONT }, /* title */
+ { 7.0, RRD_DEFAULT_FONT }, /* axis */
+ { 8.0, RRD_DEFAULT_FONT }, /* unit */
+ { 8.0, RRD_DEFAULT_FONT } /* legend */
};
xlab_t xlab[] = {
0x90909080, /* grid */
0xE0505080, /* major grid */
0x000000FF, /* font */
- 0xFF0000FF, /* arrow */
- 0x404040FF /* axis */
+ 0x802020FF, /* arrow */
+ 0x202020FF /* axis */
};
'E'};/* 10e18 Exa */
int symbcenter = 6;
- double digits;
+ double digits,viewdigits=0;
+ 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 */
- digits = floor(im->unitsexponent / 3);
+ viewdigits = floor(im->unitsexponent / 3);
} else {
- digits = floor( log( max( fabs(im->minval),fabs(im->maxval)))/log((double)im->base));
+ viewdigits = digits;
}
- im->magfact = pow((double)im->base , digits);
+ im->magfact = pow((double)im->base , digits);
+
#ifdef DEBUG
printf("digits %6.3f im->magfact %6.3f\n",digits,im->magfact);
#endif
- if ( ((digits+symbcenter) < sizeof(symbol)) &&
- ((digits+symbcenter) >= 0) )
- im->symbol = symbol[(int)digits+symbcenter];
+ 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];
else
- im->symbol = ' ';
+ im->symbol = '?';
}
/* move min and max values around to become sensible */
-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 */
if (!strcmp(im->gdes[i].format,"%c")) { /* VDEF time print */
char ctime_buf[128]; /* PS: for ctime_r, must be >= 26 chars */
+ int iii=0;
+ ctime_r(&printtime,ctime_buf);
+ while(isprint(ctime_buf[iii])){iii++;}
+ ctime_buf[iii]='\0';
if (im->gdes[i].gf == GF_PRINT){
(*prdata)[prlines-2] = malloc((FMT_LEG_LEN+2)*sizeof(char));
- sprintf((*prdata)[prlines-2],"%s (%lu)",
- ctime_r(&printtime,ctime_buf),printtime);
+ sprintf((*prdata)[prlines-2],"%s (%lu)",ctime_buf,printtime);
(*prdata)[prlines-1] = NULL;
} else {
- sprintf(im->gdes[i].legend,"%s (%lu)",
- ctime_r(&printtime,ctime_buf),printtime);
+ sprintf(im->gdes[i].legend,"%s (%lu)",ctime_buf,printtime);
graphelement = 1;
}
} else {
+ legspace[ii]
+ glue;
}
- leg_y += im->text_prop[TEXT_PROP_LEGEND].size*1.7;
+ 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;
decimals = 1;
fractionals = floor(log10(range));
- if(fractionals < 0) /* small amplitude. */
- sprintf(im->ygrid_scale.labfmt, "%%%d.%df", decimals - fractionals + 1, -fractionals + 1);
- else
- sprintf(im->ygrid_scale.labfmt, "%%%d.1f", decimals + 1);
+ 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);
if(im->ygrid_scale.gridstep == 0) /* range is one -> 0.1 is reasonable scale */
im->ygrid_scale.gridstep = 0.1;
else {
for(i=0;ylab[i].grid > 0;i++){
pixel = im->ysize / (scaledrange / ylab[i].grid);
- if (gridind == -1 && pixel > 5) {
+ if (pixel > 5) {
gridind = i;
break;
}
if (i==0 || im->symbol == ' ') {
if(scaledstep < 1){
if(im->extra_flags & ALTYGRID) {
- sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*i);
+ sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*im->viewfactor*i);
}
else {
- sprintf(graph_label,"%4.1f",scaledstep*i);
+ sprintf(graph_label,"%4.1f",scaledstep*im->viewfactor*i);
}
} else {
- sprintf(graph_label,"%4.0f",scaledstep*i);
+ sprintf(graph_label,"%4.0f",scaledstep*im->viewfactor*i);
}
}else {
if(scaledstep < 1){
- sprintf(graph_label,"%4.1f %c",scaledstep*i, im->symbol);
+ sprintf(graph_label,"%4.1f %c",scaledstep*im->viewfactor*i, im->symbol);
} else {
- sprintf(graph_label,"%4.0f %c",scaledstep*i, im->symbol);
+ sprintf(graph_label,"%4.0f %c",scaledstep*im->viewfactor*i, im->symbol);
}
}
gfx_new_text ( im->canvas,
- X0-im->text_prop[TEXT_PROP_AXIS].size/1.5, Y0,
+ 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,
sprintf(graph_label,"%3.0e",value * yloglab[majoridx][i]);
gfx_new_text ( im->canvas,
- X0-im->text_prop[TEXT_PROP_AXIS].size/1.5, Y0,
+ 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,
# 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.5,
+ xtr(im,tilab), Y0+im->text_prop[TEXT_PROP_AXIS].size,
im->graph_col[GRC_FONT],
im->text_prop[TEXT_PROP_AXIS].font,
im->text_prop[TEXT_PROP_AXIS].size,
MGRIDWIDTH, im->graph_col[GRC_AXIS]);
- /* arrow for X axis direction */
+ /* 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]);
+
gfx_new_area ( im->canvas,
- im->xorigin+im->xsize+3, im->yorigin-3,
- im->xorigin+im->xsize+3, im->yorigin+4,
- im->xorigin+im->xsize+8, im->yorigin+0.5, /* LINEOFFSET */
+ 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]);
}
*/
int Xvertical=0, Yvertical=0,
Xtitle =0, Ytitle =0,
- Xylabel =0, Yylabel =0,
+ Xylabel =0,
Xmain =0, Ymain =0,
#ifdef WITH_PIECHART
Xpie =0, Ypie =0,
#endif
- Xxlabel =0, Yxlabel =0,
+ Yxlabel =0,
#if 0
Xlegend =0, Ylegend =0,
#endif
- Xspacing =10, Yspacing =10;
+ Xspacing =15, Yspacing =15;
if (im->extra_flags & ONLY_GRAPH) {
im->xorigin =0;
Xmain=im->xsize;
Ymain=im->ysize;
if (im->draw_x_grid) {
- Xxlabel=Xmain;
Yxlabel=im->text_prop[TEXT_PROP_AXIS].size *2.5;
}
if (im->draw_y_grid) {
- Xylabel=im->text_prop[TEXT_PROP_AXIS].size *6;
- Yylabel=Ymain;
+ 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 + im->text_prop[TEXT_PROP_AXIS].size * 2;
}
}
}
} /* for */
-
- if (im->gdes[i].col != 0x0){
+
+ /* *******************************************************
+ ___
+ | | ___
+ ____| | | |
+ | |___|
+ -------|---------------------------------------
+
+ if we know the value of y at time t was a then
+ we draw a square from t-1 to t with the value a.
+
+ ********************************************************* */
+ if (im->gdes[i].col != 0x0){
/* GF_LINE and friend */
if(stack_gf == GF_LINE ){
node = NULL;
for(ii=1;ii<im->xsize;ii++){
- if ( ! isnan(im->gdes[i].p_data[ii-1])
- && ! isnan(im->gdes[i].p_data[ii])){
- if (node == NULL){
- node = gfx_new_line(im->canvas,
- ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii-1]),
+ if (isnan(im->gdes[i].p_data[ii])){
+ node = NULL;
+ continue;
+ }
+ if ( node == NULL ) {
+ node = gfx_new_line(im->canvas,
+ ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii]),
ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]),
im->gdes[i].linewidth,
im->gdes[i].col);
- } else {
- gfx_add_point(node,ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]));
- }
- } else {
- node = NULL;
- }
+ } else {
+ gfx_add_point(node,ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii]));
+ gfx_add_point(node,ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]));
+ };
+
}
} else {
- int area_start=-1;
- node = NULL;
for(ii=1;ii<im->xsize;ii++){
- /* open an area */
- if ( ! isnan(im->gdes[i].p_data[ii-1])
- && ! isnan(im->gdes[i].p_data[ii])){
- if (node == NULL){
- float ybase = 0.0;
-/*
- if (im->gdes[i].gf == GF_STACK) {
-*/
- if ( (im->gdes[i].gf == GF_STACK)
- || (im->gdes[i].stack) ) {
-
- ybase = ytr(im,lastgdes->p_data[ii-1]);
- } else {
- ybase = ytr(im,areazero);
- }
- area_start = ii-1;
- node = gfx_new_area(im->canvas,
- ii-1+im->xorigin,ybase,
- ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii-1]),
- ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]),
- im->gdes[i].col
- );
- } else {
- gfx_add_point(node,ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]));
- }
+ /* keep things simple for now, just draw these bars
+ do not try to build a big and complex area */
+ float ybase,ytop;
+ if ( isnan(im->gdes[i].p_data[ii]) ) {
+ continue;
+ }
+ ytop = ytr(im,im->gdes[i].p_data[ii]);
+ if ( im->gdes[i].stack ) {
+ ybase = ytr(im,lastgdes->p_data[ii]);
+ } else {
+ ybase = ytr(im,areazero);
}
-
- if ( node != NULL && (ii+1==im->xsize || isnan(im->gdes[i].p_data[ii]) )){
- /* GF_AREA STACK type*/
-/*
- if (im->gdes[i].gf == GF_STACK ) {
-*/
- if ( (im->gdes[i].gf == GF_STACK)
- || (im->gdes[i].stack) ) {
- int iii;
- for (iii=ii-1;iii>area_start;iii--){
- gfx_add_point(node,iii+im->xorigin,ytr(im,lastgdes->p_data[iii]));
- }
- } else {
- gfx_add_point(node,ii+im->xorigin,ytr(im,areazero));
- };
- node=NULL;
- };
+ if ( ybase == ytop ){
+ continue;
+ }
+ node = gfx_new_area(im->canvas,
+ ii-1+im->xorigin,ybase,
+ ii-1+im->xorigin,ytop,
+ ii+im->xorigin,ytop,
+ im->gdes[i].col
+ );
+ gfx_add_point(node,ii+im->xorigin,ybase);
}
} /* else GF_LINE */
} /* if color != 0x0 */
/* make sure we do not run into trouble when stacking on NaN */
for(ii=0;ii<im->xsize;ii++){
if (isnan(im->gdes[i].p_data[ii])) {
- if (lastgdes && (im->gdes[i].gf == GF_STACK)) {
+ 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);
}
#endif
- if( !(im->extra_flags & ONLY_GRAPH) )
- axis_paint(im);
/* grid_paint also does the text */
if( !(im->extra_flags & ONLY_GRAPH) )
grid_paint(im);
+
+
+ if( !(im->extra_flags & ONLY_GRAPH) )
+ axis_paint(im);
/* the RULES are the last thing to paint ... */
for(i=0;i<im->gdes_c;i++){
#ifdef HAVE_SETLOCALE
setlocale(LC_TIME,"");
#endif
-
+ im->yorigin=0;
+ im->xorigin=0;
+ im->minval=0;
im->xlab_user.minsec = -1;
im->ximg=0;
im->yimg=0;
im->minval = DNAN;
im->maxval = DNAN;
im->unitsexponent= 9999;
+ im->unitslength= 6;
+ im->symbol = ' ';
+ im->viewfactor = 1.0;
im->extra_flags= 0;
im->rigid = 0;
im->gridfit = 1;
if (windir != NULL) {
strncpy(rrd_win_default_font,windir,999);
rrd_win_default_font[999] = '\0';
- strcat(rrd_win_default_font,"\\fonts\\cour.ttf");
+ strcat(rrd_win_default_font,"\\fonts\\");
+ 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';
}
+ }
}
#endif
{
char *deffont;
deffont = getenv("RRD_DEFAULT_FONT");
- /* %windir% is something like D:\windows or C:\winnt */
if (deffont != NULL) {
for(i=0;i<DIM(text_prop);i++){
strncpy(text_prop[i].font,deffont,sizeof(text_prop[i].font)-1);
{"no-minor", no_argument, 0, 'I'},
{"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'},
{"step", required_argument, 0, 'S'},
{"tabwidth", required_argument, 0, 'T'},
- {"no-gridfit", no_argument, 0, 'N'},
{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:zgjFYAMX:S:NT:",
+ "s:e:x:y:v:w:h:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMX:L:S:T:N",
long_options, &option_index);
if (opt == EOF)
case 'X':
im->unitsexponent = atoi(optarg);
break;
+ case 'L':
+ im->unitslength = atoi(optarg);
+ break;
case 'T':
im->tabwidth = atof(optarg);
break;
case 'S':
im->step = atoi(optarg);
break;
- case 262:
+ case 'N':
im->gridfit = 0;
break;
case 's':
break;
case 'c':
if(sscanf(optarg,
- "%10[A-Z]#%8lx",
- col_nam,&color) == 2){
+ "%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 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;
}
} else {
rrd_set_error("invalid color def format");