diff --git a/src/rrd_graph.c b/src/rrd_graph.c
index 5c739becc9cf8459cbdaf0042f957815ce2cc2b4..3f8ee1bff143af2dc004eb0e83ffaac4200b8e9f 100644 (file)
--- a/src/rrd_graph.c
+++ b/src/rrd_graph.c
{5.5, RRD_DEFAULT_FONT,NULL} /* watermark */
};
{5.5, RRD_DEFAULT_FONT,NULL} /* watermark */
};
+char week_fmt[128] = "Week %V";
+
xlab_t xlab[] = {
{0, 0, TMT_SECOND, 30, TMT_MINUTE, 5, TMT_MINUTE, 5, 0, "%H:%M"}
,
xlab_t xlab[] = {
{0, 0, TMT_SECOND, 30, TMT_MINUTE, 5, TMT_MINUTE, 5, 0, "%H:%M"}
,
,
{2400, 0, TMT_HOUR, 12, TMT_DAY, 1, TMT_DAY, 2, 24 * 3600, "%a"}
,
,
{2400, 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 %V"}
+ {3600, 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,
,
{3 * 3600, 0, TMT_WEEK, 1, TMT_MONTH, 1, TMT_WEEK, 2, 7 * 24 * 3600,
- "Week %V"}
+ week_fmt}
,
{6 * 3600, 0, TMT_MONTH, 1, TMT_MONTH, 1, TMT_MONTH, 1, 30 * 24 * 3600,
"%b"}
,
{6 * 3600, 0, TMT_MONTH, 1, TMT_MONTH, 1, TMT_MONTH, 1, 30 * 24 * 3600,
"%b"}
&im->gdes[i].ds_cnt,
&im->gdes[i].ds_namv,
&im->gdes[i].data)) == -1) {
&im->gdes[i].ds_cnt,
&im->gdes[i].ds_namv,
&im->gdes[i].data)) == -1) {
- return -1;
- }
+ return -1;
+ }
}
im->gdes[i].data_first = 1;
}
im->gdes[i].data_first = 1;
+ /* must reduce to at least im->step
+ otherwhise we end up with more data than we can handle in the
+ chart and visibility of data will be random */
+ im->gdes[i].step = max(im->gdes[i].step,im->step);
if (ft_step < im->gdes[i].step) {
reduce_data(im->gdes[i].cf_reduce,
ft_step,
if (ft_step < im->gdes[i].step) {
reduce_data(im->gdes[i].cf_reduce,
ft_step,
localtime_r(¤t, &tm);
localtime_r(¤t, &tm);
+ int limit = 2;
+ switch (baseint) {
+ case TMT_SECOND: limit = 7200; break;
+ case TMT_MINUTE: limit = 120; break;
+ case TMT_HOUR: limit = 2; break;
+ default: limit = 2; break;
+ }
do {
switch (baseint) {
case TMT_SECOND:
do {
switch (baseint) {
case TMT_SECOND:
tm. tm_year += basestep;
}
madetime = mktime(&tm);
tm. tm_year += basestep;
}
madetime = mktime(&tm);
- } while (madetime == -1); /* this is necessary to skip impssible times
+ } while (madetime == -1 && limit-- >= 0); /* this is necessary to skip impossible times
like the daylight saving time skips */
return madetime;
like the daylight saving time skips */
return madetime;
}
} /* prepare printval */
}
} /* prepare printval */
- if ((percent_s = strstr(im->gdes[i].format, "%S")) != NULL) {
+ if (!im->gdes[i].strftm && (percent_s = strstr(im->gdes[i].format, "%S")) != NULL) {
/* Magfact is set to -1 upon entry to print_calc. If it
* is still less than 0, then we need to run auto_scale.
* Otherwise, put the value into the correct units. If
/* Magfact is set to -1 upon entry to print_calc. If it
* is still less than 0, then we need to run auto_scale.
* Otherwise, put the value into the correct units. If
printval /= magfact;
}
*(++percent_s) = 's';
printval /= magfact;
}
*(++percent_s) = 's';
- } else if (strstr(im->gdes[i].format, "%s") != NULL) {
+ } else if (!im->gdes[i].strftm && strstr(im->gdes[i].format, "%s") != NULL) {
auto_scale(im, &printval, &si_symb, &magfact);
}
auto_scale(im, &printval, &si_symb, &magfact);
}
glue = 0;
}
if (prt_fctn == 'c')
glue = 0;
}
if (prt_fctn == 'c')
- leg_x = (double)(legendwidth - fill) / 2.0;
+ leg_x = border + (double)(legendwidth - fill) / 2.0;
if (prt_fctn == 'r')
leg_x = legendwidth - fill + border;
for (ii = mark; ii <= i; ii++) {
if (prt_fctn == 'r')
leg_x = legendwidth - fill + border;
for (ii = mark; ii <= i; ii++) {
}
}
else {
}
}
else {
- sprintf(graph_label_right,im->second_axis_format,sval);
+ sprintf(graph_label_right,im->second_axis_format,sval,"");
}
gfx_text ( im,
}
gfx_text ( im,
mgridtm,
im->xlab_user.
mgridst);
mgridtm,
im->xlab_user.
mgridst);
- ti < im->end;
+ ti < im->end && ti != -1;
ti =
find_next_time(ti, im->xlab_user.gridtm, im->xlab_user.gridst)
) {
/* are we inside the graph ? */
if (ti < im->start || ti > im->end)
continue;
ti =
find_next_time(ti, im->xlab_user.gridtm, im->xlab_user.gridst)
) {
/* are we inside the graph ? */
if (ti < im->start || ti > im->end)
continue;
- while (timajor < ti) {
+ while (timajor < ti && timajor != -1) {
timajor = find_next_time(timajor,
im->
xlab_user.
mgridtm, im->xlab_user.mgridst);
}
timajor = find_next_time(timajor,
im->
xlab_user.
mgridtm, im->xlab_user.mgridst);
}
+ if (timajor == -1) break; /* fail in case of problems with time increments */
if (ti == timajor)
continue; /* skip as falls on major grid line */
X0 = xtr(im, ti);
if (ti == timajor)
continue; /* skip as falls on major grid line */
X0 = xtr(im, ti);
im->
xlab_user.
mgridst);
im->
xlab_user.
mgridst);
- ti < im->end;
+ ti < im->end && ti != -1;
ti = find_next_time(ti, im->xlab_user.mgridtm, im->xlab_user.mgridst)
) {
/* are we inside the graph ? */
ti = find_next_time(ti, im->xlab_user.mgridtm, im->xlab_user.mgridst)
) {
/* are we inside the graph ? */
labtm,
im->xlab_user.
labst);
labtm,
im->xlab_user.
labst);
- ti <=
+ (ti <=
im->end -
im->end -
- im->xlab_user.precis / 2;
+ im->xlab_user.precis / 2) && ti != -1;
ti = find_next_time(ti, im->xlab_user.labtm, im->xlab_user.labst)
) {
tilab = ti + im->xlab_user.precis / 2; /* correct time for the label */
ti = find_next_time(ti, im->xlab_user.labtm, im->xlab_user.labst)
) {
tilab = ti + im->xlab_user.precis / 2; /* correct time for the label */
}
else{
// we have no title; get a little clearing from the top
}
else{
// we have no title; get a little clearing from the top
- Ytitle = 1.5 * Yspacing;
+ Ytitle = Yspacing;
}
if (elements) {
}
if (elements) {
/* reserve space for padding below the graph */
if (im->extra_flags & NOLEGEND) {
/* reserve space for padding below the graph */
if (im->extra_flags & NOLEGEND) {
- Ymain -= Yspacing;
+ Ymain -= 0.5*Yspacing;
}
if (im->watermark[0] != '\0') {
}
if (im->watermark[0] != '\0') {
}
/* reserve space for padding below the graph */
if (im->extra_flags & NOLEGEND) {
}
/* reserve space for padding below the graph */
if (im->extra_flags & NOLEGEND) {
- im->yimg += Yspacing;
+ im->yimg += 0.5*Yspacing;
}
if (im->watermark[0] != '\0') {
}
if (im->watermark[0] != '\0') {
*/
switch(im->legendposition){
case NORTH:
*/
switch(im->legendposition){
case NORTH:
- im->xOriginTitle = Xvertical + Xylabel + (im->xsize / 2);
+ im->xOriginTitle = (im->ximg / 2);
im->yOriginTitle = 0;
im->xOriginLegend = 0;
im->yOriginTitle = 0;
im->xOriginLegend = 0;
break;
case WEST:
break;
case WEST:
- im->xOriginTitle = im->legendwidth + Xvertical + Xylabel + im->xsize / 2;
+ im->xOriginTitle = im->legendwidth + im->xsize / 2;
im->yOriginTitle = 0;
im->xOriginLegend = 0;
im->yOriginTitle = 0;
im->xOriginLegend = 0;
break;
case SOUTH:
break;
case SOUTH:
- im->xOriginTitle = Xvertical + Xylabel + im->xsize / 2;
+ im->xOriginTitle = im->ximg / 2;
im->yOriginTitle = 0;
im->xOriginLegend = 0;
im->yOriginTitle = 0;
im->xOriginLegend = 0;
break;
case EAST:
break;
case EAST:
- im->xOriginTitle = Xvertical + Xylabel + im->xsize / 2;
+ im->xOriginTitle = im->xsize / 2;
im->yOriginTitle = 0;
im->xOriginLegend = Xvertical + Xylabel + Xmain + Xvertical2;
im->yOriginTitle = 0;
im->xOriginLegend = Xvertical + Xylabel + Xmain + Xvertical2;
break;
case GF_LINE:
case GF_AREA:
break;
case GF_LINE:
case GF_AREA:
- case GF_GRAD:
- /* fix data points at oo and -oo */
+ case GF_GRAD: {
+ rrd_value_t diffval = im->maxval - im->minval;
+ rrd_value_t maxlimit = im->maxval + 9 * diffval;
+ rrd_value_t minlimit = im->minval - 9 * diffval;
for (ii = 0; ii < im->xsize; ii++) {
for (ii = 0; ii < im->xsize; ii++) {
+ /* fix data points at oo and -oo */
if (isinf(im->gdes[i].p_data[ii])) {
if (im->gdes[i].p_data[ii] > 0) {
im->gdes[i].p_data[ii] = im->maxval;
} else {
im->gdes[i].p_data[ii] = im->minval;
}
if (isinf(im->gdes[i].p_data[ii])) {
if (im->gdes[i].p_data[ii] > 0) {
im->gdes[i].p_data[ii] = im->maxval;
} else {
im->gdes[i].p_data[ii] = im->minval;
}
-
}
}
+ /* some versions of cairo go unstable when trying
+ to draw way out of the canvas ... lets not even try */
+ if (im->gdes[i].p_data[ii] > maxlimit) {
+ im->gdes[i].p_data[ii] = maxlimit;
+ }
+ if (im->gdes[i].p_data[ii] < minlimit) {
+ im->gdes[i].p_data[ii] = minlimit;
+ }
} /* for */
/* *******************************************************
} /* for */
/* *******************************************************
}
lastgdes = &(im->gdes[i]);
break;
}
lastgdes = &(im->gdes[i]);
break;
+ } /* GF_AREA, GF_LINE, GF_GRAD */
case GF_STACK:
rrd_set_error
("STACK should already be turned into LINE or AREA here");
case GF_STACK:
rrd_set_error
("STACK should already be turned into LINE or AREA here");
char *old_locale;
rrd_graph_init(&im);
/* a dummy surface so that we can measure text sizes for placements */
char *old_locale;
rrd_graph_init(&im);
/* a dummy surface so that we can measure text sizes for placements */
- old_locale = setlocale(LC_NUMERIC, "C");
+ old_locale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "C");
rrd_graph_options(argc, argv, &im);
if (rrd_test_error()) {
rrd_graph_options(argc, argv, &im);
if (rrd_test_error()) {
+ setlocale(LC_NUMERIC, old_locale); /* reenable locale */
rrd_info_free(im.grinfo);
im_free(&im);
return NULL;
}
if (optind >= argc) {
rrd_info_free(im.grinfo);
im_free(&im);
return NULL;
}
if (optind >= argc) {
+ setlocale(LC_NUMERIC, old_locale); /* reenable locale */
rrd_info_free(im.grinfo);
im_free(&im);
rrd_set_error("missing filename");
rrd_info_free(im.grinfo);
im_free(&im);
rrd_set_error("missing filename");
}
if (strlen(argv[optind]) >= MAXPATH) {
}
if (strlen(argv[optind]) >= MAXPATH) {
+ setlocale(LC_NUMERIC, old_locale); /* reenable locale */
rrd_set_error("filename (including path) too long");
rrd_info_free(im.grinfo);
im_free(&im);
rrd_set_error("filename (including path) too long");
rrd_info_free(im.grinfo);
im_free(&im);
{ "border", required_argument, 0, 1007},
{ "grid-dash", required_argument, 0, 1008},
{ "dynamic-labels", no_argument, 0, 1009},
{ "border", required_argument, 0, 1007},
{ "grid-dash", required_argument, 0, 1008},
{ "dynamic-labels", no_argument, 0, 1009},
+ { "week-fmt", required_argument, 0, 1010},
{ 0, 0, 0, 0}
};
/* *INDENT-ON* */
{ 0, 0, 0, 0}
};
/* *INDENT-ON* */
case 1009: /* enable dynamic labels */
im->dynamic_labels = 1;
break;
case 1009: /* enable dynamic labels */
im->dynamic_labels = 1;
break;
+ case 1010:
+ strncpy(week_fmt,optarg,sizeof week_fmt);
+ week_fmt[(sizeof week_fmt)-1]='\0';
+ break;
case 1002: /* right y axis */
if(sscanf(optarg,
case 1002: /* right y axis */
if(sscanf(optarg,