patch to do vertical gradients

6 messages Options
Embed this post
Permalink
Rian Shelley

patch to do vertical gradients

Reply Threaded More More options
Print post
Permalink
Somebody on the irc channel suggested that I post this patch here. The
patch is against rrdtool 1.3.8.

This adds the GRAD element, which acts more or less like an AREA,
except you can specify a second color and a height which is used to
create a gradient from one color to the next.

I also attached an example graph that uses this patch. The gradients
in it are generated with these commands:

GRAD:ips#4444ff:half\\ firewall\\ states
GRAD:Bin#00cc00#0099441f:0:incoming\\ bandwidth

The syntax is
vname-or-value[#color[#color:gradientheight][:legend]][:STACK]

if the second color is missing, it is assumed to be #00000000 and the
gradientheight defaults to 50

gradientheight can actually produce 3 kinds of results depending on its value:
gradientheight > 0
    generates a fixed-height gradient from the data point down. (fire style)
gradientheight < 0
    generates a fixed-height gradient from the 0 line to the data
point. (fixed style)
gradientheight == 0
    generates a gradient that is stretched from the data point to the 0 line.
    this is what the example image is using.

I would appreciate any comments or suggestions.


--
rian

[grad.patch]

diff -crB rrdtool-1.3.8/src/rrd_gfx.c ../rrdtool-1.3.8/src/rrd_gfx.c
*** rrdtool-1.3.8/src/rrd_gfx.c Tue May 19 07:45:05 2009
--- ../rrdtool-1.3.8/src/rrd_gfx.c Thu Nov  5 10:17:01 2009
***************
*** 105,110 ****
--- 106,147 ----
      cairo_line_to(cr, x, y);
  }
 
+ /* add a point to a line or to an area */
+ void gfx_add_rect_fadey(
+     image_desc_t *im,
+     double x1,double y1,
+ double x2,double y2,
+ double py,
+     gfx_color_t color1,
+ gfx_color_t color2,
+ double height)
+ {
+     cairo_t  *cr = im->cr;
+    
+ cairo_new_path(cr);
+     gfx_area_fit(im, &x1, &y1);
+     gfx_area_fit(im, &x2, &y2);
+     cairo_line_to(cr, x1, y1);
+     cairo_line_to(cr, x1, y2);
+ cairo_line_to(cr, x2, y2);
+ cairo_line_to(cr, x2, y1);
+ cairo_close_path(cr);
+ cairo_pattern_t* p;
+ if (height < 0) {
+ p = cairo_pattern_create_linear(x1,y1,x2,y1+height);
+ } else if (height > 0) {
+ p = cairo_pattern_create_linear(x1,(y2+py)/2+height,x2,(y2+py)/2);
+ } else {
+ p = cairo_pattern_create_linear(x1,y1,x2,(y2+py)/2);
+ }
+ //cairo_pattern_t* p = cairo_pattern_create_linear(x1,py+50,x2,py);
+ cairo_pattern_add_color_stop_rgba(p, 1, color1.red,color1.green,color1.blue,color1.alpha);
+ cairo_pattern_add_color_stop_rgba(p, 0, color2.red,color2.green,color2.blue,color2.alpha);
+     cairo_set_source(cr, p);
+ cairo_pattern_destroy(p);
+ cairo_fill(cr);
+ }
+
  void gfx_close_path(
      image_desc_t *im)
  {
diff -crB rrdtool-1.3.8/src/rrd_graph.c ../rrdtool-1.3.8/src/rrd_graph.c
*** rrdtool-1.3.8/src/rrd_graph.c Tue May 19 07:45:05 2009
--- ../rrdtool-1.3.8/src/rrd_graph.c Thu Nov  5 10:19:45 2009
***************
*** 227,232 ****
--- 227,233 ----
      conv_if(VRULE, GF_VRULE);
      conv_if(LINE, GF_LINE);
      conv_if(AREA, GF_AREA);
+ conv_if(GRAD, GF_GRAD);
      conv_if(STACK, GF_STACK);
      conv_if(TICK, GF_TICK);
      conv_if(TEXTALIGN, GF_TEXTALIGN);
***************
*** 1176,1182 ****
      /* memory for the processed data */
      for (i = 0; i < im->gdes_c; i++) {
          if ((im->gdes[i].gf == GF_LINE) ||
!             (im->gdes[i].gf == GF_AREA) || (im->gdes[i].gf == GF_TICK)) {
              if ((im->gdes[i].p_data = (rrd_value_t*)(malloc((im->xsize + 1)
                                               * sizeof(rrd_value_t)))) == NULL) {
                  rrd_set_error("malloc data_proc");
--- 1177,1185 ----
      /* memory for the processed data */
      for (i = 0; i < im->gdes_c; i++) {
          if ((im->gdes[i].gf == GF_LINE) ||
!             (im->gdes[i].gf == GF_AREA) ||
! (im->gdes[i].gf == GF_GRAD) ||
! (im->gdes[i].gf == GF_TICK)) {
              if ((im->gdes[i].p_data = (rrd_value_t*)(malloc((im->xsize + 1)
                                               * sizeof(rrd_value_t)))) == NULL) {
                  rrd_set_error("malloc data_proc");
***************
*** 1197,1202 ****
--- 1200,1206 ----
              switch (im->gdes[ii].gf) {
              case GF_LINE:
              case GF_AREA:
+ case GF_GRAD:
              case GF_TICK:
                  if (!im->gdes[ii].stack)
                      paintval = 0.0;
***************
*** 1576,1581 ****
--- 1580,1586 ----
              break;
          case GF_LINE:
          case GF_AREA:
+ case GF_GRAD:
          case GF_TICK:
              graphelement = 1;
              break;
***************
*** 3208,3213 ****
--- 3213,3219 ----
              break;
          case GF_LINE:
          case GF_AREA:
+ case GF_GRAD:
              /* fix data points at oo and -oo */
              for (ii = 0; ii < im->xsize; ii++) {
                  if (isinf(im->gdes[i].p_data[ii])) {
***************
*** 3306,3311 ****
--- 3312,3319 ----
                      cairo_stroke(im->cr);
                      cairo_restore(im->cr);
                  } else {
+ double lastx=0;
+ double lasty=0;
                      int       idxI = -1;
                      double   *foreY =
                          (double *) malloc(sizeof(double) * im->xsize * 2);
***************
*** 3336,3347 ****
                                                             [cntI + 1], 4)) {
                                  cntI++;
                              }
!                             gfx_new_area(im,
!                                          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
--- 3344,3360 ----
                                                             [cntI + 1], 4)) {
                                  cntI++;
                              }
! if (im->gdes[i].gf != GF_GRAD) {
!                             gfx_new_area(im,
!                                         backX[0], backY[0],
!                                         foreX[0], foreY[0],
!                                         foreX[cntI],
!                                         foreY[cntI], im->gdes[i].col);
! } else {
! lastx = foreX[cntI];
! lasty = foreY[cntI];
! }
! while (cntI < idxI) {
                                  lastI = cntI;
                                  cntI++;
                                  while (cntI < idxI
***************
*** 3357,3365 ****
                                                                  + 1], 4)) {
                                      cntI++;
                                  }
!                                 gfx_add_point(im, foreX[cntI], foreY[cntI]);
                              }
!                             gfx_add_point(im, backX[idxI], backY[idxI]);
                              while (idxI > 1) {
                                  lastI = idxI;
                                  idxI--;
--- 3370,3401 ----
                                                                  + 1], 4)) {
                                      cntI++;
                                  }
! if (im->gdes[i].gf != GF_GRAD) {
!                                gfx_add_point(im, foreX[cntI], foreY[cntI]);
! } else {
! gfx_add_rect_fadey(im,
! lastx, foreY[0],
! foreX[cntI], foreY[cntI], lasty,
! im->gdes[i].col,
! im->gdes[i].col2,
! im->gdes[i].gradheight
! );
! lastx = foreX[cntI];
! lasty = foreY[cntI];
! }
                              }
! if (im->gdes[i].gf != GF_GRAD) {
!                             gfx_add_point(im, backX[idxI], backY[idxI]);
! } else {
! gfx_add_rect_fadey(im,
! lastx, foreY[0],
! backX[idxI], backY[idxI], lasty,
! im->gdes[i].col,
! im->gdes[i].col2,
! im->gdes[i].gradheight);
! lastx = backX[idxI];
! lasty = backY[idxI];
! }
                              while (idxI > 1) {
                                  lastI = idxI;
                                  idxI--;
***************
*** 3376,3386 ****
                                                                  - 1], 4)) {
                                      idxI--;
                                  }
!                                 gfx_add_point(im, backX[idxI], backY[idxI]);
                              }
                              idxI = -1;
                              drawem = 0;
!                             gfx_close_path(im);
                          }
                          if (drawem != 0) {
                              drawem = 0;
--- 3412,3434 ----
                                                                  - 1], 4)) {
                                      idxI--;
                                  }
! if (im->gdes[i].gf != GF_GRAD) {
!                                gfx_add_point(im, backX[idxI], backY[idxI]);
! } else {
! gfx_add_rect_fadey(im,
! lastx, foreY[0],
! backX[idxI], backY[idxI], lasty,
! im->gdes[i].col,
! im->gdes[i].col2,
! im->gdes[i].gradheight);
! lastx = backX[idxI];
! lasty = backY[idxI];
! }
                              }
                              idxI = -1;
                              drawem = 0;
! if (im->gdes[i].gf != GF_GRAD)
!                            gfx_close_path(im);
                          }
                          if (drawem != 0) {
                              drawem = 0;
***************
*** 3574,3579 ****
--- 3622,3632 ----
      im->gdes[im->gdes_c - 1].col.green = 0.0;
      im->gdes[im->gdes_c - 1].col.blue = 0.0;
      im->gdes[im->gdes_c - 1].col.alpha = 0.0;
+     im->gdes[im->gdes_c - 1].col2.red = 0.0;
+     im->gdes[im->gdes_c - 1].col2.green = 0.0;
+     im->gdes[im->gdes_c - 1].col2.blue = 0.0;
+     im->gdes[im->gdes_c - 1].col2.alpha = 0.0;
+     im->gdes[im->gdes_c - 1].gradheight = 50.0;
      im->gdes[im->gdes_c - 1].legend[0] = '\0';
      im->gdes[im->gdes_c - 1].format[0] = '\0';
      im->gdes[im->gdes_c - 1].strftm = 0;
diff -crB rrdtool-1.3.8/src/rrd_graph.h ../rrdtool-1.3.8/src/rrd_graph.h
*** rrdtool-1.3.8/src/rrd_graph.h Fri Dec 26 01:05:03 2008
--- ../rrdtool-1.3.8/src/rrd_graph.h Thu Nov  5 10:36:52 2009
***************
*** 51,57 ****
  #define GRIDWIDTH  0.4
 
  enum gf_en { GF_PRINT = 0, GF_GPRINT, GF_COMMENT, GF_HRULE, GF_VRULE, GF_LINE,
!     GF_AREA, GF_STACK, GF_TICK, GF_TEXTALIGN,
      GF_DEF, GF_CDEF, GF_VDEF, GF_SHIFT,
      GF_XPORT
  };
--- 51,57 ----
  #define GRIDWIDTH  0.4
 
  enum gf_en { GF_PRINT = 0, GF_GPRINT, GF_COMMENT, GF_HRULE, GF_VRULE, GF_LINE,
!     GF_AREA,GF_GRAD, GF_STACK, GF_TICK, GF_TEXTALIGN,
      GF_DEF, GF_CDEF, GF_VDEF, GF_SHIFT,
      GF_XPORT
  };
***************
*** 156,162 ****
      long      ds;       /* data source number */
      enum cf_en cf;      /* consolidation function */
      enum cf_en cf_reduce;   /* consolidation function for reduce_data() */
!     struct gfx_color_t col; /* graph color */
      char      format[FMT_LEG_LEN + 5];  /* format for PRINT AND GPRINT */
      char      legend[FMT_LEG_LEN + 5];  /* legend */
      int       strftm;   /* should the VDEF legend be formated with strftime */
--- 156,163 ----
      long      ds;       /* data source number */
      enum cf_en cf;      /* consolidation function */
      enum cf_en cf_reduce;   /* consolidation function for reduce_data() */
!     struct gfx_color_t col, col2; /* graph color */
! double    gradheight;
      char      format[FMT_LEG_LEN + 5];  /* format for PRINT AND GPRINT */
      char      legend[FMT_LEG_LEN + 5];  /* legend */
      int       strftm;   /* should the VDEF legend be formated with strftime */
***************
*** 424,429 ****
--- 425,449 ----
      double x,
      double y);
 
+ /* create a rect that has a gradient from color1 to color2 in height pixels
+  * height > 0:
+  * gradient starts at top and goes down a fixed number of pixels (fire style)
+  * height < 0:
+  * gradient starts at bottom and goes up a fixed number of pixels (constant style)
+  * height == 0:
+  * gradient is stretched between two points
+  */
+ void gfx_add_rect_fadey(
+     image_desc_t *im,
+     double x1,double y1,
+     double x2,double y2,
+ double py,
+     gfx_color_t color1,
+ gfx_color_t color2,
+ double height);
+
+
+
  /* close current path so it ends at the same point as it started */
  void      gfx_close_path(
      image_desc_t *im);
diff -crB rrdtool-1.3.8/src/rrd_graph_helper.c ../rrdtool-1.3.8/src/rrd_graph_helper.c
*** rrdtool-1.3.8/src/rrd_graph_helper.c Tue May 19 07:45:05 2009
--- ../rrdtool-1.3.8/src/rrd_graph_helper.c Thu Nov  5 10:38:27 2009
***************
*** 532,538 ****
      graph_desc_t *const gdp,
      image_desc_t *const im)
  {
!     int       i, j, k;
      int       colorfound = 0;
      char      tmpstr[MAX_VNAME_LEN + 10];   /* vname#RRGGBBAA\0 */
      static int spacecnt = 0;
--- 532,538 ----
      graph_desc_t *const gdp,
      image_desc_t *const im)
  {
!     int       i, j, k, j2;
      int       colorfound = 0;
      char      tmpstr[MAX_VNAME_LEN + 10];   /* vname#RRGGBBAA\0 */
      static int spacecnt = 0;
***************
*** 567,576 ****
          rrd_set_error("Cannot parse line '%s'", line);
          return 1;
      }
!
!     j = i;
      while (j > 0 && tmpstr[j] != '#')
          j--;
 
      if (j) {
          tmpstr[j] = '\0';
--- 567,588 ----
          rrd_set_error("Cannot parse line '%s'", line);
          return 1;
      }
!    
! j = i;
      while (j > 0 && tmpstr[j] != '#')
          j--;
+ //see if there is a second color
+ j2 = j-1;
+ while (j2 > 0 && tmpstr[j2] != '#')
+ j2--;
+ if (j && j2) {   //yes, swap j and j2, so that j is first color, j2 is second
+ int tmp = j;
+ j = j2;
+ j2 = tmp;
+ tmpstr[j2] = '\0';
+ } else {
+ j2 = 0;
+ }
 
      if (j) {
          tmpstr[j] = '\0';
***************
*** 578,585 ****
      /* We now have:
       * tmpstr[0]    containing vname
       * tmpstr[j]    if j!=0 then containing color
!      * i            size of vname + color
       * j            if j!=0 then size of vname
       */
 
      /* Number or vname ?
--- 590,599 ----
      /* We now have:
       * tmpstr[0]    containing vname
       * tmpstr[j]    if j!=0 then containing color
!      * tmpstr[j2]   if j2!=0 then containing second color
!      * i            size of vname
       * j            if j!=0 then size of vname
+      * j2 if j2!=0 then size of vname + first color
       */
 
      /* Number or vname ?
***************
*** 644,649 ****
--- 658,690 ----
          dprintf("- parsed color %0.0f,%0.0f,%0.0f,%0.0f\n", gdp->col.red,
                  gdp->col.green, gdp->col.blue, gdp->col.alpha);
          colorfound = 1;
+ if (j2) { //second color?
+ j2++;
+ dprintf("- examining second color '%s'\n", &tmpstr[j2]);
+ //TODO: maybe rrd_parse_color should take a pointer to gdp->col instead of gdp
+ struct gfx_color_t firstcol = gdp->col;
+         if (rrd_parse_color(&tmpstr[j2], gdp)) {
+             rrd_set_error("Could not parse color in '%s'", &tmpstr[j2]);
+            return 1;
+        }
+         dprintf("- parsed color %0.0f,%0.0f,%0.0f,%0.0f\n", gdp->col.red,
+                gdp->col.green, gdp->col.blue, gdp->col.alpha);
+ gdp->col2 = gdp->col;
+ gdp->col = firstcol;
+ //we now have a mandatory grid height
+     (*eaten) += i;
+ if (line[*eaten] != '\0') {
+ (*eaten)++;
+ }
+ dprintf("- examining gradient height\n");
+ i = scan_for_col(&line[*eaten], MAX_VNAME_LEN + 9, tmpstr);
+ sscanf(tmpstr, "%lf%n", &gdp->gradheight, &j);
+ if (i != j) {
+ rrd_set_error("Could not parse gradient height in '%s'", tmpstr);
+ return 1;
+ }
+ dprintf("- parsed gradientheight %0.0f\n", gdp->gradheight);
+ }
      } else {
          dprintf("- no color present in '%s'\n", tmpstr);
      }
***************
*** 1113,1118 ****
--- 1154,1160 ----
          case GF_HRULE: /* value#color[:legend] */
          case GF_LINE:  /* vname-or-value[#color[:legend]][:STACK] */
          case GF_AREA:  /* vname-or-value[#color[:legend]][:STACK] */
+ case GF_GRAD:  /* vname-or-value[#color[:legend][#color[:gradientheight]]][:STACK] */
          case GF_TICK:  /* vname#color[:num[:legend]] */
              if (rrd_parse_PVHLAST(argv[i], &eaten, gdp, im))
                  return;
***************
*** 1122,1128 ****
          case GF_STACK: /* vname-or-value[#color[:legend]] */
              if (rrd_parse_PVHLAST(argv[i], &eaten, gdp, im))
                  return;
!             if (last_gf == GF_LINE || last_gf == GF_AREA) {
                  gdp->gf = last_gf;
                  gdp->linewidth = last_linewidth;
              } else {
--- 1164,1170 ----
          case GF_STACK: /* vname-or-value[#color[:legend]] */
              if (rrd_parse_PVHLAST(argv[i], &eaten, gdp, im))
                  return;
!             if (last_gf == GF_LINE || last_gf == GF_AREA || last_gf == GF_GRAD) {
                  gdp->gf = last_gf;
                  gdp->linewidth = last_linewidth;
              } else {



_______________________________________________
rrd-developers mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers

samplegradientgraph.png (98K) Download Attachment
Rian Shelley

Re: patch to do vertical gradients

Reply Threaded More More options
Print post
Permalink
> thanks for this ... it looks cool ... quersion though, is there
> some information carying capability in this feature ?

Not really. For the most part, I wanted to add some control over how
the AREA's were drawn, especially when you have two of them on the
same graph that keep covering one another, it makes it easier for the
eye to pick out the two graphs, as opposed to simply using an alpha,
which gives a solid color that can be mis-interpreted as another
graph.

I also wanted the ability to make it so that peak values could be
highlighted in a different color if desired, as in a cpu graph going
from green through yellow to red.

I haven't thought about making it carry information, although it might
be neat to show temporal distribution of an average value (ie, turn
the dataset on its side, and make it represent color instead of
displacement). I don't really know how to get into that, since all
I've played with so far is the drawing code.

>
> can you please also add a patch for the documentation ?

Hopefully the attached patch will suffice.


--
rian

_______________________________________________
rrd-developers mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers
Rian Shelley

Re: patch to do vertical gradients

Reply Threaded More More options
Print post
Permalink
This time i remembered to attach the patch :D


> thanks for this ... it looks cool ... quersion though, is there
> some information carying capability in this feature ?

Not really. For the most part, I wanted to add some control over how
the AREA's were drawn, especially when you have two of them on the
same graph that keep covering one another, it makes it easier for the
eye to pick out the two graphs, as opposed to simply using an alpha,
which gives a solid color that can be mis-interpreted as another
graph.

I also wanted the ability to make it so that peak values could be
highlighted in a different color if desired, as in a cpu graph going
from green through yellow to red.

I haven't thought about making it carry information, although it might
be neat to show temporal distribution of an average value (ie, turn
the dataset on its side, and make it represent color instead of
displacement). I don't really know how to get into that, since all
I've played with so far is the drawing code.

>
> can you please also add a patch for the documentation ?

Hopefully the attached patch will suffice.


--
rian

[grad_doc.patch]

diff -crB rrdtool-1.3.8/doc/rrdgraph_graph.pod ../rrdtool-1.3.8/doc/rrdgraph_graph.pod
*** rrdtool-1.3.8/doc/rrdgraph_graph.pod Sat Feb 21 02:43:58 2009
--- ../rrdtool-1.3.8/doc/rrdgraph_graph.pod Thu Nov  5 12:23:08 2009
***************
*** 262,267 ****
--- 262,275 ----
  See B<LINE>, however the area between the x-axis and the line will
  be filled.
 
+ =head3 B<GRAD>B<:>I<value>[B<#>I<color1>[B<#>I<color2>B<:>I<height>][B<:>[I<legend>][B<:STACK>]]
+
+ Similar to B<AREA>, except the area between the line and the x-axis will contain a gradient from color1 to color2.
+
+ The I<height> parameter can create three different behaviors. If I<height> > 0, then the gradient is a fixed height, starting at the line going down. If I<height> < 0, then the gradient starts at fixed height above the x-axis, going down to the x-axis. If I<height> == 0, then the gradient goes from the line to x-axis.
+
+ If not present, I<color2> defaults to #00000000 and I<height> defaults to 50.
+
  =head3 B<TICK>B<:>I<vname>B<#>I<rrggbb>[I<aa>][B<:>I<fraction>[B<:>I<legend>]]
 
  Plot a tick mark (a vertical line) for each value of I<vname> that is


_______________________________________________
rrd-developers mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers
oetiker

Re: patch to do vertical gradients

Reply Threaded More More options
Print post
Permalink
Hi Rian,

Today Rian Shelley wrote:

> This time i remembered to attach the patch :D
>
>
> > thanks for this ... it looks cool ... quersion though, is there
> > some information carying capability in this feature ?
>
> Not really. For the most part, I wanted to add some control over how
> the AREA's were drawn, especially when you have two of them on the
> same graph that keep covering one another, it makes it easier for the
> eye to pick out the two graphs, as opposed to simply using an alpha,
> which gives a solid color that can be mis-interpreted as another
> graph.
>
> I also wanted the ability to make it so that peak values could be
> highlighted in a different color if desired, as in a cpu graph going
> from green through yellow to red.
>
> I haven't thought about making it carry information, although it might
> be neat to show temporal distribution of an average value (ie, turn
> the dataset on its side, and make it represent color instead of
> displacement). I don't really know how to get into that, since all
> I've played with so far is the drawing code.
>
> >
> > can you please also add a patch for the documentation ?
>
> Hopefully the attached patch will suffice.

great ... thanks very much
tobi

>
>
> --
> rian
>

--
Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
http://it.oetiker.ch [hidden email] ++41 62 775 9902 / sb: -9900

_______________________________________________
rrd-developers mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers
Mark Mills-2

Re: patch to do vertical gradients

Reply Threaded More More options
Print post
Permalink
Tobias Oetiker wrote:
>>> thanks for this ... it looks cool ... quersion though, is there
>>> some information carying capability in this feature ?
>>>      
If it was used to carry information, one that might help would be scale
differences. I have had issues in the past where my boss at the time
freaked out when a graph spiked and we had to point out that the one he
was looking at had spiked from bits to kbits... not from mbits to gbits.
;-) A way to color the scale in the area (logarithmically?) would help
when scanning graphs quickly. It wouldn't give the same cool fire effect
but "ripples" in the area paint could effectively replace the need for
grid lines.


I'd also recommend that the default second color be set to the graph
background color with the transparency set to 0x20 and not be forced to
#000000. Might as well make it do something cool by default no matter
what color scheme they use.

Also, I'm jealous of Rian because I've been wanting to write this patch
for like 5-6 years and never had the time. ;-) It looks even better than
I hoped. I'm looking forward to this being in the main build.

--mark

_______________________________________________
rrd-developers mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers
Rian Shelley

Re: patch to do vertical gradients

Reply Threaded More More options
Print post
Permalink
On Fri, Nov 6, 2009 at 7:20 AM, Mark Mills <[hidden email]> wrote:
> If it was used to carry information, one that might help would be scale
> differences. I have had issues in the past where my boss at the time
> freaked out when a graph spiked and we had to point out that the one he
> was looking at had spiked from bits to kbits... not from mbits to gbits.
> ;-) A way to color the scale in the area (logarithmically?) would help
> when scanning graphs quickly. It wouldn't give the same cool fire effect
> but "ripples" in the area paint could effectively replace the need for
> grid lines.

Thats one of the reasons I wrote it. A negative height would be
aligned to the x axis, so that increasing values on the line change to
the next color, ie a gradient from green to red. Of course, to be
really useful, I would need to change it so that the height was
relative to the data set, and not given in pixels. I'll have to see
how to do that. gfx_area_fit maybe?

> I'd also recommend that the default second color be set to the graph
> background color with the transparency set to 0x20 and not be forced to
> #000000. Might as well make it do something cool by default no matter
> what color scheme they use.

Maybe. I figured it didn't matter much what the color was if the alpha
was zero. That way it always appeared to fade into whatever is behind
it, be it the background or another AREA. I'll have to play with it
and see what it looks like.

> Also, I'm jealous of Rian because I've been wanting to write this patch
> for like 5-6 years and never had the time. ;-) It looks even better than
> I hoped. I'm looking forward to this being in the main build.

All the heavy lifting is done by cairo :D. All I did was allow the
source pattern to be a gradient as well as a solid color. I think the
other option is to make the source pattern another image.

--
rian

_______________________________________________
rrd-developers mailing list
[hidden email]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers