enum if_en if_conv(char *string){
- conv_if(GIF,IF_GIF)
conv_if(PNG,IF_PNG)
return (-1);
} /* 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");
case GF_DEF:
case GF_CDEF:
case GF_VDEF:
+ case GF_PART:
break;
}
}
/* 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 (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 (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 )
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;
+ x1 = x0;
x2 = x0+boxH;
- x3 = x0;
- y1 = y0;
+ x3 = x0+boxH;
+ y1 = y0+boxV;
y2 = y0+boxV;
- y3 = y0+boxV;
+ y3 = y0;
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 );
+/* 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 );
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;
case IF_PNG:
size = PngSize(fd,&(im->xgif),&(im->ygif));
break;
return size;
}
+void
+pie_part(gfx_canvas_t *canvas, 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<startangle) return;
+
+ /* Hidden feature: Radius decreases each full circle */
+ angle=startangle;
+ while (angle>=2*M_PI) {
+ angle -= 2*M_PI;
+ Radius *= 0.8;
+ }
+
+ node=gfx_new_area(canvas,
+ PieCenterX+sin(startangle)*Radius,
+ PieCenterY-cos(startangle)*Radius,
+ PieCenterX,
+ PieCenterY,
+ PieCenterX+sin(endangle)*Radius,
+ PieCenterY-cos(endangle)*Radius,
+ color);
+ for (angle=endangle;angle-startangle>=step;angle-=step) {
+ gfx_add_point(node,
+ PieCenterX+sin(angle)*Radius,
+ PieCenterY-cos(angle)*Radius );
+ }
+}
/* draw that picture thing ... */
int
{
int i,ii;
int lazy = lazy_check(im);
- int piechart = 0, PieSize, PieCenterX, PieCenterY;
- double PieStart=0.0;
+ int piechart = 0;
+ double PieStart=0.0, PieSize=0.0, PieCenterX=0.0, PieCenterY=0.0;
FILE *fo;
gfx_canvas_t *canvas;
gfx_node_t *node;
}
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.
and set im->ygif to match space requirements for text */
if(leg_place(im)==-1)
canvas=gfx_new_canvas();
+
/* the actual graph is created by going through the individual
graph elements and then drawing them */
gfx_add_point(node,im->xorigin, im->yorigin - im->ysize);
+#if 0
+/******************************************************************
+ ** Just to play around. If you see this, I forgot to remove it **
+ ******************************************************************/
+ im->ygif+=100;
+ node=gfx_new_area(canvas,
+ 0, im->ygif-100,
+ im->xgif, im->ygif-100,
+ im->xgif, im->ygif,
+ im->graph_col[GRC_CANVAS]);
+ gfx_add_point(node,0,im->ygif);
+
+ /* Four areas:
+ ** top left: current way, solid color
+ ** top right: proper way, solid color
+ ** bottom left: current way, alpha=0x80, partially overlapping
+ ** bottom right: proper way, alpha=0x80, partially overlapping
+ */
+ {
+ double x,y,x1,y1,x2,y2,x3,y3,x4,y4;
+
+ x=(im->xgif-40)/6;
+ y= (100-40)/6;
+ x1= 20; y1=im->ygif-100+20;
+ x2=3*x+20; y2=im->ygif-100+20;
+ x3= x+20; y3=im->ygif-100+20+2*y;
+ x4=4*x+20; y4=im->ygif-100+20+2*y;
+
+ node=gfx_new_area(canvas,
+ x1,y1,
+ x1+3*x,y1,
+ x1+3*x,y1+3*y,
+ 0xFF0000FF);
+ gfx_add_point(node,x1,y1+3*y);
+ node=gfx_new_area(canvas,
+ x2,y2,
+ x2,y2+3*y,
+ x2+3*x,y2+3*y,
+ 0xFFFF00FF);
+ gfx_add_point(node,x2+3*x,y2);
+ node=gfx_new_area(canvas,
+ x3,y3,
+ x3+2*x,y3,
+ x3+2*x,y3+3*y,
+ 0x00FF007F);
+ gfx_add_point(node,x3,y3+3*y);
+ node=gfx_new_area(canvas,
+ x4,y4,
+ x4,y4+3*y,
+ x4+2*x,y4+3*y,
+ 0x0000FF7F);
+ gfx_add_point(node,x4+2*x,y4);
+ }
+
+#endif
+
if (piechart) {
- 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);
+ pie_part(canvas,im->graph_col[GRC_CANVAS],PieCenterX,PieCenterY,PieSize*0.6,0,2*M_PI);
}
if (im->minval > 0.0)
}
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 */
+ pie_part(canvas,im->gdes[i].col,
+ PieCenterX,PieCenterY,PieSize/2,
+ M_PI*2.0*PieStart/100.0,
+ M_PI*2.0*(PieStart+im->gdes[i].yrule)/100.0);
+ PieStart += im->gdes[i].yrule;
}
break;
- } /* GF_PART */
} /* switch */
}
grid_paint(im,canvas);
}
}
switch (im->imgformat) {
- case IF_GIF:
- break;
case IF_PNG:
gfx_render_png (canvas,im->xgif,im->ygif,im->zoom,0x0,fo);
break;
im->gdes_c = 0;
im->gdes = NULL;
im->zoom = 1.0;
- im->imgformat = IF_GIF; /* we default to GIF output */
+ im->imgformat = IF_PNG; /* we default to PNG output */
for(i=0;i<DIM(graph_col);i++)
im->graph_col[i]=graph_col[i];