ploot

plot images or real-time plain text from a .csv file
Log | Files | Refs | README

commit ebc69990bb78af4e042f28bff9198d6f9445f657
parent 8112f382b3e9104289ade9cae2d777ab4d68ea1b
Author: Josuah Demangeon <mail@josuah.net>
Date:   Fri,  2 Feb 2018 22:55:31 +0100

adjust vaxis

Diffstat:
MMakefile | 4++--
Aploot | 0
Aploot.c | 150+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dplot | 0
Dplot.c | 89-------------------------------------------------------------------------------
5 files changed, 152 insertions(+), 91 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,4 +1,4 @@ CFLAGS = -Wall -Wextra -Werror -std=c89 -pedantic -all: plot.o config.h - ${CC} -o plot plot.o +all: ploot.o config.h + ${CC} -o ploot ploot.o diff --git a/ploot b/ploot Binary files differ. diff --git a/ploot.c b/ploot.c @@ -0,0 +1,150 @@ +#include <stdio.h> +#include <string.h> + +#include "config.h" + +#define MARGIN 9 + +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define LEN(x) (sizeof(x) / sizeof(*x)) + +/* + * Set `str' to a human-readable form of `num' with always a width of 7 (+ 1 + * the '\0' terminator). Buffer overflow is ensured not to happen due to the + * max size of a double. + */ +void +humanize(char *str, double val) +{ + int exp; + char *label = " kMGTE", fmt[] = "%+.?f%c"; + + for (exp = 0; ABS(val) > 1000; exp++) + val /= 1000; + + fmt[3] = (ABS(val) < 10) ? '3' : (ABS(val) < 100) ? '2' : '1'; + if (exp == 0) { + fmt[5] = '\0'; + fmt[3]++; + } + snprintf(str, 8, fmt, val, label[exp]); + if (val >= 0) + str[0] = ' '; +} + +/* + * Returns the maximal double of values between `beg' and `end'. + */ +double +maxdv(double *beg, double *end) +{ + double *val, max; + + max = *beg; + for (val = beg; val < end; val++) { + if (*val > max) + max = *val; + } + return max; +} + +/* + * If not null, print the title `str' centered on width. + */ +void +title(char *str, int width) +{ + if (str == NULL) + return; + printf("%*s\n\n", (int)(width - strlen(str)) / 2 + MARGIN, str); +} + +/* + * Print vertical axis with humanized number from time to time, with occurences + * determined after the position on the vertical axis from the bottom `pos'. + */ +void +vaxis(double val, int pos) +{ + char label[8]; + + if (pos % 4 == 0) { + humanize(label, val); + printf("%s -", label); + } else { + printf(" "); + } +} + +/* + * Print horizontal axis for up to `col' values. + */ +void +haxis(int col) +{ + printf("%*d -+", MARGIN - 2, 0); + while (col-- > 0) + putchar('-'); + putchar('\n'); +} + +/* + * Print two rows of a plot into a single line using ' ', '.' and ':'. + */ +void +line(double *beg, double *end, double top, double bot) +{ + double *val; + + putchar('|'); + for (val = beg; val != end; val++) + putchar((*val < bot) ? ' ' : (*val < top) ? '.' : ':'); + putchar('\n'); +} + +/* + * Plot values between `beg' and `end' in a plot of height `height'. + * If `str' is not NULL, it is set as a title above the graph. + */ +void +plot(int height, double *beg, double *end, char *str) +{ + double top, bot, max; + int h; + + title(str, end - beg); + + max = maxdv(beg, end); + for (h = height + height % 2; h > 0; h -= 2) { + top = h * max / height; + bot = (h - 1) * max / height; + + vaxis(top, h); + line(beg, end, top, bot); + } + haxis(end - beg); +} + +void +read_simple() +{ + ; +} + +int +main() +{ + double val[] = { 1000, 3030, 3000, 2456, 3005, 3000, 1031, 2000, 3345, + 1000, 1833, 2452, 432, 1456, 435, 1646, 435, 1345, 554, 5245, 3456, + 1000, 1833, 2452, 432, 1456, 435, 1646, 435, 1345, 554, 5245, 3456, + 1000, 1833, 2452, 432, 1456, 435, 1646, 435, 1345, 554, 5245, 3456, + 5000, 3444, 1034, 1833, 2452, 2555, 432, 2456, 435, 1646, 435, 346, + 1000, 1833, 2452, 432, 1456, 435, 1646, 435, 1345, 554, 5245, 3456, + 1000, 1833, 2452, 432, 1456, 435, 1646, 435, 1345, 554, 5245, 3456, + 1833, 2452, 1456, 435, 435, 554, 5456, 1034, 2452, 432, 1435, 1646, + 1000, 1833, 2452, 432, 1456, 435, 1646, 435, 1345, 554, 5245, 3456, + 1456, 3498, 834, 834, 804, 234, 544, 3456, 2984, 983, 2583, 2583 }; + + plot(30, val, val + LEN(val), "title"); + return 0; +} diff --git a/plot b/plot Binary files differ. diff --git a/plot.c b/plot.c @@ -1,89 +0,0 @@ -#include <stdio.h> -#include <string.h> - -#include "config.h" - -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#define LEN(x) (sizeof(x) / sizeof(*x)) - -/* - * Set `str' to a human-readable form of `num' with always a width of 7 (+ 1 - * the '\0' terminator). Buffer overflow is ensured not to happen due to the - * max size of a double. - */ -void -humanize(char *str, double num) -{ - int exp; - char *label = " kMGTE", fmt[] = "%+.?f%c"; - - for (exp = 0; ABS(num) > 1000; exp++) - num /= 1000; - - fmt[3] = (ABS(num) < 10) ? '3' : (ABS(num) < 100) ? '2' : '1'; - if (exp == 0) { - fmt[5] = '\0'; - fmt[3]++; - } - snprintf(str, 8, fmt, num, label[exp]); - if (num >= 0) - str[0] = ' '; -} - -/* - * Print two rows of a plot into a single line using ' ', '.' and ':'. - */ -void -line(double *beg, double *end, double top, double bot) -{ - double *val; - - for (val = beg; val <= end; val++) - putchar((*val < bot) ? ' ' : (*val < top) ? '.' : ':'); -} - -/* - * Returns the maximal double of values between `beg' and `end'. - */ -double -maxdv(double *beg, double *end) -{ - double *val, max; - - max = *beg; - for (val = beg; val < end; val++) { - if (*val > max) - max = *val; - } - return max; -} - -/* - * Plot values between `beg' and `end' in a plot of height `height'. - */ -void -plot(int height, double *beg, double *end) -{ - double top, bot, max; - int h; -/* - char label[8]; -*/ - - max = maxdv(beg, end); - - for (h = height + height % 2; h > 0; h -= 2) { - top = h * max / height; - bot = (h - 1) * max / height; - line(beg, end, top, bot); - putchar('\n'); - } -} - -int -main() -{ - double val[] = { 0.0, 0.4, 3.4, 2.1, 3.5, 3.0, 1.1, 2.0 } ; - plot(10, val, val + LEN(val)); - return 0; -}