In rrd_graph: the width/height values are written into rrd_infoval_t's u_cnt
[rrdtool.git] / src / rrd_graph.c
index 989a2b4..0de1aa8 100644 (file)
@@ -10,7 +10,9 @@
 
 #ifdef WIN32
 #include "strftime.h"
+#include "plbasename.h"
 #endif
+
 #include "rrd_tool.h"
 
 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
@@ -3223,7 +3225,7 @@ int graph_paint(
                     if (im->gdes[i].yrule > 0) {
                         gfx_line(im,
                                  im->xorigin + ii,
-                                 im->yorigin,
+                                 im->yorigin + 1.0,
                                  im->xorigin + ii,
                                  im->yorigin -
                                  im->gdes[i].yrule *
@@ -3231,11 +3233,11 @@ int graph_paint(
                     } else if (im->gdes[i].yrule < 0) {
                         gfx_line(im,
                                  im->xorigin + ii,
-                                 im->yorigin - im->ysize,
+                                 im->yorigin - im->ysize - 1.0,
                                  im->xorigin + ii,
-                                 im->yorigin - (1 -
+                                 im->yorigin - im->ysize -
                                                 im->gdes[i].
-                                                yrule) *
+                                                yrule *
                                  im->ysize, 1.0, im->gdes[i].col);
                     }
                 }
@@ -3688,9 +3690,9 @@ int rrd_graph(
     *ymax = 0;
     while (walker) {
         if (strcmp(walker->key, "image_width") == 0) {
-            *xsize = walker->value.u_int;
+            *xsize = walker->value.u_cnt;
         } else if (strcmp(walker->key, "image_height") == 0) {
-            *ysize = walker->value.u_int;
+            *ysize = walker->value.u_cnt;
         } else if (strcmp(walker->key, "value_min") == 0) {
             *ymin = walker->value.u_val;
         } else if (strcmp(walker->key, "value_max") == 0) {
@@ -4584,6 +4586,8 @@ int vdef_parse(
     }
     if (!strcmp("PERCENT", func))
         gdes->vf.op = VDEF_PERCENT;
+    else if (!strcmp("PERCENTNAN", func))
+        gdes->vf.op = VDEF_PERCENTNAN;
     else if (!strcmp("MAXIMUM", func))
         gdes->vf.op = VDEF_MAXIMUM;
     else if (!strcmp("AVERAGE", func))
@@ -4611,6 +4615,7 @@ int vdef_parse(
     };
     switch (gdes->vf.op) {
     case VDEF_PERCENT:
+    case VDEF_PERCENTNAN:
         if (isnan(param)) { /* no parameter given */
             rrd_set_error
                 ("Function '%s' needs parameter in VDEF '%s'\n",
@@ -4695,6 +4700,34 @@ int vdef_calc(
 #endif
     }
         break;
+    case VDEF_PERCENTNAN:{
+        rrd_value_t *array;
+        int       field;
+       /* count number of "valid" values */
+       int nancount=0;
+       for (step = 0; step < steps; step++) {
+         if (!isnan(data[step * src->ds_cnt])) { nancount++; }
+       }
+       /* and allocate it */
+        if ((array = (rrd_value_t*)malloc(nancount * sizeof(double))) == NULL) {
+            rrd_set_error("malloc VDEV_PERCENT");
+            return -1;
+        }
+       /* and fill it in */
+       field=0;
+        for (step = 0; step < steps; step++) {
+           if (!isnan(data[step * src->ds_cnt])) {
+                array[field] = data[step * src->ds_cnt];
+               field++;
+            }
+        }
+        qsort(array, nancount, sizeof(double), vdef_percent_compar);
+        field = (nancount - 1) * dst->vf.param / 100;
+        dst->vf.val = array[field];
+        dst->vf.when = 0;   /* no time component */
+        free(array);
+    }
+        break;
     case VDEF_MAXIMUM:
         step = 0;
         while (step != steps && isnan(data[step * src->ds_cnt]))