Module: Scruffy::Helpers::LayerContainer

Included in:
Graph, Layers::Pie, Layers::Stacked
Defined in:
lib/scruffy/helpers/layer_container.rb

Overview

Scruffy::Helpers::LayerContainer

Author

Brasten Sager

Date

August 16th, 2006

Adds some common functionality to any object which needs to act as a container for graph layers. The best example of this is the Scruffy::Graph object itself, but this module is also used by Scruffy::Layer::Stacked.

Instance Method Summary collapse

Instance Method Details

#<<(*args, &block) ⇒ Object Also known as: add

Adds a Layer to the Graph/Container. Accepts either a list of arguments used to build a new layer, or a Scruffy::Layers::Base-derived object. When passing a list of arguments, all arguments are optional, but the arguments specified must be provided in a particular order: type (Symbol), title (String), points (Array), options (Hash).

Both #add and #<< can be used.

graph.add(:line, [100, 200, 150])     # Create and add an untitled line graph

graph << (:line, "John's Sales", [150, 100])    # Create and add a titled line graph

graph << Scruffy::Layers::Bar.new({...})   # Adds Bar layer to graph


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/scruffy/helpers/layer_container.rb', line 27

def <<(*args, &block)
  if args[0].kind_of?(Scruffy::Layers::Base)
    layers << args[0]
  else
    type = args.first.is_a?(Symbol) ? args.shift : @default_type
    title = args.shift if args.first.is_a?(String)
    
    # Layer handles PointContainer mixin, don't do it here
    points = [Array, Hash].include?(args.first.class) ? args.shift : []
    options = args.first.is_a?(Hash) ? args.shift : {}
    
    title ||= ''
    
    raise ArgumentError, 
            'You must specify a graph type (:area, :bar, :line, etc) if you do not have a default type specified.' if type.nil?
          
    class_name = "Scruffy::Layers::#{to_camelcase(type.to_s)}"
    layer_class = Kernel::module_eval(class_name)
    options = {:points => points, :title => title}.merge options
    layer = layer_class.new(options, &block)
    layers << layer
  end
  layer
end

#bottom_value(padding = nil) ⇒ Object

Returns the lowest value in any of this container’s layers.

If padding is set to :padded, a 15% padding is added below the lowest value. If the lowest value is greater than zero, then the padding will not cross the zero line, preventing negative values from being introduced into the graph purely due to padding.



78
79
80
81
82
83
84
85
86
# File 'lib/scruffy/helpers/layer_container.rb', line 78

def bottom_value(padding=nil) # :nodoc:
  botval = layers.inject(top_value) { |min, layer| (min = ((min > layer.bottom_value) ? layer.bottom_value : min)) unless layer.bottom_value.nil?; min }
  above_zero = (botval > 0)
  botval = (botval - ((top_value - botval) * 0.15))

  # Don't introduce negative values solely due to padding.
  # A user-provided value must be negative before padding will extend into negative values.
  (above_zero && botval < 0) ? 0 : botval
end

#layersObject

Layer Reader



61
62
63
# File 'lib/scruffy/helpers/layer_container.rb', line 61

def layers
  @layers ||= []
end

#layers=(val) ⇒ Object

Layer Writer



56
57
58
# File 'lib/scruffy/helpers/layer_container.rb', line 56

def layers=(val)
  @layers = val
end

#top_value(padding = nil) ⇒ Object

Returns the highest value in any of this container’s layers.

If padding is set to :padded, a 15% padding is added to the highest value.



68
69
70
71
# File 'lib/scruffy/helpers/layer_container.rb', line 68

def top_value(padding=nil) # :nodoc:
  topval = layers.inject(0) { |max, layer| (max = ((max < layer.top_value) ? layer.top_value : max)) unless layer.top_value.nil?; max }
  padding == :padded ? (topval - ((topval - bottom_value) * 0.15)) : topval
end