iput code in commont between ploot-ff.c and ploot-braille.c to separate files - ploot - simple plotting tools Err bitreich.org 70 hgit clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot URL:git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot bitreich.org 70 1Log /scm/ploot/log.gph bitreich.org 70 1Files /scm/ploot/files.gph bitreich.org 70 1Refs /scm/ploot/refs.gph bitreich.org 70 1Tags /scm/ploot/tag bitreich.org 70 1README /scm/ploot/file/README.md.gph bitreich.org 70 1LICENSE /scm/ploot/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 1c1a69494de95f4f5a3a439a16fac98026e2aa09 /scm/ploot/commit/1c1a69494de95f4f5a3a439a16fac98026e2aa09.gph bitreich.org 70 1parent 62211b846caa7b980b6a43dea1fdf0a0e2f6de34 /scm/ploot/commit/62211b846caa7b980b6a43dea1fdf0a0e2f6de34.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:me@josuah.net bitreich.org 70 iDate: Sat, 8 Feb 2020 18:38:14 +0100 Err bitreich.org 70 i Err bitreich.org 70 iput code in commont between ploot-ff.c and ploot-braille.c to separate files Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 2 +- Err bitreich.org 70 i M arg.h | 6 +++--- Err bitreich.org 70 i M def.h | 27 +++++++++++++++++++++------ Err bitreich.org 70 i A ploot-braille.c | 200 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i M ploot-ff.c | 295 +++++++------------------------ Err bitreich.org 70 i D ploot-plot.c | 201 ------------------------------ Err bitreich.org 70 i Err bitreich.org 70 i6 files changed, 292 insertions(+), 439 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/ploot/file/Makefile.gph bitreich.org 70 i@@ -5,7 +5,7 @@ BIN = ploot-ff ploot-feed Err bitreich.org 70 i LIB = -lm Err bitreich.org 70 i MANDIR = $(PREFIX)/share/man Err bitreich.org 70 i Err bitreich.org 70 i-SRC = util.c drawille.c font.c font7.c font8.c font13.c Err bitreich.org 70 i+SRC = csv.c drawille.c font.c font7.c font8.c font13.c util.c scale.c Err bitreich.org 70 i Err bitreich.org 70 i all: $(BIN) Err bitreich.org 70 i Err bitreich.org 70 1diff --git a/arg.h b/arg.h /scm/ploot/file/arg.h.gph bitreich.org 70 i@@ -5,11 +5,11 @@ extern char const *arg0; Err bitreich.org 70 i Err bitreich.org 70 i #define ARG_SWITCH(argc, argv) \ Err bitreich.org 70 i arg0 = *argv; \ Err bitreich.org 70 i- while (++argv && --argc && **argv == '-' && (*argv)[1]) \ Err bitreich.org 70 i+ while (++argv && --argc && **argv == '-' && (*argv)[1]) \ Err bitreich.org 70 i if ((*argv)[1] == '-' && (*argv)[2] == '\0') { \ Err bitreich.org 70 i ++argv; break; \ Err bitreich.org 70 i- } else for (int stop = 0; !stop && *++*argv != '\0' ;) \ Err bitreich.org 70 i- switch (**argv) Err bitreich.org 70 i+ } else for (int stop = 0; !stop && *++*argv != '\0' ;) \ Err bitreich.org 70 i+ switch (**argv) Err bitreich.org 70 i Err bitreich.org 70 i #define ARG ((*++*argv != '\0' || *++argv != NULL) \ Err bitreich.org 70 i ? ((stop = 1), argc--, *argv) \ Err bitreich.org 70 1diff --git a/def.h b/def.h /scm/ploot/file/def.h.gph bitreich.org 70 i@@ -23,6 +23,23 @@ struct font { Err bitreich.org 70 i char *glyph[128]; /* 0: end, 1: off, 2: on. */ Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * List of values and timestamps. Both have their dedicated buffer Err bitreich.org 70 i+ * so that the timestamp buffer can be shared across vlist objects. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+struct vlist { Err bitreich.org 70 i+ time_t *t; /* array of timestamps */ Err bitreich.org 70 i+ double *v; /* array of values */ Err bitreich.org 70 i+ size_t n; /* number of values */ Err bitreich.org 70 i+ char *label; /* for the legend */ Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+/* csv.c */ Err bitreich.org 70 i+ Err bitreich.org 70 i+void csv_addrow (struct vlist *, size_t, char *); Err bitreich.org 70 i+void csv_values (struct vlist *, size_t); Err bitreich.org 70 i+void csv_labels (struct vlist *, char **, char *); Err bitreich.org 70 i+ Err bitreich.org 70 i /* drawille.c */ Err bitreich.org 70 i Err bitreich.org 70 i size_t drawille_fmt_row (struct drawille *, char *, size_t, int); Err bitreich.org 70 i@@ -38,17 +55,15 @@ char * drawille_text (struct drawille *, int, int, struct font *, char *); Err bitreich.org 70 i size_t font_width (struct font *, int); Err bitreich.org 70 i size_t font_strlen (struct font *, char *); Err bitreich.org 70 i Err bitreich.org 70 i-/* font13.c */ Err bitreich.org 70 i+/* font*.c */ Err bitreich.org 70 i Err bitreich.org 70 i struct font font13; Err bitreich.org 70 i- Err bitreich.org 70 i-/* font7.c */ Err bitreich.org 70 i- Err bitreich.org 70 i+struct font font7; Err bitreich.org 70 i struct font font8; Err bitreich.org 70 i Err bitreich.org 70 i-/* font8.c */ Err bitreich.org 70 i+/* scale.c */ Err bitreich.org 70 i Err bitreich.org 70 i-struct font font8; Err bitreich.org 70 i+void scale (struct vlist *, int, time_t *, time_t *, time_t *, double *, double *, double *); Err bitreich.org 70 i Err bitreich.org 70 i /* util.c */ Err bitreich.org 70 i Err bitreich.org 70 1diff --git a/ploot-braille.c b/ploot-braille.c /scm/ploot/file/ploot-braille.c.gph bitreich.org 70 i@@ -0,0 +1,200 @@ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#include "def.h" Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Adjust the vertical scale so that it gets possible to Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static void Err bitreich.org 70 i+plot_scale(double *min, double *max, int row) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ double unit, range, mi; Err bitreich.org 70 i+ Err bitreich.org 70 i+ range = *max - *min; Err bitreich.org 70 i+ unit = 1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Zoom until it fills the canvas. */ Err bitreich.org 70 i+ for (; (row - 1) * unit > range; unit /= 10) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Dezoom until it fits the canvas. */ Err bitreich.org 70 i+ for (; (row - 1) * unit < range; unit *= 10) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Fine tune. */ Err bitreich.org 70 i+ if ((row - 1) * unit / 5 > range) Err bitreich.org 70 i+ unit /= 5; Err bitreich.org 70 i+ if ((row - 1) * unit / 4 > range) Err bitreich.org 70 i+ unit /= 4; Err bitreich.org 70 i+ if ((row - 1) * unit / 2 > range) Err bitreich.org 70 i+ unit /= 2; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Align the minimum (and the zero). */ Err bitreich.org 70 i+ for (mi = 0; mi > *min - unit; mi -= unit) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Update the displayed minimal and maximal. */ Err bitreich.org 70 i+ *min = mi; Err bitreich.org 70 i+ *max = mi + unit * row; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Return the step between two values. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static int Err bitreich.org 70 i+plot_time_interval(time_t step) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ time_t scale[] = { Err bitreich.org 70 i+ 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, Err bitreich.org 70 i+ 3600, 3600*2, 3600*5, 3600*10, 3600*18, 3600*24, 3600*24*2, Err bitreich.org 70 i+ 3600*24*5, 3600*24*10, 3600*24*20, 3600*24*30, 3600*24*50, Err bitreich.org 70 i+ 3600*24*100, 3600*24*365, 0 Err bitreich.org 70 i+ }; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (time_t *s = scale; *s != 0; s++) Err bitreich.org 70 i+ if (*s >= 20 * step) Err bitreich.org 70 i+ return *s; Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static size_t Err bitreich.org 70 i+plot_axis_x(char *buf, size_t sz, time_t step, time_t t2, int col) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int x, prec; Err bitreich.org 70 i+ char tmp[sizeof("MM/DD HH:MM")], *fmt; Err bitreich.org 70 i+ size_t n; Err bitreich.org 70 i+ time_t t, interval; Err bitreich.org 70 i+ Err bitreich.org 70 i+ interval = plot_time_interval(step); Err bitreich.org 70 i+ fmt = (step < 3600 * 12) ? "^%H:%M:%S" : Err bitreich.org 70 i+ (step < 3600 * 24) ? "^%m/%d %H:%M" : Err bitreich.org 70 i+ "^%Y/%m/%d"; Err bitreich.org 70 i+ n = x = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ t = t2 - col * 2 * step; Err bitreich.org 70 i+ t += interval - t % interval; Err bitreich.org 70 i+ for (; t < t2; t += interval) { Err bitreich.org 70 i+ strftime(tmp, sizeof tmp, fmt, localtime(&t)); Err bitreich.org 70 i+ x = ((t - t2) / 2 + col * step) / step; Err bitreich.org 70 i+ prec = x - n + strlen(tmp); Err bitreich.org 70 i+ assert((n += snprintf(buf+n, sz-n, "%*s", prec, tmp)) <= sz); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ assert((n += strlcpy(buf+n, "\n", sz-n)) < sz); Err bitreich.org 70 i+ return n; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Plot a single line out of the y axis, at row out of . Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static size_t Err bitreich.org 70 i+plot_axis_y(char *buf, size_t sz, double min, double max, int r, int rows) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ size_t i; Err bitreich.org 70 i+ char tmp[10] = "", *s; Err bitreich.org 70 i+ double val; Err bitreich.org 70 i+ Err bitreich.org 70 i+ val = (max - min) * (rows - r) / rows + min; Err bitreich.org 70 i+ humanize(tmp, sizeof tmp, val); Err bitreich.org 70 i+ s = (r == 0) ? "┌" : Err bitreich.org 70 i+ (r == rows - 1) ? "└" : Err bitreich.org 70 i+ "├"; Err bitreich.org 70 i+ i = snprintf(buf, sz, "%s%-6s ", s, tmp); Err bitreich.org 70 i+ return (i > sz) ? (sz) : (i); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static char * Err bitreich.org 70 i+plot_render(struct drawille *drw, double min, double max, time_t step, time_t t2) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ char *buf; Err bitreich.org 70 i+ size_t sz; Err bitreich.org 70 i+ size_t n; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Render the plot line by line. */ Err bitreich.org 70 i+ sz = drw->row * (20 + drw->col * 3 + 1) + 1; Err bitreich.org 70 i+ sz += drw->col + 1 + 100000; Err bitreich.org 70 i+ if ((buf = calloc(sz, 1)) == NULL) Err bitreich.org 70 i+ goto err; Err bitreich.org 70 i+ n = 0; Err bitreich.org 70 i+ for (int row = 0; row < drw->row; row++) { Err bitreich.org 70 i+ n += drawille_fmt_row(drw, buf+n, sz-n, row); Err bitreich.org 70 i+ n += plot_axis_y(buf+n, sz-n, min, max, row, drw->row); Err bitreich.org 70 i+ n += strlcpy(buf+n, "\n", sz-n); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ plot_axis_x(buf+n, sz-n, step, t2, drw->col); Err bitreich.org 70 i+ return buf; Err bitreich.org 70 i+err: Err bitreich.org 70 i+ errno = ENOBUFS; Err bitreich.org 70 i+ free(buf); Err bitreich.org 70 i+ return NULL; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Plot the body as an histogram interpolating the gaps and include Err bitreich.org 70 i+ * a vertical and horizontal axis. Err bitreich.org 70 i+ */ Err bitreich.org 70 i+static char * Err bitreich.org 70 i+plot_hist(struct vlist *vl, time_t t2, struct drawille *drw) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int x, y, zero, shift; Err bitreich.org 70 i+ double min, max, val; Err bitreich.org 70 i+ time_t t1, t; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Adjust the y scale. */ Err bitreich.org 70 i+ shift = min = max = 0; Err bitreich.org 70 i+ timeserie_stats(vl, &min, &max); Err bitreich.org 70 i+ if (drw->row > 1) { Err bitreich.org 70 i+ shift = 2; /* Align values to the middle of the scale: |- */ Err bitreich.org 70 i+ plot_scale(&min, &max, drw->row); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ zero = timeserie_ypos(0, min, max, drw->row*4) - shift; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Adjust the x scale. */ Err bitreich.org 70 i+ t2 = t2 + vl->step - t2 % vl->step; Err bitreich.org 70 i+ t1 = t2 - vl->step * vl->len; Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Plot the data in memory in starting from the end (t2). */ Err bitreich.org 70 i+ t = t2; Err bitreich.org 70 i+ for (x = drw->col * 2; x > 0; x--) { Err bitreich.org 70 i+ val = timeserie_get(vl, t); Err bitreich.org 70 i+ if (!isnan(val)) { Err bitreich.org 70 i+ y = timeserie_ypos(val, min, max, drw->row*4) - shift; Err bitreich.org 70 i+ drawille_dot_hist(drw, x, y, zero); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ t -= vl->step; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ return plot_render(drw, min, max, vl->step, t2); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static char * Err bitreich.org 70 i+plot(struct vlist *vl, time_t t2, int row, int col) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct drawille *drw; Err bitreich.org 70 i+ size_t len; Err bitreich.org 70 i+ char *buf; Err bitreich.org 70 i+ Err bitreich.org 70 i+ len = 500; Err bitreich.org 70 i+ buf = NULL; Err bitreich.org 70 i+ drw = NULL; Err bitreich.org 70 i+ col -= 8; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (timeserie_read(vl) == -1) Err bitreich.org 70 i+ goto err; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if ((drw = drawille_new(row, col)) == NULL) Err bitreich.org 70 i+ goto err; Err bitreich.org 70 i+ Err bitreich.org 70 i+ buf = plot_hist(vl, t2, drw); Err bitreich.org 70 i+err: Err bitreich.org 70 i+ if (buf == NULL) Err bitreich.org 70 i+ timedb_close(&vl->db); Err bitreich.org 70 i+ free(drw); Err bitreich.org 70 i+ return buf; Err bitreich.org 70 i+} Err bitreich.org 70 1diff --git a/ploot-ff.c b/ploot-ff.c /scm/ploot/file/ploot-ff.c.gph bitreich.org 70 i@@ -18,9 +18,6 @@ Err bitreich.org 70 i Err bitreich.org 70 i #define MARGIN 4 Err bitreich.org 70 i Err bitreich.org 70 i-#define XDENSITX 7 /* nb of values on x axis */ Err bitreich.org 70 i-#define YDENSITX 7 /* nb of values on y axis */ Err bitreich.org 70 i- Err bitreich.org 70 i #define IMAGE_H (TITLE_H + PLOT_H + XLABEL_H) Err bitreich.org 70 i #define IMAGE_W (YLABEL_W + PLOT_W + LEGEND_W) Err bitreich.org 70 i Err bitreich.org 70 i@@ -45,8 +42,8 @@ Err bitreich.org 70 i #define PLOT_H (160) Err bitreich.org 70 i Err bitreich.org 70 i #define LEGEND_X (IMAGE_W - LEGEND_W) Err bitreich.org 70 i-#define LEGEND_Y (XLABEL_H) Err bitreich.org 70 i-#define LEGEND_W (150) Err bitreich.org 70 i+#define LEGEND_Y (TITLE_H + PLOT_H - (font)->height) Err bitreich.org 70 i+#define LEGEND_W (100) Err bitreich.org 70 i #define LEGEND_H (PLOT_H) Err bitreich.org 70 i Err bitreich.org 70 i struct color { Err bitreich.org 70 i@@ -56,12 +53,9 @@ struct color { Err bitreich.org 70 i uint16_t alpha; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i-struct vlist { Err bitreich.org 70 i- struct color color; /* color to use to draw the line */ Err bitreich.org 70 i- time_t *t; /* array of timestamps */ Err bitreich.org 70 i- double *v; /* array of values */ Err bitreich.org 70 i- int n; /* number of values */ Err bitreich.org 70 i- char *label; /* for the legend */ Err bitreich.org 70 i+struct cname { Err bitreich.org 70 i+ char *name; Err bitreich.org 70 i+ struct color color; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i struct canvas { Err bitreich.org 70 i@@ -72,17 +66,12 @@ struct canvas { Err bitreich.org 70 i struct color *buf; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i-struct clist { Err bitreich.org 70 i- char *name; Err bitreich.org 70 i- struct color color; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i char const *arg0; Err bitreich.org 70 i static char *tflag = ""; Err bitreich.org 70 i static char *uflag = ""; Err bitreich.org 70 i static struct font *font = &font13; Err bitreich.org 70 i Err bitreich.org 70 i-struct clist clist[] = { Err bitreich.org 70 i+static struct cname cname[] = { Err bitreich.org 70 i /* name red green blue alpha */ Err bitreich.org 70 i { "red", { 0xffff, 0x4444, 0x4444, 0xffff } }, Err bitreich.org 70 i { "orange", { 0xffff, 0x9999, 0x4444, 0xffff } }, Err bitreich.org 70 i@@ -93,98 +82,6 @@ struct clist clist[] = { Err bitreich.org 70 i { NULL, { 0, 0, 0, 0 } } Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i-static struct color * Err bitreich.org 70 i-name_to_color(char *name) Err bitreich.org 70 i-{ Err bitreich.org 70 i- for (struct clist *c = clist; c->name != NULL; c++) Err bitreich.org 70 i- if (strcmp(name, c->name) == 0) Err bitreich.org 70 i- return &c->color; Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static void Err bitreich.org 70 i-scale_minmax(struct vlist *v, int n, Err bitreich.org 70 i- time_t *tmin, time_t *tmax, Err bitreich.org 70 i- double *vmin, double *vmax) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int i; Err bitreich.org 70 i- Err bitreich.org 70 i- *vmin = *vmax = 0; Err bitreich.org 70 i- *tmin = *tmax = *v->t; Err bitreich.org 70 i- Err bitreich.org 70 i- for (; n-- > 0; v++) { Err bitreich.org 70 i- for (i = 0; i < v->n; i++) { Err bitreich.org 70 i- if (v->v[i] < *vmin) Err bitreich.org 70 i- *vmin = v->v[i]; Err bitreich.org 70 i- if (v->v[i] > *vmax) Err bitreich.org 70 i- *vmax = v->v[i]; Err bitreich.org 70 i- if (v->t[i] < *tmin) Err bitreich.org 70 i- *tmin = v->t[i]; Err bitreich.org 70 i- if (v->t[i] > *tmax) Err bitreich.org 70 i- *tmax = v->t[i]; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static void Err bitreich.org 70 i-scale_tstep(time_t *step, int density, time_t min, time_t max) Err bitreich.org 70 i-{ Err bitreich.org 70 i- time_t dt, *s, scale[] = { Err bitreich.org 70 i- 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, 3600, Err bitreich.org 70 i- 3600*2, 3600*5, 3600*10, 3600*18, 3600*24, 3600*24*2, Err bitreich.org 70 i- 3600*24*5, 3600*24*10, 3600*24*20, 3600*24*30, 3600*24*50, Err bitreich.org 70 i- 3600*24*100, 3600*24*365, 0 Err bitreich.org 70 i- }; Err bitreich.org 70 i- Err bitreich.org 70 i- dt = max - min; Err bitreich.org 70 i- Err bitreich.org 70 i- for (s = scale; s < scale + LEN(scale); s++) { Err bitreich.org 70 i- if (dt < *s * density) { Err bitreich.org 70 i- *step = *s; Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static void Err bitreich.org 70 i-scale_vstep(double *step, int density, double min, double max) Err bitreich.org 70 i-{ Err bitreich.org 70 i- double dv, *s, scale[] = { 1, 2, 3, 5 }; Err bitreich.org 70 i- int i; Err bitreich.org 70 i- Err bitreich.org 70 i- dv = max - min; Err bitreich.org 70 i- Err bitreich.org 70 i- if (dv > 1) { Err bitreich.org 70 i- for (i = 1; i != 0; i *= 10) { Err bitreich.org 70 i- for (s = scale; s < scale + LEN(scale); s++) { Err bitreich.org 70 i- if (dv < *s * i * density) { Err bitreich.org 70 i- *step = *s * i; Err bitreich.org 70 i- return; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i- } else { Err bitreich.org 70 i- for (i = 1; i != 0; i *= 10) { Err bitreich.org 70 i- for (s = scale + LEN(scale) - 1; s >= scale; s--) { Err bitreich.org 70 i- if (dv > *s / i * density / 2) { Err bitreich.org 70 i- *step = *s / i; Err bitreich.org 70 i- return; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static void Err bitreich.org 70 i-scale(struct vlist *v, int n, Err bitreich.org 70 i- time_t *tmin, time_t *tmax, time_t *tstep, Err bitreich.org 70 i- double *vmin, double *vmax, double *vstep) Err bitreich.org 70 i-{ Err bitreich.org 70 i- scale_minmax(v, n, tmin, tmax, vmin, vmax); Err bitreich.org 70 i- scale_tstep(tstep, XDENSITX, *tmin, *tmax); Err bitreich.org 70 i- scale_vstep(vstep, YDENSITX, *vmin, *vmax); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i /* Err bitreich.org 70 i * Convert (x,y) coordinates to (row,col) for printing into the buffer. Err bitreich.org 70 i * The buffer only contain one number, so the coordinate is a single integer: Err bitreich.org 70 i@@ -196,18 +93,18 @@ scale(struct vlist *v, int n, Err bitreich.org 70 i * - (0,1) is above it. +--x Err bitreich.org 70 i */ Err bitreich.org 70 i static void Err bitreich.org 70 i-ff_pixel(struct canvas *can, struct color *col, Err bitreich.org 70 i+ff_pixel(struct canvas *can, struct color *color, Err bitreich.org 70 i int x, int y) Err bitreich.org 70 i { Err bitreich.org 70 i x += can->x; Err bitreich.org 70 i y += can->y; Err bitreich.org 70 i if (x < 0 || x >= can->w || y < 0 || y >= can->h) Err bitreich.org 70 i return; Err bitreich.org 70 i- memcpy(can->buf + can->w * (can->h - 1 - y) + x, col, sizeof(*can->buf)); Err bitreich.org 70 i+ memcpy(can->buf + can->w * (can->h - 1 - y) + x, color, sizeof(*can->buf)); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i-ff_rectangle(struct canvas *can, struct color *col, Err bitreich.org 70 i+ff_rectangle(struct canvas *can, struct color *color, Err bitreich.org 70 i int y1, int x1, Err bitreich.org 70 i int y2, int x2) Err bitreich.org 70 i { Err bitreich.org 70 i@@ -218,14 +115,14 @@ ff_rectangle(struct canvas *can, struct color *col, Err bitreich.org 70 i Err bitreich.org 70 i for (y = ymin; y <= ymax; y++) Err bitreich.org 70 i for (x = xmin; x <= xmax; x++) Err bitreich.org 70 i- ff_pixel(can, col, x, y); Err bitreich.org 70 i+ ff_pixel(can, color, x, y); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i /* Err bitreich.org 70 i * From Bresenham's line algorithm and dcat's tplot. Err bitreich.org 70 i */ Err bitreich.org 70 i static void Err bitreich.org 70 i-ff_line(struct canvas *can, struct color *col, Err bitreich.org 70 i+ff_line(struct canvas *can, struct color *color, Err bitreich.org 70 i int x0, int y0, Err bitreich.org 70 i int x1, int y1) Err bitreich.org 70 i { Err bitreich.org 70 i@@ -238,7 +135,7 @@ ff_line(struct canvas *can, struct color *col, Err bitreich.org 70 i err = (dy > dx ? dy : -dx) / 2; Err bitreich.org 70 i Err bitreich.org 70 i for (;;) { Err bitreich.org 70 i- ff_pixel(can, col, x0, y0); Err bitreich.org 70 i+ ff_pixel(can, color, x0, y0); Err bitreich.org 70 i Err bitreich.org 70 i if (y0 == y1 && x0 == x1) Err bitreich.org 70 i break; Err bitreich.org 70 i@@ -259,7 +156,7 @@ ff_line(struct canvas *can, struct color *col, Err bitreich.org 70 i * Draw a coloured glyph from font f centered on y. Err bitreich.org 70 i */ Err bitreich.org 70 i static int Err bitreich.org 70 i-ff_char(struct canvas *can, struct color *col, char c, Err bitreich.org 70 i+ff_char(struct canvas *can, struct color *color, char c, Err bitreich.org 70 i int x, int y) Err bitreich.org 70 i { Err bitreich.org 70 i int yf, xf, wf; Err bitreich.org 70 i@@ -271,7 +168,7 @@ ff_char(struct canvas *can, struct color *col, char c, Err bitreich.org 70 i for (xf = 0; xf < wf; xf++) Err bitreich.org 70 i for (yf = 0; yf < font->height; yf++) Err bitreich.org 70 i if (font->glyph[(int)c][wf * (font->height - yf) + xf] == 3) Err bitreich.org 70 i- ff_pixel(can, col, x + xf, y + yf); Err bitreich.org 70 i+ ff_pixel(can, color, x + xf, y + yf); Err bitreich.org 70 i return wf + 1; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -279,11 +176,11 @@ ff_char(struct canvas *can, struct color *col, char c, Err bitreich.org 70 i * Draw a left aligned string without wrapping it. Err bitreich.org 70 i */ Err bitreich.org 70 i static size_t Err bitreich.org 70 i-ff_text_left(struct canvas *can, struct color *col, char *s, Err bitreich.org 70 i+ff_text_left(struct canvas *can, struct color *color, char *s, Err bitreich.org 70 i int x, int y) Err bitreich.org 70 i { Err bitreich.org 70 i for (; *s != '\0'; s++) Err bitreich.org 70 i- x += ff_char(can, col, *s, x, y); Err bitreich.org 70 i+ x += ff_char(can, color, *s, x, y); Err bitreich.org 70 i return x; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -291,22 +188,22 @@ ff_text_left(struct canvas *can, struct color *col, char *s, Err bitreich.org 70 i * Draw a center aligned string without wrapping it. Err bitreich.org 70 i */ Err bitreich.org 70 i static size_t Err bitreich.org 70 i-ff_text_center(struct canvas *can, struct color *col, char *s, Err bitreich.org 70 i+ff_text_center(struct canvas *can, struct color *color, char *s, Err bitreich.org 70 i int x, int y) Err bitreich.org 70 i { Err bitreich.org 70 i x -= font_strlen(font, s) / 2; Err bitreich.org 70 i- return ff_text_left(can, col, s, x, y); Err bitreich.org 70 i+ return ff_text_left(can, color, s, x, y); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i /* Err bitreich.org 70 i * Draw a right aligned string without wrapping it. Err bitreich.org 70 i */ Err bitreich.org 70 i static size_t Err bitreich.org 70 i-ff_text_right(struct canvas *can, struct color *col, char *s, Err bitreich.org 70 i+ff_text_right(struct canvas *can, struct color *color, char *s, Err bitreich.org 70 i int x, int y) Err bitreich.org 70 i { Err bitreich.org 70 i x -= font_strlen(font, s); Err bitreich.org 70 i- return ff_text_left(can, col, s, x, y); Err bitreich.org 70 i+ return ff_text_left(can, color, s, x, y); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -326,12 +223,16 @@ ff_print(struct canvas *can) Err bitreich.org 70 i static int Err bitreich.org 70 i ff_t2x(time_t t, time_t tmin, time_t tmax) Err bitreich.org 70 i { Err bitreich.org 70 i+ if (tmin == tmax) Err bitreich.org 70 i+ return PLOT_W; Err bitreich.org 70 i return (t - tmin) * PLOT_W / (tmax - tmin); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static int Err bitreich.org 70 i ff_v2y(double v, double vmin, double vmax) Err bitreich.org 70 i { Err bitreich.org 70 i+ if (vmin == vmax) Err bitreich.org 70 i+ return PLOT_H; Err bitreich.org 70 i return (v - vmin) * PLOT_H / (vmax - vmin); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -394,7 +295,7 @@ ff_title(struct canvas *can, Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i-ff_plot(struct canvas *can, struct vlist *v, Err bitreich.org 70 i+ff_plot(struct canvas *can, struct vlist *vl, struct color *color, Err bitreich.org 70 i double vmin, double vmax, Err bitreich.org 70 i time_t tmin, time_t tmax) Err bitreich.org 70 i { Err bitreich.org 70 i@@ -403,12 +304,12 @@ ff_plot(struct canvas *can, struct vlist *v, Err bitreich.org 70 i int x, y, n, ylast, xlast, first; Err bitreich.org 70 i Err bitreich.org 70 i first = 1; Err bitreich.org 70 i- for (tp = v->t, vp = v->v, n = v->n; n > 0; n--, vp++, tp++) { Err bitreich.org 70 i+ for (tp = vl->t, vp = vl->v, n = vl->n; n > 0; n--, vp++, tp++) { Err bitreich.org 70 i y = ff_v2y(*vp, vmin, vmax); Err bitreich.org 70 i x = ff_t2x(*tp, tmin, tmax); Err bitreich.org 70 i Err bitreich.org 70 i if (!first) Err bitreich.org 70 i- ff_line(can, &v->color, xlast, ylast, x, y); Err bitreich.org 70 i+ ff_line(can, color, xlast, ylast, x, y); Err bitreich.org 70 i Err bitreich.org 70 i ylast = y; Err bitreich.org 70 i xlast = x; Err bitreich.org 70 i@@ -417,24 +318,24 @@ ff_plot(struct canvas *can, struct vlist *v, Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i-ff_values(struct canvas *can, struct vlist *v, int n, Err bitreich.org 70 i+ff_values(struct canvas *can, struct vlist *vl, struct color **cl, size_t ncol, Err bitreich.org 70 i time_t tmin, time_t tmax, Err bitreich.org 70 i double vmin, double vmax) Err bitreich.org 70 i { Err bitreich.org 70 i- for (; n > 0; n--, v++) Err bitreich.org 70 i- ff_plot(can, v, vmin, vmax, tmin, tmax); Err bitreich.org 70 i+ for (; ncol > 0; ncol--, vl++, cl++) Err bitreich.org 70 i+ ff_plot(can, vl, *cl, vmin, vmax, tmin, tmax); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i-ff_legend(struct canvas *can, struct color *label_fg, struct vlist *v, int n) Err bitreich.org 70 i+ff_legend(struct canvas *can, struct color *fg, struct vlist *vl, struct color **cl, size_t ncol) Err bitreich.org 70 i { Err bitreich.org 70 i- int i, x, y; Err bitreich.org 70 i+ size_t i, x, y; Err bitreich.org 70 i Err bitreich.org 70 i- for (i = 0; i < n; i++, v++) { Err bitreich.org 70 i- x = MARGIN; Err bitreich.org 70 i- x = ff_text_left(can, &v->color, "\1", x, y); Err bitreich.org 70 i- x = ff_text_left(can, label_fg, v->label, x, y); Err bitreich.org 70 i- y = LEGEND_H - i * (font->height + MARGIN) - font->height / 2; Err bitreich.org 70 i+ for (i = 0; i < ncol; i++, vl++, cl++) { Err bitreich.org 70 i+ x = MARGIN * 2; Err bitreich.org 70 i+ x = ff_text_left(can, *cl, "\1", x, y) + MARGIN; Err bitreich.org 70 i+ x = ff_text_left(can, fg, vl->label, x, y); Err bitreich.org 70 i+ y = LEGEND_H - i * (font->height + MARGIN); Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -450,7 +351,7 @@ ff_legend(struct canvas *can, struct color *label_fg, struct vlist *v, int n) Err bitreich.org 70 i * x label here Err bitreich.org 70 i */ Err bitreich.org 70 i static void Err bitreich.org 70 i-ff(struct vlist *v, int n, char *name, char *units) Err bitreich.org 70 i+ff(struct vlist *vl, struct color **cl, size_t ncol, char *name, char *units) Err bitreich.org 70 i { Err bitreich.org 70 i struct canvas can = { IMAGE_W, IMAGE_H, 0, 0, NULL }; Err bitreich.org 70 i struct color plot_bg = { 0x2222, 0x2222, 0x2222, 0xffff }; Err bitreich.org 70 i@@ -461,7 +362,7 @@ ff(struct vlist *v, int n, char *name, char *units) Err bitreich.org 70 i double vmin, vmax, vstep; Err bitreich.org 70 i time_t tmin, tmax, tstep; Err bitreich.org 70 i Err bitreich.org 70 i- scale(v, n, &tmin, &tmax, &tstep, &vmin, &vmax, &vstep); Err bitreich.org 70 i+ scale(vl, ncol, &tmin, &tmax, &tstep, &vmin, &vmax, &vstep); Err bitreich.org 70 i Err bitreich.org 70 i assert(can.buf = calloc(IMAGE_H * IMAGE_W, sizeof *can.buf)); Err bitreich.org 70 i Err bitreich.org 70 i@@ -487,108 +388,41 @@ ff(struct vlist *v, int n, char *name, char *units) Err bitreich.org 70 i Err bitreich.org 70 i can.x = PLOT_X; Err bitreich.org 70 i can.y = PLOT_Y; Err bitreich.org 70 i- ff_values(&can, v, n, tmin, tmax, vmin, vmax); Err bitreich.org 70 i+ ff_values(&can, vl, cl, ncol, tmin, tmax, vmin, vmax); Err bitreich.org 70 i Err bitreich.org 70 i can.x = LEGEND_X; Err bitreich.org 70 i can.y = LEGEND_Y; Err bitreich.org 70 i- ff_legend(&can, &label_fg, v, n); Err bitreich.org 70 i+ ff_legend(&can, &label_fg, vl, cl, ncol); Err bitreich.org 70 i Err bitreich.org 70 i ff_print(&can); Err bitreich.org 70 i } Err bitreich.org 70 i- Err bitreich.org 70 i-static void Err bitreich.org 70 i-csv_labels(struct vlist *v, char **argv, char *buf) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct color *color; Err bitreich.org 70 i- Err bitreich.org 70 i- if (esfgets(buf, LINE_MAX, stdin) == NULL) Err bitreich.org 70 i- err(1, "missing label line"); Err bitreich.org 70 i- Err bitreich.org 70 i- if (strcmp(strsep(&buf, ","), "epoch") != 0) Err bitreich.org 70 i- err(1, "first label must be \"epoch\""); Err bitreich.org 70 i- Err bitreich.org 70 i- for (; *argv != NULL; v++, argv++) { Err bitreich.org 70 i- if ((v->label = strsep(&buf, ",")) == NULL) Err bitreich.org 70 i- err(1, "more arguments than columns"); Err bitreich.org 70 i- else if ((color = name_to_color(*argv)) == NULL) Err bitreich.org 70 i- err(1, "unknown color: %s", *argv); Err bitreich.org 70 i- v->color = *color; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- if (strsep(&buf, ",") != NULL) Err bitreich.org 70 i- err(1, "more columns than arguments"); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static int Err bitreich.org 70 i-csv_addval(struct vlist *v, size_t sz, size_t nval, double field, time_t epoch) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (nval >= sz) { Err bitreich.org 70 i- sz = sz * 2 + 1; Err bitreich.org 70 i- if ((v->v = realloc(v->v, sz * sizeof(*v->v))) == NULL) Err bitreich.org 70 i- err(1, "reallocating values buffer"); Err bitreich.org 70 i- if ((v->t = realloc(v->t, sz * sizeof(*v->t))) == NULL) Err bitreich.org 70 i- err(1, "reallocating values buffer"); Err bitreich.org 70 i- } Err bitreich.org 70 i- v->v[nval] = field; Err bitreich.org 70 i- v->t[nval] = epoch; Err bitreich.org 70 i- v->n = nval + 1; Err bitreich.org 70 i- Err bitreich.org 70 i- return sz; Err bitreich.org 70 i-} Err bitreich.org 70 i Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Add to each column the value on the current row. Err bitreich.org 70 i- */ Err bitreich.org 70 i-static int Err bitreich.org 70 i-csv_addrow(struct vlist *v, size_t sz, size_t ncol, size_t nval, char *line) Err bitreich.org 70 i+static struct color * Err bitreich.org 70 i+name_to_color(char *name) Err bitreich.org 70 i { Err bitreich.org 70 i- time_t epoch; Err bitreich.org 70 i- int bs; Err bitreich.org 70 i- char *field, *dot; Err bitreich.org 70 i- Err bitreich.org 70 i- if ((field = strsep(&line, ",")) == NULL) Err bitreich.org 70 i- err(1, "%d: missing epoch", nval); Err bitreich.org 70 i- Err bitreich.org 70 i- if ((dot = strchr(field, '.')) != NULL) Err bitreich.org 70 i- *dot = '\0'; Err bitreich.org 70 i- epoch = eatol(field); Err bitreich.org 70 i- for (; (field = strsep(&line, ",")) != NULL; ncol--, v++) { Err bitreich.org 70 i- if (ncol <= 0) Err bitreich.org 70 i- err(1, "%d: too many fields", nval); Err bitreich.org 70 i- bs = csv_addval(v, sz, nval, eatof(field), epoch); Err bitreich.org 70 i- } Err bitreich.org 70 i- if (ncol > 0) Err bitreich.org 70 i- err(1, "%d: too few fields", ncol); Err bitreich.org 70 i+ struct cname *cn; Err bitreich.org 70 i Err bitreich.org 70 i- return bs; Err bitreich.org 70 i+ for (cn = cname; cn->name != NULL; cn++) Err bitreich.org 70 i+ if (strcmp(name, cn->name) == 0) Err bitreich.org 70 i+ return &cn->color; Err bitreich.org 70 i+ return NULL; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-/* Err bitreich.org 70 i- * < ncol > Err bitreich.org 70 i- * epoch,a1,b1,c1 ^ Err bitreich.org 70 i- * epoch,a2,b2,c2 nval Err bitreich.org 70 i- * epoch,a3,b3,c3 v Err bitreich.org 70 i- */ Err bitreich.org 70 i static void Err bitreich.org 70 i-csv_values(struct vlist *v, size_t ncol) Err bitreich.org 70 i+argv_to_color(struct color **cl, char **argv) Err bitreich.org 70 i { Err bitreich.org 70 i- int nval, sz; Err bitreich.org 70 i- char line[LINE_MAX]; Err bitreich.org 70 i- Err bitreich.org 70 i- sz = 0; Err bitreich.org 70 i- for (nval = 0; esfgets(line, sizeof(line), stdin) != NULL; nval++) Err bitreich.org 70 i- sz = csv_addrow(v, sz, ncol, nval, line); Err bitreich.org 70 i- if (nval == 0) Err bitreich.org 70 i- err(1, "no value could be read\n"); Err bitreich.org 70 i+ for (; *argv != NULL; cl++, argv++) Err bitreich.org 70 i+ if ((*cl = name_to_color(*argv)) == NULL) Err bitreich.org 70 i+ err(1, "unknown color name: %s", *argv); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i usage(void) Err bitreich.org 70 i { Err bitreich.org 70 i fprintf(stderr, "usage: %s [-t title] [-u unit] {", arg0); Err bitreich.org 70 i- fputs(clist->name, stderr); Err bitreich.org 70 i- for (struct clist *c = clist + 1; c->name != NULL; c++) Err bitreich.org 70 i- fprintf(stderr, ",%s", c->name); Err bitreich.org 70 i+ fputs(cname->name, stderr); Err bitreich.org 70 i+ for (struct cname *cn = cname + 1; cn->name != NULL; cn++) Err bitreich.org 70 i+ fprintf(stderr, ",%s", cn->name); Err bitreich.org 70 i fputs("}...\n", stderr); Err bitreich.org 70 i exit(1); Err bitreich.org 70 i } Err bitreich.org 70 i@@ -596,7 +430,8 @@ usage(void) Err bitreich.org 70 i int Err bitreich.org 70 i main(int argc, char **argv) Err bitreich.org 70 i { Err bitreich.org 70 i- struct vlist *v; Err bitreich.org 70 i+ struct vlist *vl; Err bitreich.org 70 i+ struct color **cl; Err bitreich.org 70 i char labels[LINE_MAX]; Err bitreich.org 70 i Err bitreich.org 70 i ARG_SWITCH(argc, argv) { Err bitreich.org 70 i@@ -610,15 +445,19 @@ main(int argc, char **argv) Err bitreich.org 70 i usage(); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- fflush(stdout); Err bitreich.org 70 i+ if (argc == 0) Err bitreich.org 70 i+ usage(); Err bitreich.org 70 i Err bitreich.org 70 i- if ((v = calloc(argc, sizeof(*v))) == NULL) Err bitreich.org 70 i- err(1, "calloc value list"); Err bitreich.org 70 i+ assert(vl = calloc(argc, sizeof(*vl))); Err bitreich.org 70 i+ assert(cl = calloc(argc, sizeof(*cl))); Err bitreich.org 70 i Err bitreich.org 70 i- csv_labels(v, argv, labels); Err bitreich.org 70 i- csv_values(v, argc); Err bitreich.org 70 i+ csv_labels(vl, argv, labels); Err bitreich.org 70 i+ csv_values(vl, argc); Err bitreich.org 70 i+ argv_to_color(cl, argv); Err bitreich.org 70 i Err bitreich.org 70 i- ff(v, argc, tflag, uflag); Err bitreich.org 70 i+ ff(vl, cl, argc, tflag, uflag); Err bitreich.org 70 i Err bitreich.org 70 i+ free(vl); Err bitreich.org 70 i+ free(cl); Err bitreich.org 70 i return 0; Err bitreich.org 70 i } Err bitreich.org 70 1diff --git a/ploot-plot.c b/ploot-plot.c /scm/ploot/file/ploot-plot.c.gph bitreich.org 70 i@@ -1,201 +0,0 @@ Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#include "def.h" Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Adjust the vertical scale so that it gets possible to Err bitreich.org 70 i- */ Err bitreich.org 70 i-static void Err bitreich.org 70 i-plot_scale(double *min, double *max, int row) Err bitreich.org 70 i-{ Err bitreich.org 70 i- double unit, range, mi; Err bitreich.org 70 i- Err bitreich.org 70 i- range = *max - *min; Err bitreich.org 70 i- unit = 1; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Zoom until it fills the canvas. */ Err bitreich.org 70 i- for (; (row - 1) * unit > range; unit /= 10) Err bitreich.org 70 i- continue; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Dezoom until it fits the canvas. */ Err bitreich.org 70 i- for (; (row - 1) * unit < range; unit *= 10) Err bitreich.org 70 i- continue; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Fine tune. */ Err bitreich.org 70 i- if ((row - 1) * unit / 5 > range) Err bitreich.org 70 i- unit /= 5; Err bitreich.org 70 i- if ((row - 1) * unit / 4 > range) Err bitreich.org 70 i- unit /= 4; Err bitreich.org 70 i- if ((row - 1) * unit / 2 > range) Err bitreich.org 70 i- unit /= 2; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Align the minimum (and the zero). */ Err bitreich.org 70 i- for (mi = 0; mi > *min - unit; mi -= unit) Err bitreich.org 70 i- continue; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Update the displayed minimal and maximal. */ Err bitreich.org 70 i- *min = mi; Err bitreich.org 70 i- *max = mi + unit * row; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Return the step between two values. Err bitreich.org 70 i- */ Err bitreich.org 70 i-static int Err bitreich.org 70 i-plot_time_interval(time_t step) Err bitreich.org 70 i-{ Err bitreich.org 70 i- time_t scale[] = { Err bitreich.org 70 i- 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, Err bitreich.org 70 i- 3600, 3600*2, 3600*5, 3600*10, 3600*18, 3600*24, 3600*24*2, Err bitreich.org 70 i- 3600*24*5, 3600*24*10, 3600*24*20, 3600*24*30, 3600*24*50, Err bitreich.org 70 i- 3600*24*100, 3600*24*365, 0 Err bitreich.org 70 i- }; Err bitreich.org 70 i- Err bitreich.org 70 i- for (time_t *s = scale; *s != 0; s++) Err bitreich.org 70 i- if (*s >= 20 * step) Err bitreich.org 70 i- return *s; Err bitreich.org 70 i- return 1; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static size_t Err bitreich.org 70 i-plot_axis_x(char *buf, size_t sz, time_t step, time_t t2, int col) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int x, prec; Err bitreich.org 70 i- char tmp[sizeof("MM/DD HH:MM")], *fmt; Err bitreich.org 70 i- size_t n; Err bitreich.org 70 i- time_t t, interval; Err bitreich.org 70 i- Err bitreich.org 70 i- interval = plot_time_interval(step); Err bitreich.org 70 i- fmt = (step < 3600 * 12) ? "^%H:%M:%S" : Err bitreich.org 70 i- (step < 3600 * 24) ? "^%m/%d %H:%M" : Err bitreich.org 70 i- "^%Y/%m/%d"; Err bitreich.org 70 i- n = x = 0; Err bitreich.org 70 i- Err bitreich.org 70 i- t = t2 - col * 2 * step; Err bitreich.org 70 i- t += interval - t % interval; Err bitreich.org 70 i- for (; t < t2; t += interval) { Err bitreich.org 70 i- strftime(tmp, sizeof tmp, fmt, localtime(&t)); Err bitreich.org 70 i- x = ((t - t2) / 2 + col * step) / step; Err bitreich.org 70 i- prec = x - n + strlen(tmp); Err bitreich.org 70 i- assert((n += snprintf(buf+n, sz-n, "%*s", prec, tmp)) <= sz); Err bitreich.org 70 i- } Err bitreich.org 70 i- assert((n += strlcpy(buf+n, "\n", sz-n)) < sz); Err bitreich.org 70 i- return n; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Plot a single line out of the y axis, at row out of . Err bitreich.org 70 i- */ Err bitreich.org 70 i-static size_t Err bitreich.org 70 i-plot_axis_y(char *buf, size_t sz, double min, double max, int r, int rows) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t i; Err bitreich.org 70 i- char tmp[10] = "", *s; Err bitreich.org 70 i- double val; Err bitreich.org 70 i- Err bitreich.org 70 i- val = (max - min) * (rows - r) / rows + min; Err bitreich.org 70 i- humanize(tmp, sizeof tmp, val); Err bitreich.org 70 i- s = (r == 0) ? "┌" : Err bitreich.org 70 i- (r == rows - 1) ? "└" : Err bitreich.org 70 i- "├"; Err bitreich.org 70 i- i = snprintf(buf, sz, "%s%-6s ", s, tmp); Err bitreich.org 70 i- return (i > sz) ? (sz) : (i); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static char * Err bitreich.org 70 i-plot_render(struct drawille *drw, double min, double max, time_t step, time_t t2) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char *buf; Err bitreich.org 70 i- size_t sz; Err bitreich.org 70 i- size_t n; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Render the plot line by line. */ Err bitreich.org 70 i- sz = drw->row * (20 + drw->col * 3 + 1) + 1; Err bitreich.org 70 i- sz += drw->col + 1 + 100000; Err bitreich.org 70 i- if ((buf = calloc(sz, 1)) == NULL) Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- n = 0; Err bitreich.org 70 i- for (int row = 0; row < drw->row; row++) { Err bitreich.org 70 i- n += drawille_fmt_row(drw, buf+n, sz-n, row); Err bitreich.org 70 i- n += plot_axis_y(buf+n, sz-n, min, max, row, drw->row); Err bitreich.org 70 i- n += strlcpy(buf+n, "\n", sz-n); Err bitreich.org 70 i- } Err bitreich.org 70 i- plot_axis_x(buf+n, sz-n, step, t2, drw->col); Err bitreich.org 70 i- Err bitreich.org 70 i- return buf; Err bitreich.org 70 i-err: Err bitreich.org 70 i- errno = ENOBUFS; Err bitreich.org 70 i- free(buf); Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * Plot the body as an histogram interpolating the gaps and include Err bitreich.org 70 i- * a vertical and horizontal axis. Err bitreich.org 70 i- */ Err bitreich.org 70 i-static char * Err bitreich.org 70 i-plot_hist(struct timeserie *ts, time_t t2, struct drawille *drw) Err bitreich.org 70 i-{ Err bitreich.org 70 i- int x, y, zero, shift; Err bitreich.org 70 i- double min, max, val; Err bitreich.org 70 i- time_t t1, t; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Adjust the y scale. */ Err bitreich.org 70 i- shift = min = max = 0; Err bitreich.org 70 i- timeserie_stats(ts, &min, &max); Err bitreich.org 70 i- if (drw->row > 1) { Err bitreich.org 70 i- shift = 2; /* Align values to the middle of the scale: |- */ Err bitreich.org 70 i- plot_scale(&min, &max, drw->row); Err bitreich.org 70 i- } Err bitreich.org 70 i- zero = timeserie_ypos(0, min, max, drw->row*4) - shift; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Adjust the x scale. */ Err bitreich.org 70 i- t2 = t2 + ts->step - t2 % ts->step; Err bitreich.org 70 i- t1 = t2 - ts->step * ts->len; Err bitreich.org 70 i- Err bitreich.org 70 i- /* Plot the data in memory in starting from the end (t2). */ Err bitreich.org 70 i- t = t2; Err bitreich.org 70 i- for (x = drw->col * 2; x > 0; x--) { Err bitreich.org 70 i- val = timeserie_get(ts, t); Err bitreich.org 70 i- if (!isnan(val)) { Err bitreich.org 70 i- y = timeserie_ypos(val, min, max, drw->row*4) - shift; Err bitreich.org 70 i- drawille_dot_hist(drw, x, y, zero); Err bitreich.org 70 i- } Err bitreich.org 70 i- t -= ts->step; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- return plot_render(drw, min, max, ts->step, t2); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-static char * Err bitreich.org 70 i-plot(struct timeserie *ts, time_t t2, int row, int col) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct drawille *drw; Err bitreich.org 70 i- size_t len; Err bitreich.org 70 i- char *buf; Err bitreich.org 70 i- Err bitreich.org 70 i- len = 500; Err bitreich.org 70 i- buf = NULL; Err bitreich.org 70 i- drw = NULL; Err bitreich.org 70 i- col -= 8; Err bitreich.org 70 i- Err bitreich.org 70 i- if (timeserie_read(ts) == -1) Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- Err bitreich.org 70 i- if ((drw = drawille_new(row, col)) == NULL) Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- Err bitreich.org 70 i- buf = plot_hist(ts, t2, drw); Err bitreich.org 70 i-err: Err bitreich.org 70 i- if (buf == NULL) Err bitreich.org 70 i- timedb_close(&ts->db); Err bitreich.org 70 i- free(drw); Err bitreich.org 70 i- return buf; Err bitreich.org 70 i-} Err bitreich.org 70 .