refactor a bit - ploot - simple plotting tools | |
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
commit a2f50e1cb8af6ef5571c142b93b8ade388e0bfa5 | |
parent 1f4e757723ea483ab2c60c8fec2937569441af9e | |
Author: Josuah Demangeon <[email protected]> | |
Date: Tue, 18 Feb 2020 08:33:24 +0100 | |
refactor a bit | |
Diffstat: | |
M def.h | 48 +++++++----------------------… | |
M drawille.c | 58 +++++++++++++++++++++++------… | |
M ploot-braille.c | 106 +++++++++--------------------… | |
M ploot-farbfeld.c | 8 ++++---- | |
M ploot-feed.c | 6 +++--- | |
M test.csv | 1 + | |
M util.c | 46 -----------------------------… | |
7 files changed, 90 insertions(+), 183 deletions(-) | |
--- | |
diff --git a/def.h b/def.h | |
@@ -35,62 +35,34 @@ struct vlist { | |
char *label; /* for the legend */ | |
}; | |
-/* csv.c */ | |
- | |
+/**/ | |
void csv_addrow (struct vlist *, size_t, char *); | |
void csv_labels (FILE *, char *, struct vlist **… | |
void csv_values (FILE *, struct vlist *, size_t); | |
- | |
-/* drawille.c */ | |
- | |
-size_t drawille_fmt_row (struct drawille *, char *, size… | |
+size_t drawille_put_row (struct drawille *, FILE *, int); | |
void drawille_dot (struct drawille *, int, int); | |
struct drawille *drawille_new (int, int); | |
void drawille_line (struct drawille *, int, int,… | |
-void drawille_line_hist (struct drawille *, int, int, in… | |
-void drawille_dot_hist (struct drawille *, int, int, int… | |
+void drawille_histogram_dot (struct drawille *, int, int… | |
+void drawille_histogram_line (struct drawille *, int, in… | |
+int drawille_histogram (struct vlist *, struct drawille … | |
char * drawille_text (struct drawille *, int, in… | |
- | |
-/* font.c */ | |
- | |
size_t font_width (struct font *, int); | |
size_t font_strlen (struct font *, char *); | |
- | |
-/* font*.c */ | |
- | |
-struct font font13; | |
-struct font font7; | |
-struct font font8; | |
- | |
-/* ploot-braille.c */ | |
- | |
+struct font font13; | |
+struct font font7; | |
+struct font font8; | |
char const *arg0; | |
- | |
-/* ploot-farbfeld.c */ | |
- | |
-char const *arg0; | |
- | |
-/* ploot-feed.c */ | |
- | |
-char const *arg0; | |
- | |
-/* scale.c */ | |
- | |
int scale_ypos (double, double, double, int); | |
int scale_xpos (time_t, time_t, time_t, int); | |
void scale_vminmax (double *, double *, int); | |
void scale (struct vlist *, int, time_t … | |
- | |
-/* util.c */ | |
- | |
size_t strlcpy (char *, const char *, si… | |
void put3utf (long); | |
char * strsep (char **, const char *); | |
void estriplf (char *); | |
double eatof (char *); | |
long eatol (char *); | |
-char * esfgets (char *, size_t, FILE *); | |
int humanize (char *, double); | |
-void vlog (char const *, char const *, v… | |
-void warn (char const *, ...); | |
-void err (int, char const *, ...); | |
+ | |
+#endif | |
diff --git a/drawille.c b/drawille.c | |
@@ -6,6 +6,7 @@ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
+#include <math.h> | |
#include "def.h" | |
@@ -52,7 +53,7 @@ drawille_get(struct drawille *drw, int row, int col) | |
} | |
size_t | |
-drawille_fmt_row(struct drawille *drw, char *buf, size_t sz, int row) | |
+drawille_put_row(struct drawille *drw, FILE *fp, int row) | |
{ | |
char txt[] = "xxx"; | |
size_t n; | |
@@ -60,7 +61,7 @@ drawille_fmt_row(struct drawille *drw, char *buf, size_t sz, … | |
n = 0; | |
for (int col = 0; col < drw->col; col++) { | |
drawille_cell_utf(drawille_get(drw, row, col), txt); | |
- n += snprintf(buf+n, sz-n, "%s", txt); | |
+ n += fputs(txt, fp); | |
} | |
return n; | |
} | |
@@ -111,7 +112,7 @@ drawille_line_next(struct line *l) | |
int e; | |
if (l->x0 == l->x1 && l->y0 == l->y1) | |
- return -1; | |
+ return 0; | |
e = l->err; | |
if (e > -l->dx) { | |
@@ -122,7 +123,7 @@ drawille_line_next(struct line *l) | |
l->y0 += l->sy; | |
l->err += l->dx; | |
} | |
- return 0; | |
+ return 1; | |
} | |
void | |
@@ -137,27 +138,54 @@ drawille_line(struct drawille *drw, int x0, int y0, int x… | |
} | |
void | |
-drawille_line_hist(struct drawille *drw, int x0, int y0, int x1, int y1, int z… | |
+drawille_histogram_dot(struct drawille *drw, int x, int y, int zero) | |
{ | |
- struct line l; | |
int sign; | |
+ sign = (y > zero) ? (+1) : (-1); | |
+ for (; y != zero + sign; y -= sign) | |
+ drawille_dot(drw, x, y); | |
+} | |
+ | |
+void | |
+drawille_histogram_line(struct drawille *drw, int x0, int y0, int x1, int y1, … | |
+{ | |
+ struct line l; | |
+ | |
drawille_line_init(&l, x0, y0, x1, y1); | |
do { | |
- sign = (l.y0 > zero) ? (-1) : (+1); | |
- for (int y = l.y0; y != zero + sign; y += sign) | |
- drawille_dot(drw, l.x0, y); | |
+ drawille_histogram_dot(drw, l.x0, l.y0, zero); | |
} while (drawille_line_next(&l)); | |
} | |
-void | |
-drawille_dot_hist(struct drawille *drw, int x, int y, int zero) | |
+/* | |
+ * Plot the body as an histogram interpolating the gaps and include | |
+ * a vertical and horizontal axis. | |
+ */ | |
+int | |
+drawille_histogram(struct vlist *vl, struct drawille *drw, | |
+ time_t tmin, time_t tmax, double vmin, double vmax) | |
{ | |
- int sign; | |
+ int x, xprev, y, yprev, zero; | |
+ double *v; | |
+ time_t *t; | |
+ size_t n; | |
- sign = (y > zero) ? (-1) : (+1); | |
- for (; y != zero + sign; y += sign) | |
- drawille_dot(drw, x, y); | |
+ zero = scale_ypos(0, vmin, vmax, drw->row*4); | |
+ v = vl->v; | |
+ t = vl->t; | |
+ n = vl->n; | |
+ for (; n > 0; n--, t++, v++) { | |
+ if (isnan(*v)) /* XXX: better handling? */ | |
+ continue; | |
+ y = scale_ypos(*v, vmin, vmax, drw->row * 4); | |
+ x = scale_xpos(*t, tmin, tmax, drw->col * 2); | |
+ if (n < vl->n) | |
+ drawille_histogram_line(drw, xprev, yprev, x, y, zero); | |
+ xprev = x; | |
+ yprev = y; | |
+ } | |
+ return 0; | |
} | |
static int | |
diff --git a/ploot-braille.c b/ploot-braille.c | |
@@ -12,61 +12,43 @@ | |
char const *arg0 = NULL; | |
-/* | |
- * Return the step between two values. | |
- */ | |
static int | |
-braille_time_interval(time_t step) | |
+braille_axis_x(FILE *fp, time_t tmin, time_t tmax, time_t tstep, int col) | |
{ | |
- time_t scale[] = { | |
- 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, | |
- 3600, 3600*2, 3600*5, 3600*10, 3600*18, 3600*24, 3600*24*2, | |
- 3600*24*5, 3600*24*10, 3600*24*20, 3600*24*30, 3600*24*50, | |
- 3600*24*100, 3600*24*365, 0 | |
- }; | |
- | |
- for (time_t *s = scale; *s != 0; s++) | |
- if (*s >= 20 * step) | |
- return *s; | |
- return 1; | |
-} | |
- | |
-static size_t | |
-braille_axis_x(FILE *fp, time_t step, time_t tmax, int col) | |
-{ | |
- int x, prec; | |
+ int x, o, prec; | |
char tmp[sizeof("MM/DD HH:MM")], *fmt; | |
size_t n; | |
- time_t t, interval; | |
+ time_t t; | |
- interval = braille_time_interval(step); | |
- fmt = (step < 3600 * 12) ? "^%H:%M:%S" : | |
- (step < 3600 * 24) ? "^%m/%d %H:%M" : | |
+ fmt = (tstep < 3600 * 12) ? "^%H:%M:%S" : | |
+ (tstep < 3600 * 24) ? "^%m/%d %H:%M" : | |
"^%Y/%m/%d"; | |
n = x = 0; | |
- t = tmax - col * 2 * step; | |
- t += interval - t % interval; | |
- for (; t < tmax; t += interval) { | |
+ t = tmin; | |
+ t += tstep - t % tstep; | |
+ for (; t < tmax; t += tstep) { | |
+ x = (t - tmin) * col / (tmax - tmin); | |
strftime(tmp, sizeof tmp, fmt, localtime(&t)); | |
- x = ((t - tmax) / 2 + col * step) / step; | |
prec = x - n + strlen(tmp); | |
- fprintf(fp, "%*s", prec, tmp); | |
+ if ((o = fprintf(fp, "%*s", prec, tmp)) < 0) | |
+ return -1; | |
+ n += o; | |
} | |
fputc('\n', fp); | |
- return 1; | |
+ return 0; | |
} | |
/* | |
* Plot a single line out of the y axis, at row <r> out of <rows>. | |
*/ | |
static void | |
-braille_axis_y(FILE *fp, double min, double max, int r, int rows) | |
+braille_axis_y(FILE *fp, double vmin, double vmax, int r, int rows) | |
{ | |
char tmp[10] = "", *s; | |
double val; | |
- val = (max - min) * (rows - r) / rows + min; | |
+ val = (rows - r) * (vmax - vmin) / rows; | |
humanize(tmp, val); | |
s = (r == 0) ? "┌" : | |
(r == rows - 1) ? "└" : | |
@@ -75,70 +57,40 @@ braille_axis_y(FILE *fp, double min, double max, int r, int… | |
} | |
static int | |
-braille_render(struct drawille *drw, FILE *fp, time_t tmin, time_t tmax) | |
+braille_render(struct drawille *drw, FILE *fp, double vmin, double vmax) | |
{ | |
- char buf[LINE_MAX]; | |
- | |
/* Render the plot line by line. */ | |
for (int row = 0; row < drw->row; row++) { | |
- drawille_fmt_row(drw, buf, sizeof buf, row); | |
- braille_axis_y(fp, tmin, tmax, row, drw->row); | |
+ drawille_put_row(drw, fp, row); | |
+ braille_axis_y(fp, vmin, vmax, row, drw->row); | |
fputc('\n', fp); | |
} | |
return 0; | |
} | |
-/* | |
- * Plot the body as an histogram interpolating the gaps and include | |
- * a vertical and horizontal axis. | |
- */ | |
-static int | |
-braille_hist(struct vlist *vl, FILE *fp, time_t tmin, time_t tmax, int row, in… | |
-{ | |
- int x, y, zero, shift; | |
- double *v, vmin, vmax; | |
- time_t *t; | |
- size_t n; | |
- struct drawille *drw; | |
- | |
- if ((drw = drawille_new(row, col)) == NULL) | |
- err(1, "allocating drawille canvas"); | |
- | |
- shift = (drw->row > 1) ? (2) : (0); /* center values on "|-" marks */ | |
- vmin = vmax = 0; | |
- zero = scale_ypos(0, vmin, vmax, drw->row*4) - shift; | |
- v = vl->v; | |
- t = vl->t; | |
- n = vl->n; | |
- for (; n > 0; n--, t++, v++) { | |
- if (isnan(*v)) /* XXX: better handling? */ | |
- continue; | |
- y = scale_ypos(*v, vmin, vmax, drw->row * 4) - shift; | |
- x = scale_xpos(*t, tmin, tmax, drw->col * 2); | |
- drawille_dot_hist(drw, x, y, zero); | |
- } | |
- if (braille_render(drw, fp, tmin, tmax) == -1) | |
- err(1, "rendering braille canvas"); | |
- free(drw); | |
- return 0; | |
-} | |
- | |
-static int | |
+static void | |
plot(struct vlist *vl, FILE *fp, size_t ncol, int row, int col) | |
{ | |
size_t len; | |
double vmin, vmax, vstep; | |
time_t tmin, tmax, tstep; | |
+ struct drawille *drw; | |
len = 500; | |
col -= 8; | |
scale(vl, ncol, &tmin, &tmax, &tstep, &vmin, &vmax, &vstep); | |
+ warn("vstep=%lf vstep=%ld", vstep, tstep); | |
- if (braille_hist(vl, fp, tmin, tmax, row, col) == -1) | |
+ if ((drw = drawille_new(row, col)) == NULL) | |
err(1, "allocating drawille canvas"); | |
- braille_axis_x(fp, tstep, tmax, col); | |
- return 0; | |
+ if (drawille_histogram(vl, drw, tmin, tmax, vmin, vmax) == -1) | |
+ err(1, "allocating drawille canvas"); | |
+ if (braille_render(drw, fp, vmin, vmax) == -1) | |
+ err(1, "rendering braille canvas"); | |
+ if (braille_axis_x(fp, tmin, tmax, tstep, col) == -1) | |
+ err(1, "printing x axis");; | |
+ free(drw); | |
} | |
static void | |
diff --git a/ploot-farbfeld.c b/ploot-farbfeld.c | |
@@ -65,10 +65,10 @@ struct canvas { | |
struct color *buf; | |
}; | |
-char const *arg0 = NULL; | |
-static char *tflag = ""; | |
-static char *uflag = ""; | |
-static struct font *font = &font13; | |
+char const *arg0 = NULL; | |
+static char *tflag = ""; | |
+static char *uflag = ""; | |
+static struct font *font = &font13; | |
static struct cname cname[] = { | |
/* name red green blue alpha */ | |
diff --git a/ploot-feed.c b/ploot-feed.c | |
@@ -13,9 +13,9 @@ | |
#define WIDTH_MAX 1024 | |
#define BRAILLE_START 10240 | |
-char const *arg0 = NULL; | |
-static int wflag = 80; | |
-static int width = 0; | |
+char const *arg0 = NULL; | |
+static int wflag = 80; | |
+static int width = 0; | |
/* | |
* Turn the bit at position (row, col) on in the . | |
diff --git a/test.csv b/test.csv | |
@@ -109,5 +109,6 @@ epoch,shortterm,midterm,longterm | |
1525294298,0.278198,0.260864,0.242920 | |
1525295198,0.192505,0.183716,0.200806 | |
1525296098,0.109375,0.185669,0.207153 | |
+1525296098,-0.109375,0.185669,0.207153 | |
1525296998,0.137085,0.126221,0.138184 | |
1525297898,0.077881,0.092529,0.109619 | |
diff --git a/util.c b/util.c | |
@@ -77,19 +77,6 @@ eatol(char *str) | |
return atol(str); | |
} | |
-char * | |
-esfgets(char *buf, size_t n, FILE *file) | |
-{ | |
- if (fgets(buf, n, file) == NULL) { | |
- if (ferror(stdin)) | |
- perror("fread from stdin"), exit(1); | |
- else | |
- return NULL; | |
- } | |
- estriplf(buf); | |
- return buf; | |
-} | |
- | |
/* | |
* Set 'str' to a human-readable form of 'num' with always a width of 8 (+1 for | |
* the '\0' terminator). Buffer overflow is ensured not to happen due to the | |
@@ -114,36 +101,3 @@ humanize(char *str, double val) | |
return exp * 3; | |
} | |
- | |
-void | |
-vlog(char const *base, char const *fmt, va_list va) | |
-{ | |
- fprintf(stderr, "%s: ", base); | |
- vfprintf(stderr, fmt, va); | |
- if (errno) | |
- fprintf(stderr, ": %s", strerror(errno)); | |
- fputc('\n', stderr); | |
- fflush(stderr); | |
- errno = 0; /* avoid repeating the error in loop */ | |
-} | |
- | |
-void | |
-warn(char const *fmt, ...) | |
-{ | |
- va_list va; | |
- | |
- va_start(va, fmt); | |
- vlog(arg0, fmt, va); | |
- va_end(va); | |
-} | |
- | |
-void | |
-err(int e, char const *fmt, ...) | |
-{ | |
- va_list va; | |
- | |
- va_start(va, fmt); | |
- vlog(arg0, fmt, va); | |
- va_end(va); | |
- exit(e); | |
-} |