lib/sparklines.rb in sparklines-0.4.8 vs lib/sparklines.rb in sparklines-0.5.0
- old
+ new
@@ -53,10 +53,11 @@
area
discrete
pie
smooth
bar
+ bullet
whisker
General Defaults:
:type => 'smooth'
@@ -72,21 +73,21 @@
Licensed under the MIT license.
=end
class Sparklines
- VERSION = '0.4.8'
+ VERSION = '0.5.0'
@@label_margin = 5.0
@@pointsize = 10.0
class << self
- # Does the actual plotting of the graph.
- # Calls the appropriate subclass based on the :type argument.
- # Defaults to 'smooth'
- def plot(data=[], options={})
+ ##
+ # Plots a sparkline and returns a Magic::Image object.
+
+ def plot_to_image(data=[], options={})
defaults = {
:type => 'smooth',
:height => 14,
:upper => 50,
:diameter => 20,
@@ -126,11 +127,24 @@
else
sparkline.plot_error options_sym
end
end
- # Writes a graph to disk with the specified filename, or "sparklines.png"
+ ##
+ # Does the actual plotting of the graph.
+ # Calls the appropriate subclass based on the :type argument.
+ # Defaults to 'smooth'.
+ #
+ # Returns a blob.
+
+ def plot(data=[], options={})
+ plot_to_image(data, options).to_blob
+ end
+
+ ##
+ # Writes a graph to disk with the specified filename, or "sparklines.png".
+
def plot_to_file(filename="sparklines.png", data=[], options={})
File.open( filename, 'wb' ) do |png|
png << self.plot( data, options)
end
end
@@ -230,11 +244,11 @@
drawbox(coords[@norm_data.index(@norm_data.max)+1], 1, max_color) if has_max == true
drawbox(coords[-2], 1, last_color) if has_last == true
@draw.draw(@canvas)
- @canvas.to_blob
+ @canvas
end
##
# A bar graph.
@@ -258,11 +272,11 @@
i + step - 2, @canvas.rows - ( (r / @maximum_value) * @canvas.rows) )
i += step
end
@draw.draw(@canvas)
- @canvas.to_blob
+ @canvas
end
##
# Creates a discretized sparkline
@@ -300,11 +314,11 @@
i, (@canvas.rows - r/(101.0/(height-4))).to_f)
i += step
end
@draw.draw(@canvas)
- @canvas.to_blob
+ @canvas
end
##
# Creates a pie-chart sparkline
@@ -333,16 +347,16 @@
# Special exceptions
if percent == 0
# For 0% return blank
@draw.draw(@canvas)
- return @canvas.to_blob
+ return @canvas
elsif percent == 100
# For 100% just draw a full circle
@draw.ellipse(r + 2, r + 2, r , r , 0, 360)
@draw.draw(@canvas)
- return @canvas.to_blob
+ return @canvas
end
# Okay, this part is as confusing as hell, so pay attention:
# This line determines the horizontal portion of the point on the circle where the X-Axis
# should end. It's caculated by taking the center of the on-image circle and adding that
@@ -368,15 +382,15 @@
# More info on the SVG path string format at: http://www.w3.org/TR/SVG/paths.html
path = "M#{r + 2},#{r + 2} h#{r} A#{r},#{r} 0 #{large_arc_flag},1 #{arc_end_x},#{arc_end_y} z"
@draw.path(path)
@draw.draw(@canvas)
- @canvas.to_blob
+ @canvas
end
##
- # Creates a smooth sparkline.
+ # Creates a smooth line graph sparkline.
#
# :step - An integer that determines the distance between each point on the sparkline. Defaults to 2.
#
# :height - An integer that determines what the height of the sparkline will be. Defaults to 14
#
@@ -395,10 +409,15 @@
# :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.
#
# :std_dev_color - A string or color code representing the color that the standard deviation bar behind the smooth graph will be displayed as. Defaults to #efefef
#
# :underneath_color - A string or color code representing the color that will be used to fill in the area underneath the line. Optional.
+ #
+ # :target - A 1px horizontal line will be drawn at this value. Useful for showing an average.
+ #
+ # :target_color - Color of the target line. Defaults to white.
+
def smooth
step = @options[:step].to_f
height = @options[:height].to_f
width = ((@norm_data.size - 1) * step).to_f
@@ -414,10 +433,13 @@
has_last = @options[:has_last]
line_color = @options[:line_color]
has_std_dev = @options[:has_std_dev]
std_dev_color = @options[:std_dev_color]
+ target = @options.has_key?(:target) ? @options[:target].to_f : nil
+ target_color = @options[:target_color] || 'white'
+
drawstddevbox(width,height,std_dev_color) if has_std_dev == true
@draw.stroke(line_color)
coords = []
i=0
@@ -430,16 +452,23 @@
closed_polygon(height, width, coords)
else
open_ended_polyline(coords)
end
+ unless target.nil?
+ normalized_target_value = ((target.to_f - @minimum_value)/(@maximum_value - @minimum_value)) * 100.0
+ adjusted_target_value = (height - 3 - normalized_target_value/(101.0/(height-4))).to_i
+ @draw.stroke(target_color)
+ open_ended_polyline([[-5, adjusted_target_value], [width + 5, adjusted_target_value]])
+ end
+
drawbox(coords[@norm_data.index(@norm_data.min)], 2, min_color) if has_min == true
drawbox(coords[@norm_data.index(@norm_data.max)], 2, max_color) if has_max == true
drawbox(coords[-1], 2, last_color) if has_last == true
@draw.draw(@canvas)
- @canvas.to_blob
+ @canvas
end
##
# Creates a whisker sparkline to track on/off type data. There are five states:
# on, off, no value, exceptional on, exceptional off. On values create an up
@@ -457,15 +486,15 @@
#
# :exception_color - the color of exceptional whiskers; defaults to red
def whisker
- # step = @options[:step].to_f
+ step = @options[:step].to_i
height = @options[:height].to_f
background_color = @options[:background_color]
- create_canvas(@data.size * 2 - 1, height, background_color)
+ create_canvas(@data.size * step - 1, height, background_color)
whisker_color = @options[:whisker_color] || 'black'
exception_color = @options[:exception_color] || 'red'
on_row = (@canvas.rows/2.0 - 1).ceil
@@ -489,52 +518,80 @@
y_end_point = @canvas.rows
end
@draw.stroke( color )
@draw.line( i, y_mid_point, i, y_end_point )
- i += 2
+ i += step
end
@draw.draw(@canvas)
- @canvas.to_blob
+ @canvas
end
+ ##
+ # A bullet graph, a la Stephen Few in "Information Dashboard Design."
+ #
+ # * data - A single value for the thermometer part of the bullet.
+ # Represents the current value.
+ # * options - a hash
+ #
+ # :good - Numeric. Maximum value that will be shown on the graph. Required.
+ #
+ # :height - Numeric. Defaults to 15. Should be a multiple of three.
+ #
+ # :width - This graph expands to any specified width. Defaults to 100.
+ #
+ # :bad - Numeric. A darker shade background will be drawn up to this point.
+ #
+ # :satisfactory - Numeric. A medium background will be drawn up to this point.
+ #
+ # :target - Numeric value. A thin vertical bar will be drawn.
+ #
+ # :good_color - Color for the rightmost section of the bullet.
+ #
+ # :satisfactory_color - Color for the middle background of the bullet.
+ #
+ # :bad_color - Color for the lowest, leftmost section.
+
def bullet
height = @options[:height].to_f
- @graph_width = @options.has_key?(:width) ? @options[:width].to_f : 100.0
- background_color = '#eeeeee' # @options[:background_color]
+ @graph_width = @options.has_key?(:width) ? @options[:width].to_f : 100.0
+ good_color = @options.has_key?(:good_color) ? @options[:good_color] : '#eeeeee'
+ satisfactory_color = @options.has_key?(:satisfactory_color) ? @options[:satisfactory_color] : '#bbbbbb'
+ bad_color = @options.has_key?(:bad_color) ? @options[:bad_color] : '#999999'
+ bullet_color = @options.has_key?(:bullet_color) ? @options[:bullet_color] : 'black'
@thickness = height/3.0
- create_canvas(@graph_width, height, background_color)
+ create_canvas(@graph_width, height, good_color)
@value = @norm_data
@good_value = @options[:good].to_f
-
+
@graph_height = @options[:height]
- qualitative_range_colors = ['#bbbbbb', '#999999']
+ qualitative_range_colors = [satisfactory_color, bad_color]
[:satisfactory, :bad].each_with_index do |indicator, index|
next unless @options.has_key?(indicator)
@draw = @draw.fill(qualitative_range_colors[index])
indicator_width_x = @graph_width * (@options[indicator].to_f / @good_value)
@draw = @draw.rectangle(0, 0, indicator_width_x.to_i, @graph_height)
end
if @options.has_key?(:target)
- @draw = @draw.fill 'black'
+ @draw = @draw.fill(bullet_color)
target_x = @graph_width * (@options[:target].to_f / @good_value)
half_thickness = (@thickness / 2.0).to_i
bar_width = 1.0
@draw = @draw.rectangle(target_x.to_i, half_thickness, (target_x + bar_width).to_i, @thickness * 2 + half_thickness)
end
# Value
- @draw = @draw.fill 'black'
+ @draw = @draw.fill(bullet_color)
@draw = @draw.rectangle(0, @thickness.to_i, @graph_width * (@data.first.to_f / @good_value), (@thickness * 2.0).to_i)
@draw.draw(@canvas)
- @canvas.to_blob
+ @canvas
end
##
# Draw the error Sparkline.
@@ -544,10 +601,10 @@
@draw.fill('red')
@draw.line(0,0,40,15)
@draw.line(0,15,40,0)
@draw.draw(@canvas)
- @canvas.to_blob
+ @canvas
end
private
def normalize_data