misc fixed and TREND and reduce functionality by
[rrdtool.git] / src / rrd_graph.c
index 36c8054..d22c853 100644 (file)
@@ -41,7 +41,7 @@ char rrd_win_default_font[80];
 
 text_prop_t text_prop[] = {   
      { 10.0, RRD_DEFAULT_FONT }, /* default */
-     { 12.0, RRD_DEFAULT_FONT }, /* title */
+     { 10.0, RRD_DEFAULT_FONT }, /* title */
      { 8.0,  RRD_DEFAULT_FONT },  /* axis */
      { 10.0, RRD_DEFAULT_FONT },  /* unit */
      { 10.0, RRD_DEFAULT_FONT }  /* legend */
@@ -188,6 +188,7 @@ enum gf_en gf_conv(char *string){
     conv_if(VDEF,GF_VDEF)
     conv_if(PART,GF_PART)
     conv_if(XPORT,GF_XPORT)
+    conv_if(SHIFT,GF_SHIFT)
     
     return (-1);
 }
@@ -601,7 +602,7 @@ printf("row_cnt after:   %lu\n",row_cnt);
     ** into one interval for the destination.
     */
 
-    for (dst_row=0;row_cnt>=reduce_factor;dst_row++) {
+    for (dst_row=0;(long int)row_cnt>=reduce_factor;dst_row++) {
        for (col=0;col<(*ds_cnt);col++) {
            rrd_value_t newval=DNAN;
            unsigned long validval=0;
@@ -681,11 +682,11 @@ for (col=0;col<row_cnt;col++) {
 int
 data_fetch(image_desc_t *im )
 {
-    unsigned int i,ii;
+    int i,ii;
     int                skip;
 
     /* pull the data from the log files ... */
-    for (i=0;i<im->gdes_c;i++){
+    for (i=0;i< (int)im->gdes_c;i++){
        /* only GF_DEF elements fetch data */
        if (im->gdes[i].gf != GF_DEF) 
            continue;
@@ -697,6 +698,7 @@ data_fetch(image_desc_t *im )
                continue;
            if ((strcmp(im->gdes[i].rrd, im->gdes[ii].rrd) == 0)
                        && (im->gdes[i].cf    == im->gdes[ii].cf)
+                       && (im->gdes[i].cf_reduce == im->gdes[ii].cf_reduce)
                        && (im->gdes[i].start == im->gdes[ii].start)
                        && (im->gdes[i].end   == im->gdes[ii].end)
                        && (im->gdes[i].step  == im->gdes[ii].step)) {
@@ -729,9 +731,10 @@ data_fetch(image_desc_t *im )
                return -1;
            }
            im->gdes[i].data_first = 1;     
+           im->gdes[i].step = im->step;
        
            if (ft_step < im->gdes[i].step) {
-               reduce_data(im->gdes[i].cf,
+               reduce_data(im->gdes[i].cf_reduce,
                            ft_step,
                            &im->gdes[i].start,
                            &im->gdes[i].end,
@@ -743,8 +746,8 @@ data_fetch(image_desc_t *im )
            }
        }
        
-        /* lets see if the required data source is realy there */
-       for(ii=0;ii<im->gdes[i].ds_cnt;ii++){
+        /* lets see if the required data source is really there */
+       for(ii=0;ii<(int)im->gdes[i].ds_cnt;ii++){
            if(strcmp(im->gdes[i].ds_namv[ii],im->gdes[i].ds_nam) == 0){
                im->gdes[i].ds=ii; }
        }
@@ -822,6 +825,28 @@ data_calc( image_desc_t *im){
        switch (im->gdes[gdi].gf) {
            case GF_XPORT:
              break;
+           case GF_SHIFT: {
+               graph_desc_t    *vdp = &im->gdes[im->gdes[gdi].vidx];
+               
+               /* remove current shift */
+               vdp->start -= vdp->shift;
+               vdp->end -= vdp->shift;
+               
+               /* vdef */
+               if (im->gdes[gdi].shidx >= 0) 
+                       vdp->shift = im->gdes[im->gdes[gdi].shidx].vf.val;
+               /* constant */
+               else
+                       vdp->shift = im->gdes[gdi].shval;
+
+               /* normalize shift to multiple of consolidated step */
+               vdp->shift = (vdp->shift / (long)vdp->step) * (long)vdp->step;
+
+               /* apply shift */
+               vdp->start += vdp->shift;
+               vdp->end += vdp->shift;
+               break;
+           }
            case GF_VDEF:
                /* A VDEF has no DS.  This also signals other parts
                 * of rrdtool that this is a VDEF value, not a CDEF.
@@ -912,12 +937,12 @@ data_calc( image_desc_t *im){
                if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE ||
                   im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER){
                         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;
-                        }
+                       long diff = im->gdes[gdi].start - im->gdes[ptr].start;
+
+                        if(diff > 0)
+                           im->gdes[gdi].rpnp[rpi].data += (diff / im->gdes[ptr].step) * im->gdes[ptr].ds_cnt;
                      }
                 }
-        
 
                if(steparray == NULL){
                    rrd_set_error("rpn expressions without DEF"
@@ -1015,8 +1040,10 @@ data_proc( image_desc_t *im ){
                        ** the time of the graph. Beware.
                        */
                        vidx = im->gdes[ii].vidx;
-                       if (    (gr_time >= im->gdes[vidx].start) &&
-                               (gr_time <= im->gdes[vidx].end) ) {
+                       if (im->gdes[vidx].gf == GF_VDEF) {
+                           value = im->gdes[vidx].vf.val;
+                       } else if (((long int)gr_time >= (long int)im->gdes[vidx].start) &&
+                                  ((long int)gr_time <= (long int)im->gdes[vidx].end) ) {
                            value = im->gdes[vidx].data[
                                (unsigned long) floor(
                                    (double)(gr_time - im->gdes[vidx].start)
@@ -1332,6 +1359,7 @@ print_calc(image_desc_t *im, char ***prdata)
        case GF_CDEF:       
        case GF_VDEF:       
        case GF_PART:
+       case GF_SHIFT:
        case GF_XPORT:
            break;
        }
@@ -1900,16 +1928,16 @@ grid_paint(image_desc_t   *im)
                          7, (im->yorigin - im->ysize/2),
                          im->graph_col[GRC_FONT],
                          im->text_prop[TEXT_PROP_AXIS].font,
-                         im->text_prop[TEXT_PROP_AXIS].size, im->tabwidth, 270.0,
+                         im->text_prop[TEXT_PROP_AXIS].size, im->tabwidth, 
+                         RRDGRAPH_YLEGEND_ANGLE,
                          GFX_H_LEFT, GFX_V_CENTER,
                          im->ylegend);
        } else {
            /* horrible hack until we can actually print vertically */
            {
                int n;
-               int l=strlen(im->ylegend);
                char s[2];
-               for (n=0;n<strlen(im->ylegend);n++) {
+               for (n=0;n< (int)strlen(im->ylegend);n++) {
                    s[0]=im->ylegend[n];
                    s[1]='\0';
                    gfx_new_text(im->canvas,7,im->text_prop[TEXT_PROP_AXIS].size*(n+1),
@@ -2347,6 +2375,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
     case GF_HRULE:
     case GF_VRULE:
     case GF_XPORT:
+    case GF_SHIFT:
       break;
     case GF_TICK:
       for (ii = 0; ii < im->xsize; ii++)
@@ -2543,13 +2572,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
 int
 gdes_alloc(image_desc_t *im){
 
-    unsigned long def_step = (im->end-im->start)/im->xsize;
-    
-    if (im->step > def_step) /* step can be increassed ... no decreassed */
-      def_step = im->step;
-
     im->gdes_c++;
-    
     if ((im->gdes = (graph_desc_t *) rrd_realloc(im->gdes, (im->gdes_c)
                                           * sizeof(graph_desc_t)))==NULL){
        rrd_set_error("realloc graph_descs");
@@ -2557,7 +2580,7 @@ gdes_alloc(image_desc_t *im){
     }
 
 
-    im->gdes[im->gdes_c-1].step=def_step; 
+    im->gdes[im->gdes_c-1].step=im->step;
     im->gdes[im->gdes_c-1].stack=0;
     im->gdes[im->gdes_c-1].debug=0;
     im->gdes[im->gdes_c-1].start=im->start; 
@@ -2568,6 +2591,7 @@ gdes_alloc(image_desc_t *im){
     im->gdes[im->gdes_c-1].data_first=0;
     im->gdes[im->gdes_c-1].p_data=NULL;
     im->gdes[im->gdes_c-1].rpnp=NULL;
+    im->gdes[im->gdes_c-1].shift=0;
     im->gdes[im->gdes_c-1].col = 0x0;
     im->gdes[im->gdes_c-1].legend[0]='\0';
     im->gdes[im->gdes_c-1].rrd[0]='\0';
@@ -2630,7 +2654,7 @@ rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize, FILE *s
     strncpy(im.graphfile,argv[optind],MAXPATH-1);
     im.graphfile[MAXPATH-1]='\0';
 
-    rrd_graph_script(argc,argv,&im);
+    rrd_graph_script(argc,argv,&im,1);
     if (rrd_test_error()) {
        im_free(&im);
        return -1;
@@ -2775,7 +2799,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
            {"lazy",       no_argument,       0,  'z'},
             {"zoom",       required_argument, 0,  'm'},
            {"no-legend",  no_argument,       0,  'g'},
-           {"only-graph", no_argument,       0,  'j'},
+            {"only-graph", no_argument,       0,  'j'},
            {"alt-y-grid", no_argument,       0,  'Y'},
             {"no-minor",   no_argument,       0,  'I'},
            {"alt-autoscale", no_argument,    0,  'A'},
@@ -2852,13 +2876,13 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
                      &im->xlab_user.precis,
                      &stroff) == 7 && stroff != 0){
                 strncpy(im->xlab_form, optarg+stroff, sizeof(im->xlab_form) - 1);
-               if((im->xlab_user.gridtm = tmt_conv(scan_gtm)) == -1){
+               if((int)(im->xlab_user.gridtm = tmt_conv(scan_gtm)) == -1){
                    rrd_set_error("unknown keyword %s",scan_gtm);
                    return;
-               } else if ((im->xlab_user.mgridtm = tmt_conv(scan_mtm)) == -1){
+               } else if ((int)(im->xlab_user.mgridtm = tmt_conv(scan_mtm)) == -1){
                    rrd_set_error("unknown keyword %s",scan_mtm);
                    return;
-               } else if ((im->xlab_user.labtm = tmt_conv(scan_ltm)) == -1){
+               } else if ((int)(im->xlab_user.labtm = tmt_conv(scan_ltm)) == -1){
                    rrd_set_error("unknown keyword %s",scan_ltm);
                    return;
                } 
@@ -2935,7 +2959,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
            im->imginfo = optarg;
            break;
        case 'a':
-           if((im->canvas->imgformat = if_conv(optarg)) == -1) {
+           if((int)(im->canvas->imgformat = if_conv(optarg)) == -1) {
                rrd_set_error("unsupported graphics format '%s'",optarg);
                return;
            }
@@ -3053,6 +3077,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
     
     im->start = start_tmp;
     im->end = end_tmp;
+    im->step = max((long)im->step, (im->end-im->start)/im->xsize);
 }
 
 int
@@ -3166,12 +3191,12 @@ char *str;
     
     n=0;
     sscanf(str,"%le,%29[A-Z]%n",&param,func,&n);
-    if (n==strlen(str)) { /* matched */
+    if (n== (int)strlen(str)) { /* matched */
        ;
     } else {
        n=0;
        sscanf(str,"%29[A-Z]%n",func,&n);
-       if (n==strlen(str)) { /* matched */
+       if (n== (int)strlen(str)) { /* matched */
            param=DNAN;
        } else {
            rrd_set_error("Unknown function string '%s' in VDEF '%s'"