Hello, I thought it would be nice if there was a graph style similar to AREA but fills area between value1 and value2 instead of value1 and zero.
I just call it RANGE and hacked a bit, and got a result like http://rodem.ingrid.org:8080/shimizu/waseda2.png The usage is like this. ./rrdtool graph waseda2.png --title="Waseda" DEF:val1=waseda-s.rrd:util:MAX DEF:val2=waseda-s.rrd:util:MIN RANGE:val1,val2#00EE00:MAX_MIN I don't know the name RANGE is good or not, but attach my patch here anyway. This may be slow (not evaluated yet though) because I did not use gfx_add_point but used gfx_new_node for every region. This patch is applied for cvs-snap on Nov 4th, but I think it's OK for the latest. Thanks a lot, Susumu -------------------------------------------------------------------- diff --recursive --unified rrdtool-2003-11-04/src/rrd_gfx.c rrdtool-2003-11-04-range/src/rrd_gfx.c --- rrdtool-2003-11-04/src/rrd_gfx.c Mon Oct 27 04:29:56 2003 +++ rrdtool-2003-11-04-range/src/rrd_gfx.c Thu Nov 6 11:37:00 2003 @@ -153,6 +154,37 @@ return node; } +/* create a new range */ +gfx_node_t *gfx_new_range (gfx_canvas_t *canvas, + double X0, double Y0, + double X1, double Y1, + double X2, double Y2, + double X3, double Y3, + gfx_color_t color) { + + gfx_node_t *node; + ArtVpath *vec; + + node = gfx_new_node(canvas,GFX_RANGE); + if (node == NULL) return NULL; + vec = art_new(ArtVpath, 6); + if (vec == NULL) return NULL; + vec[0].code = ART_MOVETO; vec[0].x=X0; vec[0].y=Y0; + vec[1].code = ART_LINETO; vec[1].x=X1; vec[1].y=Y1; + vec[2].code = ART_LINETO; vec[2].x=X2; vec[2].y=Y2; + vec[3].code = ART_LINETO; vec[3].x=X3; vec[3].y=Y3; + vec[4].code = ART_LINETO; vec[4].x=X0; vec[4].y=Y0; + vec[5].code = ART_END; + + node->points = 6; + node->points_max = 6; + node->color = color; + node->path = vec; + + return node; +} + + /* add a point to a line or to an area */ int gfx_add_point (gfx_node_t *node, double x, double y){ @@ -496,6 +528,7 @@ while(node){ switch (node->type) { case GFX_LINE: + case GFX_RANGE: case GFX_AREA: { ArtVpath *vec; double dst[6]; @@ -1181,6 +1214,7 @@ case GFX_LINE: svg_multi_path(fp, &node); break; + case GFX_RANGE: case GFX_AREA: svg_area(fp, node); break; @@ -1516,6 +1550,7 @@ for (node = state->canvas->firstnode; node; node = node->next) { switch (node->type) { case GFX_LINE: + case GFX_RANGE: case GFX_AREA: eps_write_linearea(state, node); break; @@ -1822,7 +1857,7 @@ ArtVpath *vec = node->path + i; double x = vec->x; double y = state->page_height - vec->y; - if (node->type == GFX_AREA) { + if ((node->type == GFX_AREA)||(node->type == GFX_RANGE)) { x += LINEOFFSET; /* adjust for libart handling of areas */ y -= LINEOFFSET; } @@ -1956,6 +1991,7 @@ for (node = state->canvas->firstnode; node; node = node->next) { switch (node->type) { case GFX_LINE: + case GFX_RANGE: case GFX_AREA: pdf_write_linearea(state, node); break; diff --recursive --unified rrdtool-2003-11-04/src/rrd_gfx.h rrdtool-2003-11-04-range/src/rrd_gfx.h --- rrdtool-2003-11-04/src/rrd_gfx.h Mon Oct 27 04:29:56 2003 +++ rrdtool-2003-11-04-range/src/rrd_gfx.h Wed Nov 5 14:26:08 2003 @@ -10,7 +10,7 @@ #include <libart.h> enum gfx_if_en {IF_PNG=0,IF_SVG,IF_EPS,IF_PDF}; -enum gfx_en { GFX_LINE=0,GFX_AREA,GFX_TEXT }; +enum gfx_en { GFX_LINE=0,GFX_AREA,GFX_RANGE,GFX_TEXT }; enum gfx_h_align_en { GFX_H_NULL=0, GFX_H_LEFT, GFX_H_RIGHT, GFX_H_CENTER }; enum gfx_v_align_en { GFX_V_NULL=0, GFX_V_TOP, GFX_V_BOTTOM, GFX_V_CENTER }; typedef unsigned long gfx_color_t; diff --recursive --unified rrdtool-2003-11-04/src/rrd_graph.c rrdtool-2003-11-04-range/src/rrd_graph.c --- rrdtool-2003-11-04/src/rrd_graph.c Mon Oct 27 04:29:56 2003 +++ rrdtool-2003-11-04-range/src/rrd_graph.c Thu Nov 6 11:36:30 2003 @@ -136,7 +136,8 @@ ytr(image_desc_t *im, double value){ static double pixie; double yval; - if (isnan(value)){ + + if ((isnan(value))||(pixie == 0.0)){ if(!im->logarithmic) pixie = (double) im->ysize / (im->maxval - im->minval); else @@ -181,6 +182,7 @@ conv_if(VRULE,GF_VRULE) conv_if(LINE,GF_LINE) conv_if(AREA,GF_AREA) + conv_if(RANGE,GF_RANGE) conv_if(STACK,GF_STACK) conv_if(TICK,GF_TICK) conv_if(DEF,GF_DEF) @@ -985,6 +987,7 @@ 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_RANGE) || (im->gdes[i].gf==GF_TICK) || (im->gdes[i].gf==GF_STACK)) { if((im->gdes[i].p_data = malloc((im->xsize +1) @@ -1005,6 +1008,7 @@ switch (im->gdes[ii].gf) { case GF_LINE: case GF_AREA: + case GF_RANGE: case GF_TICK: if (!im->gdes[ii].stack) paintval = 0.0; @@ -1316,6 +1320,7 @@ break; case GF_LINE: case GF_AREA: + case GF_RANGE: case GF_TICK: case GF_STACK: case GF_HRULE: @@ -2327,6 +2332,7 @@ break; case GF_LINE: case GF_AREA: + case GF_RANGE: stack_gf = im->gdes[i].gf; case GF_STACK: /* fix data points at oo and -oo */ @@ -2360,7 +2366,20 @@ } else { node = NULL; } - } + } /* end for ii */ + } else if (im->gdes[i].gf == GF_RANGE) { /* GF_RANGE */ + for(ii=1;ii<im->xsize;ii++){ + if ( ! isnan(im->gdes[i].p_data[ii-1]) + && ! isnan(im->gdes[i+1].p_data[ii-1])){ + node = gfx_new_range(im->canvas, + (double)ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii-1]), + (double)ii-1+im->xorigin,ytr(im,im->gdes[i+1].p_data[ii-1]), + (double)ii+im->xorigin,ytr(im,im->gdes[i+1].p_data[ii]), + (double)ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]), + im->gdes[i].col); + } + } /* end for */ + i++; /* consumed two gdes for RANGE */ } else { int area_start=-1; node = NULL; @@ -2409,7 +2428,7 @@ node=NULL; }; } - } /* else GF_LINE */ + } /* else GF_LINE-GF_RANGE */ } /* if color != 0x0 */ /* make sure we do not run into trouble when stacking on NaN */ for(ii=0;ii<im->xsize;ii++){ diff --recursive --unified rrdtool-2003-11-04/src/rrd_graph.h rrdtool-2003-11-04-range/src/rrd_graph.h --- rrdtool-2003-11-04/src/rrd_graph.h Thu Jul 24 23:51:46 2003 +++ rrdtool-2003-11-04-range/src/rrd_graph.h Wed Nov 5 11:19:36 2003 @@ -25,7 +25,7 @@ #define GRIDWIDTH 0.4 enum gf_en {GF_PRINT=0,GF_GPRINT,GF_COMMENT,GF_HRULE,GF_VRULE,GF_LINE, - GF_AREA,GF_STACK,GF_TICK, + GF_AREA,GF_RANGE, GF_STACK,GF_TICK, GF_DEF, GF_CDEF, GF_VDEF, GF_PART, GF_XPORT}; diff --recursive --unified rrdtool-2003-11-04/src/rrd_graph_helper.c rrdtool-2003-11-04-range/src/rrd_graph_helper.c --- rrdtool-2003-11-04/src/rrd_graph_helper.c Thu Feb 13 16:05:27 2003 +++ rrdtool-2003-11-04-range/src/rrd_graph_helper.c Wed Nov 5 18:58:11 2003 @@ -189,11 +189,32 @@ if (j) dprintf("- found number: %f\n",gdp->yrule); } if (!j) { + if (gdp->gf == GF_RANGE) { + char varname[30]; + char varname2[30]; + sscanf(tmpstr,"%29[^,],%29[^:#]%n",varname,varname2,&j); + if ((gdp->vidx=find_var(im,varname))<0) { + rrd_set_error("Not a valid vname: %s in line %s",varname,line); + return 1; + } + dprintf("- found vname1: '%s' vidx %li\n",varname, gdp->vidx); + gdes_alloc(im); + im->gdes[im->gdes_c-1].gf = GF_RANGE; + if ((im->gdes[im->gdes_c-1].vidx=find_var(im,varname2))<0) { + im_free(im); + rrd_set_error("Not a valid vname: %s in line %s",varname2,line); + return 1; + } + dprintf("- found vname2: '%s' vidx %li\n",varname2, im->gdes[im->gdes_c-1].vidx); + + } + else { if ((gdp->vidx=find_var(im,tmpstr))<0) { rrd_set_error("Not a valid vname: %s in line %s",tmpstr,line); return 1; } dprintf("- found vname: '%s' vidx %li\n",tmpstr,gdp->vidx); + } } /* "*eaten" is still pointing to the original location, ** "*eaten +i" is pointing to the character after the color @@ -476,6 +497,7 @@ case GF_HRULE: /* value#color[:legend] */ case GF_LINE: /* vname-or-value[#color[:legend]][:STACK] */ case GF_AREA: /* vname-or-value[#color[:legend]][:STACK] */ + case GF_RANGE: /* vname1,vname2[#color[:legend]][:STACK] */ case GF_STACK: /* vname-or-value[#color[:legend]] */ case GF_TICK: /* vname#color[:num[:legend]] */ if (rrd_parse_PVHLAST(argv[i],&eaten,gdp,im)) return; ------------------------------------------------------------------------ Shimizu, Susumu # +-----+ Waseda Univ., Tokyo [EMAIL PROTECTED],*| [EMAIL PROTECTED] +-----+ -- Unsubscribe mailto:[EMAIL PROTECTED] Help mailto:[EMAIL PROTECTED] Archive http://www.ee.ethz.ch/~slist/rrd-developers WebAdmin http://www.ee.ethz.ch/~slist/lsg2.cgi
