SMOLNET PORTAL home about changes
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 <me@josuah.net>	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 <assert.h>	Err	bitreich.org	70
i+#include <errno.h>	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i+#include <stdio.h>	Err	bitreich.org	70
i+#include <stdlib.h>	Err	bitreich.org	70
i+#include <string.h>	Err	bitreich.org	70
i+#include <time.h>	Err	bitreich.org	70
i+#include <math.h>	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 <r> out of <rows>.	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 <drw> 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 <assert.h>	Err	bitreich.org	70
i-#include <errno.h>	Err	bitreich.org	70
i-#include <stdint.h>	Err	bitreich.org	70
i-#include <stdio.h>	Err	bitreich.org	70
i-#include <stdlib.h>	Err	bitreich.org	70
i-#include <string.h>	Err	bitreich.org	70
i-#include <time.h>	Err	bitreich.org	70
i-#include <math.h>	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 <r> out of <rows>.	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 <drw> 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
.
Response: text/plain
Original URLgopher://bitreich.org/0/scm/ploot/commit/1c1a69494de95f4f...
Content-Typetext/plain; charset=utf-8