B<HRULE>B<:>I<value>B<#>I<color>[B<:>I<legend>][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
-B<LINE>[I<width>]B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
+B<LINE>[I<width>]B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>][B<:skipscale>][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
-B<AREA>B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]]
+B<AREA>B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>][B<:skipscale>]]
B<TICK>B<:>I<vname>B<#>I<rrggbb>[I<aa>][B<:>I<fraction>[B<:>I<legend>]]
will have no effect on the scale of the graph. If a HRULE is outside the
graphing area it will just not be visible.
-=head3 B<LINE>[I<width>]B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
+=head3 B<LINE>[I<width>]B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>][B<:skipscale>]][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
Draw a line of the specified width onto the graph. I<width> can be a
floating point number. If the color is not specified, the drawing is done
is stacked on top of the previous element which can be a B<LINE> or an
B<AREA>.
+Normally the graphing function makes sure that the entire B<LINE> or B<AREA>
+is visible in the chart. The scaling of the chart will be modified
+accordingly if necessary. Any B<LINE> or B<AREA> can be excluded from this
+process by adding the option B<skipscale>.
+
The B<dashes> modifier enables dashed line style. Without any further options
a symmetric dashed line with a segment length of 5 pixels will be drawn. The
dash pattern can be changed if the B<dashes=> parameter is followed by either
at which the stroke begins.
When you do not specify a color, you cannot specify a legend. Should
-you want to use STACK, use the "LINEx:<value>::STACK" form.
+you want to use B<STACK>, use the "LINEx:<value>::STACK" form.
+
-=head3 B<AREA>B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]]
+=head3 B<AREA>B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>][B<:skipscale>]]
See B<LINE>, however the area between the x-axis and the line will
be filled.
/* GF_TICK: the data values are not
** relevant for min and max
*/
- if (finite(paintval) && im->gdes[ii].gf != GF_TICK) {
+ if (finite(paintval) && im->gdes[ii].gf != GF_TICK && !im->gdes[ii].skipscale) {
if ((isnan(minval) || paintval < minval) &&
!(im->logarithmic && paintval <= 0.0))
minval = paintval;
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].stack = 0;
+ im->gdes[im->gdes_c - 1].skipscale = 0;
im->gdes[im->gdes_c - 1].linewidth = 0;
im->gdes[im->gdes_c - 1].debug = 0;
im->gdes[im->gdes_c - 1].start = im->start;
# define MAX_AXIS 4
typedef struct graph_desc_t {
- enum gf_en gf; /* graphing function */
- int stack; /* boolean */
- int debug; /* boolean */
+ enum gf_en gf; /* graphing function */
+ int stack; /* boolean */
+ int debug; /* boolean */
+ int skipscale; /* boolean */
char vname[MAX_VNAME_LEN + 1]; /* name of the variable */
- long vidx; /* gdes reference */
+ long vidx; /* gdes reference */
char rrd[1024]; /* name of the rrd_file containing data */
char ds_nam[DS_NAM_SIZE]; /* data source name */
long ds; /* data source number */
int ndash; /* number of dash segments */
double offset; /* dash offset along the line */
+
enum txa_en txtalign; /* change default alignment strategy for text */
/* the axis to use for this graph in x and y*/
* this code initially written by Alex van den Bogaerdt
****************************************************************************/
+#include <locale.h>
+
#include "rrd_graph.h"
+
#define dprintf(...) if (gdp->debug&1) fprintf(stderr,__VA_ARGS__);
#define dprintfparsed(...) if (gdp->debug&2) fprintf(stderr,__VA_ARGS__);
int getDouble(const char* v, double *val,char**extra) {
/* try to execute the parser */
/* NOTE that this may be a bit different from the original parser */
+ char *old_locale;
*extra=NULL;
+ old_locale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "C");
+ errno = 0;
+ *val = strtod(v,extra);
+ if (errno > 0) {
+ rrd_set_error("converting '%s' to float: %s", v, rrd_strerror(errno));
+ return -1;
+ };
+ setlocale(LC_NUMERIC, old_locale);
+
*val=strtod(v,extra);
/* and error handling */
if (extra==NULL) {
} else if ((poscnt>0)&&(strcmp(field,"strftime")==0)) {
key="strftime";
value="1";
+ } else if ((poscnt>0)&&(strcmp(field,"skipscale")==0)) {
+ key="skipscale";
+ value="1";
} else {
if (poscnt>9) {
rrd_set_error("too many positional arguments");
#define PARSE_XAXIS (PARSE_FIELD1|(1L<<13))
#define PARSE_YAXIS (PARSE_FIELD1|(1L<<14))
#define PARSE_REDUCE (PARSE_FIELD1|(1L<<15))
+#define PARSE_SKIPSCALE (PARSE_FIELD1|(1L<<16))
+
#define PARSE_DASHES (PARSE_FIELD1|(1L<<20))
#define PARSE_HEIGHT (PARSE_FIELD1|(1L<<21))
#define PARSE_FORMAT (PARSE_FIELD1|(1L<<22))
gdp->stack=(stack)?1:0;
dprintfparsed("got stack: %s\n",stack);
}
+ if (bitscmp(PARSE_SKIPSCALE)) {
+ char *skipscale=getKeyValueArgument("skipscale",1,pa);
+ gdp->skipscale =(skipscale)?1:0;
+ dprintfparsed("got skipscale: %s\n",skipscale);
+ }
if (bitscmp(PARSE_REDUCE)) {
char *reduce=getKeyValueArgument("reduce",1,pa);
if (reduce) {
graph_desc_t *gdp=newGraphDescription(im,gf,pa,
PARSE_VNAMECOLORLEGEND
|PARSE_STACK
+ |PARSE_SKIPSCALE
|PARSE_LINEWIDTH
|PARSE_DASHES
|PARSE_XAXIS
gdp->col2.red,gdp->col2.green,gdp->col2.blue,gdp->col2.alpha);
dprintf("LEGEND: %s\n",gdp->legend);
dprintf("STACK : %i\n",gdp->stack);
+ dprintf("SKIPSCALE : %i\n",gdp->skipscale);
dprintf("WIDTH : %g\n",gdp->linewidth);
dprintf("XAXIS : %i\n",gdp->xaxisidx);
dprintf("YAXIS : %i\n",gdp->yaxisidx);
graph_desc_t *gdp=newGraphDescription(im,gf,pa,
PARSE_VNAMECOLORLEGEND
|PARSE_STACK
+ |PARSE_SKIPSCALE
|PARSE_XAXIS
|PARSE_YAXIS
|PARSE_HEIGHT
gdp->col2.red,gdp->col2.green,gdp->col2.blue,gdp->col2.alpha);
dprintf("LEGEND: %s\n",gdp->legend);
dprintf("STACK : %i\n",gdp->stack);
+ dprintf("SKIPSCALE : %i\n",gdp->skipscale);
dprintf("XAXIS : %i\n",gdp->xaxisidx);
dprintf("YAXIS : %i\n",gdp->yaxisidx);
dprintf("=================================\n");
if (parseArguments(argv[i],&pa)) {
return; }
+ /* dumpArguments(&pa); */
/* now let us handle the field based on the first command or cmd=...*/
char*cmd=NULL;
/* and try to get via cmd */