summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 009ac7a)
raw | patch | inline | side by side (parent: 009ac7a)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Wed, 30 May 2007 05:23:07 +0000 (05:23 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Wed, 30 May 2007 05:23:07 +0000 (05:23 +0000) |
size of the canvas: --full-size-mode -- matthew.chambers vanderbilt.edu
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1089 a5681a0c-68f1-0310-ab6d-d61299d08faa
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1089 a5681a0c-68f1-0310-ab6d-d61299d08faa
CONTRIBUTORS | patch | blob | history | |
doc/rrdgraph.pod | patch | blob | history | |
src/rrd_graph.c | patch | blob | history | |
src/rrd_graph.h | patch | blob | history |
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index aaf7718dcec9c881824ba617cbd0b8c727035338..0dabaeac3612a6c8142daba1bc37b98617ac3dd2 100644 (file)
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
Jost.Krieger <Jost.Krieger with ruhr-uni-bochum.de>
Kai Siering <kai.siering with mediaways.net>
Larry Leszczynski <larryl with furph.com>
+Matt Chambers <matthew.chambers with vanderbilt.edu> --full-size-mode for rrdgraph
McCreary mccreary with xoanon.colorado.edu
Mike Mitchell <mcm with unx.sas.com>
Mike Slifcak <slif with bellsouth.net> many rrdtool-1.1.x fixes
diff --git a/doc/rrdgraph.pod b/doc/rrdgraph.pod
index 9060bd831b97d695edbe6d1ac3392bd79174ee4d..c451f06a31e0461313c7b24cc0f040d3aa902b7f 100644 (file)
--- a/doc/rrdgraph.pod
+++ b/doc/rrdgraph.pod
[B<-w>|B<--width> I<pixels>]
[B<-h>|B<--height> I<pixels>]
[B<-j>|B<--only-graph>]
+[B<-D>|B<--full-size-mode>]
-The width and height of the B<canvas> (the part of the graph with
+By default, the width and height of the B<canvas> (the part with
the actual data and such). This defaults to 400 pixels by 100 pixels.
+If you specify the B<--full-size-mode> option, the width and height
+specify the final dimensions of the output image and the canvas
+is automatically resized to fit.
+
If you specify the B<--only-graph> option and set the height E<lt> 32
pixels you will get a tiny graph image (thumbnail) to use as an icon
for use in an overview, for example. All labeling will be stripped off
diff --git a/src/rrd_graph.c b/src/rrd_graph.c
index f33cfc3dd8b981f1f820cb3494f6dc237a8c7bb4..2aba6f92c5d1f6a9612280eb7b4396ce97c35645 100644 (file)
--- a/src/rrd_graph.c
+++ b/src/rrd_graph.c
/* 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);
}
** 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;
}
- if (im->ylegend[0] != '\0') {
- Xvertical = im->text_prop[TEXT_PROP_UNIT].size * 2;
+ /** +---+--------------------------------------------+
+ ** | 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
+ /* 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 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;
- }
- if (im->draw_y_grid || im->forceleftspace) {
- Xylabel = gfx_get_text_width(im->canvas, 0,
- im->text_prop[TEXT_PROP_AXIS].font,
- im->text_prop[TEXT_PROP_AXIS].size,
- im->tabwidth,
- "0", 0) * im->unitslength;
- }
+ if (im->draw_x_grid) {
+ Yxlabel=im->text_prop[TEXT_PROP_AXIS].size *2.5;
+ }
+ if (im->draw_y_grid || im->forceleftspace ) {
+ Xylabel=gfx_get_text_width(im->canvas, 0,
+ im->text_prop[TEXT_PROP_AXIS].font,
+ im->text_prop[TEXT_PROP_AXIS].size,
+ im->tabwidth,
+ "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;
+ }
- im->yimg = Ymain + Yxlabel;
+ if (elements) {
+ Xmain=im->xsize;
+ Ymain=im->ysize;
+ }
#ifdef WITH_PIECHART
- if (im->yimg < Ypie)
- im->yimg = Ypie;
+ if (piechart) {
+ im->piesize=im->xsize<im->ysize?im->xsize:im->ysize;
+ Xpie=im->piesize;
+ Ypie=im->piesize;
+ }
#endif
- im->yorigin = im->yimg - 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. */
- /* 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;
+ /* 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;
- /* Determine where to place the legends onto the image.
- ** Adjust im->yimg to match the space requirements.
- */
- if (leg_place(im) == -1)
- return -1;
+#ifdef WITH_PIECHART
+ im->ximg += Xpie;
+#endif
- if (im->watermark[0] != '\0') {
- im->yimg += Ywatermark;
+ if (Xmain) im->ximg += Xspacing;
+#ifdef WITH_PIECHART
+ if (Xpie) im->ximg += Xspacing;
+#endif
+
+ 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 */
+ 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;
#ifdef WITH_PIECHART
/* The pie is placed in the upper right hand corner,
- ** just below the title (if any) and with sufficient
- ** padding.
- */
+ ** just below the title (if any) and with sufficient
+ ** padding.
+ */
if (elements) {
- im->pie_x = im->ximg - Xspacing - Xpie / 2;
- im->pie_y = im->yorigin - Ymain + Ypie / 2;
+ im->pie_x = im->ximg - Xspacing - Xpie/2;
+ im->pie_y = im->yorigin-Ymain+Ypie/2;
} else {
- im->pie_x = im->ximg / 2;
- im->pie_y = im->yorigin - Ypie / 2;
+ im->pie_x = im->ximg/2;
+ im->pie_y = im->yorigin-Ypie/2;
}
#endif
- ytr(im, DNAN);
+ ytr(im,DNAN);
return 0;
}
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 */
{"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;
diff --git a/src/rrd_graph.h b/src/rrd_graph.h
index 22523be540a5f4ffb31feec6630bc24c4624e91b..8d5dc35cae9421998a60eadef125f2760fb6385f 100644 (file)
--- a/src/rrd_graph.h
+++ b/src/rrd_graph.h
#define FORCE_UNITS 0x100 /* mask for all FORCE_UNITS_* flags */
#define FORCE_UNITS_SI 0x100 /* force use of SI units in Y axis (no effect in linear graph, SI instead of E in log graph) */
+#define FULL_SIZE_MODE 0x200 /* -width and -height indicate the total size of the image */
+
enum tmt_en { TMT_SECOND = 0, TMT_MINUTE, TMT_HOUR, TMT_DAY,
TMT_WEEK, TMT_MONTH, TMT_YEAR
};
image_desc_t *,
char ***);
int leg_place(
- image_desc_t *);
+ image_desc_t *,
+ int*);
int calc_horizontal_grid(
image_desc_t *);
int draw_horizontal_grid(