/* initialize with xtr(im,0); */
int xtr(
- image_desc_t * im,
+ image_desc_t *im,
time_t mytime)
{
static double pixie;
/* translate data values into y coordinates */
double ytr(
- image_desc_t * im,
+ image_desc_t *im,
double value)
{
static double pixie;
#undef conv_if
int im_free(
- image_desc_t * im)
+ image_desc_t *im)
{
unsigned long i, ii;
/* find SI magnitude symbol for the given number*/
void auto_scale(
- image_desc_t * im, /* image description */
+ image_desc_t *im, /* image description */
double *value,
char **symb_ptr,
double *magfact)
/* find SI magnitude symbol for the numbers on the y-axis*/
void si_unit(
- image_desc_t * im /* image description */
+ image_desc_t *im /* image description */
)
{
/* move min and max values around to become sensible */
void expand_range(
- image_desc_t * im)
+ image_desc_t *im)
{
double sensiblevalues[] = { 1000.0, 900.0, 800.0, 750.0, 700.0,
600.0, 500.0, 400.0, 300.0, 250.0,
}
void apply_gridfit(
- image_desc_t * im)
+ image_desc_t *im)
{
if (isnan(im->minval) || isnan(im->maxval))
return;
time_t *end, /* ... by the application will be ... */
unsigned long *step, /* ... adjusted to represent reality */
unsigned long *ds_cnt, /* number of data sources in file */
- rrd_value_t ** data)
+ rrd_value_t **data)
{ /* two dimensional array containing the data */
int i, reduce_factor = ceil((double) (*step) / (double) cur_step);
unsigned long col, dst_row, row_cnt, start_offset, end_offset, skiprows =
relevant rrds ... */
int data_fetch(
- image_desc_t * im)
+ image_desc_t *im)
{
int i, ii;
int skip;
/* find gdes containing var*/
long find_var(
- image_desc_t * im,
+ image_desc_t *im,
char *key)
{
long ii;
/* run the rpn calculator on all the VDEF and CDEF arguments */
int data_calc(
- image_desc_t * im)
+ image_desc_t *im)
{
int gdi;
/* massage data so, that we get one value for each x coordinate in the graph */
int data_proc(
- image_desc_t * im)
+ image_desc_t *im)
{
long i, ii;
double pixstep = (double) (im->end - im->start)
struct tm tm;
localtime_r(&start, &tm);
+
switch (baseint) {
case TMT_SECOND:
- tm.tm_sec -= tm.tm_sec % basestep;
+ tm. tm_sec -= tm.tm_sec % basestep;
+
break;
case TMT_MINUTE:
- tm.tm_sec = 0;
- tm.tm_min -= tm.tm_min % basestep;
+ tm. tm_sec = 0;
+ tm. tm_min -= tm.tm_min % basestep;
+
break;
case TMT_HOUR:
- tm.tm_sec = 0;
- tm.tm_min = 0;
- tm.tm_hour -= tm.tm_hour % basestep;
+ tm. tm_sec = 0;
+ tm. tm_min = 0;
+ tm. tm_hour -= tm.tm_hour % basestep;
+
break;
case TMT_DAY:
/* we do NOT look at the basestep for this ... */
- tm.tm_sec = 0;
- tm.tm_min = 0;
- tm.tm_hour = 0;
+ tm. tm_sec = 0;
+ tm. tm_min = 0;
+ tm. tm_hour = 0;
+
break;
case TMT_WEEK:
/* we do NOT look at the basestep for this ... */
- tm.tm_sec = 0;
- tm.tm_min = 0;
- tm.tm_hour = 0;
- tm.tm_mday -= tm.tm_wday - 1; /* -1 because we want the monday */
+ tm. tm_sec = 0;
+ tm. tm_min = 0;
+ tm. tm_hour = 0;
+ tm. tm_mday -= tm.tm_wday - 1; /* -1 because we want the monday */
+
if (tm.tm_wday == 0)
- tm.tm_mday -= 7; /* we want the *previous* monday */
+ tm. tm_mday -= 7; /* we want the *previous* monday */
+
break;
case TMT_MONTH:
- tm.tm_sec = 0;
- tm.tm_min = 0;
- tm.tm_hour = 0;
- tm.tm_mday = 1;
- tm.tm_mon -= tm.tm_mon % basestep;
+ tm. tm_sec = 0;
+ tm. tm_min = 0;
+ tm. tm_hour = 0;
+ tm. tm_mday = 1;
+ tm. tm_mon -= tm.tm_mon % basestep;
+
break;
case TMT_YEAR:
- tm.tm_sec = 0;
- tm.tm_min = 0;
- tm.tm_hour = 0;
- tm.tm_mday = 1;
- tm.tm_mon = 0;
- tm.tm_year -= (tm.tm_year + 1900) % basestep;
+ tm. tm_sec = 0;
+ tm. tm_min = 0;
+ tm. tm_hour = 0;
+ tm. tm_mday = 1;
+ tm. tm_mon = 0;
+ tm. tm_year -= (
+ tm.tm_year + 1900) %basestep;
}
return mktime(&tm);
time_t madetime;
localtime_r(¤t, &tm);
+
do {
switch (baseint) {
case TMT_SECOND:
- tm.tm_sec += basestep;
+ tm. tm_sec += basestep;
+
break;
case TMT_MINUTE:
- tm.tm_min += basestep;
+ tm. tm_min += basestep;
+
break;
case TMT_HOUR:
- tm.tm_hour += basestep;
+ tm. tm_hour += basestep;
+
break;
case TMT_DAY:
- tm.tm_mday += basestep;
+ tm. tm_mday += basestep;
+
break;
case TMT_WEEK:
- tm.tm_mday += 7 * basestep;
+ tm. tm_mday += 7 * basestep;
+
break;
case TMT_MONTH:
- tm.tm_mon += basestep;
+ tm. tm_mon += basestep;
+
break;
case TMT_YEAR:
- tm.tm_year += basestep;
+ tm. tm_year += basestep;
}
madetime = mktime(&tm);
} while (madetime == -1); /* this is necessary to skip impssible times
/* calculate values required for PRINT and GPRINT functions */
int print_calc(
- image_desc_t * im,
+ image_desc_t *im,
char ***prdata)
{
long i, ii, validsteps;
/* place legends with color spots */
int leg_place(
- image_desc_t * im)
+ image_desc_t *im,
+ int *gY)
{
/* graph labels */
int interleg = im->text_prop[TEXT_PROP_LEGEND].size * 2.0;
return -1;
}
+ if (im->extra_flags & FULL_SIZE_MODE)
+ leg_y = leg_y_prev =
+ leg_y - (int) (im->text_prop[TEXT_PROP_LEGEND].size * 1.8);
+
for (i = 0; i < im->gdes_c; i++) {
fill_last = fill;
- /* hid legends for rules which are not displayed */
+ /* hide legends for rules which are not displayed */
if (!(im->extra_flags & FORCE_RULES_LEGEND)) {
if (im->gdes[i].gf == GF_HRULE &&
+ glue;
}
leg_y_prev = leg_y;
- /* only add y space if there was text on the line */
- if (leg_x > border || prt_fctn == 's')
- leg_y += im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
- if (prt_fctn == 's')
- leg_y -= im->text_prop[TEXT_PROP_LEGEND].size;
+ if (im->extra_flags & FULL_SIZE_MODE) {
+ /* only add y space if there was text on the line */
+ if (leg_x > border || prt_fctn == 's')
+ leg_y -= im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+ if (prt_fctn == 's')
+ leg_y += im->text_prop[TEXT_PROP_LEGEND].size;
+ } else {
+ if (leg_x > border || prt_fctn == 's')
+ leg_y += im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+ if (prt_fctn == 's')
+ leg_y -= im->text_prop[TEXT_PROP_LEGEND].size;
+ }
fill = 0;
leg_c = 0;
mark = ii;
}
}
- im->yimg = leg_y_prev;
- /* if we did place some legends we have to add vertical space */
- if (leg_y != im->yimg) {
- im->yimg += im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+
+ if (im->extra_flags & FULL_SIZE_MODE) {
+ if (leg_y != leg_y_prev) {
+ *gY = leg_y - im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+ im->yorigin =
+ leg_y - im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+ }
+ } else {
+ im->yimg = leg_y_prev;
+ /* if we did place some legends we have to add vertical space */
+ if (leg_y != im->yimg)
+ im->yimg += im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
}
free(legspace);
}
int calc_horizontal_grid(
- image_desc_t * im)
+ image_desc_t *im)
{
double range;
double scaledrange;
}
int draw_horizontal_grid(
- image_desc_t * im)
+ image_desc_t *im)
{
int i;
double scaledstep;
/* logaritmic horizontal grid */
int horizontal_log_grid(
- image_desc_t * im)
+ image_desc_t *im)
{
double yloglab[][10] = {
{1.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
void vertical_grid(
- image_desc_t * im)
+ image_desc_t *im)
{
int xlab_sel; /* which sort of label and grid ? */
time_t ti, tilab, timajor;
void axis_paint(
- image_desc_t * im)
+ image_desc_t *im)
{
/* draw x and y axis */
/* gfx_new_line ( im->canvas, im->xorigin+im->xsize,im->yorigin,
}
void grid_paint(
- image_desc_t * im)
+ image_desc_t *im)
{
long i;
int res = 0;
*****************************************************/
int lazy_check(
- image_desc_t * im)
+ image_desc_t *im)
{
FILE *fd = NULL;
int size = 1;
#ifdef WITH_PIECHART
void pie_part(
- image_desc_t * im,
+ image_desc_t *im,
gfx_color_t color,
double PieCenterX,
double PieCenterY,
#endif
int graph_size_location(
- image_desc_t * im,
+ image_desc_t *im,
int elements
#ifdef WITH_PIECHART
,
** and other things outside the graph area
*/
- /* +-+-------------------------------------------+
- ** |l|.................title.....................|
- ** |e+--+-------------------------------+--------+
- ** |b| b| | |
- ** |a| a| | pie |
- ** |l| l| main graph area | chart |
- ** |.| .| | area |
- ** |t| y| | |
- ** |r+--+-------------------------------+--------+
- ** |e| | x-axis labels | |
- ** |v+--+-------------------------------+--------+
- ** | |..............legends......................|
- ** +-+-------------------------------------------+
- ** | watermark |
- ** +---------------------------------------------+
- */
int Xvertical = 0, Ytitle = 0, Xylabel = 0, Xmain = 0, Ymain = 0,
#ifdef WITH_PIECHART
Xpie = 0, Ypie = 0,
return 0;
}
+ /** +---+--------------------------------------------+
+ ** | y |...............graph title..................|
+ ** | +---+-------------------------------+--------+
+ ** | a | y | | |
+ ** | x | | | |
+ ** | i | a | | pie |
+ ** | s | x | main graph area | chart |
+ ** | | i | | area |
+ ** | t | s | | |
+ ** | i | | | |
+ ** | t | l | | |
+ ** | l | b +-------------------------------+--------+
+ ** | e | l | x axis labels | |
+ ** +---+---+-------------------------------+--------+
+ ** |....................legends.....................|
+ ** +------------------------------------------------+
+ ** | watermark |
+ ** +------------------------------------------------+
+ */
+
if (im->ylegend[0] != '\0') {
Xvertical = im->text_prop[TEXT_PROP_UNIT].size * 2;
}
-
if (im->title[0] != '\0') {
/* The title is placed "inbetween" two text lines so it
** automatically has some vertical spacing. The horizontal
** spacing is added here, on each side.
*/
- /* don't care for the with of the title
- Xtitle = gfx_get_text_width(im->canvas, 0,
- im->text_prop[TEXT_PROP_TITLE].font,
- im->text_prop[TEXT_PROP_TITLE].size,
- im->tabwidth,
- im->title, 0) + 2*Xspacing; */
+ /* if necessary, reduce the font size of the title until it fits the image width */
Ytitle = im->text_prop[TEXT_PROP_TITLE].size * 2.6 + 10;
}
if (elements) {
- Xmain = im->xsize;
- Ymain = im->ysize;
if (im->draw_x_grid) {
Yxlabel = im->text_prop[TEXT_PROP_AXIS].size * 2.5;
}
"0", 0) * im->unitslength;
}
}
+
+ if (im->extra_flags & FULL_SIZE_MODE) {
+ /* The actual size of the image to draw has been determined by the user.
+ ** The graph area is the space remaining after accounting for the legend,
+ ** the watermark, the pie chart, the axis labels, and the title.
+ */
+ im->xorigin = 0;
+ im->ximg = im->xsize;
+ im->yimg = im->ysize;
+ im->yorigin = im->ysize;
+ Xmain = im->ximg;
+ Ymain = im->yimg;
+
+ im->yorigin += Ytitle;
+
#ifdef WITH_PIECHART
- if (piechart) {
- im->piesize = im->xsize < im->ysize ? im->xsize : im->ysize;
- Xpie = im->piesize;
- Ypie = im->piesize;
- }
+ if (piechart) {
+ im->piesize = im->xsize < im->ysize ? im->xsize : im->ysize;
+ Xpie = im->piesize;
+ Ypie = im->piesize;
+ }
#endif
- /* Now calculate the total size. Insert some spacing where
- desired. im->xorigin and im->yorigin need to correspond
- with the lower left corner of the main graph area or, if
- this one is not set, the imaginary box surrounding the
- pie chart area. */
+ /* Now calculate the total size. Insert some spacing where
+ desired. im->xorigin and im->yorigin need to correspond
+ with the lower left corner of the main graph area or, if
+ this one is not set, the imaginary box surrounding the
+ pie chart area. */
- /* The legend width cannot yet be determined, as a result we
- ** have problems adjusting the image to it. For now, we just
- ** forget about it at all; the legend will have to fit in the
- ** size already allocated.
- */
- im->ximg = Xylabel + Xmain + 2 * Xspacing;
+ /* Initial size calculation for the main graph area */
+ Xmain = im->ximg - (Xylabel + 2 * Xspacing);
+ if (Xmain)
+ Xmain -= Xspacing; /* put space between main graph area and right edge */
#ifdef WITH_PIECHART
- im->ximg += Xpie;
+ Xmain -= Xpie; /* remove pie width from main graph area */
+ if (Xpie)
+ Xmain -= Xspacing; /* put space between pie and main graph area */
#endif
- if (Xmain)
- im->ximg += Xspacing;
+ im->xorigin = Xspacing + Xylabel;
+
+ /* the length of the title should not influence with width of the graph
+ if (Xtitle > im->ximg) im->ximg = Xtitle; */
+
+ if (Xvertical) { /* unit description */
+ Xmain -= Xvertical;
+ im->xorigin += Xvertical;
+ }
+ im->xsize = Xmain;
+ xtr(im, 0);
+
+ /* The vertical size of the image is known in advance. The main graph area
+ ** (Ymain) and im->yorigin must be set according to the space requirements
+ ** of the legend and the axis labels.
+ */
+
+ /* Determine where to place the legends onto the image.
+ ** Set Ymain and adjust im->yorigin to match the space requirements.
+ */
+ if (leg_place(im, &Ymain) == -1)
+ return -1;
+
#ifdef WITH_PIECHART
- if (Xpie)
- im->ximg += Xspacing;
+ /* if (im->yimg < Ypie) im->yimg = Ypie; * not sure what do about this */
#endif
- im->xorigin = Xspacing + Xylabel;
+ /* remove title space *or* some padding above the graph from the main graph area */
+ if (Ytitle) {
+ Ymain -= Ytitle;
+ } else {
+ Ymain -= 1.5 * Yspacing;
+ }
- /* the length of the title should not influence with width of the graph
- if (Xtitle > im->ximg) im->ximg = Xtitle; */
+ /* watermark doesn't seem to effect the vertical size of the main graph area, oh well! */
+ if (im->watermark[0] != '\0') {
+ Ymain -= Ywatermark;
+ }
- if (Xvertical) { /* unit description */
- im->ximg += Xvertical;
- im->xorigin += Xvertical;
- }
- xtr(im, 0);
+ im->ysize = Ymain;
+
+ } else { /* dimension options -width and -height refer to the dimensions of the main graph area */
+
+ /* The actual size of the image to draw is determined from
+ ** several sources. The size given on the command line is
+ ** the graph area but we need more as we have to draw labels
+ ** and other things outside the graph area.
+ */
+
+ if (im->ylegend[0] != '\0') {
+ Xvertical = im->text_prop[TEXT_PROP_UNIT].size * 2;
+ }
- /* The vertical size is interesting... we need to compare
- ** the sum of {Ytitle, Ymain, Yxlabel, Ylegend, Ywatermark} with
- ** Yvertical however we need to know {Ytitle+Ymain+Yxlabel}
- ** in order to start even thinking about Ylegend or Ywatermark.
- **
- ** Do it in three portions: First calculate the inner part,
- ** then do the legend, then adjust the total height of the img,
- ** adding space for a watermark if one exists;
- */
- /* reserve space for main and/or pie */
+ if (im->title[0] != '\0') {
+ /* The title is placed "inbetween" two text lines so it
+ ** automatically has some vertical spacing. The horizontal
+ ** spacing is added here, on each side.
+ */
+ /* don't care for the with of the title
+ Xtitle = gfx_get_text_width(im->canvas, 0,
+ im->text_prop[TEXT_PROP_TITLE].font,
+ im->text_prop[TEXT_PROP_TITLE].size,
+ im->tabwidth,
+ im->title, 0) + 2*Xspacing; */
+ Ytitle = im->text_prop[TEXT_PROP_TITLE].size * 2.6 + 10;
+ }
+
+ if (elements) {
+ Xmain = im->xsize;
+ Ymain = im->ysize;
+ }
+#ifdef WITH_PIECHART
+ if (piechart) {
+ im->piesize = im->xsize < im->ysize ? im->xsize : im->ysize;
+ Xpie = im->piesize;
+ Ypie = im->piesize;
+ }
+#endif
- im->yimg = Ymain + Yxlabel;
+ /* Now calculate the total size. Insert some spacing where
+ desired. im->xorigin and im->yorigin need to correspond
+ with the lower left corner of the main graph area or, if
+ this one is not set, the imaginary box surrounding the
+ pie chart area. */
+
+ /* The legend width cannot yet be determined, as a result we
+ ** have problems adjusting the image to it. For now, we just
+ ** forget about it at all; the legend will have to fit in the
+ ** size already allocated.
+ */
+ im->ximg = Xylabel + Xmain + 2 * Xspacing;
#ifdef WITH_PIECHART
- if (im->yimg < Ypie)
- im->yimg = Ypie;
+ im->ximg += Xpie;
#endif
- im->yorigin = im->yimg - Yxlabel;
+ if (Xmain)
+ im->ximg += Xspacing;
+#ifdef WITH_PIECHART
+ if (Xpie)
+ im->ximg += Xspacing;
+#endif
- /* reserve space for the title *or* some padding above the graph */
- if (Ytitle) {
- im->yimg += Ytitle;
- im->yorigin += Ytitle;
- } else {
- im->yimg += 1.5 * Yspacing;
- im->yorigin += 1.5 * Yspacing;
- }
- /* reserve space for padding below the graph */
- im->yimg += Yspacing;
+ im->xorigin = Xspacing + Xylabel;
- /* Determine where to place the legends onto the image.
- ** Adjust im->yimg to match the space requirements.
- */
- if (leg_place(im) == -1)
- return -1;
+ /* the length of the title should not influence with width of the graph
+ if (Xtitle > im->ximg) im->ximg = Xtitle; */
- if (im->watermark[0] != '\0') {
- im->yimg += Ywatermark;
+ if (Xvertical) { /* unit description */
+ im->ximg += Xvertical;
+ im->xorigin += Xvertical;
+ }
+ xtr(im, 0);
+
+ /* The vertical size is interesting... we need to compare
+ ** the sum of {Ytitle, Ymain, Yxlabel, Ylegend, Ywatermark} with
+ ** Yvertical however we need to know {Ytitle+Ymain+Yxlabel}
+ ** in order to start even thinking about Ylegend or Ywatermark.
+ **
+ ** Do it in three portions: First calculate the inner part,
+ ** then do the legend, then adjust the total height of the img,
+ ** adding space for a watermark if one exists;
+ */
+
+ /* reserve space for main and/or pie */
+
+ im->yimg = Ymain + Yxlabel;
+
+#ifdef WITH_PIECHART
+ if (im->yimg < Ypie)
+ im->yimg = Ypie;
+#endif
+
+ im->yorigin = im->yimg - Yxlabel;
+
+ /* reserve space for the title *or* some padding above the graph */
+ if (Ytitle) {
+ im->yimg += Ytitle;
+ im->yorigin += Ytitle;
+ } else {
+ im->yimg += 1.5 * Yspacing;
+ im->yorigin += 1.5 * Yspacing;
+ }
+ /* reserve space for padding below the graph */
+ im->yimg += Yspacing;
+
+ /* Determine where to place the legends onto the image.
+ ** Adjust im->yimg to match the space requirements.
+ */
+ if (leg_place(im, 0) == -1)
+ return -1;
+
+ if (im->watermark[0] != '\0') {
+ im->yimg += Ywatermark;
+ }
}
+
#if 0
if (Xlegend > im->ximg) {
im->ximg = Xlegend;
/* draw that picture thing ... */
int graph_paint(
- image_desc_t * im,
+ image_desc_t *im,
char ***calcpr)
{
int i, ii;
piechart = 2;
#endif
+/**************************************************************
+ *** Calculating sizes and locations became a bit confusing ***
+ *** so I moved this into a separate function. ***
+ **************************************************************/
+ if (graph_size_location(im, i
+#ifdef WITH_PIECHART
+ , piechart
+#endif
+ ) == -1)
+ return -1;
+
/* get actual drawing data and find min and max values */
if (data_proc(im) == -1)
return -1;
if (im->gridfit)
apply_gridfit(im);
-
-/**************************************************************
- *** Calculating sizes and locations became a bit confusing ***
- *** so I moved this into a separate function. ***
- **************************************************************/
- if (graph_size_location(im, i
-#ifdef WITH_PIECHART
- , piechart
-#endif
- ) == -1)
- return -1;
-
/* the actual graph is created by going through the individual
graph elements and then drawing them */
*****************************************************/
int gdes_alloc(
- image_desc_t * im)
+ image_desc_t *im)
{
im->gdes_c++;
}
void rrd_graph_init(
- image_desc_t * im)
+ image_desc_t *im)
{
unsigned int i;
void rrd_graph_options(
int argc,
char *argv[],
- image_desc_t * im)
+ image_desc_t *im)
{
int stroff;
char *parsetime_error = NULL;
{"vertical-label", required_argument, 0, 'v'},
{"width", required_argument, 0, 'w'},
{"height", required_argument, 0, 'h'},
+ {"full-size-mode", no_argument, 0, 'D'},
{"interlaced", no_argument, 0, 'i'},
{"upper-limit", required_argument, 0, 'u'},
{"lower-limit", required_argument, 0, 'l'},
int col_start, col_end;
opt = getopt_long(argc, argv,
- "s:e:x:y:v:w:h:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:",
+ "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:",
long_options, &option_index);
if (opt == EOF)
}
im->ysize = long_tmp;
break;
+ case 'D':
+ im->extra_flags |= FULL_SIZE_MODE;
+ break;
case 'i':
im->canvas->interlaced = 1;
break;
}
int rrd_graph_color(
- image_desc_t * im,
+ image_desc_t *im,
char *var,
char *err,
int optional)