commit 91faf1d7c8c56ea1ca8ad8ad55ab41f42167dbb8
parent 3774ac899b83777408be7219200d9174f3c444a2
Author: Remy Noulin <loader2x@gmail.com>
Date: Sat, 9 Feb 2019 15:22:42 +0100
add bar
.gitignore | 11 ++++++
README.md | 19 ++++++++++-
bar.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bar.h | 5 +++
ervy.c | 0
ervy.h | 3 ++
example.c | 49 +++++++++++++++++++++++++++
imgs/bar.png | Bin 0 -> 1171 bytes
package.yml | 37 ++++++++++++++++++++
utils.c | 55 ++++++++++++++++++++++++++++++
utils.h | 13 +++++++
11 files changed, 300 insertions(+), 1 deletion(-)
Diffstat:
11 files changed, 300 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
@@ -1,3 +1,14 @@
+# Vim
+*.sw*
+
+# Debug
+.gdb_history
+
+# Coverage
+*.gcov
+*.gcda
+*.gcno
+
# Prerequisites
*.d
diff --git a/README.md b/README.md
@@ -1,2 +1,19 @@
+# Sheepy
+This is a sheepy package for [sheepy](https://github.com/RemyNoulin/sheepy) and using [libsheepy](https://github.com/RemyNoulin/libsheepy)
+
# ervy
-Bring charts to terminal.
+
+Bring charts to terminal. (inspired by [chunqiuyiyu/ervy](https://github.com/chunqiuyiyu/ervy.git))
+
+# Usage
+
+Install with spm: `spm install ervy`
+
+Include header file:
+- `#include "shpPackages/ervy/ervy.h"`
+
+See `example.c` for an example.
+
+## Supported Chart types
+### Bar
+
diff --git a/bar.c b/bar.c
@@ -0,0 +1,109 @@
+
+#include "bar.h"
+#include "math.h"
+#include "limits.h"
+
+char *bar(char *data, char *opts) {
+ var dat = verifyData(data);
+ if (!dat) ret NULL;
+
+ createSmallJson(newOpts);
+ parseG(&newOpts, "{\
+ barWidth: 3,\
+ left: 1,\
+ height: 6,\
+ padding: 3,\
+ style: '*'\
+ }");
+
+ createAllocateSmallJson(oopts);
+ if (opts) {
+ parseG(oopts, opts);
+ }
+
+ mergeNSmashG(&newOpts, oopts);
+
+ var barWidth = getG(&newOpts, rtI64, "barWidth");
+ var left = getG(&newOpts, rtI64, "left");
+ var height = getG(&newOpts, rtI64, "height");
+ var padding = getG(&newOpts, rtI64, "padding");
+ var style = getG(&newOpts, rtChar, "style");
+
+ var result = repeatS(PAD, left);
+
+
+ createSmallArray(values);
+
+ iter(dat, V) {
+ cast(smallDictt*, v, V);
+ pushG(&values, getNumG(v, "value"));
+ }
+
+ var max = getG(&values, rtF64, 0);
+
+ range(i, lenG(&values)) {
+ max = maxV(max, getNumG(&values, i));
+ }
+ var length = lenG(dat);
+
+ range(i, height + 2) {
+ range(j, length) {
+ var tmp = getG(dat, rtSmallDictt, j);
+ var valStr = toStringG((i64)getNumG(tmp, "value"));
+ var curStyle = style;
+ if (hasG(tmp, "style")) curStyle = getG(tmp, rtChar, "style");
+
+ var ratio = height - (height * getNumG(tmp, "value") / max);
+
+ var padChar = ratio > (i + 2) ? PAD
+ : round(ratio) == i
+ ? valStr
+ : round(ratio) < i
+ ? curStyle : PAD;
+
+ if (eqG(padChar, valStr)) {
+ var pad = repeatS(PAD, padding);
+ var mid = padMid(valStr, barWidth);
+ iAppendManyS(&result, mid, pad);
+ freeManyS(pad, mid);
+ goto cont;
+ }
+
+ if (i != height + 1) {
+ var pad = repeatS(padChar, barWidth);
+ var pad2 = repeatS(PAD, padding);
+
+ iAppendManyS(&result, pad, pad2);
+ freeManyS(pad, pad2);
+ } else {
+ if (lenG(getG(tmp, rtChar, "key")) > barWidth) {
+ var s = padEndS(getG(tmp, rtChar, "key"), barWidth + padding, PAD);
+ iAppendS(&result, s);
+ free(s);
+ }
+ else {
+ var pad = repeatS(PAD, padding);
+ var mid = padMid(getG(tmp, rtChar, "key"), barWidth);
+ iAppendManyS(&result, mid, pad);
+ freeManyS(pad, mid);
+ }
+ }
+
+ cont:
+ free(valStr);
+ finishG(tmp);
+ }
+
+ if (i != height + 1) {
+ var pad = repeatS(PAD, left);
+ iAppendManyS(&result, EOL, pad);
+ free(pad);
+ }
+ }
+
+ freeManyG(&newOpts, &values);
+ terminateG(dat);
+
+ ret result;
+}
+// vim: set expandtab ts=2 sw=2:
diff --git a/bar.h b/bar.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "utils.h"
+
+char *bar(char *data, char *opts);
diff --git a/ervy.c b/ervy.c
diff --git a/ervy.h b/ervy.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include "bar.h"
diff --git a/example.c b/example.c
@@ -0,0 +1,49 @@
+#! /usr/bin/env sheepy
+/* or direct path to sheepy: #! /usr/local/bin/sheepy */
+
+/* Libsheepy documentation: http://spartatek.se/libsheepy/ */
+#include "libsheepyObject.h"
+#include "ervy.h"
+
+int argc; char **argv;
+
+/* enable/disable logging */
+/* #undef pLog */
+/* #define pLog(...) */
+
+int main(int ARGC, char** ARGV) {
+
+ argc = ARGC; argv = ARGV;
+
+ initLibsheepy(ARGV[0]);
+ setLogMode(LOG_VERBOSE);
+ //setLogSymbols(LOG_UTF8);
+
+
+ char *barData = "[\
+ { key: 'A', value: 5.3, style: '*' },\
+ { key: 'B', value: 3.1, style: '+' },\
+ { key: 'C', value: 11 },\
+ { key: 'D', value: 1, style: '"BGRED " "RST"' },\
+ { key: 'E', value: 5, style: '"BGGRN " "RST"' },\
+ { key: 'F', value: 7, style: '"BGBLU " "RST"', padding: 1 }\
+ ]";
+ /* char *barData = "[\ */
+ /* { key: 'Aqweqwe ', value: 5, style: '*' },\ */
+ /* { key: 'Bxcvxcvcvv ', value: 3, style: '+' },\ */
+ /* { key: 'C', value: 11 },\ */
+ /* { key: 'D', value: 1, style: '"BGRED " "RST"' },\ */
+ /* { key: 'E', value: 5, style: '"BGGRN " "RST"' },\ */
+ /* { key: 'F', value: 7, style: '"BGBLU " "RST"', padding: 1 }\ */
+ /* ]"; */
+
+
+ puts(bar(barData, NULL));
+
+
+ /* char *opts = "{barWidth: 12, left: 0, height: 30, padding: 5, style: '~'}"; */
+ /* */
+ /* puts(bar(barData, opts)); */
+
+}
+// vim: set expandtab ts=2 sw=2:
diff --git a/imgs/bar.png b/imgs/bar.png
Binary files differ.
diff --git a/package.yml b/package.yml
@@ -0,0 +1,37 @@
+---
+ name: ervy
+ version: 0.0.3
+ description: "bring chart to terminal"
+ bin: ./ervy.c
+ #cflags: -DA -ggdb -std=gnu11 -fPIC -pipe
+ lflags: -lm -rdynamic
+ repository:
+ type: git
+ url: git+https://github.com/RemyNoulin/ervy.git
+ keywords:
+ - utility
+ - library
+ - char
+ - ascii
+ - terminal
+ - console
+ - data-visualization
+ author: Remy
+ license: MIT
+ bugs:
+ url: https://github.com/RemyNoulin/ervy/issues
+ homepage: https://github.com/RemyNoulin/ervy#readme
+ #compileHelp: # text displayed when there is a compilation error
+ #dependencies:
+ # md4c:
+ # Test configuration:
+ #testBin: ./testervy.c
+ #testCflags: -ggdb -std=gnu11 -fPIC -pipe -fprofile-arcs -ftest-coverage -Wall -Wextra
+ #testLflags: -lcheck_pic -lrt -lm -lsubunit -fprofile-arcs -ftest-coverage -rdynamic
+ # Memcheck configuration:
+ #memcheckBin: ./memcheckervy.c
+ #memcheckCmd: valgrind --leak-check=full --show-leak-kinds=all
+ #memcheckCflags: -ggdb -std=gnu11 -fPIC -pipe
+ #memcheckLflags: -rdynamic
+ #documentationCmd: # command for generating the documentation with spm doc
+ private: false # true for private package
diff --git a/utils.c b/utils.c
@@ -0,0 +1,55 @@
+
+#include "utils.h"
+#include "math.h"
+
+char *padMid(char *str, size_t width) {
+ var mid = round((double)(width - lenG(str)) / 2);
+
+ if (lenG(str) > width) {
+ ret dupG(str);
+ }
+ else {
+ var pmid = repeatS(PAD, mid);
+ var pmid2 = repeatS(PAD, mid + ((mid * 2 + lenG(str)) > width ? -1 : 0));
+ var r = catS(pmid, str, pmid2);
+ freeManyS(pmid, pmid2);
+ ret r;
+ }
+}
+
+smallJsont* verifyData(char *data) {
+
+ createAllocateSmallJson(r);
+
+ parseG(r, data);
+
+ var top = getTopTypeG(r);
+
+ if (!eqG(top, "array") or !lenG(r)) goto fail;
+
+ bool allHaveKeyValue = true;
+
+ range(i, lenG(r)) {
+ var d = getG(r, rtSmallDictt, i);
+ if (!d) {
+ allHaveKeyValue = false;
+ break;
+ }
+ if (!hasG(d, "key") or !hasG(d, "value")) {
+ finishG(d);
+ allHaveKeyValue = false;
+ break;
+ }
+ finishG(d);
+ }
+
+ if (!allHaveKeyValue) goto fail;
+
+ ret r;
+
+ fail:
+ logC("Invalid data: %s", data);
+ terminateG(r);
+ ret NULL;
+}
+// vim: set expandtab ts=2 sw=2:
diff --git a/utils.h b/utils.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "libsheepyObject.h"
+
+#define PAD " "
+#define EOL "\n"
+
+char *bg(char *color, size_t length);
+
+char *padMid(char *str, size_t width);
+
+smallJsont* verifyData(char *data);
+// vim: set expandtab ts=2 sw=2: