sparklines 0.4.6 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
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