X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_graph.c;h=3ce39598c8b5d28e7d54ce3f87f4fc9e30d4916f;hb=13b2b80a81d0fb22fc19ea95960b6ce71b8558b5;hp=a06417e3aecccae9c03df913dea3ea27eca29f1b;hpb=5a3f89cd664c1c7ccf9cbffe3422e42e87bff7c3;p=rrdtool.git diff --git a/src/rrd_graph.c b/src/rrd_graph.c index a06417e..3ce3959 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -1,5 +1,5 @@ /**************************************************************************** - * RRDtool 1.2.10 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 ****************************************************************************/ @@ -2242,13 +2242,12 @@ graph_size_location(image_desc_t *im, int elements /* reserve space for main and/or pie */ im->yimg = Ymain + Yxlabel; - + #ifdef WITH_PIECHART if (im->yimg < Ypie) im->yimg = Ypie; #endif im->yorigin = im->yimg - Yxlabel; - ytr(im,DNAN); /* reserve space for the title *or* some padding above the graph */ if (Ytitle) { @@ -2260,7 +2259,7 @@ graph_size_location(image_desc_t *im, int elements } /* reserve space for padding below the graph */ im->yimg += Yspacing; - + /* Determine where to place the legends onto the image. ** Adjust im->yimg to match the space requirements. */ @@ -2289,6 +2288,7 @@ graph_size_location(image_desc_t *im, int elements } #endif + ytr(im,DNAN); return 0; } @@ -2472,31 +2472,35 @@ graph_paint(image_desc_t *im, char ***calcpr) if (im->gdes[i].col != 0x0){ /* GF_LINE and friend */ if(stack_gf == GF_LINE ){ + double last_y=0; node = NULL; - for(ii=1;iixsize;ii++){ + for(ii=1;iixsize;ii++){ 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 ){ 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]), + ii-1+im->xorigin,last_y, + ii+im->xorigin,last_y, im->gdes[i].linewidth, im->gdes[i].col); } else { node = gfx_new_line(im->canvas, ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii-1]), - ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]), + ii+im->xorigin,last_y, im->gdes[i].linewidth, im->gdes[i].col); } } else { - if ( im->slopemode==0 ){ - gfx_add_point(node,ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii])); + double new_y = ytr(im,im->gdes[i].p_data[ii]); + if ( im->slopemode==0 && new_y != last_y){ + gfx_add_point(node,ii-1+im->xorigin,new_y); + last_y = new_y; }; - gfx_add_point(node,ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii])); + gfx_add_point(node,ii+im->xorigin,new_y); }; } @@ -3182,7 +3186,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im) case 'n':{ char prop[15]; double size = 1; - char font[1024]; + char font[1024] = ""; if(sscanf(optarg, "%10[A-Z]:%lf:%1000s", @@ -3402,6 +3406,9 @@ char *str; 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 @@ -3437,6 +3444,9 @@ char *str; 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; @@ -3595,6 +3605,48 @@ printf("DEBUG: %3li:%10.2f %c\n",step,array[step],step==field?'*':' '); 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;stepds_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 = cnt*src->step; + } else if (dst->vf.op == VDEF_LSLINT) { + dst->vf.val = y_intercept; + dst->vf.when = cnt*src->step; + } else if (dst->vf.op == VDEF_LSLCORREL) { + dst->vf.val = correl; + dst->vf.when = cnt*src->step; + }; + + } else { + dst->vf.val = DNAN; + dst->vf.when = 0; + } + } + break; } return 0; }