Introduction
Introduction Statistics Contact Development Disclaimer Help
ploot-farbfeld: comeback - ploot - simple plotting tools
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65…
Log
Files
Refs
Tags
README
LICENSE
---
commit 8836c19534760f2ce037c39bde9dc5591011ed07
parent eb816ab512727f55665f05809c78563ff93a94cc
Author: Josuah Demangeon <[email protected]>
Date: Sun, 27 Jun 2021 04:51:38 +0200
ploot-farbfeld: comeback
Diffstat:
M Makefile | 2 +-
M csv.c | 27 ++++++++++++++++++++++++++-
M csv.h | 1 +
A example.png | 0
M ploot-braille.c | 90 +++--------------------------…
M ploot-farbfeld.1 | 4 ----
M ploot-farbfeld.c | 64 +++++++++++++----------------…
M util.c | 53 ++++++++++++++++++++++++++++++
M util.h | 3 +++
9 files changed, 118 insertions(+), 126 deletions(-)
---
diff --git a/Makefile b/Makefile
@@ -9,7 +9,7 @@ MANOREFIX = $(PREFIX)/share/man
SRC = csv.c drawille.c font.c font13.c font8.c util.c
INC = csv.h drawille.h font.h util.h
-BIN = ploot-feed ploot-braille ploot-text # ploot-farbfeld
+BIN = ploot-feed ploot-braille ploot-text ploot-farbfeld
OBJ = ${SRC:.c=.o}
all: ${BIN}
diff --git a/csv.c b/csv.c
@@ -9,9 +9,34 @@
#include "util.h"
/*
- * Read CSV data onto a set of (struct csv).
+ * Read CSV data onto a set of (struct csv) and some utilities to work on thes…
*/
+int
+csv_min_max(struct csv *vl, int ncol,
+ time_t *tmin, time_t *tmax,
+ double *vmin, double *vmax)
+{
+ double *v;
+ time_t *t;
+ size_t n;
+
+ *vmin = *vmax = 0; /* always show 0 on the scale */
+ *tmin = *tmax = *vl->t;
+
+ for (; ncol > 0; ncol--, vl++) {
+ for (t = vl->t, v = vl->v, n = vl->n; n > 0; t++, v++, n--) {
+ if (*v < *vmin) *vmin = *v;
+ if (*v > *vmax) *vmax = *v;
+ if (*t < *tmin) *tmin = *t;
+ if (*t > *tmax) *tmax = *t;
+ }
+ }
+ if (*tmin == *tmax)
+ return -1;
+ return 0;
+}
+
static void
csv_add_time(struct csv *vl, time_t epoch)
{
diff --git a/csv.h b/csv.h
@@ -17,5 +17,6 @@ struct csv {
void csv_labels(FILE *, struct csv **, size_t *);
void csv_values(FILE *, struct csv *, size_t);
+int csv_min_max(struct csv *, int, time_t *, time_t *, double *, double…
#endif
diff --git a/example.png b/example.png
Binary files differ.
diff --git a/ploot-braille.c b/ploot-braille.c
@@ -15,85 +15,6 @@
#define pledge(...) 0
#endif
-static int
-get_min_max(struct csv *vl, int ncol,
- time_t *tmin, time_t *tmax,
- double *vmin, double *vmax)
-{
- double *v;
- time_t *t;
- size_t n;
-
- *vmin = *vmax = 0; /* always show 0 on the scale */
- *tmin = *tmax = *vl->t;
-
- for (; ncol > 0; ncol--, vl++) {
- for (t = vl->t, v = vl->v, n = vl->n; n > 0; t++, v++, n--) {
- if (*v < *vmin) *vmin = *v;
- if (*v > *vmax) *vmax = *v;
- if (*t < *tmin) *tmin = *t;
- if (*t > *tmax) *tmax = *t;
- }
- }
- if (*tmin == *tmax)
- return -1;
- return 0;
-}
-
-static time_t
-time_mark_step(time_t min, time_t max, int dots)
-{
- time_t dt, scale[] = {
- 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, 3600…
- 3600*2, 3600*6, 3600*12, 3600*24, 3600*24*2,
- 3600*24*7, 3600*24*14, 3600*24*20, 3600*24*21, 3600*24*28, 360…
- 3600*24*100, 3600*24*365, 0
- };
-
- dt = max - min;
- for (time_t *sc = scale; *sc > 0; sc++)
- if (dt < *sc * dots)
- return *sc;
- return dt / dots;
-}
-
-/*
- * Make the value scale aligned with round values by changing the
- * minimal and maximal values.
- */
-static void
-adjust_scale(double *min, double *max, int rows)
-{
- double dv, step, scale[] = { 1, 2, 2.5, 5, };
-
- dv = *max - *min;
-
- step = 1;
- if (dv > 1) {
- for (double mant = 1;; mant *= 10) {
- double *sc = scale;
- for (; sc < scale + LEN(scale); sc++) {
- step = mant * *sc;
- if (dv < rows * step)
- goto end;
- }
- }
- } else {
- for (double mant = 1;; mant /= 10) {
- double *sc = scale + LEN(scale) - 1;
- for (; sc >= scale; sc--) {
- double tmp = mant * *sc;
- if (dv > rows * tmp)
- goto end;
- step = tmp;
- }
- }
- }
-end:
- *min = (int)(*min / step) * step;
- *max = *min + step * rows;
-}
-
/*
* Plot the body as an histogram interpolating the gaps and include
* a vertical and horizontal axis.
@@ -185,17 +106,20 @@ braille_render(struct drawille *drw, FILE *fp, double min…
static void
plot(struct csv *vl, size_t ncol, int rows, int cols, FILE *fp)
{
- double vmin, vmax;
+ double vmin, vmax, vstep;
time_t tmin, tmax, tstep;
struct drawille *drw;
rows = MAX(rows, 2); /* readable */
- if (get_min_max(vl, ncol, &tmin, &tmax, &vmin, &vmax) < 0)
+ if (csv_min_max(vl, ncol, &tmin, &tmax, &vmin, &vmax) < 0)
err(1, "invalid scale: tmin=%lld tmax=%lld vmin=%fd vmax=%fd",
(long long)tmin, (long long)tmax, vmin, vmax);
- adjust_scale(&vmin, &vmax, rows);
- tstep = time_mark_step(tmin, tmax, cols);
+
+ tstep = scale_time_t(tmin, tmax, cols);
+ vstep = scale_double(vmin, vmax, rows);
+ vmin = (int)(vmin / vstep) * vstep;
+ vmax = vmin + vstep * rows;
for (; ncol > 0; vl++, ncol--) {
if ((drw = drawille_new(rows, cols)) == NULL)
diff --git a/ploot-farbfeld.1 b/ploot-farbfeld.1
@@ -13,7 +13,6 @@
.
.Nm ploot-ffplot
.Op Fl t Ar title
-.Op Fl u Ar unit
.Ar colors...
.
.
@@ -28,9 +27,6 @@ utility plots an image in the ffplot format out of csv values…
.It Fl t
Set the title of the plot printed at the top left corner.
.
-.It Fl u
-Set the unit description printed at the top right corner.
-.
.It Ar colors
List of argument that specify the color for each column.
If the input csv have 5 columns in addition of the timestamp, there must
diff --git a/ploot-farbfeld.c b/ploot-farbfeld.c
@@ -13,24 +13,23 @@
#include <unistd.h>
#include "csv.h"
#include "font.h"
-#include "scale.h"
#include "util.h"
#ifndef __OpenBSD__
#define pledge(...) 0
#endif
-#define MARGIN 4
+#define MARGIN 8
#define IMAGE_H (TITLE_H + PLOT_H + XLABEL_H)
-#define IMAGE_W (YLABEL_W + PLOT_W + LEGEND_W)
+#define IMAGE_W (MARGIN + YLABEL_W + PLOT_W + MARGIN)
-#define TITLE_X (YLABEL_W)
-#define TITLE_Y (IMAGE_H - TITLE_H)
+#define TITLE_X (MARGIN)
+#define TITLE_Y (IMAGE_H - TITLE_H / 2)
#define TITLE_H ((font)->height * 2)
#define TITLE_W (PLOT_W)
-#define YLABEL_X (0)
+#define YLABEL_X (MARGIN)
#define YLABEL_Y (PLOT_Y)
#define YLABEL_H (PLOT_H)
#define YLABEL_W (40 + MARGIN)
@@ -40,14 +39,13 @@
#define XLABEL_H ((font)->height * 2)
#define XLABEL_W (PLOT_W)
-#define PLOT_X (YLABEL_W)
+#define PLOT_X (YLABEL_X + YLABEL_W)
#define PLOT_Y (XLABEL_H)
#define PLOT_W (700)
#define PLOT_H (160)
-#define LEGEND_X (IMAGE_W - LEGEND_W)
-#define LEGEND_Y (TITLE_H + PLOT_H - (font)->height)
-#define LEGEND_W (100)
+#define LEGEND_X (IMAGE_W / 2)
+#define LEGEND_Y (TITLE_Y)
#define LEGEND_H (PLOT_H)
struct ffcolor {
@@ -76,8 +74,7 @@ static struct colorname {
{ NULL, { 0, 0, 0, 0 } }
};
-static char *tflag = "";
-static char *uflag = "";
+static char *flag_title = "";
static struct font *font = &font13;
/*
@@ -212,7 +209,7 @@ ffplot_print(FILE *fp, struct ffplot *plot)
w = htonl(plot->w);
h = htonl(plot->h);
- fprintf(stdout, "ffplot");
+ fprintf(stdout, "farbfeld");
fwrite(&w, sizeof(w), 1, fp);
fwrite(&h, sizeof(h), 1, fp);
fwrite(plot->buf, plot->w * plot->h, sizeof(*plot->buf), fp);
@@ -284,12 +281,9 @@ ffplot_yaxis(struct ffplot *plot, struct ffcolor *label, s…
}
static void
-ffplot_title(struct ffplot *plot,
- struct ffcolor *ct, char *title,
- struct ffcolor *cu, char *unit)
+ffplot_title(struct ffplot *plot, struct ffcolor *ct, char *title)
{
ffplot_text_left(plot, ct, font, title, TITLE_H / 2, 0);
- ffplot_text_right(plot, cu, font, unit, TITLE_H / 2, TITLE_W);
}
static void
@@ -329,27 +323,26 @@ ffplot_legend(struct ffplot *plot, struct ffcolor *fg, st…
{
size_t x, y;
+ x = y = 0;
for (; ncol > 0; ncol--, vl++, cl++) {
- y = -(ncol - 1) * (font->height + MARGIN);
- x = MARGIN * 2;
x = ffplot_text_left(plot, *cl, font, "-", x, y) + MARGIN;
x = ffplot_text_left(plot, fg, font, vl->label, x, y);
+ x = ffplot_text_left(plot, fg, font, " ", x, y);
}
}
/*
- * Plot the 'n' values list of the 'v' arrax with title 'name' and
- * 'units' label.
+ * Plot the 'n' values list of the 'v' arrax with title 'name' label.
*
- * Title (units)
- * x ^ Legend
- * label | - + - + - + - + - ....
- * here | - + - + - + - + - ....
+ * Title Legend
+ * x ^
+ * label | - + - + - + - + -
+ * here | - + - + - + - + -
* +---+---+---+---+-->
* x label here
*/
static void
-plot(struct csv *vl, struct ffcolor **cl, size_t ncol, char *name, char *units)
+plot(struct csv *vl, struct ffcolor **cl, size_t ncol, char *name)
{
struct ffplot plot = { IMAGE_W, IMAGE_H, 0, 0, NULL };
struct ffcolor plot_bg = { 0x2222, 0x2222, 0x2222, 0xffff };
@@ -360,9 +353,9 @@ plot(struct csv *vl, struct ffcolor **cl, size_t ncol, char…
double vmin, vmax, vstep;
time_t tmin, tmax, tstep;
- scale_minmax(vl, ncol, &tmin, &tmax, &vmin, &vmax);
- tstep = scale_tstep(tmin, tmax, 7);
- vstep = scale_vstep(vmin, vmax, 7);
+ csv_min_max(vl, ncol, &tmin, &tmax, &vmin, &vmax);
+ tstep = scale_time_t(tmin, tmax, 7);
+ vstep = scale_double(vmin, vmax, 7);
if ((plot.buf = calloc(IMAGE_H * IMAGE_W, sizeof *plot.buf)) == NULL)
err(1, "calloc: %s", strerror(errno));
@@ -385,7 +378,7 @@ plot(struct csv *vl, struct ffcolor **cl, size_t ncol, char…
plot.x = TITLE_X;
plot.y = TITLE_Y;
- ffplot_title(&plot, &title_fg, name, &label_fg, units);
+ ffplot_title(&plot, &title_fg, name);
plot.x = PLOT_X;
plot.y = PLOT_Y;
@@ -420,7 +413,7 @@ argv_to_color(struct ffcolor **cl, char **argv)
static void
usage(void)
{
- fprintf(stderr, "usage: %s [-t title] [-u unit] {", arg0);
+ fprintf(stderr, "usage: %s [-t title] {", arg0);
fputs(colorname->name, stderr);
for (struct colorname *cn = colorname + 1; cn->name != NULL; cn++)
fprintf(stderr, ",%s", cn->name);
@@ -440,13 +433,10 @@ main(int argc, char **argv)
err(1, "pledge: %s", strerror(errno));
arg0 = *argv;
- while ((c = getopt(argc, argv, "t:u:")) > -1) {
+ while ((c = getopt(argc, argv, "t:")) > -1) {
switch (c) {
case 't':
- tflag = optarg;
- break;
- case 'u':
- uflag = optarg;
+ flag_title = optarg;
break;
default:
usage();
@@ -469,7 +459,7 @@ main(int argc, char **argv)
csv_values(stdin, vl, ncol);
argv_to_color(cl, argv);
- plot(vl, cl, argc, tflag, uflag);
+ plot(vl, cl, argc, flag_title);
free(vl);
free(cl);
diff --git a/util.c b/util.c
@@ -1,4 +1,5 @@
#include "util.h"
+#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
@@ -122,3 +123,55 @@ humanize(char *str, double val)
return exp * 3;
}
+
+time_t
+scale_time_t(time_t min, time_t max, int dots)
+{
+ time_t dt, scale[] = {
+ 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, 3600…
+ 3600*2, 3600*6, 3600*12, 3600*24, 3600*24*2,
+ 3600*24*7, 3600*24*14, 3600*24*20, 3600*24*21, 3600*24*28, 360…
+ 3600*24*100, 3600*24*365, 0
+ };
+
+ dt = max - min;
+ for (time_t *sc = scale; *sc > 0; sc++)
+ if (dt < *sc * dots)
+ return *sc;
+ return dt / dots;
+}
+
+/*
+ * Make the value scale aligned with round values by changing the
+ * minimal and maximal values.
+ */
+double
+scale_double(double min, double max, int rows)
+{
+ double dv, step, scale[] = { 1, 2, 2.5, 5, };
+
+ dv = max - min;
+ step = 1;
+ if (dv > 1) {
+ for (double mant = 1;; mant *= 10) {
+ double *sc = scale;
+ for (; sc < scale + LEN(scale); sc++) {
+ step = mant * *sc;
+ if (dv < rows * step)
+ return step;
+ }
+ }
+ } else {
+ for (double mant = 1;; mant /= 10) {
+ double *sc = scale + LEN(scale) - 1;
+ for (; sc >= scale; sc--) {
+ double tmp = mant * *sc;
+ if (dv > rows * tmp)
+ return step;
+ step = tmp;
+ }
+ }
+ }
+ assert(!"not reached");
+ return 0;
+}
diff --git a/util.h b/util.h
@@ -2,6 +2,7 @@
#define TOOL_H
#include <stddef.h>
+#include <time.h>
#define LEN(x) (sizeof(x) / sizeof(*x))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
@@ -18,5 +19,7 @@ void put3utf(long);
char *strsep(char **, const char *);
void strchomp(char *);
int humanize(char *, double);
+time_t scale_time_t(time_t, time_t, int);
+double scale_double(double, double, int);
#endif
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.