Introduction
Introduction Statistics Contact Development Disclaimer Help
ploot-braille.c - ploot - simple plotting tools
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65…
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) - (…
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,…
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…
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) =…
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 }
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.