diff --git a/src/rrd_graph.c b/src/rrd_graph.c
index 50a640a7edea604f63c4a98db69399b143ccf256..317beccc97d3686f62857e291bbae32004299bdd 100644 (file)
--- a/src/rrd_graph.c
+++ b/src/rrd_graph.c
conv_if(SVG, IF_SVG);
conv_if(EPS, IF_EPS);
conv_if(PDF, IF_PDF);
conv_if(SVG, IF_SVG);
conv_if(EPS, IF_EPS);
conv_if(PDF, IF_PDF);
+ conv_if(XML, IF_XML);
+ conv_if(XMLENUM, IF_XMLENUM);
+ conv_if(CSV, IF_CSV);
+ conv_if(TSV, IF_TSV);
+ conv_if(SSV, IF_SSV);
+ conv_if(JSON, IF_JSON);
+ conv_if(JSONTIME, IF_JSONTIME);
return (enum gfx_if_en)(-1);
}
return (enum gfx_if_en)(-1);
}
+enum gfx_type_en type_conv(
+ char *string)
+{
+ conv_if(TIME , GTYPE_TIME);
+ conv_if(XY, GTYPE_XY);
+ return (enum gfx_type_en)(-1);
+}
+
enum tmt_en tmt_conv(
char *string)
{
enum tmt_en tmt_conv(
char *string)
{
}
}
}
}
+/* power prefixes */
static char si_symbol[] = {
static char si_symbol[] = {
+ 'y', /* 10e-24 Yocto */
+ 'z', /* 10e-21 Zepto */
'a', /* 10e-18 Atto */
'f', /* 10e-15 Femto */
'p', /* 10e-12 Pico */
'a', /* 10e-18 Atto */
'f', /* 10e-15 Femto */
'p', /* 10e-12 Pico */
'T', /* 10e12 Tera */
'P', /* 10e15 Peta */
'E', /* 10e18 Exa */
'T', /* 10e12 Tera */
'P', /* 10e15 Peta */
'E', /* 10e18 Exa */
+ 'Z', /* 10e21 Zeta */
+ 'Y' /* 10e24 Yotta */
};
};
-static const int si_symbcenter = 6;
+static const int si_symbcenter = 8;
/* find SI magnitude symbol for the numbers on the y-axis*/
void si_unit(
/* find SI magnitude symbol for the numbers on the y-axis*/
void si_unit(
struct tm tm;
localtime_r(&start, &tm);
struct tm tm;
localtime_r(&start, &tm);
+ /* let mktime figure this dst on its own */
+ tm.tm_isdst = -1;
switch (baseint) {
case TMT_SECOND:
switch (baseint) {
case TMT_SECOND:
time_t madetime;
localtime_r(¤t, &tm);
time_t madetime;
localtime_r(¤t, &tm);
+ /* let mktime figure this dst on its own */
+ tm.tm_isdst = -1;
int limit = 2;
switch (baseint) {
int limit = 2;
switch (baseint) {
im->gdes[i].format);
return -1;
}
im->gdes[i].format);
return -1;
}
-#ifdef HAVE_SNPRINTF
snprintf(im->gdes[i].legend,
FMT_LEG_LEN - 2,
im->gdes[i].format, printval, si_symb);
snprintf(im->gdes[i].legend,
FMT_LEG_LEN - 2,
im->gdes[i].format, printval, si_symb);
-#else
- sprintf(im->gdes[i].legend,
- im->gdes[i].format, printval, si_symb);
-#endif
}
graphelement = 1;
}
}
graphelement = 1;
}
("STACK should already be turned into LINE or AREA here");
return -1;
break;
("STACK should already be turned into LINE or AREA here");
return -1;
break;
+ case GF_XAXIS:
+ case GF_YAXIS:
+ break;
}
}
return graphelement;
}
}
return graphelement;
for (i = 0; i < im->gdes_c; i++) {
char prt_fctn; /*special printfunctions */
if(calc_width){
for (i = 0; i < im->gdes_c; i++) {
char prt_fctn; /*special printfunctions */
if(calc_width){
- strcpy(saved_legend, im->gdes[i].legend);
+ strncpy(saved_legend, im->gdes[i].legend, sizeof saved_legend);
}
fill_last = fill;
}
fill_last = fill;
prt_fctn != 'j' &&
prt_fctn != 'c' &&
prt_fctn != 'u' &&
prt_fctn != 'j' &&
prt_fctn != 'c' &&
prt_fctn != 'u' &&
+ prt_fctn != '.' &&
prt_fctn != 's' && prt_fctn != '\0' && prt_fctn != 'g') {
free(legspace);
rrd_set_error
prt_fctn != 's' && prt_fctn != '\0' && prt_fctn != 'g') {
free(legspace);
rrd_set_error
if (prt_fctn == 'n') {
prt_fctn = 'l';
}
if (prt_fctn == 'n') {
prt_fctn = 'l';
}
+ /* \. is a null operation to allow strings ending in \x */
+ if (prt_fctn == '.') {
+ prt_fctn = '\0';
+ }
/* remove exess space from the end of the legend for \g */
while (prt_fctn == 'g' &&
/* remove exess space from the end of the legend for \g */
while (prt_fctn == 'g' &&
}
if(calc_width){
}
if(calc_width){
- strcpy(im->gdes[i].legend, saved_legend);
+ strncpy(im->gdes[i].legend, saved_legend, sizeof im->gdes[0].legend);
}
}
}
}
if (im->unitslength < len + 2)
im->unitslength = len + 2;
if (im->unitslength < len + 2)
im->unitslength = len + 2;
- sprintf(im->ygrid_scale.labfmt,
+ snprintf(im->ygrid_scale.labfmt, sizeof im->ygrid_scale.labfmt,
"%%%d.%df%s", len,
-fractionals, (im->symbol != ' ' ? " %c" : ""));
} else {
"%%%d.%df%s", len,
-fractionals, (im->symbol != ' ' ? " %c" : ""));
} else {
if (im->unitslength < len + 2)
im->unitslength = len + 2;
if (im->unitslength < len + 2)
im->unitslength = len + 2;
- sprintf(im->ygrid_scale.labfmt,
+ snprintf(im->ygrid_scale.labfmt, sizeof im->ygrid_scale.labfmt,
"%%%d.0f%s", len, (im->symbol != ' ' ? " %c" : ""));
}
} else { /* classic rrd grid */
"%%%d.0f%s", len, (im->symbol != ' ' ? " %c" : ""));
}
} else { /* classic rrd grid */
&& (YN < im->yorigin - im->ysize || YN > im->yorigin))) {
if (im->symbol == ' ') {
if (im->extra_flags & ALTYGRID) {
&& (YN < im->yorigin - im->ysize || YN > im->yorigin))) {
if (im->symbol == ' ') {
if (im->extra_flags & ALTYGRID) {
- sprintf(graph_label,
+ snprintf(graph_label, sizeof graph_label,
im->ygrid_scale.labfmt,
scaledstep * (double) i);
} else {
if (MaxY < 10) {
im->ygrid_scale.labfmt,
scaledstep * (double) i);
} else {
if (MaxY < 10) {
- sprintf(graph_label, "%4.1f",
+ snprintf(graph_label, sizeof graph_label, "%4.1f",
scaledstep * (double) i);
} else {
scaledstep * (double) i);
} else {
- sprintf(graph_label, "%4.0f",
+ snprintf(graph_label, sizeof graph_label, "%4.0f",
scaledstep * (double) i);
}
}
scaledstep * (double) i);
}
}
char sisym = (i == 0 ? ' ' : im->symbol);
if (im->extra_flags & ALTYGRID) {
char sisym = (i == 0 ? ' ' : im->symbol);
if (im->extra_flags & ALTYGRID) {
- sprintf(graph_label,
+ snprintf(graph_label, sizeof graph_label,
im->ygrid_scale.labfmt,
scaledstep * (double) i, sisym);
} else {
if (MaxY < 10) {
im->ygrid_scale.labfmt,
scaledstep * (double) i, sisym);
} else {
if (MaxY < 10) {
- sprintf(graph_label, "%4.1f %c",
+ snprintf(graph_label, sizeof graph_label, "%4.1f %c",
scaledstep * (double) i, sisym);
} else {
scaledstep * (double) i, sisym);
} else {
- sprintf(graph_label, "%4.0f %c",
+ snprintf(graph_label, sizeof graph_label, "%4.0f %c",
scaledstep * (double) i, sisym);
}
}
scaledstep * (double) i, sisym);
}
}
sval /= second_axis_magfact;
if(MaxY < 10) {
sval /= second_axis_magfact;
if(MaxY < 10) {
- sprintf(graph_label_right,"%5.1f %s",sval,second_axis_symb);
+ snprintf(graph_label_right, sizeof graph_label_right, "%5.1f %s",sval,second_axis_symb);
} else {
} else {
- sprintf(graph_label_right,"%5.0f %s",sval,second_axis_symb);
+ snprintf(graph_label_right, sizeof graph_label_right, "%5.0f %s",sval,second_axis_symb);
}
}
else {
}
}
else {
- sprintf(graph_label_right,im->second_axis_format,sval);
+ snprintf(graph_label_right, sizeof graph_label_right, im->second_axis_format,sval,"");
}
gfx_text ( im,
X1+7, Y0,
}
gfx_text ( im,
X1+7, Y0,
symbol = si_symbol[scale + si_symbcenter];
else
symbol = '?';
symbol = si_symbol[scale + si_symbcenter];
else
symbol = '?';
- sprintf(graph_label, "%3.0f %c", pvalue, symbol);
+ snprintf(graph_label, sizeof graph_label, "%3.0f %c", pvalue, symbol);
} else {
} else {
- sprintf(graph_label, "%3.0e", value);
+ snprintf(graph_label, sizeof graph_label, "%3.0e", value);
}
if (im->second_axis_scale != 0){
char graph_label_right[100];
}
if (im->second_axis_scale != 0){
char graph_label_right[100];
double mfac = 1;
char *symb = "";
auto_scale(im,&sval,&symb,&mfac);
double mfac = 1;
char *symb = "";
auto_scale(im,&sval,&symb,&mfac);
- sprintf(graph_label_right,"%4.0f %s", sval,symb);
+ snprintf(graph_label_right, sizeof graph_label_right, "%4.0f %s", sval,symb);
}
else {
}
else {
- sprintf(graph_label_right,"%3.0e", sval);
+ snprintf(graph_label_right, sizeof graph_label_right, "%3.0e", sval);
}
}
else {
}
}
else {
- sprintf(graph_label_right,im->second_axis_format,sval,"");
+ snprintf(graph_label_right, sizeof graph_label_right, im->second_axis_format,sval,"");
}
gfx_text ( im,
}
gfx_text ( im,
int graph_paint(
image_desc_t *im)
{
int graph_paint(
image_desc_t *im)
{
- int i, ii;
int lazy = lazy_check(im);
int lazy = lazy_check(im);
- double areazero = 0.0;
- graph_desc_t *lastgdes = NULL;
- rrd_infoval_t info;
+ int cnt;
-// PangoFontMap *font_map = pango_cairo_font_map_get_default();
+ /* imgformat XML or higher dispatch to xport
+ * output format there is selected via graph_type
+ */
+ if (im->imgformat >= IF_XML) {
+ return rrd_graph_xport(im);
+ }
/* pull the data from the rrd files ... */
if (data_fetch(im) == -1)
/* pull the data from the rrd files ... */
if (data_fetch(im) == -1)
* if there are no graph elements (i==0) we stop here ...
* if we are lazy, try to quit ...
*/
* if there are no graph elements (i==0) we stop here ...
* if we are lazy, try to quit ...
*/
- i = print_calc(im);
- if (i < 0)
+ cnt = print_calc(im);
+ if (cnt < 0)
return -1;
/* if we want and can be lazy ... quit now */
return -1;
/* if we want and can be lazy ... quit now */
- if (i == 0)
+ if (cnt == 0)
return 0;
return 0;
+ /* otherwise call graph_paint_timestring */
+ switch (im->graph_type) {
+ case GTYPE_TIME:
+ return graph_paint_timestring(im,lazy,cnt);
+ break;
+ case GTYPE_XY:
+ return graph_paint_xy(im,lazy,cnt);
+ break;
+ }
+ /* final return with error*/
+ rrd_set_error("Graph type %i is not implemented",im->graph_type);
+ return -1;
+}
+
+int graph_paint_timestring(
+ image_desc_t *im, int lazy, int cnt)
+{
+ int i,ii;
+ double areazero = 0.0;
+ graph_desc_t *lastgdes = NULL;
+ rrd_infoval_t info;
+
/**************************************************************
*** Calculating sizes and locations became a bit confusing ***
*** so I moved this into a separate function. ***
**************************************************************/
/**************************************************************
*** Calculating sizes and locations became a bit confusing ***
*** so I moved this into a separate function. ***
**************************************************************/
- if (graph_size_location(im, i) == -1)
+ if (graph_size_location(im, cnt) == -1)
return -1;
info.u_cnt = im->xorigin;
return -1;
info.u_cnt = im->xorigin;
ytr(im, DNAN);
/* if (im->gridfit)
apply_gridfit(im); */
ytr(im, DNAN);
/* if (im->gridfit)
apply_gridfit(im); */
- /* the actual graph is created by going through the individual
- graph elements and then drawing them */
- cairo_surface_destroy(im->surface);
- switch (im->imgformat) {
- case IF_PNG:
- im->surface =
- cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
- im->ximg * im->zoom,
- im->yimg * im->zoom);
- break;
- case IF_PDF:
- im->gridfit = 0;
- im->surface = strlen(im->graphfile)
- ? cairo_pdf_surface_create(im->graphfile, im->ximg * im->zoom,
- im->yimg * im->zoom)
- : cairo_pdf_surface_create_for_stream
- (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom);
- break;
- case IF_EPS:
- im->gridfit = 0;
- im->surface = strlen(im->graphfile)
- ?
- cairo_ps_surface_create(im->graphfile, im->ximg * im->zoom,
- im->yimg * im->zoom)
- : cairo_ps_surface_create_for_stream
- (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom);
- break;
- case IF_SVG:
- im->gridfit = 0;
- im->surface = strlen(im->graphfile)
- ?
- cairo_svg_surface_create(im->
- graphfile,
- im->ximg * im->zoom, im->yimg * im->zoom)
- : cairo_svg_surface_create_for_stream
- (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom);
- cairo_svg_surface_restrict_to_version
- (im->surface, CAIRO_SVG_VERSION_1_1);
- break;
- };
- cairo_destroy(im->cr);
- im->cr = cairo_create(im->surface);
- cairo_set_antialias(im->cr, im->graph_antialias);
- cairo_scale(im->cr, im->zoom, im->zoom);
-// pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(font_map), 100);
- gfx_new_area(im, 0, 0, 0, im->yimg,
- im->ximg, im->yimg, im->graph_col[GRC_BACK]);
- gfx_add_point(im, im->ximg, 0);
- gfx_close_path(im);
- gfx_new_area(im, im->xorigin,
- im->yorigin,
- im->xorigin +
- im->xsize, im->yorigin,
- im->xorigin +
- im->xsize,
- im->yorigin - im->ysize, im->graph_col[GRC_CANVAS]);
- gfx_add_point(im, im->xorigin, im->yorigin - im->ysize);
- gfx_close_path(im);
- cairo_rectangle(im->cr, im->xorigin, im->yorigin - im->ysize - 1.0,
- im->xsize, im->ysize + 2.0);
- cairo_clip(im->cr);
+
+ /* set up cairo */
+ if (graph_cairo_setup(im)) { return -1; }
+
+ /* other stuff */
if (im->minval > 0.0)
areazero = im->minval;
if (im->maxval < 0.0)
if (im->minval > 0.0)
areazero = im->minval;
if (im->maxval < 0.0)
case GF_VRULE:
case GF_XPORT:
case GF_SHIFT:
case GF_VRULE:
case GF_XPORT:
case GF_SHIFT:
+ case GF_XAXIS:
+ case GF_YAXIS:
break;
case GF_TICK:
for (ii = 0; ii < im->xsize; ii++) {
break;
case GF_TICK:
for (ii = 0; ii < im->xsize; ii++) {
break;
}
}
break;
}
}
+ /* close the graph via cairo*/
+ return graph_cairo_finish(im);
+}
+int graph_cairo_setup (image_desc_t *im)
+{
+ /* the actual graph is created by going through the individual
+ graph elements and then drawing them */
+ cairo_surface_destroy(im->surface);
+ switch (im->imgformat) {
+ case IF_PNG:
+ im->surface =
+ cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ im->ximg * im->zoom,
+ im->yimg * im->zoom);
+ break;
+ case IF_PDF:
+ im->gridfit = 0;
+ im->surface = strlen(im->graphfile)
+ ? cairo_pdf_surface_create(im->graphfile, im->ximg * im->zoom,
+ im->yimg * im->zoom)
+ : cairo_pdf_surface_create_for_stream
+ (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom);
+ break;
+ case IF_EPS:
+ im->gridfit = 0;
+ im->surface = strlen(im->graphfile)
+ ?
+ cairo_ps_surface_create(im->graphfile, im->ximg * im->zoom,
+ im->yimg * im->zoom)
+ : cairo_ps_surface_create_for_stream
+ (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom);
+ break;
+ case IF_SVG:
+ im->gridfit = 0;
+ im->surface = strlen(im->graphfile)
+ ?
+ cairo_svg_surface_create(im->
+ graphfile,
+ im->ximg * im->zoom, im->yimg * im->zoom)
+ : cairo_svg_surface_create_for_stream
+ (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom);
+ cairo_svg_surface_restrict_to_version
+ (im->surface, CAIRO_SVG_VERSION_1_1);
+ break;
+ case IF_XML:
+ case IF_XMLENUM:
+ case IF_CSV:
+ case IF_TSV:
+ case IF_SSV:
+ case IF_JSON:
+ case IF_JSONTIME:
+ break;
+ };
+ cairo_destroy(im->cr);
+ im->cr = cairo_create(im->surface);
+ cairo_set_antialias(im->cr, im->graph_antialias);
+ cairo_scale(im->cr, im->zoom, im->zoom);
+// pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(font_map), 100);
+ gfx_new_area(im, 0, 0, 0, im->yimg,
+ im->ximg, im->yimg, im->graph_col[GRC_BACK]);
+ gfx_add_point(im, im->ximg, 0);
+ gfx_close_path(im);
+ gfx_new_area(im, im->xorigin,
+ im->yorigin,
+ im->xorigin +
+ im->xsize, im->yorigin,
+ im->xorigin +
+ im->xsize,
+ im->yorigin - im->ysize, im->graph_col[GRC_CANVAS]);
+ gfx_add_point(im, im->xorigin, im->yorigin - im->ysize);
+ gfx_close_path(im);
+ cairo_rectangle(im->cr, im->xorigin, im->yorigin - im->ysize - 1.0,
+ im->xsize, im->ysize + 2.0);
+ cairo_clip(im->cr);
+ return 0;
+}
+
+int graph_cairo_finish (image_desc_t *im)
+{
switch (im->imgformat) {
case IF_PNG:
switch (im->imgformat) {
case IF_PNG:
}
break;
}
}
break;
}
+ case IF_XML:
+ case IF_XMLENUM:
+ case IF_CSV:
+ case IF_TSV:
+ case IF_SSV:
+ case IF_JSON:
+ case IF_JSONTIME:
+ break;
default:
if (strlen(im->graphfile)) {
cairo_show_page(im->cr);
default:
if (strlen(im->graphfile)) {
cairo_show_page(im->cr);
return 0;
}
return 0;
}
+int graph_paint_xy(
+ image_desc_t *im, int lazy, int cnt)
+{
+ /* to stop compiler warnings for now */
+ lazy=cnt=(int)im->gdes_c;
+ rrd_set_error("XY diagramm not implemented");
+ return -1;
+}
/*****************************************************
* graph stuff
/*****************************************************
* graph stuff
return -1;
}
return -1;
}
+ /* set to zero */
+ memset(&(im->gdes[im->gdes_c - 1]),0,sizeof(graph_desc_t));
im->gdes[im->gdes_c - 1].step = im->step;
im->gdes[im->gdes_c - 1].step_orig = im->step;
im->gdes[im->gdes_c - 1].step = im->step;
im->gdes[im->gdes_c - 1].step_orig = im->step;
return 0;
}
/* imginfo goes to position 0 in the prdata array */
return 0;
}
/* imginfo goes to position 0 in the prdata array */
- (*prdata)[prlines - 1] = (char*)malloc((strlen(walker->value.u_str)
- + 2) * sizeof(char));
- strcpy((*prdata)[prlines - 1], walker->value.u_str);
+ (*prdata)[prlines - 1] = strdup(walker->value.u_str);
(*prdata)[prlines] = NULL;
}
/* skip anything else */
(*prdata)[prlines] = NULL;
}
/* skip anything else */
rrd_set_error("realloc prdata");
return 0;
}
rrd_set_error("realloc prdata");
return 0;
}
- (*prdata)[prlines - 1] = (char*)malloc((strlen(walker->value.u_str)
- + 2) * sizeof(char));
+ (*prdata)[prlines - 1] = strdup(walker->value.u_str);
(*prdata)[prlines] = NULL;
(*prdata)[prlines] = NULL;
- strcpy((*prdata)[prlines - 1], walker->value.u_str);
} else if (strcmp(walker->key, "image") == 0) {
if ( fwrite(walker->value.u_blo.ptr, walker->value.u_blo.size, 1,
(stream ? stream : stdout)) == 0 && ferror(stream ? stream : stdout)){
} else if (strcmp(walker->key, "image") == 0) {
if ( fwrite(walker->value.u_blo.ptr, walker->value.u_blo.size, 1,
(stream ? stream : stdout)) == 0 && ferror(stream ? stream : stdout)){
** - options parsing now in rrd_graph_options()
** - script parsing now in rrd_graph_script()
*/
** - options parsing now in rrd_graph_options()
** - script parsing now in rrd_graph_script()
*/
+
rrd_info_t *rrd_graph_v(
int argc,
char **argv)
rrd_info_t *rrd_graph_v(
int argc,
char **argv)
im_free(&im);
return NULL;
}
im_free(&im);
return NULL;
}
-
+
/* Everything is now read and the actual work can start */
/* Everything is now read and the actual work can start */
-
if (graph_paint(&im) == -1) {
if (graph_paint(&im) == -1) {
- rrd_info_free(im.grinfo);
- im_free(&im);
- return NULL;
+ rrd_info_free(im.grinfo);
+ im_free(&im);
+ return NULL;
}
}
-
/* The image is generated and needs to be output.
** Also, if needed, print a line with information about the image.
*/
/* The image is generated and needs to be output.
** Also, if needed, print a line with information about the image.
*/
static PangoFontMap *fontmap = NULL;
PangoContext *context;
static PangoFontMap *fontmap = NULL;
PangoContext *context;
+ /* zero the whole structure first */
+ memset(im,0,sizeof(image_desc_t));
+
#ifdef HAVE_TZSET
tzset();
#endif
#ifdef HAVE_TZSET
tzset();
#endif
-
+ im->graph_type = GTYPE_TIME;
im->base = 1000;
im->daemon_addr = NULL;
im->draw_x_grid = 1;
im->base = 1000;
im->daemon_addr = NULL;
im->draw_x_grid = 1;
{ "grid-dash", required_argument, 0, 1008},
{ "dynamic-labels", no_argument, 0, 1009},
{ "week-fmt", required_argument, 0, 1010},
{ "grid-dash", required_argument, 0, 1008},
{ "dynamic-labels", no_argument, 0, 1009},
{ "week-fmt", required_argument, 0, 1010},
+ { "graph-type", required_argument, 0, 1011},
{ 0, 0, 0, 0}
};
/* *INDENT-ON* */
{ 0, 0, 0, 0}
};
/* *INDENT-ON* */
return;
}
break;
return;
}
break;
+ case 1011:
+ if ((int)
+ (im->graph_type = type_conv(optarg)) == -1) {
+ rrd_set_error("unsupported graphics type '%s'", optarg);
+ return;
+ }
+ break;
case 'z':
im->lazy = 1;
break;
case 'z':
im->lazy = 1;
break;