when stacking known on unknown, then we asume unknown was zero ...
[rrdtool.git] / src / rrd_graph.c
index 7259eef..bfbd455 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.2.9  Copyright by Tobi Oetiker, 1997-2005
+ * RRDtool 1.2.10  Copyright by Tobi Oetiker, 1997-2005
  ****************************************************************************
  * rrd__graph.c  produce graphs from data in rrdfiles
  ****************************************************************************/
@@ -350,8 +350,6 @@ si_unit(
 
     im->viewfactor = im->magfact / pow((double)im->base , viewdigits);
 
-    pow((double)im->base , viewdigits);
-
     if ( ((viewdigits+symbcenter) < sizeof(symbol)) &&
                    ((viewdigits+symbcenter) >= 0) )
         im->symbol = symbol[(int)viewdigits+symbcenter];
@@ -1549,7 +1547,7 @@ calc_horizontal_grid(image_desc_t   *im)
            if(decimals <= 0) /* everything is small. make place for zero */
                decimals = 1;
            
-           im->ygrid_scale.gridstep = pow((double)10, floor(log10(range)));
+           im->ygrid_scale.gridstep = pow((double)10, floor(log10(range*im->viewfactor/im->magfact)))/im->viewfactor*im->magfact;
            
            if(im->ygrid_scale.gridstep == 0) /* range is one -> 0.1 is reasonable scale */
                im->ygrid_scale.gridstep = 0.1;
@@ -1575,7 +1573,7 @@ calc_horizontal_grid(image_desc_t   *im)
            } else {
                int len = decimals + 1;
                if (im->unitslength < len+2) im->unitslength = len+2;
-               sprintf(im->ygrid_scale.labfmt, "%%%d.1f%s", len, ( im->symbol != ' ' ? " %c" : "" ));
+               sprintf(im->ygrid_scale.labfmt, "%%%d.0f%s", len, ( im->symbol != ' ' ? " %c" : "" ));
            }
        }
        else {
@@ -1614,8 +1612,8 @@ int draw_horizontal_grid(image_desc_t *im)
     int sgrid = (int)( im->minval / im->ygrid_scale.gridstep - 1);
     int egrid = (int)( im->maxval / im->ygrid_scale.gridstep + 1);
     double MaxY;
-    scaledstep = im->ygrid_scale.gridstep/im->magfact;
-    MaxY = scaledstep*(double)im->viewfactor*(double)egrid;
+    scaledstep = im->ygrid_scale.gridstep/(double)im->magfact*(double)im->viewfactor;
+    MaxY = scaledstep*(double)egrid;
     for (i = sgrid; i <= egrid; i++){
        double Y0=ytr(im,im->ygrid_scale.gridstep*i);
        if ( Y0 >= im->yorigin-im->ysize
@@ -1623,23 +1621,23 @@ int draw_horizontal_grid(image_desc_t *im)
            if(i % im->ygrid_scale.labfact == 0){               
                if (im->symbol == ' ') {
                    if(im->extra_flags & ALTYGRID) {
-                       sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*im->viewfactor*i);
+                       sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*(double)i);
                     } else {
                         if(MaxY < 10) {
-                          sprintf(graph_label,"%4.1f",scaledstep*im->viewfactor*i);
+                          sprintf(graph_label,"%4.1f",scaledstep*(double)i);
                        } else {
-                          sprintf(graph_label,"%4.0f",scaledstep*im->viewfactor*i);
+                          sprintf(graph_label,"%4.0f",scaledstep*(double)i);
                        }
                     }
                }else {
                    char sisym = ( i == 0  ? ' ' : im->symbol);
                    if(im->extra_flags & ALTYGRID) {
-                       sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*im->viewfactor*i,sisym);
+                       sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*(double)i,sisym);
                     } else {
                        if(MaxY < 10){
-                         sprintf(graph_label,"%4.1f %c",scaledstep*im->viewfactor*i, sisym);
+                         sprintf(graph_label,"%4.1f %c",scaledstep*(double)i, sisym);
                        } else {
-                         sprintf(graph_label,"%4.0f %c",scaledstep*im->viewfactor*i, sisym);
+                         sprintf(graph_label,"%4.0f %c",scaledstep*(double)i, sisym);
                        }
                     }
                }
@@ -1846,11 +1844,11 @@ vertical_grid(
 # error "your libc has no strftime I guess we'll abort the exercise here."
 #endif
        gfx_new_text ( im->canvas,
-                     xtr(im,tilab), Y0+im->text_prop[TEXT_PROP_AXIS].size,
+                     xtr(im,tilab), Y0+im->text_prop[TEXT_PROP_AXIS].size*1.4+5,
                      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_CENTER, GFX_V_TOP,
+                     im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_BOTTOM,
                      graph_label );
        
     }
@@ -2502,16 +2500,53 @@ graph_paint(image_desc_t *im, char ***calcpr)
 
           }
         } else {
-         double ybase0 = DNAN,ytop0=DNAN;
-          for(ii=0;ii<im->xsize;ii++){
+         int idxI=-1;
+         double *foreY=malloc(sizeof(double)*im->xsize*2);
+         double *foreX=malloc(sizeof(double)*im->xsize*2);
+         double *backY=malloc(sizeof(double)*im->xsize*2);
+         double *backX=malloc(sizeof(double)*im->xsize*2);
+         int drawem = 0;
+          for(ii=0;ii<=im->xsize;ii++){
+           double ybase,ytop;
+           if ( idxI > 0 && ( drawem != 0 || ii==im->xsize)){
+               int cntI=1;
+               int lastI=0;
+               while (cntI < idxI && foreY[lastI] == foreY[cntI] && foreY[lastI] == foreY[cntI+1]){cntI++;}
+               node = gfx_new_area(im->canvas,
+                                backX[0],backY[0],
+                                foreX[0],foreY[0],
+                                foreX[cntI],foreY[cntI], im->gdes[i].col);
+               while (cntI < idxI) {
+                 lastI = cntI;
+                 cntI++;
+                 while ( cntI < idxI && foreY[lastI] == foreY[cntI] && foreY[lastI] == foreY[cntI+1]){cntI++;} 
+                 gfx_add_point(node,foreX[cntI],foreY[cntI]);
+               }
+               gfx_add_point(node,backX[idxI],backY[idxI]);
+               while (idxI > 1){
+                 lastI = idxI;
+                 idxI--;
+                 while ( idxI > 1 && backY[lastI] == backY[idxI] && backY[lastI] == backY[idxI-1]){idxI--;} 
+                 gfx_add_point(node,backX[idxI],backY[idxI]);
+               }
+               idxI=-1;
+               drawem = 0;
+            }
+            if (drawem != 0){
+              drawem = 0;
+              idxI=-1;
+            }
+            if (ii == im->xsize) break;
+            
            /* keep things simple for now, just draw these bars
               do not try to build a big and complex area */
-           double ybase,ytop;
+
+                                                             
            if ( im->slopemode == 0 && ii==0){
                continue;
            }
            if ( isnan(im->gdes[i].p_data[ii]) ) {
-               ybase0 = DNAN;
+               drawem = 1;
                continue;
            }
             ytop = ytr(im,im->gdes[i].p_data[ii]);
@@ -2521,7 +2556,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
                   ybase = ytr(im,areazero);
             }
             if ( ybase == ytop ){
-               ybase0 = DNAN;
+               drawem = 1;
                continue;       
            }
            /* every area has to be wound clock-wise,
@@ -2531,24 +2566,22 @@ graph_paint(image_desc_t *im, char ***calcpr)
                ytop = ybase;
                ybase = extra;
            }
-           if ( im->slopemode == 0){
-                ybase0 = ybase;
-                ytop0 = ytop;
-           }
-           if ( !isnan(ybase0) ){
-                   node = gfx_new_area(im->canvas,
-                                (double)ii-1.2+(double)im->xorigin,ybase0-0.2,
-                                (double)ii-1.2+(double)im->xorigin,ytop0+0.2,
-                                (double)ii+0.2+(double)im->xorigin,ytop+0.2,
-                                im->gdes[i].col
-                               );
-                   gfx_add_point(node,
-                               (double)ii+0.02+im->xorigin,ybase-0.2
-                              );
+            if ( im->slopemode == 0 ){
+                    backY[++idxI] = ybase-0.2;
+                    backX[idxI] = ii+im->xorigin-1;
+                    foreY[idxI] = ytop+0.2;
+                    foreX[idxI] = ii+im->xorigin-1;
             }
-           ybase0=ybase;
-           ytop0=ytop;
-          }             
+            backY[++idxI] = ybase-0.2;
+            backX[idxI] = ii+im->xorigin;
+            foreY[idxI] = ytop+0.2;
+            foreX[idxI] = ii+im->xorigin;
+          }
+          /* close up any remaining area */             
+          free(foreY);
+          free(foreX);
+          free(backY);
+          free(backX);
         } /* else GF_LINE */
       } /* if color != 0x0 */
       /* make sure we do not run into trouble when stacking on NaN */
@@ -2557,7 +2590,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
           if (lastgdes && (im->gdes[i].stack)) {
             im->gdes[i].p_data[ii] = lastgdes->p_data[ii];
           } else {
-            im->gdes[i].p_data[ii] =  ytr(im,areazero);
+            im->gdes[i].p_data[ii] = areazero;
           }
         }
       } 
@@ -3152,7 +3185,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
 
            if(sscanf(optarg,
                                "%10[A-Z]:%lf:%1000s",
-                               prop,&size,font) == 3){
+                               prop,&size,font) >= 2){
                int sindex,propidx;
                if((sindex=text_prop_conv(prop)) != -1){
                   for (propidx=sindex;propidx<TEXT_PROP_LAST;propidx++){