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, #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_count, #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, #initialize, #margins=, #replace_colors, #theme=, #theme_37signals, #theme_greyscale, #theme_keynote, #theme_odeo, #theme_pastel, #theme_rails_keynote, #to_blob, #write

Constructor Details

This class inherits a constructor from Gruff::Base

Instance Attribute Details

#bar_spacingObject

Spacing factor applied between bars.



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

def bar_spacing
  @bar_spacing
end

#label_formattingObject

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



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

def label_formatting
  @label_formatting
end

#segment_spacingObject

Number of pixels between bar segments.



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

def segment_spacing
  @segment_spacing
end

#show_labels_for_bar_valuesObject

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



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

def show_labels_for_bar_values
  @show_labels_for_bar_values
end

Instance Method Details

#drawObject

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



43
44
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
92
93
94
# File 'lib/gruff/stacked_bar.rb', line 43

def draw
  calculate_maximum_by_stack
  super
  return unless data_given?

  # Setup spacing.
  #
  # Columns sit stacked.
  @bar_spacing ||= 0.9
  @segment_spacing ||= 2

  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

  Gruff::Renderer.finish
end