Redis source code analysis (5) --- sparkline micro-line chart, redissparkline

Source: Internet
Author: User

Redis source code analysis (5) --- sparkline micro-line chart, redissparkline

I didn't know what it meant when I read sparkline for the first time. I never heard of it before, but it actually appeared in the redis code, at the beginning, I thought this was also a common queue. I split it into a struct bag. The analysis is far from what I thought. In sparkline, a line chart is similar to a line chart, which consists of an information point. So you may understand what sparkline. c is used for drawing. Let's take a look at the internal structure of the drawing and what elements are needed for the drawing:

/* Sparkline. h -- ASCII Sparklines header file ** prop ** 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 co De must retain the above copyright notice, * this list of conditions and the following disclawing. ** Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclawing 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 particle 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, procurement of * substitute goods or services; LOSS OF U SE, 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 is a type of chart with low Information volume and high data density. Currently, it is used for some measurements. * The information about the changes is displayed, such as average temperature and stock market trading is active. Sparkline usually appears in a column chart or line chart in a group of multiple entries. * It can be understood as A line information * // * A sequence is represented of bytes "samples" * // * it can be understood as an information point on an image with text, the size of the value */struct sample {double value; char * label ;};/* The graph Line Information struct, which contains n element points. The plot can be described accordingly, drawing is not directly drawn by point and value */struct sequence {// number of current element points int length; // total number of texts, some vertices are not described in label, NULL int labels; // element point list struct sample * samples; // maximum value in the element, minimum value double min, max ;}; /* defines some attribute operation settings for rendering graphs */# 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); // create a line sequence struct void sparklineSequenceAddSample (struct sequence * seq, double value, char * label ); // Add an information point void freeSparklineSequence (struct sequence * seq) to the graph sequence; // release the graph sequence sds sparklineRenderRange (sds output, struct sequence * seq, int rows, int offset, int len, int flags); // The rendering line sequence is an image, which is actually a string graph sds sparklineRender (sds output, struct sequence * seq, int columns, int rows, int flags); // The method is the same as above, but only one offset is allowed. # endif/* _ SPARKLINE_H */

We can see that the above sample structure actually refers to the meaning of the "Information Point" element, which is very simple. A text label and a value are concise and clear, and then sequence is naturally a line chart, it defines the element point list, which also contains the length, maximum value, minimum value, and comprehensive line. The subsequent drawing operations are performed based on the sequence structure of the graphic line. Struct is not complex at all. But the implementation of drawing is not simple at all. How can we draw a line similar to a line based on the given point information? Don't forget, this is the line of drawing in the command line window, therefore, it is not as convenient as the GUI operations in advanced languages. Let's look at how redis code is written.

/* 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. * * ---------------------------------------------------------------------------

In sparkline. c, this code is modified from:

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

Yes, that is to say, aspark is used to display the graph effect on the c program. Later, I saw that the code was almost the same. I added my own things to the redis code and slightly modified it. There were several forms of aspark line display. The first one was, the simplest presentation:

$ ./aspark 1,2,3,4,10,7,6,5    `-_ __-`   `
The second one expands the number of rows to more rows to display more data. The preceding two rows are displayed. When there is more data, adjust the number of rows. By default, two rows are displayed.

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

Of course, it can be more visualized, And it looks more comfortable to fill characters in the blank space:

$ ./aspark 1,2,3,4,5,6,7,8,9,10,10,8,5,3,1 --rows 4 --fill       _o##_        _#|||||      o#|||||||#  _o#||||||||||#_
With the "|" symbol, it is very imaginative. The most important thing is how to achieve this effect. The core code is as follows:

/* Render part of a sequence, so that render_sequence () call this function * with differnent parts in order to create the full output without overflowing * the current terminal columns. * // * render the line information */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; cha R * 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]; // The value family uses double relval = s-> value-seq-> min; int step; if (opt_log) relval = Log (relval + 1); // Finally, the related 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 controls which character is output */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) {// fill the content with "|, more visualized 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 ;}

Due to my limited ability, I am not quite familiar with the specific details. After reading about the details, I took a slight look at the use of the variables. The above code is very good code, it's worth learning. Today, at least I know what sparkline is, haha.




Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.