sparkline这个单词,我第一次看的时候。也不知道这什么意思啊,曾经根本没听过啊,可是这真真实实的出如今了redis的代码中了,刚刚開始以为这也是属于普通的队列嘛。就把他分在了struct包里了。

好来分析完了。与原本我所想的差太大了。sparkline英文中的意思“微线图”,这么说吧。类似于折线图,由一个一个信息点构成。所以看到这个意思。你也许就明确了sparkline.c是干什么用的了吧,就是绘图用的。

我们看看这个绘图的内部结构是什么,绘图须要的元素是哪些:

/* sparkline.h -- ASCII Sparklines header file
*
* ---------------------------------------------------------------------------
*
* Copyright(C) 2011-2014 Salvatore Sanfilippo <antirez@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ #ifndef __SPARKLINE_H
#define __SPARKLINE_H /* sparkline是一类信息体积小和数据密度高的图表。 眼下它被用作一些測量,
*相关的变化的信息呈现的方式。如平均温度,股市交投活跃。sparkline经常以一组多条的形式出如今柱状图,折线图其中。 *能够理解为一个图线信息 */
/* A sequence is represented of many "samples" */
/* 能够理解为图像上的一个信息点,有文字,有值的大小 */
struct sample {
double value;
char *label;
}; /* 图线信息结构体,包含n个元素点。能够据此描写叙述出图,画图的可不是直接按点和值直接绘制的 */
struct sequence {
//当前元素点个数
int length;
//总共的文字个数,有些点没有label描写叙述。为NULL
int labels;
//元素点列表
struct sample *samples;
//元素中的最大值,最小值
double min, max;
}; /* 定义了一些渲染图时候一些属性操作设置 */
#define SPARKLINE_NO_FLAGS 0
#define SPARKLINE_FILL 1 /* Fill the area under the curve. */
#define SPARKLINE_LOG_SCALE 2 /* Use logarithmic scale. */ struct sequence *createSparklineSequence(void); //创建图线序列结构体
void sparklineSequenceAddSample(struct sequence *seq, double value, char *label); //在图线序列中加入一个信息点
void freeSparklineSequence(struct sequence *seq); //释放图线序列
sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset, int len, int flags); //渲染图线序列为一个图,事实上就是得到一个字符串组成的图
sds sparklineRender(sds output, struct sequence *seq, int columns, int rows, int flags); //方法同上,仅仅是少可一个偏移量 #endif /* __SPARKLINE_H */

我们看到上面的sample结构体事实上“信息点”元素的意思了。里面非常easy。一个文字label,一个value值,简洁明了。然后sequence就自然是图线了,里面就定义了元素点列表了。里面还有线的长度,和最大值。最小值,信息还挺全面的线。

后序的绘图操作都是依据这个图线序列结构体操作的。结构体一点都不复杂。

可是绘图的实现一点都不简单,怎样依据给定的一些点信息画出一个类似折线的图线呢。可别忘了,这是要在命令行窗体的图线哦,所以不会像高级语言中的GUI的操作那样非常方便。我们看看redis代码中是怎么写的。

/* sparkline.c -- ASCII Sparklines
* This code is modified from http://github.com/antirez/aspark and adapted
* in order to return SDS strings instead of outputting directly to
* the terminal.
*
* ---------------------------------------------------------------------------

在sparkline.c中的凝视声明,此代码改动自 http://github.com/antirez/aspark,原来是开源的代码实现,可是一開始真的不知道还有这么个叫aspark的东西,都跟BigData里的spark搞混了,然后我点击此地址,官方解释来了:

aspark is a C program to display ASCII Sparklines.
It is completely useless in 2011.

不错。意思就是说aspark就是用来在C程序上显示图线效果的。后来,我看了下,的确代码差点儿相同,redis的代码在上面加了自己的东西,稍稍改动,aspark的图线展现有几种形式,第一种。最简单的展示:

$ ./aspark 1,2,3,4,10,7,6,5
`-_
__-` `

第二张把行数扩展为很多其它行,展示很多其它的数据,上面的这个为2行展示。数据多的时候,调节行数,默认输出2行展示

$ ./aspark 1,2,3,4,5,6,7,8,9,10,10,8,5,3,1 --rows 4
_-``_
_`
-` `
_-` `_

当然能够更加可视化,在空白处填充字符。看起来更舒服:

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

用了"|"符号,非常有想象力的哦,最最关键的我们看怎样实现这种效果呢,核心代码例如以下:

/* Render part of a sequence, so that render_sequence() call call this function
* with differnent parts in order to create the full output without overflowing
* the current terminal columns. */
/* 渲染出这个图线信息 */
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;
int row = 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++) {
struct sample *s = &seq->samples[j+offset];
//value派上用处了
double relval = s->value - seq->min;
int step; if (opt_log) relval = log(relval+1);
//最后会算出相关的step
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 */
/* step控制输出的字符是哪一个 */
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;
}

因为本人能力有限,有点不太懂里面的详细细节,大概看了下,把变量用到的地方稍稍看了下,上面的代码都是很优秀的代码,值得我们学习。今天至少让我知道了什么叫sparkline叫什么 了,哈哈。

Redis源代码分析(五)--- sparkline微线图的更多相关文章

  1. Redis源代码分析(十一年)--- memtest内存测试

    今天,我们继续redis源代码test下测试在封装中的其它文件.今天读数memtest档,翻译了,那是,memory test 存储器测试工具..可是里面的提及了非常多东西,也给我涨了非常多见识,网上 ...

  2. Redis源代码分析(一)--Redis结构解析

    从今天起,本人将会展开对Redis源代码的学习,Redis的代码规模比較小,很适合学习,是一份很不错的学习资料,数了一下大概100个文件左右的样子,用的是C语言写的.希望终于能把他啃完吧,C语言好久不 ...

  3. redis 源代码分析(一) 内存管理

    一,redis内存管理介绍 redis是一个基于内存的key-value的数据库,其内存管理是很重要的,为了屏蔽不同平台之间的差异,以及统计内存占用量等,redis对内存分配函数进行了一层封装,程序中 ...

  4. Redis源代码分析(23)--- CRC循环冗余算法RAND随机数的算法

    他今天就开始学习Redis源代码的一些工具来实现,在任何一种语言工具.算法实现的原理应该是相同的,一些比較经典的算法.比方说我今天看的Crc循环冗余校验算法和rand随机数产生算法. CRC算法全称循 ...

  5. [Android] Volley源代码分析(五岁以下儿童)Q \\ u0026一个

    Volley源代码分析系列那里一段时间,告诉我,有许多私人留言,同时一些问题抛出.对于一些简单的问题,我们跳,这两天被连接到朋友@smali提出的问题.告诉我你不得不赞叹查看源代码时的详细程度,大家一 ...

  6. Redis源代码分析(三十五)--- redis.c服务端的实现分析(2)

    在Redis服务端的代码量真的是比較大,假设一个一个API的学习怎么实现,无疑是一种效率非常低的做法,所以我今天对服务端的实现代码的学习,重在他的运行流程上.而对于他的模块设计在上一篇中我已经分析过了 ...

  7. Redis源代码分析(六)--- ziplist压缩列表

    ziplist和之前我解析过的adlist列表名字看上去的非常像.可是作用却全然不同.之前的adlist主要针对的是普通的数据链表操作. 而今天的ziplist指的是压缩链表.为什么叫压缩链表呢.由于 ...

  8. Redis源代码分析(十)--- testhelp.h小测试框架和redis-check-aof.c 日志检测

    周期分析struct结构体redis代码.最后,越多越发现很多的代码其实大同小异.于struct有袋1,2不分析文件,关于set集合的一些东西,就放在下次分析好了,在选择下个分析的对象时,我考虑了一下 ...

  9. Redis源代码分析(三)---dict哈希结构

    昨天分析完adlist的Redis代码.今天立即马不停蹄的继续学习Redis代码中的哈希部分的结构学习,只是在这里他不叫什么hashMap,而是叫dict.并且是一种全新设计的一种哈希结构,他仅仅是通 ...

随机推荐

  1. ORACLE数据库创建动态表

    最近公司一个项目代码里的定时任务无法执行,查验代码良久,奈何代码过于老旧,开发人员换了一茬又一茬,现在都无法理清,故无奈只好到数据库里重新写存过,配置定时任务. 在写存过时,由于检测及安全性能要求,需 ...

  2. Luogu P2590 树的统计(树链剖分+线段树)

    题意 原文很清楚了 题解 重链剖分模板题,用线段树维护即可. #include <cstdio> #include <cstring> #include <algorit ...

  3. FZOJ 2245 动态树(离散+离线+ 树状数组)

    Problem 2245 动态树 Accept: 17    Submit: 82Time Limit: 3000 mSec    Memory Limit : 65536 KB  Problem D ...

  4. If you want to allow applications containing errors to be published on the server

    If you want to allow applications containing errors to be published on the server, enable the Allow ...

  5. 使用ICSharpCode.SharpZipLib+Aspose模板批量导出Word

    由于是Web端的项目,所以点击按钮之后直接从Aspose模板读取数据,然后在内存中操作,而不是下载到本地后再打包弄到内存中下载.废话不多说,直接上代码 public ActionResult Expo ...

  6. Python开发基础-Day5-字符编码、文件处理和函数基础(草稿)

    字符编码 为什么要有字符编码? 字符编码是为了让计算机能识别我们人写的字符,因为计算机只认识高低电平,也就是二进制数"0","1". 一个文件用什么编码方式存储 ...

  7. 机房重构包图(从三层+实体到三层+实体+外观+工厂+接口+SQLHelper)

    刚刚开始接触三层的时候,我只做了两个登录小窗体的例子.画了简单的包图,可以说,为后面机房重构留下了大量的工作(因为三层理解没有深度,也没有理解出自己的东西).不过,欠下的总要还的.在做机房重构的时候, ...

  8. cogs 1075. [省常中2011S4] 最短路径问题

    1075. [省常中2011S4] 最短路径问题 ★   输入文件:short.in   输出文件:short.out   简单对比 时间限制:1 s   内存限制:128 MB [问题描述] 平面上 ...

  9. 【思路】Aizu - 1367 - Rearranging a Sequence

    给你一个1~n排好的数组,每次提一个数到最前面,问你最后形成的序列. 就把他的输入顺序倒过来输出即可.没出现过的再按原序输出. #include<cstdio> using namespa ...

  10. python 多继承详解

    class A(object): # A must be new-style class def __init__(self): print "enter A" print &qu ...