ervy

Bring charts to terminal.
git clone https://noulin.net/git/ervy.git
Log | Files | Refs | README | LICENSE

bar.c (2548B)


      1 
      2 #include "bar.h"
      3 #include "math.h"
      4 #include "limits.h"
      5 
      6 char *bar(char *data, char *opts) {
      7   var dat = verifyData(data);
      8   if (!dat) ret NULL;
      9 
     10   createSmallJson(newOpts);
     11   parseG(&newOpts, "{\
     12     barWidth: 3,\
     13     left: 1,\
     14     height: 6,\
     15     padding: 3,\
     16     style: '*'\
     17     }");
     18 
     19   createAllocateSmallJson(oopts);
     20   if (opts) {
     21     parseG(oopts, opts);
     22   }
     23 
     24   mergeNSmashG(&newOpts, oopts);
     25 
     26   var barWidth = getG(&newOpts, rtI64, "barWidth");
     27   var left     = getG(&newOpts, rtI64, "left");
     28   var height   = getG(&newOpts, rtI64, "height");
     29   var padding  = getG(&newOpts, rtI64, "padding");
     30   var style    = getG(&newOpts, rtChar, "style");
     31 
     32   var result = repeatS(PAD, left);
     33 
     34 
     35   createSmallArray(values);
     36 
     37   iter(dat, V) {
     38     cast(smallDictt*, v, V);
     39     pushG(&values, getNumG(v, "value"));
     40   }
     41 
     42   var max = getG(&values, rtF64, 0);
     43 
     44   range(i, lenG(&values)) {
     45     max = maxV(max, getNumG(&values, i));
     46   }
     47   var length = lenG(dat);
     48 
     49   range(i, height + 2) {
     50     range(j, length) {
     51       var tmp      = getG(dat, rtSmallDictt, j);
     52       var valStr   = toStringG((i64)getNumG(tmp, "value"));
     53       var curStyle = style;
     54       if (hasG(tmp, "style")) curStyle = getG(tmp, rtChar, "style");
     55 
     56       var ratio    = height - (height * getNumG(tmp, "value") / max);
     57 
     58       var padChar = ratio > (i + 2) ? PAD
     59         : round(ratio) == i
     60           ? valStr
     61           : round(ratio) < i
     62             ? curStyle : PAD;
     63 
     64       if (eqG(padChar, valStr)) {
     65         var pad = repeatS(PAD, padding);
     66         var mid = padMid(valStr, barWidth);
     67         iAppendManyS(&result, mid, pad);
     68         freeManyS(pad, mid);
     69         goto cont;
     70       }
     71 
     72       if (i != height + 1) {
     73         var pad  = repeatS(padChar, barWidth);
     74         var pad2 = repeatS(PAD, padding);
     75 
     76         iAppendManyS(&result, pad, pad2);
     77         freeManyS(pad, pad2);
     78       } else {
     79         if (lenG(getG(tmp, rtChar, "key")) > barWidth) {
     80           var s = padEndS(getG(tmp, rtChar, "key"), barWidth + padding, PAD);
     81           iAppendS(&result, s);
     82           free(s);
     83         }
     84         else {
     85           var pad = repeatS(PAD, padding);
     86           var mid = padMid(getG(tmp, rtChar, "key"), barWidth);
     87           iAppendManyS(&result, mid, pad);
     88           freeManyS(pad, mid);
     89         }
     90       }
     91 
     92       cont:
     93       free(valStr);
     94       finishG(tmp);
     95     }
     96 
     97     if (i != height + 1) {
     98       var pad = repeatS(PAD, left);
     99       iAppendManyS(&result, EOL, pad);
    100       free(pad);
    101     }
    102   }
    103 
    104   freeManyG(&newOpts, &values);
    105   terminateG(dat);
    106 
    107   ret result;
    108 }
    109 // vim: set expandtab ts=2 sw=2: