URI: 
       plotting time series - ploot - simple plotting tools
  HTML git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
   DIR commit 51d676a1197f90fba3e657a875ad3905b95646a2
   DIR parent 413abf823787458e35396a700f9acf1af53ef239
  HTML Author: Josuah Demangeon <mail@josuah.net>
       Date:   Tue,  6 Feb 2018 23:03:45 +0100
       
       plotting time series
       
       Diffstat:
         M ploot.c                             |      77 +++++++++++++++++++++++--------
       
       1 file changed, 59 insertions(+), 18 deletions(-)
       ---
   DIR diff --git a/ploot.c b/ploot.c
       @@ -12,8 +12,8 @@
        
        #define ABS(x)                ((x) < 0 ? -(x) : (x))
        #define MIN(x, y)        ((x) < (y) ? (x) : (y))
       -#define LEN(x)                (sizeof(x) / sizeof(*x))
       -
       +#define MAX(x, y)        ((x) > (y) ? (x) : (y))
       +#define LEN(buf)        (sizeof(buf) / sizeof(*(buf)))
        
        /*
         * Add `val' at the current position `pos' of the `ring' buffer and set pos to
       @@ -37,6 +37,7 @@ do {                                                                        \
        
        int        flag_h = 20;
        char        *flag_t = NULL;
       +time_t        flag_o = 0;
        
        /*
         * Set `str' to a human-readable form of `num' with always a width of 7 (+ 1
       @@ -108,11 +109,13 @@ vaxis(double val, int pos)
         * Print horizontal axis for up to `col' values.
         */
        void
       -haxis(int col)
       +haxis(double *beg, double *end)
        {
       +        double        *tp;
       +
                printf("%*d -+", MARGIN, 0);
       -        while (col-- > 0)
       -                putchar('-');
       +        for (tp = beg; tp < end; tp++)
       +                putchar((*tp < 0) ? ('x') : ('-'));
                putchar('\n');
        }
        
       @@ -151,7 +154,7 @@ plot(int height, double *beg, double *end, char *str)
                        vaxis(top, h);
                        line(beg, end, top, bot);
                }
       -        haxis(end - beg);
       +        haxis(beg, end);
        }
        
        /*
       @@ -169,7 +172,6 @@ read_simple(double buf[MAX_VAL])
                for (p = pos = 0; scanf("%lf\n", &val) > 0; p++)
                        RING_ADD(rbuf, len, pos, val);
                len = MIN(len, p);
       -        pos = MIN(pos, p);
        
                RING_COPY(buf, rbuf, len, pos);
        
       @@ -182,43 +184,75 @@ read_simple(double buf[MAX_VAL])
         * least MAX_VAL wide and return a pointer to the last element of `vbuf' or NULL if the
         * input contains error.
         */
       -double *
       +time_t *
        read_time_series(double *vbuf, time_t *tbuf)
        {
       -        size_t        p, pos, len;
       +        size_t        p, pos, nul, len;
                double        vrbuf[MAX_VAL], vval;
                time_t        trbuf[MAX_VAL], tval;
        
                len = LEN(vrbuf);
       -        for (p = pos = 0; scanf("%zd %lf\n", &tval, &vval) > 0; p++)
       +        for (p = pos = 0; scanf("%zd %lf\n", &tval, &vval) > 0; p++) {
                        RING_ADD(trbuf, len, pos, tval);
       -                RING_ADD(vrbuf, len, pos, vval);
       +                RING_ADD(vrbuf, len, nul, vval);
       +        }
                len = MIN(len, p);
       -        pos = MIN(pos, p);
        
                RING_COPY(tbuf, trbuf, len, pos);
                RING_COPY(vbuf, vrbuf, len, pos);
        
       +        return tbuf + len;
       +}
       +
       +/*
       + * Walk from `tbeg' and `tend' and add offset in `tbuf' every time there is no
       + * value in `step' amount of time, by setting a value to -1.
       + */
       +double *
       +fill_gaps(time_t *tbeg, time_t *tend, double *vbuf, time_t step)
       +{
       +        size_t        p, pos, len;
       +        time_t        *tp, toff;
       +        double        *vp, vrbuf[MAX_VAL];
       +
       +        /* Compute the average alignment of the timestamps values according to
       +         * the step size. */
       +        toff = 0;
       +        for (tp = tbeg; tp < tend; tp++)
       +                toff += *tp % step;
       +        toff = *tbeg + toff / (tend - tbeg) + step / 2;
       +
       +        /* Fill `vbuf' with gap added at each time gap using vrbuf as
       +         * intermediate ring buffer. */
       +        len = LEN(vrbuf);
       +        for (p = pos = 0, tp = tbeg, vp = vbuf; tp < tend; p++, vp++, tp++) {
       +                for (; toff < *tp; toff += step)
       +                        RING_ADD(vrbuf, len, pos, -1);
       +                RING_ADD(vrbuf, len, pos, *vp);
       +                toff += step;
       +        }
       +        len = MAX(MIN(p, len), pos);
       +
       +        RING_COPY(vbuf, vrbuf, len, pos);
       +
                return vbuf + len;
        }
        
        void
        usage(void)
        {
       -        printf("usage: ploot [-h <height>] [-t <title>]\n");
       +        printf("usage: ploot [-h <height>] [-t <title>] -o <offset>\n");
                exit(1);
        }
        
        int
        main(int argc, char **argv)
        {
       -/*
       -        time_t        tbuf[MAX_VAL];
       -*/
       +        time_t        tbuf[MAX_VAL], *tend;
                double        vbuf[MAX_VAL], *vend;
                char        c;
        
       -        while ((c = getopt(argc, argv, "h:t:")) != -1) {
       +        while ((c = getopt(argc, argv, "h:t:o:")) != -1) {
                        switch (c) {
                        case -1:
                                break;
       @@ -229,12 +263,19 @@ main(int argc, char **argv)
                        case 't':
                                flag_t = optarg;
                                break;
       +                case 'o':
       +                        flag_o = atol(optarg);
       +                        break;
                        default:
                                usage();
                        }
                }
       +        if (flag_o == 0)
       +                usage();
       +
       +        tend = read_time_series(vbuf, tbuf);
       +        vend = fill_gaps(tbuf, tend, vbuf, flag_o);
        
       -        vend = read_simple(vbuf);
                plot(flag_h, vbuf, vend, flag_t);
                return 0;
        }