X-Git-Url: https://git.octo.it/?p=rrdtool.git;a=blobdiff_plain;f=src%2Frrd_graph.c;h=d1343b989e0d2aa4a4200c9a6dcc31c04285d803;hp=9acf82e590c72ca4812391cd6d53491369a07022;hb=591bd42a2c2ef80a7e1753e00001ea0633978660;hpb=ac630adec930653637199258efd99024d49325c7 diff --git a/src/rrd_graph.c b/src/rrd_graph.c index 9acf82e..d1343b9 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -6,10 +6,13 @@ #include +#include #ifdef WIN32 #include "strftime.h" +#include "plbasename.h" #endif + #include "rrd_tool.h" #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) @@ -235,7 +238,7 @@ enum gf_en gf_conv( conv_if(XPORT, GF_XPORT); conv_if(SHIFT, GF_SHIFT); - return (-1); + return (enum gf_en)(-1); } enum gfx_if_en if_conv( @@ -247,7 +250,7 @@ enum gfx_if_en if_conv( conv_if(EPS, IF_EPS); conv_if(PDF, IF_PDF); - return (-1); + return (enum gfx_if_en)(-1); } enum tmt_en tmt_conv( @@ -261,7 +264,7 @@ enum tmt_en tmt_conv( conv_if(WEEK, TMT_WEEK); conv_if(MONTH, TMT_MONTH); conv_if(YEAR, TMT_YEAR); - return (-1); + return (enum tmt_en)(-1); } enum grc_en grc_conv( @@ -279,7 +282,7 @@ enum grc_en grc_conv( conv_if(AXIS, GRC_AXIS); conv_if(FRAME, GRC_FRAME); - return -1; + return (enum grc_en)(-1); } enum text_prop_en text_prop_conv( @@ -292,7 +295,7 @@ enum text_prop_en text_prop_conv( conv_if(UNIT, TEXT_PROP_UNIT); conv_if(LEGEND, TEXT_PROP_LEGEND); conv_if(WATERMARK, TEXT_PROP_WATERMARK); - return -1; + return (enum text_prop_en)(-1); } @@ -302,16 +305,13 @@ int im_free( image_desc_t *im) { unsigned long i, ii; - cairo_status_t status = 0; + cairo_status_t status = (cairo_status_t) 0; if (im == NULL) return 0; - if (im->use_rrdcached) - { - rrdc_disconnect (); - im->use_rrdcached = 0; - } + if (im->daemon_addr != NULL) + free(im->daemon_addr); for (i = 0; i < (unsigned) im->gdes_c; i++) { if (im->gdes[i].data_first) { @@ -429,7 +429,7 @@ void si_unit( if (im->unitsexponent != 9999) { /* unitsexponent = 9, 6, 3, 0, -3, -6, -9, etc */ - viewdigits = floor(im->unitsexponent / 3); + viewdigits = floor((double)(im->unitsexponent / 3)); } else { viewdigits = digits; } @@ -845,7 +845,7 @@ int data_fetch( * - a connection to the daemon has been established * - this is the first occurrence of that RRD file */ - if (im->use_rrdcached) + if (rrdc_is_connected(im->daemon_addr)) { int status; @@ -869,7 +869,7 @@ int data_fetch( return (-1); } } - } /* if (im->use_rrdcached) */ + } /* if (rrdc_is_connected()) */ if ((rrd_fetch_fn(im->gdes[i].rrd, im->gdes[i].cf, @@ -941,7 +941,7 @@ long find_var( return -1; } -/* find the largest common denominator for all the numbers +/* find the greatest common divisor for all the numbers in the 0 terminated num array */ long lcd( long *num) @@ -1055,7 +1055,7 @@ int data_calc( /* 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, + (long*)rrd_realloc(steparray, (++stepcnt + 1) * sizeof(*steparray))) == NULL) { rrd_set_error("realloc steparray"); @@ -1123,7 +1123,7 @@ int data_calc( */ im->gdes[gdi].step = lcd(steparray); free(steparray); - if ((im->gdes[gdi].data = malloc(((im->gdes[gdi].end - + if ((im->gdes[gdi].data = (rrd_value_t*)malloc(((im->gdes[gdi].end - im->gdes[gdi].start) / im->gdes[gdi].step) * sizeof(double))) == NULL) { @@ -1213,7 +1213,7 @@ int data_proc( 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) + if ((im->gdes[i].p_data = (rrd_value_t*)malloc((im->xsize + 1) * sizeof(rrd_value_t))) == NULL) { rrd_set_error("malloc data_proc"); return -1; @@ -1570,7 +1570,7 @@ int print_calc( rrd_infoval_t prline; if (im->gdes[i].strftm) { - prline.u_str = malloc((FMT_LEG_LEN + 2) * sizeof(char)); + prline.u_str = (char*)malloc((FMT_LEG_LEN + 2) * sizeof(char)); strftime(prline.u_str, FMT_LEG_LEN, im->gdes[i].format, &tmvdef); } else if (bad_format(im->gdes[i].format)) { @@ -1659,27 +1659,24 @@ int leg_place( int border = im->text_prop[TEXT_PROP_LEGEND].size * 2.0; int fill = 0, fill_last; int leg_c = 0; - int leg_x = border; + double leg_x = border; int leg_y = im->yimg; int leg_y_prev = im->yimg; int leg_cc; - int glue = 0; + double glue = 0; int i, ii, mark = 0; - char prt_fctn; /*special printfunctions */ char default_txtalign = TXA_JUSTIFIED; /*default line orientation */ int *legspace; char *tab; if (!(im->extra_flags & NOLEGEND) & !(im->extra_flags & ONLY_GRAPH)) { - if ((legspace = malloc(im->gdes_c * sizeof(int))) == NULL) { + if ((legspace = (int*)malloc(im->gdes_c * sizeof(int))) == NULL) { rrd_set_error("malloc for legspace"); return -1; } - if (im->extra_flags & FULL_SIZE_MODE) - leg_y = leg_y_prev = - leg_y - (int) (im->text_prop[TEXT_PROP_LEGEND].size * 1.8); for (i = 0; i < im->gdes_c; i++) { + char prt_fctn; /*special printfunctions */ fill_last = fill; /* hide legends for rules which are not displayed */ if (im->gdes[i].gf == GF_TEXTALIGN) { @@ -1703,7 +1700,7 @@ int leg_place( tab[0] = (char) 9; } leg_cc = strlen(im->gdes[i].legend); - /* is there a controle code ant the end of the legend string ? */ + /* is there a controle code at the end of the legend string ? */ if (leg_cc >= 2 && im->gdes[i].legend[leg_cc - 2] == '\\') { prt_fctn = im->gdes[i].legend[leg_cc - 1]; leg_cc -= 2; @@ -1795,12 +1792,12 @@ int leg_place( if (prt_fctn != '\0') { leg_x = border; if (leg_c >= 2 && prt_fctn == 'j') { - glue = (im->ximg - fill - 2 * border) / (leg_c - 1); + glue = (double)(im->ximg - fill - 2 * border) / (double)(leg_c - 1); } else { glue = 0; } if (prt_fctn == 'c') - leg_x = (im->ximg - fill) / 2.0; + leg_x = (double)(im->ximg - fill) / 2.0; if (prt_fctn == 'r') leg_x = im->ximg - fill - border; for (ii = mark; ii <= i; ii++) { @@ -1809,28 +1806,20 @@ int leg_place( im->gdes[ii].leg_x = leg_x; im->gdes[ii].leg_y = leg_y; leg_x += - gfx_get_text_width(im, leg_x, + (double)gfx_get_text_width(im, leg_x, im-> text_prop [TEXT_PROP_LEGEND]. font_desc, im->tabwidth, im->gdes[ii].legend) - + legspace[ii] + +(double)legspace[ii] + glue; } leg_y_prev = leg_y; - if (im->extra_flags & FULL_SIZE_MODE) { - /* 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; - } else { - 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; - } + 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; @@ -1838,11 +1827,15 @@ int leg_place( } if (im->extra_flags & FULL_SIZE_MODE) { - if (leg_y != leg_y_prev) { - *gY = leg_y - im->text_prop[TEXT_PROP_LEGEND].size * 1.8; - im->yorigin = - leg_y - im->text_prop[TEXT_PROP_LEGEND].size * 1.8; + /* now for some backpaddeling. We have to shift up all the + legend items into the graph and tell the caller about the + space we used up. */ + long shift_up = leg_y - im->yimg - im->text_prop[TEXT_PROP_LEGEND].size * 1.8 + border * 0.7; + for (i = 0; i < im->gdes_c; i++) { + im->gdes[i].leg_y -= shift_up; } + im->yorigin = im->yorigin - leg_y + im->yimg - im->text_prop[TEXT_PROP_LEGEND].size * 1.8 - border; + *gY = im->yorigin; } else { im->yimg = leg_y - im->text_prop[TEXT_PROP_LEGEND].size * 1.8 + @@ -1970,7 +1963,9 @@ int draw_horizontal_grid( int sgrid = (int) (im->minval / im->ygrid_scale.gridstep - 1); int egrid = (int) (im->maxval / im->ygrid_scale.gridstep + 1); double MaxY; - + double second_axis_magfact = 0; + char *second_axis_symb = ""; + scaledstep = im->ygrid_scale.gridstep / (double) im->magfact * (double) im->viewfactor; @@ -2021,6 +2016,33 @@ int draw_horizontal_grid( } } nlabels++; + if (im->second_axis_scale != 0){ + char graph_label_right[100]; + double sval = im->ygrid_scale.gridstep*(double)i*im->second_axis_scale+im->second_axis_shift; + if (im->second_axis_format[0] == '\0'){ + if (!second_axis_magfact){ + double dummy = im->ygrid_scale.gridstep*(double)(sgrid+egrid)/2.0*im->second_axis_scale+im->second_axis_shift; + auto_scale(im,&dummy,&second_axis_symb,&second_axis_magfact); + } + sval /= second_axis_magfact; + + if(MaxY < 10) { + sprintf(graph_label_right,"%5.1f %s",sval,second_axis_symb); + } else { + sprintf(graph_label_right,"%5.0f %s",sval,second_axis_symb); + } + } + else { + sprintf(graph_label_right,im->second_axis_format,sval); + } + gfx_text ( im, + X1+7, Y0, + im->graph_col[GRC_FONT], + im->text_prop[TEXT_PROP_AXIS].font_desc, + im->tabwidth,0.0, GFX_H_LEFT, GFX_V_CENTER, + graph_label_right ); + } + gfx_text(im, X0 - im-> @@ -2072,7 +2094,7 @@ double frexp10( double mnt; int iexp; - iexp = floor(log(fabs(x)) / log(10)); + iexp = floor(log((double)fabs(x)) / log((double)10)); mnt = x / pow(10.0, iexp); if (mnt >= 10.0) { iexp++; @@ -2198,8 +2220,35 @@ int horizontal_log_grid( else symbol = '?'; sprintf(graph_label, "%3.0f %c", pvalue, symbol); - } else + } else { sprintf(graph_label, "%3.0e", value); + } + if (im->second_axis_scale != 0){ + char graph_label_right[100]; + double sval = value*im->second_axis_scale+im->second_axis_shift; + if (im->second_axis_format[0] == '\0'){ + if (im->extra_flags & FORCE_UNITS_SI) { + double mfac = 1; + char *symb = ""; + auto_scale(im,&sval,&symb,&mfac); + sprintf(graph_label_right,"%4.0f %s", sval,symb); + } + else { + sprintf(graph_label_right,"%3.0e", sval); + } + } + else { + sprintf(graph_label_right,im->second_axis_format,sval); + } + + gfx_text ( im, + X1+7, Y0, + im->graph_col[GRC_FONT], + im->text_prop[TEXT_PROP_AXIS].font_desc, + im->tabwidth,0.0, GFX_H_LEFT, GFX_V_CENTER, + graph_label_right ); + } + gfx_text(im, X0 - im-> @@ -2513,6 +2562,18 @@ void axis_paint( gfx_new_area(im, im->xorigin - 3, im->yorigin - im->ysize - 2, im->xorigin + 3, im->yorigin - im->ysize - 2, im->xorigin, im->yorigin - im->ysize - 7, /* vertical */ im->graph_col[GRC_ARROW]); gfx_close_path(im); + if (im->second_axis_scale != 0){ + gfx_line ( im, im->xorigin+im->xsize,im->yorigin+4, + im->xorigin+im->xsize,im->yorigin-im->ysize-4, + MGRIDWIDTH, im->graph_col[GRC_AXIS]); + gfx_new_area ( im, + im->xorigin+im->xsize-2, im->yorigin-im->ysize-2, + im->xorigin+im->xsize+3, im->yorigin-im->ysize-2, + im->xorigin+im->xsize, im->yorigin-im->ysize-7, /* LINEOFFSET */ + im->graph_col[GRC_ARROW]); + gfx_close_path(im); + } + } void grid_paint( @@ -2563,16 +2624,34 @@ void grid_paint( } /* yaxis unit description */ - gfx_text(im, - 10, - (im->yorigin - - im->ysize / 2), - im->graph_col[GRC_FONT], - im-> - text_prop[TEXT_PROP_UNIT]. - font_desc, - im->tabwidth, - RRDGRAPH_YLEGEND_ANGLE, GFX_H_CENTER, GFX_V_CENTER, im->ylegend); + if (im->ylegend[0] != '\0'){ + gfx_text(im, + 10, + (im->yorigin - + im->ysize / 2), + im->graph_col[GRC_FONT], + im-> + text_prop[TEXT_PROP_UNIT]. + font_desc, + im->tabwidth, + RRDGRAPH_YLEGEND_ANGLE, GFX_H_CENTER, GFX_V_CENTER, im->ylegend); + } + if (im->second_axis_legend[0] != '\0'){ + double Xylabel=gfx_get_text_width(im, 0, + im->text_prop[TEXT_PROP_AXIS].font_desc, + im->tabwidth, + "0") * im->unitslength + + im->text_prop[TEXT_PROP_UNIT].size *2; + gfx_text( im, + im->xorigin+im->xsize+Xylabel+8, (im->yorigin - im->ysize/2), + im->graph_col[GRC_FONT], + im->text_prop[TEXT_PROP_UNIT].font_desc, + im->tabwidth, + RRDGRAPH_YLEGEND_ANGLE, + GFX_H_CENTER, GFX_V_CENTER, + im->second_axis_legend); + } + /* graph title */ gfx_text(im, im->ximg / 2, 6, @@ -2582,14 +2661,16 @@ void grid_paint( font_desc, im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_TOP, im->title); /* rrdtool 'logo' */ - water_color = im->graph_col[GRC_FONT]; - water_color.alpha = 0.3; - gfx_text(im, im->ximg - 4, 5, - water_color, - im-> - text_prop[TEXT_PROP_WATERMARK]. - font_desc, im->tabwidth, - -90, GFX_H_LEFT, GFX_V_TOP, "RRDTOOL / TOBI OETIKER"); + if (!(im->extra_flags & NO_RRDTOOL_TAG)){ + water_color = im->graph_col[GRC_FONT]; + water_color.alpha = 0.3; + gfx_text(im, im->ximg - 4, 5, + water_color, + im-> + text_prop[TEXT_PROP_WATERMARK]. + font_desc, im->tabwidth, + -90, GFX_H_LEFT, GFX_V_TOP, "RRDTOOL / TOBI OETIKER"); + } /* graph watermark */ if (im->watermark[0] != '\0') { gfx_text(im, @@ -2741,24 +2822,24 @@ int graph_size_location( return 0; } - /** +---+--------------------------------------------+ - ** | y |...............graph title..................| - ** | +---+-------------------------------+--------+ - ** | a | y | | | - ** | x | | | | - ** | i | a | | pie | - ** | s | x | main graph area | chart | - ** | | i | | area | - ** | t | s | | | - ** | i | | | | - ** | t | l | | | - ** | l | b +-------------------------------+--------+ - ** | e | l | x axis labels | | - ** +---+---+-------------------------------+--------+ - ** |....................legends.....................| - ** +------------------------------------------------+ - ** | watermark | - ** +------------------------------------------------+ + /** +---+-----------------------------------+ + ** | y |...............graph title.........| + ** | +---+-------------------------------+ + ** | a | y | | + ** | x | | | + ** | i | a | | + ** | s | x | main graph area | + ** | | i | | + ** | t | s | | + ** | i | | | + ** | t | l | | + ** | l | b +-------------------------------+ + ** | e | l | x axis labels | + ** +---+---+-------------------------------+ + ** |....................legends............| + ** +---------------------------------------+ + ** | watermark | + ** +---------------------------------------+ */ if (im->ylegend[0] != '\0') { @@ -2792,7 +2873,7 @@ int graph_size_location( if (im->extra_flags & FULL_SIZE_MODE) { /* The actual size of the image to draw has been determined by the user. ** The graph area is the space remaining after accounting for the legend, - ** the watermark, the pie chart, the axis labels, and the title. + ** the watermark, the axis labels, and the title. */ im->xorigin = 0; im->ximg = im->xsize; @@ -2800,36 +2881,45 @@ int graph_size_location( im->yorigin = im->ysize; Xmain = im->ximg; Ymain = im->yimg; - im->yorigin += Ytitle; /* Now calculate the total size. Insert some spacing where desired. im->xorigin and im->yorigin need to correspond with the lower left corner of the main graph area or, if this one is not set, the imaginary box surrounding the pie chart area. */ /* Initial size calculation for the main graph area */ - Xmain = im->ximg - (Xylabel + 2 * Xspacing); - if (Xmain) - Xmain -= Xspacing; /* put space between main graph area and right edge */ + Xmain = im->ximg - Xylabel - 3 * Xspacing; + im->xorigin = Xspacing + Xylabel; - /* the length of the title should not influence with width of the graph - if (Xtitle > im->ximg) im->ximg = Xtitle; */ + if (Xvertical) { /* unit description */ Xmain -= Xvertical; im->xorigin += Xvertical; } + + /* adjust space for second axis */ + if (im->second_axis_scale != 0){ + Xmain -= Xylabel + Xspacing; + } + if (im->extra_flags & NO_RRDTOOL_TAG){ + Xmain += Xspacing; + } + if (im->second_axis_legend[0] != '\0' ) { + Xmain -= im->text_prop[TEXT_PROP_UNIT].size * 1.5; + } + im->xsize = Xmain; + xtr(im, 0); /* The vertical size of the image is known in advance. The main graph area ** (Ymain) and im->yorigin must be set according to the space requirements ** of the legend and the axis labels. */ if (im->extra_flags & NOLEGEND) { - /* set dimensions correctly if using full size mode with no legend */ - im->yorigin = - im->yimg - + im->yorigin = im->yimg - im->text_prop[TEXT_PROP_AXIS].size * 2.5 - Yspacing; Ymain = im->yorigin; - } else { + } + else { /* Determine where to place the legends onto the image. ** Set Ymain and adjust im->yorigin to match the space requirements. */ @@ -2871,8 +2961,7 @@ int graph_size_location( */ /* 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->text_prop[TEXT_PROP_TITLE].font_desc, im->tabwidth, im->title, 0) + 2*Xspacing; */ Ytitle = im->text_prop[TEXT_PROP_TITLE].size * 2.6 + 10; @@ -2894,6 +2983,14 @@ int graph_size_location( ** size already allocated. */ im->ximg = Xylabel + Xmain + 2 * Xspacing; + + if (im->second_axis_scale != 0){ + im->ximg += Xylabel + Xspacing; + } + if (im->extra_flags & NO_RRDTOOL_TAG){ + im->ximg -= Xspacing; + } + if (Xmain) im->ximg += Xspacing; im->xorigin = Xspacing + Xylabel; @@ -2903,6 +3000,10 @@ int graph_size_location( im->ximg += Xvertical; im->xorigin += Xvertical; } + if (im->second_axis_legend[0] != '\0' ) { + im->ximg += Xvertical; + } + xtr(im, 0); /* The vertical size is interesting... we need to compare ** the sum of {Ytitle, Ymain, Yxlabel, Ylegend, Ywatermark} with @@ -2946,10 +3047,10 @@ static cairo_status_t cairo_output( *data, unsigned int length) { - image_desc_t *im = closure; + image_desc_t *im = (image_desc_t*)closure; im->rendered_image = - realloc(im->rendered_image, im->rendered_image_size + length); + (unsigned char*)realloc(im->rendered_image, im->rendered_image_size + length); if (im->rendered_image == NULL) return CAIRO_STATUS_WRITE_ERROR; memcpy(im->rendered_image + im->rendered_image_size, data, length); @@ -3568,13 +3669,13 @@ int rrd_graph( if (strcmp(walker->key, "image_info") == 0) { prlines++; if (((*prdata) = - rrd_realloc((*prdata), + (char**)rrd_realloc((*prdata), (prlines + 1) * sizeof(char *))) == NULL) { rrd_set_error("realloc prdata"); return 0; } /* imginfo goes to position 0 in the prdata array */ - (*prdata)[prlines - 1] = malloc((strlen(walker->value.u_str) + (*prdata)[prlines - 1] = (char*)malloc((strlen(walker->value.u_str) + 2) * sizeof(char)); strcpy((*prdata)[prlines - 1], walker->value.u_str); (*prdata)[prlines] = NULL; @@ -3599,12 +3700,12 @@ int rrd_graph( } else if (strncmp(walker->key, "print", 5) == 0) { /* keys are prdate[0..] */ prlines++; if (((*prdata) = - rrd_realloc((*prdata), + (char**)rrd_realloc((*prdata), (prlines + 1) * sizeof(char *))) == NULL) { rrd_set_error("realloc prdata"); return 0; } - (*prdata)[prlines - 1] = malloc((strlen(walker->value.u_str) + (*prdata)[prlines - 1] = (char*)malloc((strlen(walker->value.u_str) + 2) * sizeof(char)); (*prdata)[prlines] = NULL; strcpy((*prdata)[prlines - 1], walker->value.u_str); @@ -3685,14 +3786,11 @@ rrd_info_t *rrd_graph_v( if (im.imginfo) { rrd_infoval_t info; + char *path; char *filename; - filename = im.graphfile + strlen(im.graphfile); - while (filename > im.graphfile) { - if (*(filename - 1) == '/' || *(filename - 1) == '\\') - break; - filename--; - } + path = strdup(im.graphfile); + filename = basename(path); info.u_str = sprintf_alloc(im.imginfo, filename, @@ -3700,6 +3798,7 @@ rrd_info_t *rrd_graph_v( im.ximg), (long) (im.zoom * im.yimg)); grinfo_push(&im, sprintf_alloc("image_info"), RD_I_STR, info); free(info.u_str); + free(path); } if (im.rendered_image) { rrd_infoval_t img; @@ -3748,6 +3847,7 @@ void rrd_graph_init( #endif #endif im->base = 1000; + im->daemon_addr = NULL; im->draw_x_grid = 1; im->draw_y_grid = 1; im->extra_flags = 0; @@ -3763,7 +3863,6 @@ void rrd_graph_init( im->grinfo_current = (rrd_info_t *) NULL; im->imgformat = IF_PNG; im->imginfo = NULL; - im->use_rrdcached = 0; im->lazy = 0; im->logarithmic = 0; im->maxval = DNAN; @@ -3790,6 +3889,10 @@ void rrd_graph_init( im->ygridstep = DNAN; im->yimg = 0; im->ylegend[0] = '\0'; + im->second_axis_scale = 0; /* 0 disables it */ + im->second_axis_shift = 0; /* no shift by default */ + im->second_axis_legend[0] = '\0'; + im->second_axis_format[0] = '\0'; im->yorigin = 0; im->ysize = 100; im->zoom = 1; @@ -3878,6 +3981,10 @@ void rrd_graph_options( { "force-rules-legend", no_argument, 0, 'F'}, { "only-graph", no_argument, 0, 'j'}, { "alt-y-grid", no_argument, 0, 'Y'}, + {"disable-rrdtool-tag", no_argument, 0, 1001}, + {"right-axis", required_argument, 0, 1002}, + {"right-axis-label", required_argument, 0, 1003}, + {"right-axis-format", required_argument, 0, 1004}, { "no-minor", no_argument, 0, 'I'}, { "slope-mode", no_argument, 0, 'E'}, { "alt-autoscale", no_argument, 0, 'A'}, @@ -3939,6 +4046,9 @@ void rrd_graph_options( case 'F': im->extra_flags |= FORCE_RULES_LEGEND; break; + case 1001: + im->extra_flags |= NO_RRDTOOL_TAG; + break; case LONGOPT_UNITS_SI: if (im->extra_flags & FORCE_UNITS) { rrd_set_error("--units can only be used once!"); @@ -4047,6 +4157,33 @@ void rrd_graph_options( return; } break; + case 1002: /* right y axis */ + + if(sscanf(optarg, + "%lf:%lf", + &im->second_axis_scale, + &im->second_axis_shift) == 2) { + if(im->second_axis_scale==0){ + rrd_set_error("the second_axis_scale must not be 0"); + return; + } + } else { + rrd_set_error("invalid right-axis format expected scale:shift"); + return; + } + break; + case 1003: + strncpy(im->second_axis_legend,optarg,150); + im->second_axis_legend[150]='\0'; + break; + case 1004: + if (bad_format(optarg)){ + rrd_set_error("use either %le or %lf formats"); + return; + } + strncpy(im->second_axis_format,optarg,150); + im->second_axis_format[150]='\0'; + break; case 'v': strncpy(im->ylegend, optarg, 150); im->ylegend[150] = '\0'; @@ -4175,7 +4312,7 @@ void rrd_graph_options( if (size > 0) { rrd_set_font_desc(im,propidx,NULL,size); } - if ((int) strlen(optarg) > end) { + if ((int) strlen(optarg) > end+2) { if (optarg[end] == ':') { rrd_set_font_desc(im,propidx,optarg + end + 1,0); } else { @@ -4254,21 +4391,20 @@ void rrd_graph_options( break; case 'd': { - int status; - if (im->use_rrdcached) + if (im->daemon_addr != NULL) { rrd_set_error ("You cannot specify --daemon " "more than once."); return; } - status = rrdc_connect (optarg); - if (status != 0) + + im->daemon_addr = strdup(optarg); + if (im->daemon_addr == NULL) { - rrd_set_error ("rrdc_connect(%s) failed with status %i.", - optarg, status); - return; + rrd_set_error("strdup failed"); + return; } - im->use_rrdcached = 1; + break; } case '?': @@ -4280,24 +4416,9 @@ void rrd_graph_options( } } /* while (1) */ - if (im->use_rrdcached == 0) - { - char *temp; - - temp = getenv (ENV_RRDCACHED_ADDRESS); - if (temp != NULL) - { - int status; - - status = rrdc_connect (temp); - if (status != 0) - { - rrd_set_error ("rrdc_connect(%s) failed with status %i.", - temp, status); - return; - } - im->use_rrdcached = 1; - } + { /* try to connect to rrdcached */ + int status = rrdc_connect(im->daemon_addr); + if (status != 0) return; } pango_cairo_context_set_font_options(pango_layout_get_context(im->layout), im->font_options); @@ -4542,27 +4663,22 @@ int vdef_calc( graph_desc_t *src, *dst; rrd_value_t *data; long step, steps; - unsigned long end; dst = &im->gdes[gdi]; src = &im->gdes[dst->vidx]; data = src->data + src->ds; - end = - src->end_orig % (long) src->step == - 0 ? src->end_orig : (src->end_orig + (long) src->step - - src->end_orig % (long) src->step); - steps = (end - src->start) / src->step; + steps = (src->end - src->start) / src->step; #if 0 printf ("DEBUG: start == %lu, end == %lu, %lu steps\n", - src->start, src->end_orig, steps); + src->start, src->end, steps); #endif switch (dst->vf.op) { case VDEF_PERCENT:{ rrd_value_t *array; int field; - if ((array = malloc(steps * sizeof(double))) == NULL) { + if ((array = (rrd_value_t*)malloc(steps * sizeof(double))) == NULL) { rrd_set_error("malloc VDEV_PERCENT"); return -1; }