sparklines 0.4.6 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/CHANGELOG +5 -0
  2. data/lib/sparklines.rb +80 -74
  3. data/test/test_all.rb +7 -0
  4. 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]
@@ -74,15 +74,15 @@ Licensed under the MIT license.
74
74
  =end
75
75
  class Sparklines
76
76
 
77
- VERSION = '0.4.6'
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
- coords.push [(2 + i), (height - 3 - r/(101.0/(height-4)))]
196
- i += step
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
- i + step - 2, @canvas.rows - ( (r / @maximum_value) * @canvas.rows) )
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
- 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
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
- # For 0% return blank
337
- @draw.draw(@canvas)
338
- return @canvas.to_blob
336
+ # For 0% return blank
337
+ @draw.draw(@canvas)
338
+ return @canvas.to_blob
339
339
  elsif percent == 100
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
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
- @minumum_value = @data.min
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 { |value| value = (value+abs_min).to_f / (@maximum_value+abs_min) * 100.0 }
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
- list << [0, height]
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
- list << [width, height]
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
- @label_width, 1.0,
587
- w - @label_and_data_last_width + @@label_margin, h - calculate_caps_height/2.0,
588
- @options[:label])
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
- @data_last_width, 1.0,
593
- w - @data_last_width - @@label_margin * 2.0, h - calculate_caps_height/2.0,
594
- @data.last.to_s)
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
 
@@ -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.0
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.6
7
- date: 2007-10-12 00:00:00 -07:00
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