Class: Gruff::StackedBar

Inherits:
Base
  • Object
show all
Includes:
BarValueLabelMixin, StackedMixin
Defined in:
lib/gruff/stacked_bar.rb

Overview

Here’s how to set up a Gruff::StackedBar.

g = Gruff::StackedBar.new
g.title = 'StackedBar Graph'
g.data :Art, [0, 5, 8, 15]
g.data :Philosophy, [10, 3, 2, 8]
g.data :Science, [2, 15, 8, 11]
g.write('stacked_bar.png')

Direct Known Subclasses

AccumulatorBar

Constant Summary

Constants inherited from Base

Base::DEFAULT_MARGIN, Base::DEFAULT_TARGET_WIDTH, Base::LABEL_MARGIN, Base::LEGEND_MARGIN

Instance Attribute Summary collapse

Attributes inherited from Base

#bold_title, #bottom_margin, #center_labels_over_point, #colors, #font_color, #has_left_labels, #hide_legend, #hide_line_markers, #hide_line_numbers, #hide_title, #label_max_size, #label_stagger_height, #label_truncation_style, #labels, #left_margin, #legend_at_bottom, #legend_box_size, #legend_font_size, #legend_margin, #marker_color, #marker_font_size, #marker_shadow_color, #maximum_value, #minimum_value, #no_data_message, #right_margin, #sort, #sorted_drawing, #title, #title_font, #title_font_size, #title_margin, #top_margin, #use_data_label, #x_axis_increment, #x_axis_label, #y_axis_increment, #y_axis_label

Instance Method Summary collapse

Methods inherited from Base

#add_color, #data, #font=, #initialize, #margins=, #replace_colors, #theme=, #theme_37signals, #theme_greyscale, #theme_keynote, #theme_odeo, #theme_pastel, #theme_rails_keynote, #to_blob, #to_image, #write

Constructor Details

This class inherits a constructor from Gruff::Base

Instance Attribute Details

#bar_spacing=(value) ⇒ Object (writeonly)

Spacing factor applied between bars.



18
19
20
# File 'lib/gruff/stacked_bar.rb', line 18

def bar_spacing=(value)
  @bar_spacing = value
end

#hide_labels=(value) ⇒ Object (writeonly)

Prevent drawing of column labels below a stacked bar graph. Default is false.



32
33
34
# File 'lib/gruff/stacked_bar.rb', line 32

def hide_labels=(value)
  @hide_labels = value
end

#label_formatting=(value) ⇒ Object (writeonly)

Set the number output format for labels using sprintf. Default is “%.2f”.



25
26
27
# File 'lib/gruff/stacked_bar.rb', line 25

def label_formatting=(value)
  @label_formatting = value
end

#segment_spacing=(value) ⇒ Object (writeonly)

Number of pixels between bar segments.



21
22
23
# File 'lib/gruff/stacked_bar.rb', line 21

def segment_spacing=(value)
  @segment_spacing = value
end

#show_labels_for_bar_values=(value) ⇒ Object (writeonly)

Output the values for the bars on a bar graph. Default is false.



29
30
31
# File 'lib/gruff/stacked_bar.rb', line 29

def show_labels_for_bar_values=(value)
  @show_labels_for_bar_values = value
end

Instance Method Details

#drawObject

Draws a bar graph, but multiple sets are stacked on top of each other.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/gruff/stacked_bar.rb', line 45

def draw
  calculate_maximum_by_stack
  super
  return unless data_given?

  # Setup spacing.
  #
  # Columns sit stacked.
  bar_width = @graph_width / column_count.to_f
  padding = (bar_width * (1 - @bar_spacing)) / 2

  height = Array.new(column_count, 0)
  bar_value_label = BarValueLabel.new(column_count, bar_width)

  store.norm_data.each_with_index do |data_row, row_index|
    data_row.points.each_with_index do |data_point, point_index|
      next if data_point == 0

      # Use incremented x and scaled y
      left_x = @graph_left + (bar_width * point_index) + padding
      left_y = @graph_top + (@graph_height -
                             data_point * @graph_height -
                             height[point_index]) + @segment_spacing
      right_x = left_x + bar_width * @bar_spacing
      right_y = @graph_top + @graph_height - height[point_index]

      # update the total height of the current stacked bar
      height[point_index] += (data_point * @graph_height)

      rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
      rect_renderer.render(left_x, left_y, right_x, right_y)

      # Calculate center based on bar_width and current row
      label_center = left_x + bar_width * @bar_spacing / 2.0
      draw_label(label_center, point_index)

      bar_value_label.coordinates[point_index] = [left_x, left_y, right_x, right_y]
      bar_value_label.values[point_index] += store.data[row_index].points[point_index]
    end
  end

  if @show_labels_for_bar_values
    bar_value_label.prepare_rendering(@label_formatting) do |x, y, text|
      draw_value_label(x, y, text, true)
    end
  end
end