Skip to content

Commit

Permalink
add configuration option BarColumnShowsRate to have the bar column in…
Browse files Browse the repository at this point in the history
… image list outputs be scaled according to the average rate column values when those values are visible, disabled by default (issue vergoh#170)
  • Loading branch information
vergoh committed Feb 1, 2021
1 parent 3f48b6e commit 8e5aef3
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 25 deletions.
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
- Add --initdb to daemon for creating a new empty database without
having the daemon process staying running, doesn't discard data
if a database already exists
- Add configuration option BarColumnShowsRate to have the bar column
in image list outputs be scaled according to the average rate column
values when those values are visible, disabled by default


2.6 / 20-Jan-2020
Expand Down
2 changes: 1 addition & 1 deletion UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# New configuration settings

* 2.7: EstimateBarVisible, EstimateStyle, ImageScale
* 2.7: BarColumnShowsRate, EstimateBarVisible, EstimateStyle, ImageScale

* 2.4 - 2.6: (none)

Expand Down
4 changes: 4 additions & 0 deletions cfg/vnstat.conf
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ ImageScale 100
# (0 = not shown, 1 = continuation of existing bar, 2 = separate bar)
EstimateStyle 1

# bar column in list outputs shows rate if OutputStyle is 3
# (1 = enabled, 0 = disabled)
BarColumnShowsRate 0

# image colors
CBackground "FFFFFF"
CEdge "AEAEAE"
Expand Down
14 changes: 13 additions & 1 deletion man/vnstat.conf.5
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH VNSTAT.CONF 5 "JANUARY 2020" "version 2.6" "User Manuals"
.TH VNSTAT.CONF 5 "FEBRUARY 2021" "version 2.7" "User Manuals"
.SH NAME
vnstat.conf \- vnStat configuration file

Expand Down Expand Up @@ -372,6 +372,18 @@ resolution.

.SH IMAGE OUTPUT RELATED KEYWORDS

.TP
.B BarColumnShowsRate
The bar column represents traffic rate in list outputs when enabled. Requires
also that
.B OutputStyle
has been configured to show the traffic rate column by using the value 3.
Enabling this option will automatically cause
.B EstimateStyle
to have the value 0. Visually this option affects only the color legend text and
the last line on the list if that line represents the currently ongoing time
period. 1 = enabled, 0 = disabled.

.TP
.B CBackground
Background color.
Expand Down
11 changes: 11 additions & 0 deletions src/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ int loadcfg(const char *cfgfile)
{"TransparentBg", 0, &cfg.transbg, 0, 0},
{"ImageScale", 0, &cfg.imagescale, 0, 0},
{"EstimateStyle", 0, &cfg.estimatestyle, 0, 0},
{"BarColumnShowsRate", 0, &cfg.barshowsrate, 0, 0},
{"CBackground", cfg.cbg, 0, 8, 0},
{"CEdge", cfg.cedge, 0, 8, 0},
{"CHeader", cfg.cheader, 0, 8, 0},
Expand Down Expand Up @@ -202,6 +203,7 @@ void validatecfg(void)
validatebool("TransparentBg", &cfg.transbg, TRANSBG);
validateint("ImageScale", &cfg.imagescale, IMAGESCALE, 50, 500);
validateint("EstimateStyle", &cfg.estimatestyle, ESTIMATESTYLE, 0, 2);
validatebool("BarColumnShowsRate", &cfg.barshowsrate, BARSHOWSRATE);
validatebool("HourlyRate", &cfg.hourlyrate, HOURLYRATE);
validatebool("SummaryRate", &cfg.summaryrate, SUMMARYRATE);
validatebool("TrafficlessEntries", &cfg.trafficlessentries, TRAFFICLESSENTRIES);
Expand Down Expand Up @@ -283,6 +285,14 @@ void validatecfg(void)
printe(PT_Config);
}
}

/* affects only image output */
if (cfg.barshowsrate && cfg.estimatebarvisible) {
cfg.estimatestyle = 0;
if (debug) {
printf("BarColumnShowsRate and EstimateBarVisible both enabled -> EstimateStyle set to 0\n");
}
}
}

void defaultcfg(void)
Expand Down Expand Up @@ -358,6 +368,7 @@ void defaultcfg(void)
cfg.transbg = TRANSBG;
cfg.imagescale = IMAGESCALE;
cfg.estimatestyle = ESTIMATESTYLE;
cfg.barshowsrate = BARSHOWSRATE;
strncpy_nt(cfg.cbg, CBACKGROUND, 8);
strncpy_nt(cfg.cedge, CEDGE, 8);
strncpy_nt(cfg.cheader, CHEADER, 8);
Expand Down
4 changes: 4 additions & 0 deletions src/cfgoutput.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ void printcfgfile(void)
printf("# (0 = not shown, 1 = continuation of existing bar, 2 = separate bar)\n");
printf("EstimateStyle %d\n\n", cfg.estimatestyle);

printf("# bar column in list outputs shows rate if OutputStyle is 3\n");
printf("# (1 = enabled, 0 = disabled)\n");
printf("BarColumnShowsRate %d\n\n", cfg.barshowsrate);

printf("# image colors\n");
printf("CBackground \"%s\"\n", cfg.cbg);
printf("CEdge \"%s\"\n", cfg.cedge);
Expand Down
5 changes: 4 additions & 1 deletion src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ and most can be changed later from the config file.
/* 0 = not shown, 1 = continuation of existing bar, 2 = separate bar */
#define ESTIMATESTYLE 1

/* bar column in list outputs shows rate when rate column is visible */
#define BARSHOWSRATE 0

/* default colors */
#define CBACKGROUND "FFFFFF"
#define CEDGE "AEAEAE"
Expand Down Expand Up @@ -282,7 +285,7 @@ typedef struct {
int32_t unitmode, rateunitmode, rateunit, bvar, qmode, sampletime, hourlyrate, summaryrate;
int32_t monthrotate, monthrotateyears, maxbw, spacecheck, trafficlessentries, transbg, ostyle;
int32_t defaultdecimals, hourlydecimals, hourlystyle, is64bit, waldb, dbsynchronous, imagescale;
int32_t estimatebarvisible, estimatestyle;
int32_t estimatebarvisible, estimatestyle, barshowsrate;
char cfgfile[512], logfile[512], pidfile[512];
char daemonuser[33], daemongroup[33];
int32_t timesyncwait, updateinterval, pollinterval, saveinterval, offsaveinterval, savestatus;
Expand Down
50 changes: 34 additions & 16 deletions src/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,25 @@ void layoutinit(IMAGECONTENT *ic, char *title, const int width, const int height
gdImageString(ic->im, gdFontGetTiny(), width - 114 - ic->showedge, height - 12 - ic->showedge, (unsigned char *)"vnStat / Teemu Toivola", ic->cvnstat);
}

void drawlegend(IMAGECONTENT *ic, const int x, const int y)
void drawlegend(IMAGECONTENT *ic, const int x, const int y, const short israte)
{
if (!ic->showlegend) {
return;
}

/* color legend */
gdImageString(ic->im, gdFontGetSmall(), x, y, (unsigned char *)"rx tx", ic->ctext);
gdImageFilledRectangle(ic->im, x - 12, y + 4, x - 6, y + 10, ic->crx);
gdImageRectangle(ic->im, x - 12, y + 4, x - 6, y + 10, ic->ctext);
gdImageFilledRectangle(ic->im, x + 30, y + 4, x + 36, y + 10, ic->ctx);
gdImageRectangle(ic->im, x + 30, y + 4, x + 36, y + 10, ic->ctext);
if (!israte) {
gdImageString(ic->im, gdFontGetSmall(), x, y, (unsigned char *)"rx tx", ic->ctext);
gdImageFilledRectangle(ic->im, x - 12, y + 4, x - 6, y + 10, ic->crx);
gdImageRectangle(ic->im, x - 12, y + 4, x - 6, y + 10, ic->ctext);
gdImageFilledRectangle(ic->im, x + 30, y + 4, x + 36, y + 10, ic->ctx);
gdImageRectangle(ic->im, x + 30, y + 4, x + 36, y + 10, ic->ctext);
} else {
gdImageString(ic->im, gdFontGetSmall(), x - 12, y, (unsigned char *)"rx tx rate", ic->ctext);
gdImageFilledRectangle(ic->im, x - 22, y + 4, x - 16, y + 10, ic->crx);
gdImageRectangle(ic->im, x - 22, y + 4, x - 16, y + 10, ic->ctext);
gdImageFilledRectangle(ic->im, x + 8, y + 4, x + 14, y + 10, ic->ctx);
gdImageRectangle(ic->im, x + 8, y + 4, x + 14, y + 10, ic->ctext);
}
}

void drawbar(IMAGECONTENT *ic, const int x, const int y, const int len, const uint64_t rx, const uint64_t tx, const uint64_t max, const short isestimate)
Expand Down Expand Up @@ -542,7 +549,7 @@ void drawhourly(IMAGECONTENT *ic, const int rate)

layoutinit(ic, buffer, width, height);
if (drawhours(ic, 12, 46 - headermod, rate)) {
drawlegend(ic, 242, 183 - headermod);
drawlegend(ic, 242, 183 - headermod, 0);
}
}

Expand All @@ -551,7 +558,7 @@ void drawlist(IMAGECONTENT *ic, const char *listname)
ListType listtype = LT_None;
int textx, texty, offsetx = 0, offsety = 0;
int width, height, headermod, i = 1, rowcount = 0;
int estimatevisible = 0;
int estimateavailable = 0, estimatevisible = 0;
int32_t limit;
uint64_t e_rx = 0, e_tx = 0, e_secs = 0;
char buffer[512], datebuff[16], daybuff[16];
Expand Down Expand Up @@ -611,12 +618,15 @@ void drawlist(IMAGECONTENT *ic, const char *listname)

datalist_i = datalist;

if (strlen(ic->dataend) == 0 && datainfo.count > 0 && (listtype == LT_Day || listtype == LT_Month || listtype == LT_Year)) {
estimatevisible = 1;
if (strlen(ic->dataend) == 0 && datainfo.count > 0 && listtype != LT_Top) {
getestimates(&e_rx, &e_tx, listtype, ic->interface.updated, &datalist);
if (cfg.estimatestyle > 0 && e_rx + e_tx > datainfo.max) {
datainfo.max = e_rx + e_tx;
}
estimateavailable = 1;
if (listtype == LT_Day || listtype == LT_Month || listtype == LT_Year) {
estimatevisible = 1;
}
}

if (listtype == LT_Top) {
Expand Down Expand Up @@ -694,16 +704,20 @@ void drawlist(IMAGECONTENT *ic, const char *listname)
if (datainfo.count) {
if (listtype == LT_Top) {
if (cfg.ostyle <= 2) {
drawlegend(ic, 398, 40 - headermod);
drawlegend(ic, 398, 40 - headermod, 0);
}
current = time(NULL);
d = localtime(&current);
strftime(daybuff, 16, stampformat, d);
} else { // everything else
if (cfg.ostyle > 2) {
drawlegend(ic, 432, 40 - headermod);
if (estimateavailable && cfg.barshowsrate) {
drawlegend(ic, 432, 40 - headermod, 1);
} else {
drawlegend(ic, 432, 40 - headermod, 0);
}
} else {
drawlegend(ic, 385, 40 - headermod);
drawlegend(ic, 385, 40 - headermod, 0);
}
}
}
Expand Down Expand Up @@ -788,7 +802,11 @@ void drawlist(IMAGECONTENT *ic, const char *listname)
}
} else { // everything else
if (cfg.ostyle > 2) {
drawbar(ic, textx + 400, texty + 4, 78, datalist_i->rx, datalist_i->tx, datainfo.max, 0);
if (datalist_i->next == NULL && estimateavailable && cfg.barshowsrate) {
drawbar(ic, textx + 400, texty + 4, 78, e_rx, e_tx, datainfo.max, 0);
} else {
drawbar(ic, textx + 400, texty + 4, 78, datalist_i->rx, datalist_i->tx, datainfo.max, 0);
}
} else {
drawbar(ic, textx + 304, texty + 4, 170, datalist_i->rx, datalist_i->tx, datainfo.max, 0);
}
Expand Down Expand Up @@ -911,7 +929,7 @@ void drawsummary(IMAGECONTENT *ic, const int layout, const int rate)
}

drawsummary_alltime(ic, 385, 57 - headermod);
drawlegend(ic, 410, 155 - headermod);
drawlegend(ic, 410, 155 - headermod, 0);

drawsummary_digest(ic, 100, 30 - headermod, "day");
drawsummary_digest(ic, 100, 113 - headermod, "month");
Expand Down
2 changes: 1 addition & 1 deletion src/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void scaleimage(IMAGECONTENT *ic);
void colorinit(IMAGECONTENT *ic);
void colorinitcheck(const char *color, const int value, const char *cfgtext, const int *rgb);
void layoutinit(IMAGECONTENT *ic, char *title, const int width, const int height);
void drawlegend(IMAGECONTENT *ic, const int x, const int y);
void drawlegend(IMAGECONTENT *ic, const int x, const int y, const short israte);
void drawbar(IMAGECONTENT *ic, const int x, const int y, const int len, const uint64_t rx, const uint64_t tx, const uint64_t max, const short isestimate);
void drawpole(IMAGECONTENT *ic, const int x, const int y, const int len, const uint64_t rx, const uint64_t tx, const uint64_t max);
void drawdonut(IMAGECONTENT *ic, const int x, const int y, const float rxp, const float txp);
Expand Down
27 changes: 24 additions & 3 deletions src/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ int issametimeslot(const ListType listtype, const time_t entry, const time_t upd
return 0;
}

// TODO: tests
uint64_t getperiodseconds(const ListType listtype, const time_t entry, const time_t updated, const short isongoing)
{
struct tm e, u;
Expand Down Expand Up @@ -486,6 +487,7 @@ uint64_t getperiodseconds(const ListType listtype, const time_t entry, const tim
return seconds;
}

// TODO: tests
void getestimates(uint64_t *rx, uint64_t *tx, const ListType listtype, const time_t updated, dbdatalist **dbdata)
{
struct tm u;
Expand All @@ -511,9 +513,28 @@ void getestimates(uint64_t *rx, uint64_t *tx, const ListType listtype, const tim
return;
}

if (listtype == LT_Day) {
div = (uint64_t)(u.tm_hour * 60 + u.tm_min);
mult = 1440;
/* LT_5min and LT_Hour don't have the estimate line visible in outputs */
/* but are used by BarColumnShowsRate which requires "past" values for */
/* full hours / 5 minutes for the bar to show correctly */
if (listtype == LT_5min) {
div = (uint64_t)((u.tm_min % 5 * 60) + u.tm_sec);
if (div == 0) {
div = 1;
mult = 1;
} else {
mult = 300;
}
} else if (listtype == LT_Hour) {
div = (uint64_t)(u.tm_min * 60 + u.tm_sec);
if (div == 0) {
div = 1;
mult = 1;
} else {
mult = 3600;
}
} else if (listtype == LT_Day) {
div = (uint64_t)(u.tm_hour * 3600 + u.tm_min * 60 + u.tm_sec);
mult = 86400;
} else if (listtype == LT_Month) {
div = (uint64_t)mosecs(datalist_i->timestamp, updated);
mult = (uint64_t)(dmonth(u.tm_mon) * 86400);
Expand Down
6 changes: 4 additions & 2 deletions tests/image_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,8 @@ START_TEST(libgd_output_comparison)
pngout = fopen("vnstati_libgd_comparison_check.png", "w");
ck_assert_ptr_ne(pngout, NULL);

drawlegend(&ic, 40, 30);
drawlegend(&ic, 40, 30, 0);
drawlegend(&ic, 240, 30, 1);

/* line 1 */
x = 40;
Expand Down Expand Up @@ -645,7 +646,8 @@ START_TEST(element_output_check)
gdImageString(ic.im, gdFontGetSmall(), 1020, 100, (unsigned char *)"Small - The quick brown fox jumps over the lazy dog", ic.ctext);
gdImageString(ic.im, gdFontGetTiny(), 1020, 120, (unsigned char *)"Tiny - The quick brown fox jumps over the lazy dog", ic.ctext);

drawlegend(&ic, 1230, 140);
drawlegend(&ic, 1130, 140, 0);
drawlegend(&ic, 1330, 140, 1);

drawbar(&ic, 1050, 160, 400, 50, 50, 100, 0);
drawbar(&ic, 1050, 180, 400, 25, 75, 100, 0);
Expand Down

0 comments on commit 8e5aef3

Please sign in to comment.