public
Description: A javascript library for creating bar and line Sparklines.
Homepage: http://www.willarson.com/code/sparklines/sparklines.html
Clone URL: git://github.com/lethain/sparklines.js.git
sparklines.js / sparklines.html
100755 529 lines (442 sloc) 19.409 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
<html> <head>
<title>Sparklines.js</title>
<!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
<script type="text/javascript" src="processing.js"></script>
<script type="text/javascript" src="sparklines.js"></script>
</head>
 
<script>
var setup_sparklines = function() {
  var opts = {};
  var data = [100,500,300,200,400,500,400,400,100,200];
  new Sparkline('simple1', data).draw();
 
  opts = {'left_padding':50,'right_padding':50,'top_padding':25, 'bottom_padding':25};
  new Sparkline('simple2',data, opts).draw();
  opts = {'left_padding':0,'right_padding':0,'top_padding':0, 'bottom_padding':0};
  new Sparkline('simple3',data, opts).draw();
  opts = {"background_color":"#FFEEDD","line_color":"#001122"};
  new Sparkline('simple4',data, opts).draw();
  opts = {"percentile_lines":[0.5]};
  new Sparkline('simple5a',data,opts).draw();
  opts = {"percentile_lines":[0.25,0.75]};
  new Sparkline('simple5',data,opts).draw();
  opts = {"percentile_lines":[0.25,0.75],"fill_between_percentile_lines":true};
  new Sparkline('simple6',data,opts).draw();
 
  var data2 = [100,200,500,1000,600,900,300,500,800,800,900,1000,50,40,200,100,900,300,400,
               400,600,700,800,900,700,800,50,100,100];
  opts = {"percentile_lines":[0.25,0.5,0.75],"fill_between_percentile_lines":true};
  new Sparkline('simple7',data2,opts).draw();
  opts = {"percentile_lines":[0.25,0.5,0.75],"fill_between_percentile_lines":true,
          "left_padding":1,"right_padding":1,"top_padding":1,"bottom_padding":1,
          "background_color":"#FFFFFF","line_color":"#444444","percentile_line_color":"#AAAAFF",
          "percentile_fill_color":"#CCCCFF"};
  new Sparkline('simple8', data2, opts).draw();
 
  var data3 = [120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
  opts = {"value_lines":[80,120],"top_padding":5,"bottom_padding":0,"fill_between_value_lines":true};
  new Sparkline('simple9', data3, opts).draw();
  opts ={"value_lines":[90,110],"top_padding":5,"bottom_padding":0,
         "fill_between_value_lines":true,
         "percentile_lines":[0.25,0.75],
         "percentile_line_color":"#FF6666"};
  new Sparkline('simple10', data3, opts).draw();
  new Sparkline('simple11', data3, opts).draw();
  new Sparkline('simple12', data3, opts).draw();
  new BarSparkline('bar1',data3).draw();
  opts = {'percentile_lines':[0.25,0.75],"fill_between_percentile_lines":true};
  new BarSparkline('bar2',data3,opts).draw();
  opts = {'percentiile_lines':[0.25,0.75],"fill_between_percentile_lines":true,"extend_markings":false};
  new BarSparkline('bar3',data3,opts).draw();
  opts = {'percentile_lines':[0.25,0.75],"fill_between_percentile_lines":true,
          'padding_between_bars':2,"left_padding":30,"right_padding":30,
  'marking_padding':16};
  new BarSparkline('bar4',data3,opts).draw();
 
  opts = {'value_lines':[85,115]};
  new BarSparkline('bar5',data3,opts).draw();
 
  opts = {'value_lines':[80,120],"fill_between_value_lines":true,"padding_between_bars":0,"bottom_padding":1};
  new BarSparkline('bar6',data3,opts).draw();
 
  new BarSparkline('test1',[530],opts).draw();
  new Sparkline('test2',[1],opts).draw();
};
 
 
</script>
 
<body onload="setup_sparklines();">
<h1 id="top">Sparklines.js</h1>
 
<ul>
  <li> <a href="#overview">Overview</a> </li>
  <li> <a href="#data">Data Formats</a> </li>
  <li> <a href="#scaling">Scaling Data</a> </li>
  <li> <a href="#lines">Line Sparklines</a> </li>
  <li> <a href="#bars">Bar Sparklines</a> </li>
  <li> <a href="#custom">Customizing Sparklines</a> </li>
  <li> <a href="#download">Download</a> </li>
  <li> <a href="#source">Source Code</a> </li>
  <li> <a href="#about">About</a> </li>
  <li> <a href="#contact">Contact</a> </li>
  <li> <a href="#license">License</a> </li>
</ul>
 
 
<p id="overview">
Sparklines.js is a simple javascript utility for building sparklines.
It has support for displaying lines at percentile points (for example,
the 0.25 percentile point is the equivalent of Q1, 0.5 is Q2 (the
median), and 0.75 is Q3), and at fixed values in terms of your data
set. (You might want lines at 80,120 in a chart of blood pressure
values, for example, where the data points would be something like
100,50,60,70,100 and so on, to indicate the points outside of normal range.)
</p>
<p>
The sparklines will size themselves appropriately to any size canvas
they are given. Be wary that charts can tell very different stories
depending on how they are sized, and that you are responsible for
giving a reasonable size for the chart to display itself on.
</p>
 
<p>
Charts can be displayed via line charts, or via bar charts, and allow
for a high degree of customization. In addition, there is support for
demarcating absolute values within the values, and also support for
displaying lines at certain percentiles (for example, you might wish
to display lines at the 25th and 75th percentile). Beyond that, it is
possible to fill in the areas between two percentile or two absolute
value lines, which is a helpful visualization to showing which values
lie between the two points.
</p>
 
<p>
Other statistical analysis functions will likely be added over time.
Feel free to <a href="#contact">suggest</a> anything that you feel
is missing.
</p>
 
 
<p> Oh, and if you're just here for a minute, here are some of my
favorite sparklines from the examples:<p>
 
<ul>
  <li> <a href="#simple7">simple7</a></li>
  <li> <a href="#simple8">simple8</a></li>
  <li> <a href="#simple11">simple11</a></li>
  <li> <a href="#bar4">bar4</a></li>
  <li> <a href="#bar6">bar6</a></li>
</ul>
 
<p>
Sparklines.js is currently piggybacking off of Processing.js to
provide its rendering, but will likely remove that dependency once
the pace of development slows down and it becomes clear which
features will need to be extracted. Processing.js is excellent
for prototyping projects, and is very pleasant to work with,
and the decoupling's justification is reduction of filesize by
removing functionality that is not used by (the fairly simple
demands of) Sparklines.js.
</p>
 
<hr>
<h2 id="data"> Data Sources </h2>
 
<p>
A quick note about the format of data sources that are given to the
sparklines. The expected standard data is simple: an array of height
values (absolute values, since they'll be scaled to the size of the
sparkline). However, you might want to pass it a
much more complex data set. You have two options. First, you can
extract the heights form your data set before passing it to the
sparkline, or you can write a function that instructions the sparkline
how to do that itself.
</p>
 
<p>
Here is a simple example demonstrating how the later method works.
</p>
 
<pre><code>var a = {'height':100,'name':"A"};
var b = {'height':150','name'="B"};
var data = [a,b];
var extract = function(x) { return x.height; };
var opts = {"parse_height":extract};
new Sparkline("canvas_id", data, opts).draw();</code></pre>
 
<p>
This should allow sufficient flexibility for using custom data sets
with sparklines.
</p>
 
<hr>
<h2 id="scaling"> Scaling Data </h2>
 
<p>
Scaling data is very simple. By default BarSparklines scale from
<em>zero</em> to <em>max</em>, and LineSparklines scale from
<em>min</em> to </em>max</em>. However, you can customize this
behavior.
</p>
<p>
For example, a line sparkline scaling from <em>zero</em> to
<em>max</em>.
</p>
 
<pre><code>var opts = {'scale_from':0};
var data = [1,2,3,4,5,6];
new Sparkline("canvas_id",data,opts).draw();</code></pre>
 
<p>
And a bar sparkline scaling from <em>min</em> to
<em>max</em> is easy as well.
</p>
<pre><code>var opts = {'scale_from':undefined};
var data = [1,2,3,4,5,6];
new BarSparkline("canvas_id",data,opts).draw();</code></pre>
 
<p>And finaly a line sparkline scaling from 50 to 150.</p>
 
<pre><code>var opts = {'scale_from':50,'scale_to':150};
var data = [1,2,3,4,5,6];
new Sparkline("canvas_id",data,opts).draw();</code></pre>
 
<p>
This should provide sufficient flexibility to size the
chart's viewport to emphasize the trend in the data that
is particularly interesting to you.
</p>
 
<hr>
<h2 id="lines""> Line Sparklines </h2>
 
<p>
The first type of Sparkline is the line sparkline, which represents
data in a simple line format. Be wary that they can tell strikingly
different stories depending on their height and width.
</p>
 
<hr>
<p> A simple sparkline. </p>
<pre><code>var data = [100,500,300,200,400,500,400,400,100,200];
new Sparkline('simple1', data).draw();</code></pre>
<canvas width="300" height="50" id="simple1" ></canvas>
 
<hr>
<p> The same sparkline, with excessive padding, in a taller
canvas. </p>
<pre><code>var data = [100,500,300,200,400,500,400,400,100,200];
var opts = {'left_padding':50,'right_padding':50,'top_padding':25, 'bottom_padding':25};
new Sparkline('simple2',data, opts).draw();</code></pre>
<canvas width="300" height="100" id="simple2" ></canvas>
 
<hr>
<p> The same sparkline, with no padding, drawn in a longer canvas. </p>
<pre><code>var data = [100,500,300,200,400,500,400,400,100,200];
var opts = {'left_padding':0,'right_padding':0,'top_padding':0, 'bottom_padding':0};
new Sparkline('simple3',data, opts).draw();</code></pre>
<canvas width="500" height="50" id="simple3" ></canvas>
 
<hr>
<p> Let's change up the colors. </p>
<pre><code>var data = [100,500,300,200,400,500,400,400,100,200];
var opts = {"background_color":"#FFEEDD","line_color":"#001122"};
new Sparkline('simple4',data, opts).draw();</code></pre>
<canvas width="500" height="50" id="simple4" ></canvas>
 
<hr>
<p> Well, it would be kind of neat to see the median (Q2). </p>
<pre><code>var data = [100,500,300,200,400,500,400,400,100,200];
var opts = {"percentile_lines":[0.5]};
new Sparkline('simple5a',data,opts).draw();</code></pre>
<canvas width="500" height="50" id="simple5a" ></canvas>
 
<hr>
<p> Well, lets remove the line at Q2, and have them at Q1 and Q3 instead. </p>
<pre><code>var data = [100,500,300,200,400,500,400,400,100,200];
var opts = {"percentile_lines":[0.25,0.75]};
new Sparkline('simple5',data,opts).draw();</code></pre>
<canvas width="500" height="50" id="simple5" ></canvas>
 
<hr>
<p> It would kind of helpful to color the interquartile range. </p>
<pre><code>var data = [100,500,300,200,400,500,400,400,100,200];
var opts = {"percentile_lines":[0.25,0.75],"fill_between_percentile_lines":true};
new Sparkline('simple6',data,opts).draw();</code></pre>
<canvas width="500" height="50" id="simple6" ></canvas>
 
<hr>
<p>
Lets see that with Q1, Q2, and Q3, with the iterquartile range
colored, and a richer dataset.
</p>
<pre><code>var data2 = [100,200,500,1000,600,900,300,500,800,800,900,1000,50,40,200,100,900,300,400,400,600,700,800,900,700,800,50,100,100];
var opts = {"percentile_lines":[0.25,0.5,0.75],"fill_between_percentile_lines":true};
new Sparkline('simple7',data2,opts).draw();</code></pre>
<canvas width="500" height="50" id="simple7" ></canvas>
 
<hr>
<p>
Okay, now lets customize the hell out of this, and shrink it down to a
much smaller size that might fit well in a blog entry or merged into a
simple webapplication.
</p>
<pre><code>var data2 = [100,200,500,1000,600,900,300,500,800,800,900,1000,50,40,200,100,900,300,400,400,600,700,800,900,700,800,50,100,100];
var opts = {
  "percentile_lines":[0.25,0.5,0.75],"fill_between_percentile_lines":true,
  "left_padding":1,"right_padding":1,"top_padding":1,"bottom_padding":1,
  "background_color":"#FFFFFF","line_color":"#444444","percentile_line_color":"#AAAAFF",
  "percentile_fill_color":"#CCCCFF"
};
new Sparkline('simple8', data2, opts).draw();</code></pre>
<canvas width="100" height="25" id="simple8" ></canvas>
 
<hr>
<p>
But, you might not want to draw lines at the quartiles (or at
whatever arbitrary percentile of entries), you might want to draw
lines at certain values instead. For example, you might want to
indicate the normal range of blood pressure in a patient.
</p>
<pre><code>var data3 =
[120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
var opts = {"value_lines":[80,120],"top_padding":5,"bottom_padding":0,"fill_between_value_lines":true};
new Sparkline('simple9', data3, opts).draw();</code></pre>
<canvas width="200" height="50" id="simple9" ></canvas>
 
<hr>
<p>
For fun, lets add some percentile lines into the mix as well.
</p>
<pre><code>var data3 =
[120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
var opts ={"value_lines":[90,110],"top_padding":5,
           "bottom_padding":0,"fill_between_value_lines":true,
           "percentile_lines":[0.25,0.75],"percentile_line_color":"#FF6666"
};
  new Sparkline('simple10', data3, opts).draw();
new Sparkline('simple10', data3, opts).draw();</code></pre>
<canvas width="500" height="200" id="simple10" ></canvas>
 
<p> Lets see that at a few different sizes. The one above it 500px by
200px. Lets try it at 300px by 100px.
</p>
 
<canvas width="300" height="100" id="simple11" ></canvas>
 
<p>
And maybe at 100px by 50px. (Although, we'd really want to reduce
the padding, since its a bit too much at this small size.)
</p>
 
<canvas width="100" height="50" id="simple12" ></canvas>
 
<hr>
<h2 id="bars"> Bar Sparklines </h2>
 
<p>
Bar sparklines can be clearer about conveying some
types of information than line sparklines. They are
more explicit about exact quatities, but are often
less effective at exposing trends within the data
they are graphing.
</p>
 
<hr>
<p> Lets start with the simplest of bar sparklines. </p>
<pre><code>var data3 =
[120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
new Sparkline('bar11', data3).draw();</code></pre>
<canvas width="500" height="200" id="bar1" ></canvas>
 
<hr>
<p> And add a nice filled region between Q1 and Q3. </p>
<pre><code>var data3 = [120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
var opts = {'percentile_lines':[0.25,0.75],"fill_between_percentile_lines":true};
new Sparkline('bar2', data3).draw();</code></pre>
<canvas width="500" height="200" id="bar2" ></canvas>
 
<hr>
<p> Notice that the percentile lines and fill between them extend
beyond the bars. Personally, I think that looks better, but you may
want to disable that. </p>
<pre><code>var data3 = [120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
var opts ={'percentile_lines':[0.25,0.75],"fill_between_percentile_lines":true, "extend_markings":false};
new Sparkline('bar3', data3).draw();</code></pre>
<canvas width="500" height="200" id="bar3" ></canvas>
 
<hr>
<p>
Maybe we want less space between lines, and some extra padding
from the sides, and while we're at it lets make that extra padding for
the percentile lines and filling a bit wider as well.
</p>
<pre><code>var data3 =[120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
var opts = {'percentile_lines':[0.25,0.75],"fill_between_percentile_lines":true,
            'padding_between_bars':2,"left_padding":30,"right_padding":30,
            'marking_padding':16};
new Sparkline('bar4', data3).draw();</code></pre>
</code></pre>
<canvas width="500" height="200" id="bar4" ></canvas>
 
<hr>
<p>
Our old friends, value lines, are still available to draw lines at
values instead of at percentiles points.
</p>
<pre><code>var data3 =[120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
var opts = {'value_lines':[85,115]};
new BarSparkline('bar5',data3,opts).draw();</code></pre>
<canvas width="400" height="150" id="bar5" ></canvas>
 
<hr>
<p>
And we can fill between the value lines too. And take away the spacing
between bars, if we feel like it.
</p>
<pre><code>var data3 =[120,130,80,100,90,105,95,60,70,75,70,90,100,110,120,130,150,100,50,80,90,100,110,110];
var opts = {'value_lines':[80,120],"fill_between_value_lines":true,"padding_between_bars":0,"bottom_padding":3};
new BarSparkline('bar6',data3,opts).draw();</code></pre>
<canvas width="500" height="100" id="bar6"></canvas>
 
 
 
<hr>
<h2 id="custom"> Customizing Sparklines </h2>
 
<p>
The simplest way to customize a sparkline is to pass in a
dictionary of modified attributes. This is the technique
that is used in all the examples on this page. It looks
something like this:
</p>
 
<pre><code>var data = [100,500,300,200,400,500,400,400,100,200];
var opts = {'left_padding':50,'right_padding':50,'top_padding':25, 'bottom_padding':25};
new Sparkline('simple2',data, opts).draw();</code></pre>
 
<p>
If you end up doing a large number of similar sparklines, you
may begin to feel that passing the arguments in each time is
getting a bit redundant. In such a case, you can subclass the
<em>Sparkline</em> or <em>BarSparkline</em> classes to
look the way you prefer. For example:
</p>
 
<pre><code>var MySparkline = function(id,data,mixins) {
  this.background_color = "rgba(255,255,255,1);";
  this.line_color = "rga(100,100,100,.7);";
  this.top_padding = 3;
  this.bottom_padding = 3;
  this.left_padding = 6;
  this.right_padding = 6;
  this.init(id,data,mixins);
}
MySparkline.prototype = new Sparkline();
 
new MySparkline("canvas_a",[1,2,3,4]);</code></pre>
 
<p>
If you wanted to customize <em>BarSparkline</em> instead, you
would change the line
<code>MySparkline.prototype = new Sparkline();</code>
to
<code>MySparkline.prototype = new BarSparkline();</code>.
</p>
 
<hr>
<h2 id="tests"> Tests </h2>
 
<p>
This section contains some visual tests for unusual
situations (zero elements, one element, etc).
</p>
 
<canvas width="500" height="100" id="test1"></canvas>
 
<canvas width="500" height="100" id="test2"></canvas>
 
 
<hr>
<h2 id="download"> Download </h2>
 
<p>
Right click <a href="sparklines.min.js">here to download the minified
sparklines.min.js file</a>.
</p>
 
<p>
Its also very easy to build your own deploy copy to have the most
recent version. Simply check out the current project from Git and
from the main project directory type:
</p>
 
<pre><code>./scripts/deploy.sh</code></pre>
 
<p>
and a deploy copy will be created named <code>sparklines.min.js</code>
which contains all necessary code merged into one file.
</p>
 
 
<hr>
<h2 id="source"> Source </h2>
<ul>
  <li> <a href="sparklines.js">sparklines.js</a> </li>
  <li> <a href="http://ejohn.org/blog/processingjs/">Processing.js</a> </li>
</ul>
 
<p>
There is a public repository available at <a
href="http://github.com/lethain/sparklines.js/tree/master">github</a>
for those interested in the most recent releases or contributing.
</p>
 
<hr>
<h2 id="about"> About </h2>
<p>
This project is inspired by a number of sources, and almost all of
those sources have appeared in my life as the result of readings and
research direct my way by <a href="http://densityofspace.com/">J.D. Hollis</a>. Beyond that,
J.D. has also provided feedback about the project, along with
a critical eye.
</p>
 
<p>
There is a huge amount of thinking about informational design
going on at the moment, and this project might be described as
a small attempt to make a small piece of that information
easier to take advantage of.
</p>
 
 
<hr>
<h2 id="contact"> Contact </h2>
 
<p>
Feel free to send requests, comments and complaints about this project
to <code>lethain@gmail.com</code>.
</p>
 
<hr>
<h2 id="license"> License </h2>
 
<p> This project has been released under the <a rel="license" href="http://www.opensource.org/licenses/mit-license.php">MIT License</a> by <a href="http://lethain.com">Will Larson</a></p>
 
</body> </html>