redis sparkline微线图(8)

2017-05-30  本文已影响29人  lmem

参考https://github.com/antirez/aspark

$ ./aspark '1,2,3,4,5:peak,4,3,1,0:base'
  _-`-_  
-`     -_
         
    p   b
    e   a
    a   s
    k   e

$ ./aspark 1,2,3,4,5,6,7,8,9,10,10,8,5,3,1 --rows 4 --fill
       _o##_   
     _#|||||   
   o#|||||||#  
_o#||||||||||#_

1.数据结构

struct sample {
    double value;
    char *label;
};

struct sequence {
    int length;
    int labels;
    struct sample *samples;
    double min, max;
};

2.画图,慢慢研究

//画图 offset标记从第几个点开始,rows 展示几行
sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset, int len, int flags) {
    int j;
    //高度,最大最小值差
    double relmax = seq->max - seq->min;
    int steps = charset_len*rows;//图最大高度,如rows=4,则会只有4个charset高度
    int row = 0;//先从第0行开始打印
    char *chars = zmalloc(len);//点的个数
    int loop = 1;
    int opt_fill = flags & SPARKLINE_FILL;
    int opt_log = flags & SPARKLINE_LOG_SCALE;

    if (opt_log) {
        relmax = log(relmax+1);
    } else if (relmax == 0) {
        relmax = 1;
    }

    while(loop) {
        loop = 0;
        memset(chars,' ',len);
        for (j = 0; j < len; j++) {//先取len个点
            struct sample *s = &seq->samples[j+offset];
            double relval = s->value - seq->min;//高度
            int step;

            if (opt_log) relval = log(relval+1);
            step = (int) (relval*steps)/relmax;//达到最高需要步数
            //不能超过最大和最小,感觉无用
            if (step < 0) step = 0;
            if (step >= steps) step = steps-1;

            if (row < rows) {
                /* Print the character needed to create the sparkline */
                int charidx = step-((rows-row-1)*charset_len);
                loop = 1;
                if (charidx >= 0 && charidx < charset_len) {
                    chars[j] = opt_fill ? charset_fill[charidx] :
                                          charset[charidx];
                } else if(opt_fill && charidx >= charset_len) {
                    chars[j] = '|';
                }
            } else {
                /* Labels spacing */
                if (seq->labels && row-rows < label_margin_top) {
                    loop = 1;
                    break;
                }
                /* Print the label if needed. */
                if (s->label) {
                    int label_len = strlen(s->label);
                    int label_char = row - rows - label_margin_top;

                    if (label_len > label_char) {
                        loop = 1;
                        chars[j] = s->label[label_char];
                    }
                }
            }
        }
        if (loop) {
            row++;
            output = sdscatlen(output,chars,len);
            output = sdscatlen(output,"\n",1);
        }
    }
    zfree(chars);
    return output;
}

/* Turn a sequence into its ASCII representation */
sds sparklineRender(sds output, struct sequence *seq, int columns, int rows, int flags) {
    int j;
    //j 数组偏移
    for (j = 0; j < seq->length; j += columns) {//遍历每一列
        int sublen = (seq->length-j) < columns ? (seq->length-j) : columns;

        if (j != 0) output = sdscatlen(output,"\n",1);
        //j 数组偏移,sublen 当前的宽度
        output = sparklineRenderRange(output, seq, rows, j, sublen, flags);
    }
    return output;
}

上一篇下一篇

猜你喜欢

热点阅读