X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_graph.c;h=bfce36f1477f872044b567e2c168c06b65a1bd05;hb=3a4825306f808c36fb2c529f27c5457a0715dfaf;hp=c7ba63e62d9493c214a2a06fdb93216ad8a50127;hpb=b7ba62419191213693d0b47c441d65d3ef88a685;p=rrdtool.git diff --git a/src/rrd_graph.c b/src/rrd_graph.c index c7ba63e..bfce36f 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -12,6 +12,7 @@ #ifdef WIN32 #include #include +#define RRD_DEFAULT_FONT "c:/winnt/fonts/COUR.TTF" #endif #include "rrd_graph.h" @@ -179,10 +180,10 @@ enum gf_en gf_conv(char *string){ return (-1); } -enum if_en if_conv(char *string){ +enum gfx_if_en if_conv(char *string){ - conv_if(GIF,IF_GIF) conv_if(PNG,IF_PNG) + conv_if(SVG,IF_SVG) return (-1); } @@ -248,6 +249,7 @@ im_free(image_desc_t *im) free (im->gdes[i].rpnp); } free(im->gdes); + gfx_destroy(im->canvas); return 0; } @@ -816,6 +818,17 @@ printf("DEBUG: value from vdef is %f\n",im->gdes[ptr].vf.val); } /* if OP_VARIABLE */ } /* loop through all rpi */ + /* move the data pointers to the correct period */ + for(rpi=0;im->gdes[gdi].rpnp[rpi].op != OP_END;rpi++){ + if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE){ + long ptr = im->gdes[gdi].rpnp[rpi].ptr; + if(im->gdes[gdi].start > im->gdes[ptr].start) { + im->gdes[gdi].rpnp[rpi].data += im->gdes[gdi].rpnp[rpi].ds_cnt; + } + } + } + + if(steparray == NULL){ rrd_set_error("rpn expressions without DEF" " or CDEF variables are not supported"); @@ -1211,7 +1224,6 @@ print_calc(image_desc_t *im, char ***prdata) case GF_LINE: case GF_AREA: case GF_TICK: - case GF_PART: case GF_STACK: case GF_HRULE: case GF_VRULE: @@ -1220,6 +1232,7 @@ print_calc(image_desc_t *im, char ***prdata) case GF_DEF: case GF_CDEF: case GF_VDEF: + case GF_PART: break; } } @@ -1270,7 +1283,7 @@ leg_place(image_desc_t *im) leg_cc--; im->gdes[i].legend[leg_cc]='\0'; } - if (leg_cc != 0 ){ + if (leg_cc != 0 ){ legspace[i]=(prt_fctn=='g' ? 0 : interleg); if (fill > 0){ @@ -1281,7 +1294,8 @@ leg_place(image_desc_t *im) im->gdes[i].gf != GF_COMMENT) { fill += box; } - fill += gfx_get_text_width(fill+border,im->text_prop[TEXT_PROP_LEGEND].font, + fill += gfx_get_text_width(im->canvas, fill+border, + im->text_prop[TEXT_PROP_LEGEND].font, im->text_prop[TEXT_PROP_LEGEND].size, im->tabwidth, im->gdes[i].legend); @@ -1328,7 +1342,8 @@ leg_place(image_desc_t *im) im->gdes[ii].leg_x = leg_x; im->gdes[ii].leg_y = leg_y; leg_x += - gfx_get_text_width(leg_x,im->text_prop[TEXT_PROP_LEGEND].font, + gfx_get_text_width(im->canvas, leg_x, + im->text_prop[TEXT_PROP_LEGEND].font, im->text_prop[TEXT_PROP_LEGEND].size, im->tabwidth, im->gdes[ii].legend) @@ -1345,7 +1360,7 @@ leg_place(image_desc_t *im) mark = ii; } } - im->ygif = leg_y+6; + im->ygif = leg_y; free(legspace); } return 0; @@ -1360,7 +1375,7 @@ leg_place(image_desc_t *im) int -horizontal_grid(gfx_canvas_t *canvas, image_desc_t *im) +horizontal_grid(image_desc_t *im) { double range; double scaledrange; @@ -1369,7 +1384,7 @@ horizontal_grid(gfx_canvas_t *canvas, image_desc_t *im) double gridstep; double scaledstep; char graph_label[100]; - double x0,x1,y0,y1; + double x0,x1,y0; int labfact,gridind; int decimals, fractionals; char labfmt[64]; @@ -1470,20 +1485,20 @@ horizontal_grid(gfx_canvas_t *canvas, image_desc_t *im) } } - gfx_new_text ( canvas, + gfx_new_text ( im->canvas, x0-im->text_prop[TEXT_PROP_AXIS].size/1.5, y0, im->graph_col[GRC_FONT], im->text_prop[TEXT_PROP_AXIS].font, im->text_prop[TEXT_PROP_AXIS].size, im->tabwidth, 0.0, GFX_H_RIGHT, GFX_V_CENTER, graph_label ); - gfx_new_line ( canvas, + gfx_new_line ( im->canvas, x0-2,y0, x1+2,y0, MGRIDWIDTH, im->graph_col[GRC_MGRID] ); } else { - gfx_new_line ( canvas, + gfx_new_line ( im->canvas, x0-1,y0, x1+1,y0, GRIDWIDTH, im->graph_col[GRC_GRID] ); @@ -1496,13 +1511,13 @@ horizontal_grid(gfx_canvas_t *canvas, image_desc_t *im) /* logaritmic horizontal grid */ int -horizontal_log_grid(gfx_canvas_t *canvas, image_desc_t *im) +horizontal_log_grid(image_desc_t *im) { double pixpex; int ii,i; int minoridx=0, majoridx=0; char graph_label[100]; - double x0,x1,y0,y1; + double x0,x1,y0; double value, pixperstep, minstep; /* find grid spaceing */ @@ -1537,7 +1552,7 @@ horizontal_log_grid(gfx_canvas_t *canvas, image_desc_t *im) while(yloglab[minoridx][++i] > 0){ y0 = ytr(im,value * yloglab[minoridx][i]); if (y0 <= im->yorigin - im->ysize) break; - gfx_new_line ( canvas, + gfx_new_line ( im->canvas, x0-1,y0, x1+1,y0, GRIDWIDTH, im->graph_col[GRC_GRID] ); @@ -1554,13 +1569,13 @@ horizontal_log_grid(gfx_canvas_t *canvas, image_desc_t *im) while(yloglab[majoridx][++i] > 0){ y0 = ytr(im,value * yloglab[majoridx][i]); if (y0 <= im->yorigin - im->ysize) break; - gfx_new_line ( canvas, + gfx_new_line ( im->canvas, x0-2,y0, x1+2,y0, MGRIDWIDTH, im->graph_col[GRC_MGRID] ); sprintf(graph_label,"%3.0e",value * yloglab[majoridx][i]); - gfx_new_text ( canvas, + gfx_new_text ( im->canvas, x0-im->text_prop[TEXT_PROP_AXIS].size/1.5, y0, im->graph_col[GRC_FONT], im->text_prop[TEXT_PROP_AXIS].font, @@ -1575,7 +1590,6 @@ horizontal_log_grid(gfx_canvas_t *canvas, image_desc_t *im) void vertical_grid( - gfx_canvas_t *canvas, image_desc_t *im ) { int xlab_sel; /* which sort of label and grid ? */ @@ -1619,7 +1633,7 @@ vertical_grid( /* are we inside the graph ? */ if (ti < im->start || ti > im->end) continue; x0 = xtr(im,ti); - gfx_new_line(canvas,x0,y0+1, x0,y1-1,GRIDWIDTH, im->graph_col[GRC_GRID]); + gfx_new_line(im->canvas,x0,y0+1, x0,y1-1,GRIDWIDTH, im->graph_col[GRC_GRID]); } @@ -1633,7 +1647,7 @@ vertical_grid( /* are we inside the graph ? */ if (ti < im->start || ti > im->end) continue; x0 = xtr(im,ti); - gfx_new_line(canvas,x0,y0+2, x0,y1-2,MGRIDWIDTH, im->graph_col[GRC_MGRID]); + gfx_new_line(im->canvas,x0,y0+2, x0,y1-2,MGRIDWIDTH, im->graph_col[GRC_MGRID]); } /* paint the labels below the graph */ @@ -1644,13 +1658,15 @@ vertical_grid( ti = find_next_time(ti,im->xlab_user.labtm,im->xlab_user.labst) ){ tilab= ti + im->xlab_user.precis/2; /* correct time for the label */ + /* are we inside the graph ? */ + if (ti < im->start || ti > im->end) continue; #if HAVE_STRFTIME strftime(graph_label,99,im->xlab_user.stst,localtime(&tilab)); #else # error "your libc has no strftime I guess we'll abort the exercise here." #endif - gfx_new_text ( canvas, + gfx_new_text ( im->canvas, xtr(im,tilab), y0+im->text_prop[TEXT_PROP_AXIS].size/1.5, im->graph_col[GRC_FONT], im->text_prop[TEXT_PROP_AXIS].font, @@ -1665,33 +1681,32 @@ vertical_grid( void axis_paint( - image_desc_t *im, - gfx_canvas_t *canvas + image_desc_t *im ) { /* draw x and y axis */ - gfx_new_line ( canvas, im->xorigin+im->xsize,im->yorigin, + gfx_new_line ( im->canvas, im->xorigin+im->xsize,im->yorigin, im->xorigin+im->xsize,im->yorigin-im->ysize, GRIDWIDTH, im->graph_col[GRC_GRID]); - gfx_new_line ( canvas, im->xorigin,im->yorigin-im->ysize, + gfx_new_line ( im->canvas, im->xorigin,im->yorigin-im->ysize, im->xorigin+im->xsize,im->yorigin-im->ysize, GRIDWIDTH, im->graph_col[GRC_GRID]); - gfx_new_line ( canvas, im->xorigin-4,im->yorigin, + gfx_new_line ( im->canvas, im->xorigin-4,im->yorigin, im->xorigin+im->xsize+4,im->yorigin, MGRIDWIDTH, im->graph_col[GRC_GRID]); - gfx_new_line ( canvas, im->xorigin,im->yorigin+4, + gfx_new_line ( im->canvas, im->xorigin,im->yorigin+4, im->xorigin,im->yorigin-im->ysize-4, MGRIDWIDTH, im->graph_col[GRC_GRID]); /* arrow for X axis direction */ - gfx_new_area ( canvas, - im->xorigin+im->xsize+4, im->yorigin-3, - im->xorigin+im->xsize+4, im->yorigin+3, - im->xorigin+im->xsize+9, im->yorigin, + 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->graph_col[GRC_ARROW]); @@ -1699,47 +1714,46 @@ axis_paint( } void -grid_paint( - image_desc_t *im, - gfx_canvas_t *canvas - - ) +grid_paint(image_desc_t *im) { long i; - int boxH=8, boxV=8; int res=0; - double x0,x1,x2,x3,y0,y1,y2,y3; /* points for filled graph and more*/ + double x0,y0; /* points for filled graph and more*/ gfx_node_t *node; - /* draw 3d border */ - node = gfx_new_area (canvas, 0,im->ygif, 0,0, im->xgif, 0,im->graph_col[GRC_SHADEA]); + node = gfx_new_area (im->canvas, 0,im->ygif, + 2,im->ygif-2, + 2,2,im->graph_col[GRC_SHADEA]); gfx_add_point( node , im->xgif - 2, 2 ); - gfx_add_point( node , 2,2 ); - gfx_add_point( node , 2,im->ygif-2 ); - gfx_add_point( node , 0,im->ygif ); + gfx_add_point( node , im->xgif, 0 ); + gfx_add_point( node , 0,0 ); +/* gfx_add_point( node , 0,im->ygif ); */ - node = gfx_new_area (canvas, 0,im->ygif, im->xgif,im->ygif, im->xgif,0,im->graph_col[GRC_SHADEB]); - gfx_add_point( node , im->xgif - 2, 2 ); - gfx_add_point( node , im->xgif-2,im->ygif-2 ); - gfx_add_point( node , 2,im->ygif-2 ); - gfx_add_point( node , 0,im->ygif ); + node = gfx_new_area (im->canvas, 2,im->ygif-2, + im->xgif-2,im->ygif-2, + im->xgif - 2, 2, + im->graph_col[GRC_SHADEB]); + gfx_add_point( node , im->xgif,0); + gfx_add_point( node , im->xgif,im->ygif); + gfx_add_point( node , 0,im->ygif); +/* gfx_add_point( node , 0,im->ygif ); */ if (im->draw_x_grid == 1 ) - vertical_grid(canvas, im); + vertical_grid(im); if (im->draw_y_grid == 1){ if(im->logarithmic){ - res = horizontal_log_grid(canvas,im); + res = horizontal_log_grid(im); } else { - res = horizontal_grid(canvas,im); + res = horizontal_grid(im); } /* dont draw horizontal grid if there is no min and max val */ if (! res ) { char *nodata = "No Data found"; - gfx_new_text(canvas,im->xgif/2, (2*im->yorigin-im->ysize) / 2, + gfx_new_text(im->canvas,im->xgif/2, (2*im->yorigin-im->ysize) / 2, im->graph_col[GRC_FONT], im->text_prop[TEXT_PROP_AXIS].font, im->text_prop[TEXT_PROP_AXIS].size, @@ -1749,68 +1763,85 @@ grid_paint( } /* yaxis description */ - gfx_new_text( 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, - im->ylegend); + if (im->canvas->imgformat != IF_PNG) { + 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, + im->ylegend); + } else { + /* horrible hack until we can actually print vertically */ + { + int n; + int l=strlen(im->ylegend); + char s[2]; + 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), + 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, + s); + } + } + } /* graph title */ - gfx_new_text( canvas, - im->xgif/2, im->text_prop[TEXT_PROP_TITLE].size*1.5, + gfx_new_text( im->canvas, + im->xgif/2, im->text_prop[TEXT_PROP_TITLE].size, im->graph_col[GRC_FONT], im->text_prop[TEXT_PROP_TITLE].font, im->text_prop[TEXT_PROP_TITLE].size, im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_CENTER, im->title); - /* graph labels */ - if( !(im->extra_flags & NOLEGEND) ) { + /* graph labels */ + if( !(im->extra_flags & NOLEGEND) ) { for(i=0;igdes_c;i++){ - if(im->gdes[i].legend[0] =='\0') - continue; + if(im->gdes[i].legend[0] =='\0') + continue; - if(im->gdes[i].gf != GF_GPRINT && im->gdes[i].gf != GF_COMMENT){ - x0 = im->gdes[i].leg_x; - y0 = im->gdes[i].leg_y+1.0; - x1 = x0+boxH; - x2 = x0+boxH; - x3 = x0; - y1 = y0; - y2 = y0+boxV; - y3 = y0+boxV; - node = gfx_new_area(canvas, x0,y0,x1,y1,x2,y2 ,im->gdes[i].col); - gfx_add_point ( node, x3, y3 ); - gfx_add_point ( node, x0, y0 ); - node = gfx_new_line(canvas, x0,y0,x1,y1 ,GRIDWIDTH, im->graph_col[GRC_FRAME]); - gfx_add_point ( node, x2, y2 ); - gfx_add_point ( node, x3, y3 ); - gfx_add_point ( node, x0, y0 ); - - gfx_new_text ( canvas, x0+boxH+6, (y0+y2) / 2.0, - im->graph_col[GRC_FONT], - im->text_prop[TEXT_PROP_AXIS].font, - im->text_prop[TEXT_PROP_AXIS].size, - im->tabwidth,0.0, GFX_H_LEFT, GFX_V_CENTER, - im->gdes[i].legend ); - - } else { - x0 = im->gdes[i].leg_x; - y0 = im->gdes[i].leg_y; - - gfx_new_text ( canvas, x0, (y0+y2) / 2.0, - im->graph_col[GRC_FONT], - im->text_prop[TEXT_PROP_AXIS].font, - im->text_prop[TEXT_PROP_AXIS].size, - im->tabwidth,0.0, GFX_H_LEFT, GFX_V_BOTTOM, - im->gdes[i].legend ); - - } - } - } -} + /* im->gdes[i].leg_y is the bottom of the legend */ + x0 = im->gdes[i].leg_x; + y0 = im->gdes[i].leg_y; + /* Box needed? */ + if ( im->gdes[i].gf != GF_GPRINT + && im->gdes[i].gf != GF_COMMENT) { + int boxH, boxV; + + 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; + boxV = boxH; + + node = gfx_new_area(im->canvas, + x0,y0-boxV, + x0,y0, + x0+boxH,y0, + im->gdes[i].col); + gfx_add_point ( node, x0+boxH, y0-boxV ); + node = gfx_new_line(im->canvas, + x0,y0-boxV, x0,y0, + 1,0x000000FF); + gfx_add_point(node,x0+boxH,y0); + gfx_add_point(node,x0+boxH,y0-boxV); + gfx_close_path(node); + x0 += boxH / 1.25 * 2; + } + gfx_new_text ( im->canvas, x0, y0, + im->graph_col[GRC_FONT], + im->text_prop[TEXT_PROP_AXIS].font, + im->text_prop[TEXT_PROP_AXIS].size, + im->tabwidth,0.0, GFX_H_LEFT, GFX_V_BOTTOM, + im->gdes[i].legend ); + } + } + } /***************************************************** @@ -1832,18 +1863,208 @@ int lazy_check(image_desc_t *im){ return 0; if ((fd = fopen(im->graphfile,"rb")) == NULL) return 0; /* the file does not exist */ - switch (im->imgformat) { - case IF_GIF: - size = GifSize(fd,&(im->xgif),&(im->ygif)); - break; + switch (im->canvas->imgformat) { case IF_PNG: size = PngSize(fd,&(im->xgif),&(im->ygif)); break; + default: + size = 1; } fclose(fd); return size; } +void +pie_part(image_desc_t *im, gfx_color_t color, + double PieCenterX, double PieCenterY, double Radius, + double startangle, double endangle) +{ + gfx_node_t *node; + double angle; + double step=M_PI/50; /* Number of iterations for the circle; + ** 10 is definitely too low, more than + ** 50 seems to be overkill + */ + + /* Strange but true: we have to work clockwise or else + ** anti aliasing nor transparency don't work. + ** + ** This test is here to make sure we do it right, also + ** this makes the for...next loop more easy to implement. + ** The return will occur if the user enters a negative number + ** (which shouldn't be done according to the specs) or if the + ** programmers do something wrong (which, as we all know, never + ** happens anyway :) + */ + if (endangle