adjust vaxis - ploot - simple plotting tools | |
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
commit ebc69990bb78af4e042f28bff9198d6f9445f657 | |
parent 8112f382b3e9104289ade9cae2d777ab4d68ea1b | |
Author: Josuah Demangeon <[email protected]> | |
Date: Fri, 2 Feb 2018 22:55:31 +0100 | |
adjust vaxis | |
Diffstat: | |
M Makefile | 4 ++-- | |
A ploot | 0 | |
A ploot.c | 150 +++++++++++++++++++++++++++++… | |
D plot | 0 | |
D plot.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… | |
+ 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; | |
-} |