X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_graph.c;h=c60717fa0828784601476464480d6d33a7e2f6dd;hb=d1e55cdc27a837fb0f4c54ed019e3946e7a6e08b;hp=18be57376507aada5ab24a74e34d1d3a8748a120;hpb=a834877016ceaec229616e4a529d811fb5e028ac;p=rrdtool.git diff --git a/src/rrd_graph.c b/src/rrd_graph.c index 18be573..c60717f 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -27,16 +27,18 @@ /* some constant definitions */ -#ifndef RRD_DEFAULT_FONT #ifdef WIN32 -#define RRD_DEFAULT_FONT "c:/winnt/fonts/COUR.TTF" -#else -#define RRD_DEFAULT_FONT "/usr/share/fonts/truetype/openoffice/ariosor.ttf" +char rrd_win_default_font[80]; +#endif + +#ifndef RRD_DEFAULT_FONT +#ifndef WIN32 +#define RRD_DEFAULT_FONT "VeraMono.ttf" +/* #define RRD_DEFAULT_FONT "/usr/share/fonts/truetype/openoffice/ariosor.ttf" */ /* #define RRD_DEFAULT_FONT "/usr/share/fonts/truetype/Arial.ttf" */ #endif #endif - text_prop_t text_prop[] = { { 10.0, RRD_DEFAULT_FONT }, /* default */ { 12.0, RRD_DEFAULT_FONT }, /* title */ @@ -677,9 +679,9 @@ for (col=0;colgdes[ii].yrule; - if (isnan(value)) { /* not a number or VDEF */ + if (isnan(value) || (im->gdes[ii].gf == GF_TICK)) { /* The time of the data doesn't necessarily match ** the time of the graph. Beware. */ @@ -1096,7 +1098,7 @@ find_first_time( ) { struct tm tm; - tm = *localtime(&start); + localtime_r(&start, &tm); switch(baseint){ case TMT_SECOND: tm.tm_sec -= tm.tm_sec % basestep; break; @@ -1149,7 +1151,7 @@ find_next_time( { struct tm tm; time_t madetime; - tm = *localtime(¤t); + localtime_r(¤t, &tm); do { switch(baseint){ case TMT_SECOND: @@ -1254,14 +1256,15 @@ print_calc(image_desc_t *im, char ***prdata) } /* prepare printval */ if (!strcmp(im->gdes[i].format,"%c")) { /* VDEF time print */ + char ctime_buf[128]; /* PS: for ctime_r, must be >= 26 chars */ if (im->gdes[i].gf == GF_PRINT){ (*prdata)[prlines-2] = malloc((FMT_LEG_LEN+2)*sizeof(char)); sprintf((*prdata)[prlines-2],"%s (%lu)", - ctime(&printtime),printtime); + ctime_r(&printtime,ctime_buf),printtime); (*prdata)[prlines-1] = NULL; } else { sprintf(im->gdes[i].legend,"%s (%lu)", - ctime(&printtime),printtime); + ctime_r(&printtime,ctime_buf),printtime); graphelement = 1; } } else { @@ -1285,6 +1288,7 @@ print_calc(image_desc_t *im, char ***prdata) if (im->gdes[i].gf == GF_PRINT){ (*prdata)[prlines-2] = malloc((FMT_LEG_LEN+2)*sizeof(char)); + (*prdata)[prlines-1] = NULL; if (bad_format(im->gdes[i].format)) { rrd_set_error("bad format for [G]PRINT in '%s'", im->gdes[i].format); return -1; @@ -1294,7 +1298,6 @@ print_calc(image_desc_t *im, char ***prdata) #else sprintf((*prdata)[prlines-2],im->gdes[i].format,printval,si_symb); #endif - (*prdata)[prlines-1] = NULL; } else { /* GF_GPRINT */ @@ -1357,6 +1360,16 @@ leg_place(image_desc_t *im) for(i=0;igdes_c;i++){ fill_last = fill; + + /* hid legends for rules which are not displayed */ + + 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); @@ -1390,7 +1403,7 @@ leg_place(image_desc_t *im) im->text_prop[TEXT_PROP_LEGEND].font, im->text_prop[TEXT_PROP_LEGEND].size, im->tabwidth, - im->gdes[i].legend); + im->gdes[i].legend, 0); leg_c++; } else { legspace[i]=0; @@ -1438,7 +1451,7 @@ leg_place(image_desc_t *im) im->text_prop[TEXT_PROP_LEGEND].font, im->text_prop[TEXT_PROP_LEGEND].size, im->tabwidth, - im->gdes[ii].legend) + im->gdes[ii].legend, 0) + legspace[ii] + glue; if (im->gdes[ii].gf != GF_GPRINT && @@ -1591,7 +1604,7 @@ int draw_horizontal_grid(image_desc_t *im) MGRIDWIDTH, im->graph_col[GRC_MGRID], im->grid_dash_on, im->grid_dash_off); - } else { + } else if (!(im->extra_flags & NOMINOR)) { gfx_new_dashed_line ( im->canvas, X0-1,Y0, X1+1,Y0, @@ -1694,7 +1707,7 @@ vertical_grid( long factor; char graph_label[100]; double X0,Y0,Y1; /* points for filled graph and more*/ - + struct tm tm; /* the type of time grid is determined by finding the number of seconds per pixel in the graph */ @@ -1721,27 +1734,30 @@ vertical_grid( /* paint the minor grid */ - for(ti = find_first_time(im->start, - im->xlab_user.gridtm, - im->xlab_user.gridst), - timajor = find_first_time(im->start, - im->xlab_user.mgridtm, - im->xlab_user.mgridst); - ti < im->end; - ti = find_next_time(ti,im->xlab_user.gridtm,im->xlab_user.gridst) - ){ - /* are we inside the graph ? */ - if (ti < im->start || ti > im->end) continue; - while (timajor < ti) { - timajor = find_next_time(timajor, - im->xlab_user.mgridtm, im->xlab_user.mgridst); - } - if (ti == timajor) continue; /* skip as falls on major grid line */ - X0 = xtr(im,ti); - gfx_new_dashed_line(im->canvas,X0,Y0+1, X0,Y1-1,GRIDWIDTH, - im->graph_col[GRC_GRID], - im->grid_dash_on, im->grid_dash_off); - + if (!(im->extra_flags & NOMINOR)) + { + for(ti = find_first_time(im->start, + im->xlab_user.gridtm, + im->xlab_user.gridst), + timajor = find_first_time(im->start, + im->xlab_user.mgridtm, + im->xlab_user.mgridst); + ti < im->end; + ti = find_next_time(ti,im->xlab_user.gridtm,im->xlab_user.gridst) + ){ + /* are we inside the graph ? */ + if (ti < im->start || ti > im->end) continue; + while (timajor < ti) { + timajor = find_next_time(timajor, + im->xlab_user.mgridtm, im->xlab_user.mgridst); + } + if (ti == timajor) continue; /* skip as falls on major grid line */ + X0 = xtr(im,ti); + gfx_new_dashed_line(im->canvas,X0,Y0+1, X0,Y1-1,GRIDWIDTH, + im->graph_col[GRC_GRID], + im->grid_dash_on, im->grid_dash_off); + + } } /* paint the major grid */ @@ -1771,7 +1787,8 @@ vertical_grid( if (ti < im->start || ti > im->end) continue; #if HAVE_STRFTIME - strftime(graph_label,99,im->xlab_user.stst,localtime(&tilab)); + 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 @@ -1872,13 +1889,14 @@ grid_paint(image_desc_t *im) } /* yaxis description */ - if (im->canvas->imgformat != IF_PNG) { +/* if (im->canvas->imgformat != IF_PNG) {*/ + if (1) { gfx_new_text( im->canvas, 7, (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, 270.0, - GFX_H_CENTER, GFX_V_CENTER, + GFX_H_LEFT, GFX_V_CENTER, im->ylegend); } else { /* horrible hack until we can actually print vertically */ @@ -1889,7 +1907,7 @@ grid_paint(image_desc_t *im) for (n=0;nylegend);n++) { s[0]=im->ylegend[n]; s[1]='\0'; - gfx_new_text(im->canvas,7,im->text_prop[TEXT_PROP_AXIS].size*(l-n), + gfx_new_text(im->canvas,7,im->text_prop[TEXT_PROP_AXIS].size*(n+1), im->graph_col[GRC_FONT], im->text_prop[TEXT_PROP_AXIS].font, im->text_prop[TEXT_PROP_AXIS].size, im->tabwidth, 270.0, @@ -1925,7 +1943,7 @@ grid_paint(image_desc_t *im) boxH = gfx_get_text_width(im->canvas, 0, im->text_prop[TEXT_PROP_AXIS].font, im->text_prop[TEXT_PROP_AXIS].size, - im->tabwidth,"M") * 1.25; + im->tabwidth,"M", 0) * 1.25; boxV = boxH; node = gfx_new_area(im->canvas, @@ -2077,7 +2095,7 @@ graph_size_location(image_desc_t *im, int elements, int piechart ) im->text_prop[TEXT_PROP_TITLE].font, im->text_prop[TEXT_PROP_TITLE].size, im->tabwidth, - im->title) + 2*Xspacing; + im->title, 0) + 2*Xspacing; Ytitle = im->text_prop[TEXT_PROP_TITLE].size*2; } @@ -2192,15 +2210,15 @@ graph_paint(image_desc_t *im, char ***calcpr) double areazero = 0.0; enum gf_en stack_gf = GF_PRINT; graph_desc_t *lastgdes = NULL; - + /* if we are lazy and there is nothing to PRINT ... quit now */ if (lazy && im->prt_c==0) return 0; - + /* pull the data from the rrd files ... */ if(data_fetch(im)==-1) return -1; - + /* evaluate VDEF and CDEF operations ... */ if(data_calc(im)==-1) return -1; @@ -2396,14 +2414,11 @@ graph_paint(image_desc_t *im, char ***calcpr) /* make sure we do not run into trouble when stacking on NaN */ for(ii=0;iixsize;ii++){ if (isnan(im->gdes[i].p_data[ii])) { - double ybase = 0.0; - if (lastgdes) { - ybase = ytr(im,lastgdes->p_data[ii-1]); - }; - if (isnan(ybase) || !lastgdes ){ - ybase = ytr(im,areazero); + if (lastgdes && (im->gdes[i].gf == GF_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] = ybase; } } lastgdes = &(im->gdes[i]); @@ -2462,15 +2477,15 @@ graph_paint(image_desc_t *im, char ***calcpr) if (strcmp(im->graphfile,"-")==0) { + fo = im->graphhandle ? im->graphhandle : stdout; #ifdef WIN32 /* Change translation mode for stdout to BINARY */ - _setmode( _fileno( stdout ), O_BINARY ); + _setmode( _fileno( fo ), O_BINARY ); #endif - fo = stdout; } else { if ((fo = fopen(im->graphfile,"wb")) == NULL) { rrd_set_error("Opening '%s' for write: %s",im->graphfile, - strerror(errno)); + rrd_strerror(errno)); return (-1); } } @@ -2488,7 +2503,7 @@ graph_paint(image_desc_t *im, char ***calcpr) int gdes_alloc(image_desc_t *im){ - long def_step = (im->end-im->start)/im->xsize; + unsigned long def_step = (im->end-im->start)/im->xsize; if (im->step > def_step) /* step can be increassed ... no decreassed */ def_step = im->step; @@ -2554,12 +2569,13 @@ scan_for_col(char *input, int len, char *output) ** - script parsing now in rrd_graph_script() */ int -rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize) +rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize, FILE *stream) { image_desc_t im; rrd_graph_init(&im); - + im.graphhandle = stream; + rrd_graph_options(argc,argv,&im); if (rrd_test_error()) { im_free(&im); @@ -2623,7 +2639,7 @@ rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize) void rrd_graph_init(image_desc_t *im) { - int i; + unsigned int i; #ifdef HAVE_TZSET tzset(); @@ -2662,7 +2678,19 @@ rrd_graph_init(image_desc_t *im) for(i=0;igraph_col[i]=graph_col[i]; - +#ifdef WIN32 + { + char *windir; + windir = getenv("windir"); + /* %windir% is something like D:\windows or C:\winnt */ + if (windir != NULL) { + strcpy(rrd_win_default_font,windir); + strcat(rrd_win_default_font,"\\fonts\\cour.ttf"); + for(i=0;itext_prop[i].size = text_prop[i].size; im->text_prop[i].font = text_prop[i].font; @@ -2677,7 +2705,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im) 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 time_value start_tv, end_tv; + struct rrd_time_value start_tv, end_tv; gfx_color_t color; parsetime("end-24h", &start_tv); @@ -2707,41 +2735,45 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im) {"lazy", no_argument, 0, 'z'}, {"zoom", required_argument, 0, 'm'}, {"no-legend", no_argument, 0, 'g'}, - {"alt-y-grid", no_argument, 0, 257 }, - {"alt-autoscale", no_argument, 0, 258 }, - {"alt-autoscale-max", no_argument, 0, 259 }, - {"units-exponent",required_argument, 0, 260}, - {"step", required_argument, 0, 261}, - {"no-gridfit", no_argument, 0, 262}, + {"alt-y-grid", no_argument, 0, 'Y'}, + {"no-minor", no_argument, 0, 'I'}, + {"alt-autoscale", no_argument, 0, 'A'}, + {"alt-autoscale-max", no_argument, 0, 'M'}, + {"units-exponent",required_argument, 0, 'X'}, + {"step", required_argument, 0, 'S'}, + {"no-gridfit", no_argument, 0, 'N'}, {0,0,0,0}}; int option_index = 0; int opt; opt = getopt_long(argc, argv, - "s:e:x:y:v:w:h:iu:l:rb:oc:n:m:t:f:a:z:g", + "s:e:x:y:v:w:h:iu:l:rb:oc:n:m:t:f:a:I:zgYAMX:S:N", long_options, &option_index); if (opt == EOF) break; switch(opt) { - case 257: + case 'I': + im->extra_flags |= NOMINOR; + break; + case 'Y': im->extra_flags |= ALTYGRID; break; - case 258: + case 'A': im->extra_flags |= ALTAUTOSCALE; break; - case 259: + case 'M': im->extra_flags |= ALTAUTOSCALE_MAX; break; case 'g': im->extra_flags |= NOLEGEND; break; - case 260: + case 'X': im->unitsexponent = atoi(optarg); break; - case 261: + case 'S': im->step = atoi(optarg); break; case 262: @@ -3064,9 +3096,9 @@ int bad_format(char *fmt) { if (*ptr == '.') ptr++; while (*ptr >= '0' && *ptr <= '9') ptr++; - /* Either 'le' or 'lf' must follow here */ + /* Either 'le', 'lf' or 'lg' must follow here */ if (*ptr++ != 'l') return 1; - if (*ptr == 'e' || *ptr == 'f') ptr++; + if (*ptr == 'e' || *ptr == 'f' || *ptr == 'g') ptr++; else return 1; n++; } @@ -3204,6 +3236,7 @@ printf("DEBUG: start == %lu, end == %lu, %lu steps\n" 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