sparklines 0.4.6 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/lib/sparklines.rb +80 -74
- data/test/test_all.rb +7 -0
- metadata +3 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
== 0.4.7
|
2
|
+
|
3
|
+
* Improved normalization for better display of close, high-values. [Matt Van Horn]
|
4
|
+
* Improved rendering of closed polyline on smooth graph with undercolor. Far left, right, and bottom of polyline are drawn offscreen so they don't show in the visible graph.
|
5
|
+
|
1
6
|
== 0.4.6
|
2
7
|
|
3
8
|
* Added :underneath_color option to smooth sparkline. [Cory Forsyth]
|
data/lib/sparklines.rb
CHANGED
@@ -74,15 +74,15 @@ Licensed under the MIT license.
|
|
74
74
|
=end
|
75
75
|
class Sparklines
|
76
76
|
|
77
|
-
VERSION = '0.4.
|
77
|
+
VERSION = '0.4.7'
|
78
78
|
|
79
79
|
@@label_margin = 5.0
|
80
80
|
@@pointsize = 10.0
|
81
81
|
|
82
82
|
class << self
|
83
83
|
|
84
|
-
# Does the actual plotting of the graph.
|
85
|
-
# Calls the appropriate subclass based on the :type argument.
|
84
|
+
# Does the actual plotting of the graph.
|
85
|
+
# Calls the appropriate subclass based on the :type argument.
|
86
86
|
# Defaults to 'smooth'
|
87
87
|
def plot(data=[], options={})
|
88
88
|
defaults = {
|
@@ -99,15 +99,15 @@ class Sparklines
|
|
99
99
|
:share_color => 'red',
|
100
100
|
:remain_color => 'lightgrey',
|
101
101
|
:min_color => 'blue',
|
102
|
-
:max_color => 'green',
|
103
|
-
:last_color => 'red',
|
102
|
+
:max_color => 'green',
|
103
|
+
:last_color => 'red',
|
104
104
|
:std_dev_color => '#efefef',
|
105
|
-
|
105
|
+
|
106
106
|
:has_min => false,
|
107
107
|
:has_max => false,
|
108
108
|
:has_last => false,
|
109
109
|
:has_std_dev => false,
|
110
|
-
|
110
|
+
|
111
111
|
:label => nil
|
112
112
|
}
|
113
113
|
|
@@ -118,7 +118,7 @@ class Sparklines
|
|
118
118
|
end
|
119
119
|
|
120
120
|
options_sym = defaults.merge(options_sym)
|
121
|
-
|
121
|
+
|
122
122
|
# Call the appropriate method for actual plotting.
|
123
123
|
sparkline = self.new(data, options_sym)
|
124
124
|
if %w(area bar pie smooth discrete whisker).include? options_sym[:type]
|
@@ -147,25 +147,25 @@ class Sparklines
|
|
147
147
|
# Creates a continuous area sparkline. Relevant options.
|
148
148
|
#
|
149
149
|
# :step - An integer that determines the distance between each point on the sparkline. Defaults to 2.
|
150
|
-
#
|
150
|
+
#
|
151
151
|
# :height - An integer that determines what the height of the sparkline will be. Defaults to 14
|
152
|
-
#
|
152
|
+
#
|
153
153
|
# :upper - An integer that determines the threshold for colorization purposes. Any value less than upper will be colored using below_color, anything above and equal to upper will use above_color. Defaults to 50.
|
154
|
-
#
|
154
|
+
#
|
155
155
|
# :has_min - Determines whether a dot will be drawn at the lowest value or not. Defaults to false.
|
156
|
-
#
|
156
|
+
#
|
157
157
|
# :has_max - Determines whether a dot will be drawn at the highest value or not. Defaults to false.
|
158
|
-
#
|
158
|
+
#
|
159
159
|
# :has_last - Determines whether a dot will be drawn at the last value or not. Defaults to false.
|
160
|
-
#
|
160
|
+
#
|
161
161
|
# :min_color - A string or color code representing the color that the dot drawn at the smallest value will be displayed as. Defaults to blue.
|
162
|
-
#
|
162
|
+
#
|
163
163
|
# :max_color - A string or color code representing the color that the dot drawn at the largest value will be displayed as. Defaults to green.
|
164
|
-
#
|
164
|
+
#
|
165
165
|
# :last_color - A string or color code representing the color that the dot drawn at the last value will be displayed as. Defaults to red.
|
166
|
-
#
|
166
|
+
#
|
167
167
|
# :above_color - A string or color code representing the color to draw values above or equal the upper value. Defaults to red.
|
168
|
-
#
|
168
|
+
#
|
169
169
|
# :below_color - A string or color code representing the color to draw values below the upper value. Defaults to gray.
|
170
170
|
|
171
171
|
def area
|
@@ -173,7 +173,7 @@ class Sparklines
|
|
173
173
|
step = @options[:step].to_f
|
174
174
|
height = @options[:height].to_f
|
175
175
|
background_color = @options[:background_color]
|
176
|
-
|
176
|
+
|
177
177
|
create_canvas((@norm_data.size - 1) * step + 4, height, background_color)
|
178
178
|
|
179
179
|
upper = @options[:upper].to_f
|
@@ -192,8 +192,8 @@ class Sparklines
|
|
192
192
|
coords = [[0,(height - 3 - upper/(101.0/(height-4)))]]
|
193
193
|
i=0
|
194
194
|
@norm_data.each do |r|
|
195
|
-
|
196
|
-
|
195
|
+
coords.push [(2 + i), (height - 3 - r/(101.0/(height-4)))]
|
196
|
+
i += step
|
197
197
|
end
|
198
198
|
coords.push [(@norm_data.size - 1) * step + 4, (height - 3 - upper/(101.0/(height-4)))]
|
199
199
|
|
@@ -225,10 +225,10 @@ class Sparklines
|
|
225
225
|
@draw.rectangle(0,0,@canvas.columns,@canvas.rows)
|
226
226
|
end
|
227
227
|
@draw.clip_path('all')
|
228
|
-
|
228
|
+
|
229
229
|
drawbox(coords[@norm_data.index(@norm_data.min)+1], 1, min_color) if has_min == true
|
230
230
|
drawbox(coords[@norm_data.index(@norm_data.max)+1], 1, max_color) if has_max == true
|
231
|
-
|
231
|
+
|
232
232
|
drawbox(coords[-2], 1, last_color) if has_last == true
|
233
233
|
|
234
234
|
@draw.draw(@canvas)
|
@@ -244,7 +244,7 @@ class Sparklines
|
|
244
244
|
background_color = @options[:background_color]
|
245
245
|
|
246
246
|
create_canvas(@norm_data.length * step + 2, height, background_color)
|
247
|
-
|
247
|
+
|
248
248
|
upper = @options[:upper].to_f
|
249
249
|
below_color = @options[:below_color]
|
250
250
|
above_color = @options[:above_color]
|
@@ -254,8 +254,8 @@ class Sparklines
|
|
254
254
|
color = (r >= upper) ? above_color : below_color
|
255
255
|
@draw.stroke('transparent')
|
256
256
|
@draw.fill(color)
|
257
|
-
@draw.rectangle( i, @canvas.rows,
|
258
|
-
|
257
|
+
@draw.rectangle( i, @canvas.rows,
|
258
|
+
i + step - 2, @canvas.rows - ( (r / @maximum_value) * @canvas.rows) )
|
259
259
|
i += step
|
260
260
|
end
|
261
261
|
|
@@ -283,9 +283,9 @@ class Sparklines
|
|
283
283
|
step = @options[:step].to_f
|
284
284
|
|
285
285
|
width = @norm_data.size * step - 1
|
286
|
-
|
286
|
+
|
287
287
|
create_canvas(@norm_data.size * step - 1, height, background_color)
|
288
|
-
|
288
|
+
|
289
289
|
below_color = @options[:below_color]
|
290
290
|
above_color = @options[:above_color]
|
291
291
|
std_dev_color = @options[:std_dev_color]
|
@@ -294,11 +294,11 @@ class Sparklines
|
|
294
294
|
|
295
295
|
i = 0
|
296
296
|
@norm_data.each do |r|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
297
|
+
color = (r >= upper) ? above_color : below_color
|
298
|
+
@draw.stroke(color)
|
299
|
+
@draw.line(i, (@canvas.rows - r/(101.0/(height-4))-4).to_f,
|
300
|
+
i, (@canvas.rows - r/(101.0/(height-4))).to_f)
|
301
|
+
i += step
|
302
302
|
end
|
303
303
|
|
304
304
|
@draw.draw(@canvas)
|
@@ -320,11 +320,11 @@ class Sparklines
|
|
320
320
|
background_color = @options[:background_color]
|
321
321
|
|
322
322
|
create_canvas(diameter, diameter, background_color)
|
323
|
-
|
323
|
+
|
324
324
|
share_color = @options[:share_color]
|
325
325
|
remain_color = @options[:remain_color]
|
326
326
|
percent = @norm_data[0]
|
327
|
-
|
327
|
+
|
328
328
|
# Adjust the radius so there's some edge left in the pie
|
329
329
|
r = diameter/2.0 - 2
|
330
330
|
@draw.fill(remain_color)
|
@@ -333,14 +333,14 @@ class Sparklines
|
|
333
333
|
|
334
334
|
# Special exceptions
|
335
335
|
if percent == 0
|
336
|
-
|
337
|
-
|
338
|
-
|
336
|
+
# For 0% return blank
|
337
|
+
@draw.draw(@canvas)
|
338
|
+
return @canvas.to_blob
|
339
339
|
elsif percent == 100
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
340
|
+
# For 100% just draw a full circle
|
341
|
+
@draw.ellipse(r + 2, r + 2, r , r , 0, 360)
|
342
|
+
@draw.draw(@canvas)
|
343
|
+
return @canvas.to_blob
|
344
344
|
end
|
345
345
|
|
346
346
|
# Okay, this part is as confusing as hell, so pay attention:
|
@@ -402,10 +402,10 @@ class Sparklines
|
|
402
402
|
step = @options[:step].to_f
|
403
403
|
height = @options[:height].to_f
|
404
404
|
width = ((@norm_data.size - 1) * step).to_f
|
405
|
-
|
405
|
+
|
406
406
|
background_color = @options[:background_color]
|
407
407
|
create_canvas(width, height, background_color)
|
408
|
-
|
408
|
+
|
409
409
|
min_color = @options[:min_color]
|
410
410
|
max_color = @options[:max_color]
|
411
411
|
last_color = @options[:last_color]
|
@@ -415,7 +415,7 @@ class Sparklines
|
|
415
415
|
line_color = @options[:line_color]
|
416
416
|
has_std_dev = @options[:has_std_dev]
|
417
417
|
std_dev_color = @options[:std_dev_color]
|
418
|
-
|
418
|
+
|
419
419
|
drawstddevbox(width,height,std_dev_color) if has_std_dev == true
|
420
420
|
|
421
421
|
@draw.stroke(line_color)
|
@@ -425,7 +425,7 @@ class Sparklines
|
|
425
425
|
coords.push [ i, (height - 3 - r/(101.0/(height-4))) ]
|
426
426
|
i += step
|
427
427
|
end
|
428
|
-
|
428
|
+
|
429
429
|
if @options[:underneath_color]
|
430
430
|
closed_polygon(height, width, coords)
|
431
431
|
else
|
@@ -439,15 +439,15 @@ class Sparklines
|
|
439
439
|
@draw.draw(@canvas)
|
440
440
|
@canvas.to_blob
|
441
441
|
end
|
442
|
-
|
442
|
+
|
443
443
|
##
|
444
|
-
# Creates a whisker sparkline to track on/off type data. There are five states:
|
445
|
-
# on, off, no value, exceptional on, exceptional off. On values create an up
|
446
|
-
# whisker and off values create a down whisker. Exceptional values may be
|
444
|
+
# Creates a whisker sparkline to track on/off type data. There are five states:
|
445
|
+
# on, off, no value, exceptional on, exceptional off. On values create an up
|
446
|
+
# whisker and off values create a down whisker. Exceptional values may be
|
447
447
|
# colored differently than regular values to indicate, for example, a shut out.
|
448
448
|
# No value produces an empty row to indicate a tie.
|
449
|
-
#
|
450
|
-
# * results - an array of integer values between -2 and 2. -2 is exceptional
|
449
|
+
#
|
450
|
+
# * results - an array of integer values between -2 and 2. -2 is exceptional
|
451
451
|
# down, 1 is regular down, 0 is no value, 1 is up, and 2 is exceptional up.
|
452
452
|
# * options - a hash that takes parameters
|
453
453
|
#
|
@@ -456,7 +456,7 @@ class Sparklines
|
|
456
456
|
# :whisker_color - the color of regular whiskers; defaults to black
|
457
457
|
#
|
458
458
|
# :exception_color - the color of exceptional whiskers; defaults to red
|
459
|
-
|
459
|
+
|
460
460
|
def whisker
|
461
461
|
|
462
462
|
# step = @options[:step].to_f
|
@@ -464,7 +464,7 @@ class Sparklines
|
|
464
464
|
background_color = @options[:background_color]
|
465
465
|
|
466
466
|
create_canvas(@data.size * 2 - 1, height, background_color)
|
467
|
-
|
467
|
+
|
468
468
|
whisker_color = @options[:whisker_color] || 'black'
|
469
469
|
exception_color = @options[:exception_color] || 'red'
|
470
470
|
|
@@ -481,7 +481,7 @@ class Sparklines
|
|
481
481
|
y_mid_point = (r >= 1) ? on_row : off_row
|
482
482
|
|
483
483
|
y_end_point = y_mid_point
|
484
|
-
if ( r > 0)
|
484
|
+
if ( r > 0)
|
485
485
|
y_end_point = 0
|
486
486
|
end
|
487
487
|
|
@@ -495,7 +495,7 @@ class Sparklines
|
|
495
495
|
end
|
496
496
|
|
497
497
|
@draw.draw(@canvas)
|
498
|
-
@canvas.to_blob
|
498
|
+
@canvas.to_blob
|
499
499
|
end
|
500
500
|
|
501
501
|
##
|
@@ -512,39 +512,45 @@ class Sparklines
|
|
512
512
|
@canvas.to_blob
|
513
513
|
end
|
514
514
|
|
515
|
-
private
|
515
|
+
private
|
516
516
|
|
517
517
|
def normalize_data
|
518
|
-
@
|
519
|
-
@maximum_value = @data.max
|
520
|
-
abs_min = @minumum_value.abs
|
518
|
+
@minimum_value = @data.min
|
519
|
+
@maximum_value = @data.max
|
521
520
|
if @options[:type].to_s == 'pie'
|
522
521
|
@norm_data = @data
|
523
522
|
else
|
524
|
-
@norm_data = @data.map
|
523
|
+
@norm_data = @data.map do |value|
|
524
|
+
value = ((value.to_f - @minimum_value)/(@maximum_value - @minimum_value)) * 100.0
|
525
|
+
end
|
525
526
|
end
|
526
527
|
end
|
527
528
|
|
528
529
|
##
|
529
530
|
# :arr - an array of points (represented as two element arrays)
|
530
|
-
|
531
|
+
|
531
532
|
def open_ended_polyline(arr)
|
532
533
|
0.upto(arr.length - 2) { |i|
|
533
534
|
@draw.line(arr[i][0], arr[i][1], arr[i+1][0], arr[i+1][1])
|
534
535
|
}
|
535
536
|
end
|
536
|
-
|
537
|
+
|
537
538
|
# Fills in the area under the line (used for a smooth graph)
|
538
539
|
def closed_polygon(height, width, coords)
|
539
540
|
return if @options[:underneath_color].nil?
|
540
541
|
list = []
|
541
|
-
|
542
|
+
# Start off screen so completed polygon doesn't show
|
543
|
+
list << [-1, height + 1]
|
544
|
+
list << [coords.first.first - 1, coords.first.last]
|
545
|
+
# Now the normal coords
|
542
546
|
list << coords
|
543
|
-
|
547
|
+
# Close offscreen
|
548
|
+
list << [coords.last.first + 1, coords.last.last]
|
549
|
+
list << [width + 1, height + 1]
|
544
550
|
@draw.fill( @options[:underneath_color] )
|
545
551
|
@draw.polygon( *list.flatten )
|
546
552
|
end
|
547
|
-
|
553
|
+
|
548
554
|
##
|
549
555
|
# Create an image to draw on and a drawable to do the drawing with.
|
550
556
|
#
|
@@ -582,16 +588,16 @@ private
|
|
582
588
|
@draw.fill = 'black'
|
583
589
|
@draw.font = @font if @font
|
584
590
|
@draw.gravity = Magick::WestGravity
|
585
|
-
@draw.annotate( @canvas,
|
586
|
-
|
587
|
-
|
588
|
-
|
591
|
+
@draw.annotate( @canvas,
|
592
|
+
@label_width, 1.0,
|
593
|
+
w - @label_and_data_last_width + @@label_margin, h - calculate_caps_height/2.0,
|
594
|
+
@options[:label])
|
589
595
|
|
590
596
|
@draw.fill = 'red'
|
591
|
-
@draw.annotate( @canvas,
|
592
|
-
|
593
|
-
|
594
|
-
|
597
|
+
@draw.annotate( @canvas,
|
598
|
+
@data_last_width, 1.0,
|
599
|
+
w - @data_last_width - @@label_margin * 2.0, h - calculate_caps_height/2.0,
|
600
|
+
@data.last.to_s)
|
595
601
|
end
|
596
602
|
end
|
597
603
|
|
data/test/test_all.rb
CHANGED
@@ -149,6 +149,13 @@ class SparklinesTest < Test::Unit::TestCase
|
|
149
149
|
})
|
150
150
|
end
|
151
151
|
|
152
|
+
def test_close_values
|
153
|
+
Sparklines.plot_to_file("#{@output_dir}/smooth_close_values.png", [100, 90, 95, 99, 80, 90], {
|
154
|
+
:type => 'smooth',
|
155
|
+
:line_color => "#6699cc",
|
156
|
+
:underneath_color => "#ebf3f6"
|
157
|
+
})
|
158
|
+
end
|
152
159
|
|
153
160
|
def test_no_type
|
154
161
|
Sparklines.plot_to_file("#{@output_dir}/error.png", 0, :type => 'nonexistent')
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: sparklines
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.4.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.4.7
|
7
|
+
date: 2007-12-05 00:00:00 -08:00
|
8
8
|
summary: Tiny graphs.
|
9
9
|
require_paths:
|
10
10
|
- lib
|