Brasten Sager
August 7th, 2006
An 'average' graph. This graph iterates through all the layers and averages all the data at each point, then draws a thick, translucent, shadowy line graph indicating the average values.
This only looks decent in SVG mode. ImageMagick doesn't retain the transparency for some reason, creating a massive black line. Any help resolving this would be useful.
Returns new Average graph.
# File lib/scruffy/layers/average.rb, line 18 def initialize(options = {}) # Set self's relevant_data to false. Otherwise we get stuck in a # recursive loop. super(options.merge({:relevant_data => false})) # The usual :points argument is actually layers for Average, name it as such @layers = options[:points] end
Render average graph.
# File lib/scruffy/layers/average.rb, line 28 def draw(svg, coords, options = {}) svg.polyline( :points => coords.join(' '), :fill => 'none', :stroke => 'black', 'stroke-width' => relative(5), 'opacity' => '0.4') end
Override default #generate_coordinates method to iterate through the layers and generate coordinates based on the average data points.
# File lib/scruffy/layers/average.rb, line 36 def generate_coordinates(options = {}) key_layer = layers.find { |layer| layer.relevant_data? } options[:point_distance] = width / (key_layer.points.size - 1).to_f coords = [] #TODO this will likely break with the new hash model key_layer.points.each_with_index do |layer, idx| sum, objects = points.inject([0, 0]) do |arr, elem| if elem.relevant_data? arr[0] += elem.points[idx] arr[1] += 1 end arr end average = sum / objects.to_f x_coord = options[:point_distance] * idx relative_percent = ((average == min_value) ? 0 : ((average - min_value) / (max_value - min_value).to_f)) y_coord = (height - (height * relative_percent)) coords << [x_coord, y_coord].join(',') end return coords end