fixed longstanding bug affection CDEFS where values from
[rrdtool.git] / src / rrd_graph.c
index abbfcdb..ea7ed0d 100644 (file)
@@ -938,6 +938,7 @@ data_proc( image_desc_t *im ){
            case GF_DEF:               
            case GF_CDEF:
            case GF_VDEF:
+           case GF_PART:
                break;
            }
        }
@@ -1850,8 +1851,8 @@ graph_paint(image_desc_t *im, char ***calcpr)
 {
   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, PieCenterX, PieCenterY;
   FILE  *fo;
   gfx_canvas_t *canvas;
   gfx_node_t *node;
@@ -1920,16 +1921,19 @@ 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.
      and set im->ygif to match space requirements for text */
   if(leg_place(im)==-1)
@@ -1937,6 +1941,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
 
   canvas=gfx_new_canvas();
 
+
   /* the actual graph is created by going through the individual
      graph elements and then drawing them */
   
@@ -1956,13 +1961,54 @@ graph_paint(image_desc_t *im, char ***calcpr)
   
   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);
+
+  node=gfx_new_line (canvas,
+               0,              im->ygif-100,
+               im->xgif-3,     im->ygif-100,
+               1.0,
+               0xFF0000FF);
+  gfx_add_point(node,im->xgif-3,im->ygif-3);
+  gfx_add_point(node,2,im->ygif-3);
+  gfx_add_point(node,2,im->ygif-100);
+
+
+#if 0
+  node=gfx_new_area ( canvas,
+                       1,              im->ygif-99,
+                       im->xgif-1,     im->ygif-99,
+                       im->xgif-1,     im->ygif-1,
+                       im->graph_col[GRC_CANVAS]);
+  gfx_add_point(node,1,im->ygif-1);
+#endif
+
+#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,
+       int n;
+
+       node=gfx_new_area(canvas,
+               PieCenterX,PieCenterY-PieSize*0.6,
+               PieCenterX,PieCenterY,
+               PieCenterX,PieCenterY-PieSize*0.6,
                im->graph_col[GRC_CANVAS]);
-    gfx_add_point(node,im->xorigin+im->xsize+50, im->yorigin - PieSize);
+       for (n=1;n<500;n++) {
+               double angle;
+               angle=M_PI*2.0*n/500.0;
+               gfx_add_point(node,
+               PieCenterX+sin(angle)*PieSize*0.6,
+               PieCenterY-cos(angle)*PieSize*0.6 );
+       }
   }
 
   if (im->minval > 0.0)
@@ -2092,48 +2138,33 @@ 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 */
+       double angle,endangle;
+       int n;
+
+       angle=M_PI*2.0*PieStart/100.0;
+       endangle=M_PI*2.0*(PieStart+im->gdes[i].yrule)/100.0;
+       node=gfx_new_area(canvas,
+               PieCenterX+sin(endangle)*PieSize/2,
+               PieCenterY-cos(endangle)*PieSize/2,
+               PieCenterX,
+               PieCenterY,
+               PieCenterX+sin(angle)*PieSize/2,
+               PieCenterY-cos(angle)*PieSize/2,
+               im->gdes[i].col);
+       for (n=1;n<100;n++) {
+               angle=M_PI*2.0*(PieStart+n/100.0*im->gdes[i].yrule)/100.0;
+               gfx_add_point(node,
+               PieCenterX+sin(angle)*PieSize/2,
+               PieCenterY-cos(angle)*PieSize/2 );
+       }
+       PieStart += im->gdes[i].yrule;
       }
       break;
-      } /* GF_PART */
     } /* switch */
   }
   grid_paint(im,canvas);