Class: Scruffy::Layers::Stacked

Inherits:
Base
  • Object
show all
Includes:
Helpers::LayerContainer
Defined in:
lib/scruffy/layers/stacked.rb

Overview

Scruffy::Layers::Stacked

Author

Brasten Sager

Date

August 12th, 2006

Provides a generic way for stacking graphs. This may or may not do what you’d expect under every situation, but it at least kills a couple birds with one stone (stacked bar graphs and stacked area graphs work fine).

Instance Attribute Summary

Attributes inherited from Base

#color, #complexity, #height, #max_value, #min_value, #opacity, #options, #preferred_color, #relevant_data, #title, #width

Instance Method Summary collapse

Methods included from Helpers::LayerContainer

#<<, #bottom_value, #layers, #layers=, #top_value

Methods inherited from Base

#bottom_value, #draw, #relevant_data?, #sum_values, #top_value

Constructor Details

#initialize(options = {}, &block) ⇒ Stacked

Returns new Stacked graph.

You can provide a block for easily adding layers during (just after) initialization. Example:

Stacked.new do |stacked|
  stacked << Scruffy::Layers::Line.new( ... )
  stacked.add(:bar, 'My Bar', [...])
end

The initialize method passes itself to the block, and since stacked is a LayerContainer, layers can be added just as if they were being added to Graph.



25
26
27
28
29
# File 'lib/scruffy/layers/stacked.rb', line 25

def initialize(options={}, &block)
  super(options)

  block.call(self)    # Allow for population of data with a block during initialization.
end

Instance Method Details

#legend_dataObject

A stacked graph has many data sets. Return legend information for all of them.



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/scruffy/layers/stacked.rb', line 50

def legend_data
  if relevant_data?
    retval = []
    layers.each do |layer|
      retval << layer.legend_data
    end
    retval
  else
    nil
  end
end

#pointsObject

TODO, special points accessor



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/scruffy/layers/stacked.rb', line 63

def points
  longest_arr = layers.inject(nil) do |longest, layer|
    longest = layer.points if (longest.nil? || longest.size < layer.points.size)
  end
  
  summed_points = (0...longest_arr.size).map do |idx|
    layers.inject(nil) do |sum, layer|
      if sum.nil? && !layer.points[idx].nil?
        sum = layer.points[idx]
      elsif !layer.points[idx].nil?
        sum += layer.points[idx]
      end
      
      sum
    end
  end

  summed_points
end

#points=(val) ⇒ Object



83
84
85
# File 'lib/scruffy/layers/stacked.rb', line 83

def points=(val)
  throw ArgumentsError, "Stacked layers cannot accept points, only other layers."
end

#render(svg, options = {}) ⇒ Object

Overrides Base#render to fiddle with layers’ points to achieve a stacked effect.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/scruffy/layers/stacked.rb', line 32

def render(svg, options = {})
  #TODO ensure this works with new points
  current_points = points.dup
  
  layers.each do |layer|
    real_points = layer.points
    layer.points = current_points
    layer_options = options.dup
    layer_options[:color] = layer.preferred_color || layer.color || options[:theme].next_color          
    layer.render(svg, layer_options)
    options.merge(layer_options)
    layer.points = real_points
    
    layer.points.each_with_index { |val, idx| current_points[idx] -= val }
  end
end