From 918ac20c690f14059763b08af1e37a3407efe738 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 13 Mar 2002 02:58:44 +0000 Subject: [PATCH] New, hopefully better, implementation of PART drawing git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk@95 a5681a0c-68f1-0310-ab6d-d61299d08faa --- program/src/rrd_gfx.c | 47 ++++++++++++++++++++++++++ program/src/rrd_gfx.h | 7 ++++ program/src/rrd_graph.c | 75 +++++++++++++++++------------------------ 3 files changed, 84 insertions(+), 45 deletions(-) diff --git a/program/src/rrd_gfx.c b/program/src/rrd_gfx.c index 724a0747..1a45439d 100644 --- a/program/src/rrd_gfx.c +++ b/program/src/rrd_gfx.c @@ -15,6 +15,7 @@ #include #include #include FT_FREETYPE_H +#include #include "rrd_gfx.h" @@ -107,6 +108,52 @@ gfx_node_t *gfx_new_area (gfx_canvas_t *canvas, return node; } +/* create an arc section (2*M_PI is full circle) */ +gfx_node_t *gfx_arc_sect (gfx_canvas_t *canvas, + double centerx, double centery, + double radiusx, double radiusy, + double start, double end, + gfx_color_t color) { + + gfx_node_t *node; + ArtVpath *vec; + int counter; + double position; + +/* 20 is too low, 100 is overkill */ +#define AMOUNT_OF_VECTORS 50 + + node = gfx_new_node(canvas,GFX_AREA); + if (node == NULL) return NULL; + vec = art_new(ArtVpath, AMOUNT_OF_VECTORS+4); + if (vec == NULL) return NULL; + + vec[0].code = ART_MOVETO; + vec[0].x = centerx; + vec[0].y = centery; + + for (counter=0;counter<=AMOUNT_OF_VECTORS;) { + position=start + counter*(end-start)/AMOUNT_OF_VECTORS; + + counter++; + vec[counter].code = ART_LINETO; + vec[counter].x = centerx + sin(position)*radiusx; + vec[counter].y = centery - cos(position)*radiusy; + } + + vec[AMOUNT_OF_VECTORS+2].code = ART_LINETO; + vec[AMOUNT_OF_VECTORS+2].x = centerx; + vec[AMOUNT_OF_VECTORS+2].y = centery; + + vec[AMOUNT_OF_VECTORS+3].code = ART_END; + + node->points = AMOUNT_OF_VECTORS+4; + node->points_max = AMOUNT_OF_VECTORS+4; + 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, diff --git a/program/src/rrd_gfx.h b/program/src/rrd_gfx.h index 808b7c40..8362ff16 100644 --- a/program/src/rrd_gfx.h +++ b/program/src/rrd_gfx.h @@ -54,6 +54,13 @@ gfx_node_t *gfx_new_area (gfx_canvas_t *canvas, double x2, double y2, gfx_color_t color); +/* create an arc section (2*M_PI is full circle) */ +gfx_node_t *gfx_arc_sect (gfx_canvas_t *canvas, + double centerx, double centery, + double radiusx, double radiusy, + double start, double end, + gfx_color_t color); + /* add a point to a line or to an area */ int gfx_add_point (gfx_node_t *node, double x, double y); diff --git a/program/src/rrd_graph.c b/program/src/rrd_graph.c index abbfcdb0..c7ba63e6 100644 --- a/program/src/rrd_graph.c +++ b/program/src/rrd_graph.c @@ -938,6 +938,7 @@ data_proc( image_desc_t *im ){ case GF_DEF: case GF_CDEF: case GF_VDEF: + case GF_PART: break; } } @@ -1920,14 +1921,17 @@ graph_paint(image_desc_t *im, char ***calcpr) } if (piechart) { + /* allocate enough space for the piechart itself (PieSize), 20% + ** more for the background and an additional 50 pixels spacing. + */ if (im->xsize < im->ysize) PieSize = im->xsize; else PieSize = im->ysize; - im->xgif += PieSize + 50; + im->xgif += PieSize*1.2 + 50; - PieCenterX = im->xorigin + im->xsize + 50 + PieSize/2; - PieCenterY = im->yorigin - PieSize/2; + PieCenterX = im->xorigin + im->xsize + 50 + PieSize*0.6; + PieCenterY = im->yorigin - PieSize*0.5; } /* determine where to place the legends onto the graphics. @@ -1957,12 +1961,21 @@ graph_paint(image_desc_t *im, char ***calcpr) gfx_add_point(node,im->xorigin, im->yorigin - im->ysize); if (piechart) { +#if 1 + node=gfx_arc_sect (canvas, + PieCenterX,PieCenterY, + PieSize*0.6, PieSize*0.6, /* 20% more as background */ + 0,M_PI*2, + im->graph_col[GRC_CANVAS]); +#else node=gfx_new_area ( canvas, - im->xorigin + im->xsize + 50, im->yorigin, - im->xorigin + im->xsize + 50 + PieSize, im->yorigin, - im->xorigin + im->xsize + 50 + PieSize, im->yorigin - PieSize, - im->graph_col[GRC_CANVAS]); - gfx_add_point(node,im->xorigin+im->xsize+50, im->yorigin - PieSize); + PieCenterX-0.6*PieSize, PieCenterY-0.6*PieSize, + PieCenterX+0.6*PieSize, PieCenterY-0.6*PieSize, + PieCenterX+0.6*PieSize, PieCenterY+0.6*PieSize, + im->graph_col[GRC_CANVAS]); + gfx_add_point(node, + PieCenterX-0.6*PieSize, PieCenterY+0.6*PieSize); +#endif } if (im->minval > 0.0) @@ -2092,48 +2105,20 @@ graph_paint(image_desc_t *im, char ***calcpr) } lastgdes = &(im->gdes[i]); break; - case GF_PART: { - int x,y , counter; - double d1,d2,d3,d4; - - /* This probably is not the most efficient algorithm... - ** If you know how to help, please do! - ** - ** If you change this routine be aware that I optimized - ** the following algorithm: - ** - ** Full circle == 100 - ** relative X-position is sin(2*pi * position/100) - ** relative Y-position is cos(2*pi * position/100) - ** - ** Position is incremented from start to end in a number - ** of steps. This number of steps corresponds with the - ** size of the pie canvas, each step being 1/PieSize. - */ - + case GF_PART: if(isnan(im->gdes[i].yrule)) /* fetch variable */ im->gdes[i].yrule = im->gdes[im->gdes[i].vidx].vf.val; - if (finite(im->gdes[i].yrule)) { - d1 = 2 * M_PI / 100; - d2 = im->gdes[i].yrule / PieSize; - d3 = PieSize/2; - - for (counter=0;counter<=PieSize;counter++) { - d4 = d1 * (PieStart + d2 * counter); - x=sin(d4) * d3; - y=cos(d4) * d3; - - gfx_new_line(canvas, - PieCenterX,PieCenterY , - PieCenterX+x,PieCenterY-y, - 1.0, - im->gdes[i].col); - } - PieStart += im->gdes[i].yrule; + if (finite(im->gdes[i].yrule)) { /* even the fetched var can be NaN */ + node=gfx_arc_sect(canvas, + PieCenterX, PieCenterY, + PieSize/2,PieSize/2, + M_PI*2.0*PieStart/100.0, + M_PI*2.0*(PieStart+im->gdes[i].yrule)/100.0, + im->gdes[i].col); + PieStart += im->gdes[i].yrule; } break; - } /* GF_PART */ } /* switch */ } grid_paint(im,canvas); -- 2.30.2