From: Maksym Sobolyev Date: Thu, 29 Jan 2015 22:29:57 +0000 (-0800) Subject: Improve auto-scaling of gridlines and placement of x-labels when X-Git-Tag: v1.5.0-rc2~14^2^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d9cb4610661dffba310e562c85bc4987aeca081;p=thirdparty%2Frrdtool-1.x.git Improve auto-scaling of gridlines and placement of x-labels when plotted_time/pixel ratio gets smaller than 2. This significantly improves readability of small graphs (i.e. around 400-pixels wide) when time range plotted becomes less than 600 seconds. Before this change you would only get few gridlines and from 1-2 to 0 labels depending on how lucky are you. Some examples of such graphs can be found here. "o" vs. "n" prefix denotes behaviour before and after the change respectively, and number after that denotes full scale of x axis in seconds: Before: http://sobomax.sippysoft.com/rrdtool/o660.png http://sobomax.sippysoft.com/rrdtool/o600.png http://sobomax.sippysoft.com/rrdtool/o540.png http://sobomax.sippysoft.com/rrdtool/o480.png http://sobomax.sippysoft.com/rrdtool/o420.png http://sobomax.sippysoft.com/rrdtool/o360.png http://sobomax.sippysoft.com/rrdtool/o300.png http://sobomax.sippysoft.com/rrdtool/o240.png http://sobomax.sippysoft.com/rrdtool/o180.png http://sobomax.sippysoft.com/rrdtool/o120.png After: http://sobomax.sippysoft.com/rrdtool/n660.png http://sobomax.sippysoft.com/rrdtool/n600.png http://sobomax.sippysoft.com/rrdtool/n540.png http://sobomax.sippysoft.com/rrdtool/n480.png http://sobomax.sippysoft.com/rrdtool/n420.png http://sobomax.sippysoft.com/rrdtool/n360.png http://sobomax.sippysoft.com/rrdtool/n300.png http://sobomax.sippysoft.com/rrdtool/n240.png http://sobomax.sippysoft.com/rrdtool/n180.png http://sobomax.sippysoft.com/rrdtool/n120.png --- diff --git a/src/rrd_graph.c b/src/rrd_graph.c index 83693470..89075c49 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -79,49 +79,53 @@ text_prop_t text_prop[] = { char week_fmt[128] = "Week %V"; xlab_t xlab[] = { - {0, 0, TMT_SECOND, 30, TMT_MINUTE, 5, TMT_MINUTE, 5, 0, "%H:%M"} + {0.0, 0, TMT_SECOND, 10, TMT_MINUTE, 1, TMT_MINUTE, 1, 0, "%H:%M"} , - {2, 0, TMT_MINUTE, 1, TMT_MINUTE, 5, TMT_MINUTE, 5, 0, "%H:%M"} + {0.6, 0, TMT_SECOND, 20, TMT_MINUTE, 1, TMT_MINUTE, 1, 0, "%H:%M"} , - {5, 0, TMT_MINUTE, 2, TMT_MINUTE, 10, TMT_MINUTE, 10, 0, "%H:%M"} + {1.0, 0, TMT_SECOND, 30, TMT_MINUTE, 2, TMT_MINUTE, 2, 0, "%H:%M"} , - {10, 0, TMT_MINUTE, 5, TMT_MINUTE, 20, TMT_MINUTE, 20, 0, "%H:%M"} + {2.0, 0, TMT_MINUTE, 1, TMT_MINUTE, 5, TMT_MINUTE, 5, 0, "%H:%M"} , - {30, 0, TMT_MINUTE, 10, TMT_HOUR, 1, TMT_HOUR, 1, 0, "%H:%M"} + {5.0, 0, TMT_MINUTE, 2, TMT_MINUTE, 10, TMT_MINUTE, 10, 0, "%H:%M"} , - {60, 0, TMT_MINUTE, 30, TMT_HOUR, 2, TMT_HOUR, 2, 0, "%H:%M"} + {10.0, 0, TMT_MINUTE, 5, TMT_MINUTE, 20, TMT_MINUTE, 20, 0, "%H:%M"} , - {60, 24 * 3600, TMT_MINUTE, 30, TMT_HOUR, 2, TMT_HOUR, 6, 0, "%a %H:%M"} + {30.0, 0, TMT_MINUTE, 10, TMT_HOUR, 1, TMT_HOUR, 1, 0, "%H:%M"} , - {180, 0, TMT_HOUR, 1, TMT_HOUR, 6, TMT_HOUR, 6, 0, "%H:%M"} + {60.0, 0, TMT_MINUTE, 30, TMT_HOUR, 2, TMT_HOUR, 2, 0, "%H:%M"} , - {180, 24 * 3600, TMT_HOUR, 1, TMT_HOUR, 6, TMT_HOUR, 12, 0, "%a %H:%M"} + {60.0, 24 * 3600, TMT_MINUTE, 30, TMT_HOUR, 2, TMT_HOUR, 6, 0, "%a %H:%M"} + , + {180.0, 0, TMT_HOUR, 1, TMT_HOUR, 6, TMT_HOUR, 6, 0, "%H:%M"} + , + {180.0, 24 * 3600, TMT_HOUR, 1, TMT_HOUR, 6, TMT_HOUR, 12, 0, "%a %H:%M"} , /*{300, 0, TMT_HOUR,3, TMT_HOUR,12, TMT_HOUR,12, 12*3600,"%a %p"}, this looks silly */ - {600, 0, TMT_HOUR, 6, TMT_DAY, 1, TMT_DAY, 1, 24 * 3600, "%a"} + {600.0, 0, TMT_HOUR, 6, TMT_DAY, 1, TMT_DAY, 1, 24 * 3600, "%a"} , - {1200, 0, TMT_HOUR, 6, TMT_DAY, 1, TMT_DAY, 1, 24 * 3600, "%d"} + {1200.0, 0, TMT_HOUR, 6, TMT_DAY, 1, TMT_DAY, 1, 24 * 3600, "%d"} , - {1800, 0, TMT_HOUR, 12, TMT_DAY, 1, TMT_DAY, 2, 24 * 3600, "%a %d"} + {1800.0, 0, TMT_HOUR, 12, TMT_DAY, 1, TMT_DAY, 2, 24 * 3600, "%a %d"} , - {2400, 0, TMT_HOUR, 12, TMT_DAY, 1, TMT_DAY, 2, 24 * 3600, "%a"} + {2400.0, 0, TMT_HOUR, 12, TMT_DAY, 1, TMT_DAY, 2, 24 * 3600, "%a"} , - {3600, 0, TMT_DAY, 1, TMT_WEEK, 1, TMT_WEEK, 1, 7 * 24 * 3600, week_fmt} + {3600.0, 0, TMT_DAY, 1, TMT_WEEK, 1, TMT_WEEK, 1, 7 * 24 * 3600, week_fmt} , - {3 * 3600, 0, TMT_WEEK, 1, TMT_MONTH, 1, TMT_WEEK, 2, 7 * 24 * 3600, week_fmt} + {3.0 * 3600.0, 0, TMT_WEEK, 1, TMT_MONTH, 1, TMT_WEEK, 2, 7 * 24 * 3600, week_fmt} , - {6 * 3600, 0, TMT_MONTH, 1, TMT_MONTH, 1, TMT_MONTH, 1, 30 * 24 * 3600, + {6.0 * 3600.0, 0, TMT_MONTH, 1, TMT_MONTH, 1, TMT_MONTH, 1, 30 * 24 * 3600, "%b"} , - {48 * 3600, 0, TMT_MONTH, 1, TMT_MONTH, 3, TMT_MONTH, 3, 30 * 24 * 3600, + {48.0 * 3600.0, 0, TMT_MONTH, 1, TMT_MONTH, 3, TMT_MONTH, 3, 30 * 24 * 3600, "%b"} , - {315360, 0, TMT_MONTH, 3, TMT_YEAR, 1, TMT_YEAR, 1, 365 * 24 * 3600, "%Y"} + {315360.0, 0, TMT_MONTH, 3, TMT_YEAR, 1, TMT_YEAR, 1, 365 * 24 * 3600, "%Y"} , - {10 * 24 * 3600, 0, TMT_YEAR, 1, TMT_YEAR, 1, TMT_YEAR, 1, + {(double)(10 * 24 * 3600), 0, TMT_YEAR, 1, TMT_YEAR, 1, TMT_YEAR, 1, 365 * 24 * 3600, "%y"} , - {-1, 0, TMT_MONTH, 0, TMT_MONTH, 0, TMT_MONTH, 0, 0, ""} + {-1.0, 0, TMT_MONTH, 0, TMT_MONTH, 0, TMT_MONTH, 0, 0, ""} }; /* sensible y label intervals ...*/ @@ -2547,21 +2551,21 @@ void vertical_grid( { int xlab_sel; /* which sort of label and grid ? */ time_t ti, tilab, timajor; - long factor; + double factor; char graph_label[100]; double X0, Y0, Y1; /* points for filled graph and more */ struct tm tm; /* the type of time grid is determined by finding the number of seconds per pixel in the graph */ - if (im->xlab_user.minsec == -1) { - factor = (im->end - im->start) / im->xsize; + if (im->xlab_user.minsec == -1.0) { + factor = (double)(im->end - im->start) / (double)im->xsize; xlab_sel = 0; while (xlab[xlab_sel + 1].minsec != - -1 && xlab[xlab_sel + 1].minsec <= factor) { + -1.0 && xlab[xlab_sel + 1].minsec <= factor) { xlab_sel++; } /* pick the last one */ - while (xlab[xlab_sel - 1].minsec == + while (xlab_sel > 0 && xlab[xlab_sel - 1].minsec == xlab[xlab_sel].minsec && xlab[xlab_sel].length > (im->end - im->start)) { xlab_sel--; @@ -4370,7 +4374,7 @@ void rrd_graph_init( im->xlab_form = NULL; im->with_markup = 0; im->ximg = 0; - im->xlab_user.minsec = -1; + im->xlab_user.minsec = -1.0; im->xorigin = 0; im->xOriginLegend = 0; im->xOriginLegendY = 0; @@ -4662,7 +4666,7 @@ void rrd_graph_options( rrd_set_error("unknown keyword %s", scan_ltm); return; } - im->xlab_user.minsec = 1; + im->xlab_user.minsec = 1.0; im->xlab_user.stst = im->xlab_form ? im->xlab_form : ""; } else { rrd_set_error("invalid x-grid format"); diff --git a/src/rrd_graph.h b/src/rrd_graph.h index bb51b5e7..12ea8b52 100644 --- a/src/rrd_graph.h +++ b/src/rrd_graph.h @@ -165,7 +165,7 @@ typedef struct vdef_t { } vdef_t; typedef struct xlab_t { - long minsec; /* minimum sec per pix */ + double minsec; /* minimum sec per pix */ long length; /* number of secs on the image */ enum tmt_en gridtm; /* grid interval in what ? */ long gridst; /* how many whats per grid */ diff --git a/src/rrd_xport.c b/src/rrd_xport.c index 5623c597..15cd0d2e 100644 --- a/src/rrd_xport.c +++ b/src/rrd_xport.c @@ -530,7 +530,7 @@ int addToBuffer(stringbuffer_t * sb,char* data,size_t len) { int rrd_xport_format_sv(char sep, stringbuffer_t *buffer,image_desc_t *im,time_t start, time_t end, unsigned long step, unsigned long col_cnt, char **legend_v, rrd_value_t* data) { /* define the time format */ char* timefmt=NULL; - if (im->xlab_user.minsec!=-1) { timefmt=im->xlab_user.stst; } + if (im->xlab_user.minsec!=-1.0) { timefmt=im->xlab_user.stst; } /* row count */ unsigned long row_cnt=(end-start)/step; @@ -601,7 +601,7 @@ int rrd_xport_format_xmljson(int flags,stringbuffer_t *buffer,image_desc_t *im,t /* unfortunatley we have to do it this way, as when no --x-graph argument is given, then the xlab_user is not in a clean state (e.g. zero-filled) */ - if (im->xlab_user.minsec!=-1) { timefmt=im->xlab_user.stst; } + if (im->xlab_user.minsec!=-1.0) { timefmt=im->xlab_user.stst; } /* row count */ unsigned long row_cnt=(end-start)/step; @@ -862,7 +862,7 @@ int rrd_xport_format_addprints(int flags,stringbuffer_t *buffer,image_desc_t *im char dbuf[1024]; char* val; char* timefmt=NULL; - if (im->xlab_user.minsec!=-1) { timefmt=im->xlab_user.stst; } + if (im->xlab_user.minsec!=-1.0) { timefmt=im->xlab_user.stst; } /* define some other stuff based on flags */ int json=0;