iploot-braille.c - 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 iploot-braille.c (4040B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 #include Err bitreich.org 70 i 2 #include Err bitreich.org 70 i 3 #include Err bitreich.org 70 i 4 #include Err bitreich.org 70 i 5 #include Err bitreich.org 70 i 6 #include Err bitreich.org 70 i 7 #include Err bitreich.org 70 i 8 #include Err bitreich.org 70 i 9 #include Err bitreich.org 70 i 10 #include "drawille.h" Err bitreich.org 70 i 11 #include "util.h" Err bitreich.org 70 i 12 #include "tsv.h" Err bitreich.org 70 i 13 Err bitreich.org 70 i 14 #ifndef __OpenBSD__ Err bitreich.org 70 i 15 #define pledge(...) 0 Err bitreich.org 70 i 16 #endif Err bitreich.org 70 i 17 Err bitreich.org 70 i 18 /* Err bitreich.org 70 i 19 * Plot the body as an histogram interpolating the gaps and include Err bitreich.org 70 i 20 * a vertical and horizontal axis. Err bitreich.org 70 i 21 */ Err bitreich.org 70 i 22 static int Err bitreich.org 70 i 23 braille_histogram(struct tsv *vl, struct drawille *drw, Err bitreich.org 70 i 24 time_t tmin, time_t tmax, double vmin, double vmax) Err bitreich.org 70 i 25 { Err bitreich.org 70 i 26 int x, xprev, y, yprev, zero; Err bitreich.org 70 i 27 double *v; Err bitreich.org 70 i 28 time_t *t; Err bitreich.org 70 i 29 size_t n; Err bitreich.org 70 i 30 Err bitreich.org 70 i 31 #define SHIFT (4 / 2) Err bitreich.org 70 i 32 #define POSITION(val, min, max, sz) ((sz) * ((val) - (min)) / ((max) - (min)) + SHIFT) Err bitreich.org 70 i 33 Err bitreich.org 70 i 34 zero = POSITION(0, vmin, vmax, drw->row*4); Err bitreich.org 70 i 35 v = vl->v; Err bitreich.org 70 i 36 t = vl->t; Err bitreich.org 70 i 37 n = vl->n; Err bitreich.org 70 i 38 for (; n > 0; n--, t++, v++) { Err bitreich.org 70 i 39 if (isnan(*v)) /* XXX: better handling? */ Err bitreich.org 70 i 40 continue; Err bitreich.org 70 i 41 y = POSITION(*v, vmin, vmax, drw->row * 4); Err bitreich.org 70 i 42 x = POSITION(*t, tmin, tmax, drw->col * 2); Err bitreich.org 70 i 43 if (n < vl->n) /* only plot when xprev, yprev are set */ Err bitreich.org 70 i 44 drawille_histogram_line(drw, xprev, yprev, x, y, zero); Err bitreich.org 70 i 45 xprev = x; Err bitreich.org 70 i 46 yprev = y; Err bitreich.org 70 i 47 } Err bitreich.org 70 i 48 Err bitreich.org 70 i 49 #undef POSITION Err bitreich.org 70 i 50 Err bitreich.org 70 i 51 return 0; Err bitreich.org 70 i 52 } Err bitreich.org 70 i 53 Err bitreich.org 70 i 54 static int Err bitreich.org 70 i 55 braille_axis_x(FILE *fp, time_t tmin, time_t tmax, time_t tstep, int col) Err bitreich.org 70 i 56 { Err bitreich.org 70 i 57 int x, o, prec; Err bitreich.org 70 i 58 char tmp[sizeof("MM/DD HH:MM")], *fmt; Err bitreich.org 70 i 59 size_t n; Err bitreich.org 70 i 60 time_t t; Err bitreich.org 70 i 61 Err bitreich.org 70 i 62 fmt = Err bitreich.org 70 i 63 (tstep < 3600 * 12) ? "^%H:%M:%S" : Err bitreich.org 70 i 64 (tstep < 3600 * 24) ? "^%m/%d %H:%M" : Err bitreich.org 70 i 65 "^%Y/%m/%d"; Err bitreich.org 70 i 66 n = x = 0; Err bitreich.org 70 i 67 Err bitreich.org 70 i 68 t = tmin + tstep - tmin % tstep; Err bitreich.org 70 i 69 for (; t < tmax; t += tstep) { Err bitreich.org 70 i 70 x = (t - tmin) * col / (tmax - tmin); Err bitreich.org 70 i 71 strftime(tmp, sizeof tmp, fmt, localtime(&t)); Err bitreich.org 70 i 72 prec = x - n + strlen(tmp); Err bitreich.org 70 i 73 if ((o = fprintf(fp, "%*s", prec, tmp)) < 0) Err bitreich.org 70 i 74 return -1; Err bitreich.org 70 i 75 n += o; Err bitreich.org 70 i 76 } Err bitreich.org 70 i 77 fprintf(fp, "\n"); Err bitreich.org 70 i 78 return 0; Err bitreich.org 70 i 79 } Err bitreich.org 70 i 80 Err bitreich.org 70 i 81 /* Err bitreich.org 70 i 82 * Plot a single line out of the y axis, at row out of . Err bitreich.org 70 i 83 */ Err bitreich.org 70 i 84 static void Err bitreich.org 70 i 85 braille_axis_y(FILE *fp, double min, double max, int r, int rows) Err bitreich.org 70 i 86 { Err bitreich.org 70 i 87 char buf[10] = ""; Err bitreich.org 70 i 88 Err bitreich.org 70 i 89 humanize(buf, (rows - 1 - r) * (max - min) / rows); Err bitreich.org 70 i 90 fprintf(fp, "├%s ", buf); Err bitreich.org 70 i 91 } Err bitreich.org 70 i 92 Err bitreich.org 70 i 93 static int Err bitreich.org 70 i 94 braille_render(struct drawille *drw, FILE *fp, double min, double max) Err bitreich.org 70 i 95 { Err bitreich.org 70 i 96 int row; Err bitreich.org 70 i 97 Err bitreich.org 70 i 98 for (row = 0; row < drw->row; row++) { Err bitreich.org 70 i 99 drawille_put_row(fp, drw, row); Err bitreich.org 70 i 100 braille_axis_y(fp, min, max, row, drw->row); Err bitreich.org 70 i 101 fprintf(fp, "\n"); Err bitreich.org 70 i 102 } Err bitreich.org 70 i 103 return 0; Err bitreich.org 70 i 104 } Err bitreich.org 70 i 105 Err bitreich.org 70 i 106 static void Err bitreich.org 70 i 107 plot(struct tsv *vl, size_t ncol, int rows, int cols, FILE *fp) Err bitreich.org 70 i 108 { Err bitreich.org 70 i 109 double vmin, vmax, vstep; Err bitreich.org 70 i 110 time_t tmin, tmax, tstep; Err bitreich.org 70 i 111 struct drawille *drw; Err bitreich.org 70 i 112 Err bitreich.org 70 i 113 rows = MAX(rows, 2); /* readable */ Err bitreich.org 70 i 114 Err bitreich.org 70 i 115 if (tsv_min_max(vl, ncol, &tmin, &tmax, &vmin, &vmax) < 0) Err bitreich.org 70 i 116 err(1, "invalid scale: tmin=%lld tmax=%lld vmin=%fd vmax=%fd", Err bitreich.org 70 i 117 (long long)tmin, (long long)tmax, vmin, vmax); Err bitreich.org 70 i 118 Err bitreich.org 70 i 119 tstep = scale_time_t(tmin, tmax, cols); Err bitreich.org 70 i 120 vstep = scale_double(vmin, vmax, rows); Err bitreich.org 70 i 121 vmin = (int)(vmin / vstep) * vstep; Err bitreich.org 70 i 122 vmax = vmin + vstep * rows; Err bitreich.org 70 i 123 Err bitreich.org 70 i 124 for (; ncol > 0; vl++, ncol--) { Err bitreich.org 70 i 125 if ((drw = drawille_new(rows, cols)) == NULL) Err bitreich.org 70 i 126 err(1, "drawille_new: %s", strerror(errno)); Err bitreich.org 70 i 127 fprintf(fp, " %s\n", vl->label); Err bitreich.org 70 i 128 if (braille_histogram(vl, drw, tmin, tmax, vmin, vmax) == -1) Err bitreich.org 70 i 129 err(1, "allocating drawille canvas"); Err bitreich.org 70 i 130 if (braille_render(drw, fp, vmin, vmax) == -1) Err bitreich.org 70 i 131 err(1, "rendering braille canvas"); Err bitreich.org 70 i 132 free(drw); Err bitreich.org 70 i 133 } Err bitreich.org 70 i 134 if (braille_axis_x(fp, tmin, tmax, tstep * 10, cols) == -1) Err bitreich.org 70 i 135 err(1, "printing x axis");; Err bitreich.org 70 i 136 } Err bitreich.org 70 i 137 Err bitreich.org 70 i 138 static void Err bitreich.org 70 i 139 usage(void) Err bitreich.org 70 i 140 { Err bitreich.org 70 i 141 fprintf(stderr, "usage: %s [-r rows] [-c cols]\n", arg0); Err bitreich.org 70 i 142 exit(1); Err bitreich.org 70 i 143 } Err bitreich.org 70 i 144 Err bitreich.org 70 i 145 int Err bitreich.org 70 i 146 main(int argc, char **argv) Err bitreich.org 70 i 147 { Err bitreich.org 70 i 148 struct tsv *vl; Err bitreich.org 70 i 149 size_t ncol; Err bitreich.org 70 i 150 int c, rows, cols; Err bitreich.org 70 i 151 Err bitreich.org 70 i 152 if (pledge("stdio", "") < 0) Err bitreich.org 70 i 153 err(1, "pledge: %s", strerror(errno)); Err bitreich.org 70 i 154 Err bitreich.org 70 i 155 rows = 4, cols = 60; Err bitreich.org 70 i 156 arg0 = *argv; Err bitreich.org 70 i 157 while ((c = getopt(argc, argv, "r:c:")) > -1) { Err bitreich.org 70 i 158 switch (c) { Err bitreich.org 70 i 159 case 'r': Err bitreich.org 70 i 160 rows = atoi(optarg); Err bitreich.org 70 i 161 if (rows < 1) { Err bitreich.org 70 i 162 warn("invalid number of rows"); Err bitreich.org 70 i 163 usage(); Err bitreich.org 70 i 164 } Err bitreich.org 70 i 165 break; Err bitreich.org 70 i 166 case 'c': Err bitreich.org 70 i 167 cols = atoi(optarg); Err bitreich.org 70 i 168 if (rows < 1) { Err bitreich.org 70 i 169 warn("invalid number of columns"); Err bitreich.org 70 i 170 usage(); Err bitreich.org 70 i 171 } Err bitreich.org 70 i 172 break; Err bitreich.org 70 i 173 Err bitreich.org 70 i 174 default: Err bitreich.org 70 i 175 usage(); Err bitreich.org 70 i 176 } Err bitreich.org 70 i 177 } Err bitreich.org 70 i 178 argc -= optind; Err bitreich.org 70 i 179 argv += optind; Err bitreich.org 70 i 180 Err bitreich.org 70 i 181 if (argc > 0) Err bitreich.org 70 i 182 usage(); Err bitreich.org 70 i 183 Err bitreich.org 70 i 184 tsv_labels(stdin, &vl, &ncol); Err bitreich.org 70 i 185 tsv_values(stdin, vl, ncol); Err bitreich.org 70 i 186 Err bitreich.org 70 i 187 plot(vl, ncol, rows, cols, stdout); Err bitreich.org 70 i 188 Err bitreich.org 70 i 189 free(vl); Err bitreich.org 70 i 190 return 0; Err bitreich.org 70 i 191 } Err bitreich.org 70 .