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