lib/sparklines.rb in sparklines-0.2.4 vs lib/sparklines.rb in sparklines-0.2.5
- old
+ new
@@ -20,10 +20,12 @@
{Geoffrey Grosenbach}[mailto:boss@topfunky.com] -- http://nubyonrails.topfunky.com
-- Conversion to module and addition of functions for using with Rails. Also changed functions to use Rails-style option hashes for parameters.
===Tangent regarding RMagick
+The easiest way to use RMagick on Mac OS X is to use darwinports. There are packages for libpng, freetype, and all the other libraries you need.
+
I had a heck of a time getting RMagick to work on my system so in the interests of saving other people the trouble here's a little set of instructions on how to get RMagick working properly and with the right image formats.
1. Install the zlib[http://www.libpng.org/pub/png/libpng.html] library
2. With zlib in the same directory as the libpng[http://www.libpng.org/pub/png/libpng.html] library, install libpng
3. Option step: Install the {jpeg library}[ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz] (You need it to use jpegs and you might want to have it)
@@ -68,10 +70,11 @@
area
discrete
pie
smooth
+ bar (results will be normalized, i.e. scaled to take up the full height of the graph)
General Defaults:
:type => 'smooth'
:height => 14px
@@ -86,11 +89,11 @@
Licensed under the MIT license.
=end
module Sparklines
- $VERSION = '0.2.3'
+ $VERSION = '0.2.5'
# Does the actually plotting of the graph. Calls the appropriate function based on the :type value passed. Defaults to 'smooth.'
def Sparklines.plot(results=[], options={})
defaults = { :type => 'smooth',
:height => 14,
@@ -113,29 +116,20 @@
:has_last => false
}
# This symbol->string->symbol is kind of awkward. Is there a more elegant way?
- # Convert all symbol keys to strings
- defaults.keys.reverse.each do |key|
- defaults[key.to_s] = defaults[key]
- end
options.keys.reverse.each do |key|
- options[key.to_s] = options[key]
- end
-
- options = defaults.merge(options)
-
- # Convert options string keys back to symbols
- options.keys.reverse.each do |key|
options[key.to_sym] = options[key]
end
-
+ options = defaults.merge(options)
+ # Minimal normalization
+ maximum_value = self.get_max_value(results).to_f
+
# Call the appropriate function for actual plotting
- #self.send('smooth', results, options)
- self.send(options[:type], results, options)
+ self.send(options[:type], results, options, maximum_value)
end
# Writes a graph to disk with the specified filename, or "Sparklines.png"
def Sparklines.plot_to_file(filename="sparklines.png", results=[], options={})
File.open( filename, 'wb' ) do |png|
@@ -152,11 +146,11 @@
# :diameter - An integer that determines what the size of the sparkline will be. Defaults to 20
#
# :share_color - A string or color code representing the color to draw the share of the pie represented by percent. Defaults to blue.
#
# :remain_color - A string or color code representing the color to draw the pie not taken by the share color. Defaults to lightgrey.
- def self.pie(results=[],options={})
+ def self.pie(results=[],options={}, maximum_value=100.0)
diameter = options[:diameter].to_i
share_color = options[:share_color]
remain_color = options[:remain_color]
percent = results[0]
@@ -224,27 +218,29 @@
# :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.
#
# :above_color - A string or color code representing the color to draw values above or equal the upper value. Defaults to red.
#
# :below_color - A string or color code representing the color to draw values below the upper value. Defaults to gray.
- def self.discrete(results=[], options = {})
+ def self.discrete(results=[], options = {}, maximum_value=100.0)
height = options[:height].to_i
upper = options[:upper].to_i
below_color = options[:below_color]
above_color = options[:above_color]
img = Magick::Image.new(results.size * 2 - 1, height) {self.background_color = options[:background_color]}
img.format = "PNG"
draw = Magick::Draw.new
- i=0
+ i = 0
results.each do |r|
- color = (r >= upper) && above_color || below_color
+ color = (r >= upper) ? above_color : below_color
draw.stroke(color)
- draw.line(i, (img.rows - r/(101.0/(height-4))-4).to_i,i,(img.rows - r/(101.0/(height-4))).to_i)
- i+=2
+ draw.line(i, (img.rows - r/(101.0/(height-4))-4).to_i,
+ i, (img.rows - r/(101.0/(height-4))).to_i)
+
+ i += 2
end
draw.draw(img)
img.to_blob
end
@@ -274,11 +270,11 @@
# :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.
#
# :above_color - A string or color code representing the color to draw values above or equal the upper value. Defaults to red.
#
# :below_color - A string or color code representing the color to draw values below the upper value. Defaults to gray.
- def self.area(results=[], options={})
+ def self.area(results=[], options={}, maximum_value=100.0)
step = options[:step].to_i
height = options[:height].to_i
upper = options[:upper].to_i
@@ -369,11 +365,11 @@
# :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.
#
# :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.
#
# :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.
- def self.smooth(results, options)
+ def self.smooth(results, options, maximum_value=100.0)
step = options[:step].to_i
height = options[:height].to_i
min_color = options[:min_color]
max_color = options[:max_color]
@@ -442,6 +438,46 @@
draw.draw(img)
img.to_blob
end
+
+ # Draws a bar graph, normalized.
+ #
+ # BUG: Last column never goes all the way to the bottom.
+ def self.bar(results=[], options = {}, maximum_value=100.0)
+ step = options[:step].to_i
+ height = options[:height].to_f
+ upper = options[:upper].to_i
+ below_color = options[:below_color]
+ above_color = options[:above_color]
+
+ img = Magick::Image.new((results.size) * step + 1, height) {
+ self.background_color = options[:background_color]
+ }
+ img.format = "PNG"
+ draw = Magick::Draw.new
+
+ i = 1
+ results.each_with_index do |r, index|
+ color = (r >= upper) ? above_color : below_color
+ draw.stroke('transparent')
+ draw.fill(color)
+ draw.rectangle( i, img.rows,
+ i + step - 2, img.rows - ((r / maximum_value) * img.rows) )
+ i += step
+ end
+
+ draw.draw(img)
+ img.to_blob
+ end
+
+
+ def self.get_max_value(values=[])
+ max_value = 0
+ values.each do |value|
+ max_value = (value > max_value) ? value : max_value
+ end
+ return max_value
+ end
+
end