@@ -2,26 +2,41 @@ module Rubyplot
22 module Artist
33 module Plot
44 class MultiStackedBar < Artist ::Plot ::Base
5- def initialize ( *, stacked_bars :)
6- super
5+ def initialize ( *args , stacked_bars :)
6+ super ( args [ 0 ] )
77 @stacked_bars = stacked_bars
88 @x_min = @stacked_bars . map ( &:x_min ) . min
99 @y_min = @stacked_bars . map ( &:y_min ) . min
1010 @x_max = @stacked_bars . map ( &:x_max ) . max
1111 @y_max = @stacked_bars . map ( &:y_max ) . max
12+ reset_axes_ranges
13+ renormalize_data
1214 configure_plot_geometry_data
1315 configure_x_ticks
1416 end
1517
1618 def draw
17-
19+ @stacked_bars . each ( & :draw )
1820 end
1921
2022 private
2123
24+ def reset_axes_ranges
25+ @axes . y_range [ 0 ] = 0
26+ @axes . x_range [ 0 ] = 0
27+ end
28+
29+ # Normalize data in the stacked bar plot w.r.t each other and new X & Y ranges.
30+ def renormalize_data
31+ @stacked_bars . each do |p |
32+ p . normalize
33+ p . renormalize @stacked_bars . size
34+ end
35+ end
36+
2237 def configure_plot_geometry_data
2338 @num_max_slots = @stacked_bars . map { |bar | bar . num_bars } . max
24- @max_slot_width = ( @axes . x_axis . abs_x2 - @axes . x_axis . abs_x1 ) . abs / @num_max_slots
39+ @max_slot_width = @axes . x_axis . length / @num_max_slots
2540 @spacing_ratio = @stacked_bars [ 0 ] . spacing_ratio
2641 @padding = @spacing_ratio * @max_slot_width
2742 @max_bars_width = @max_slot_width - @padding
@@ -32,15 +47,31 @@ def configure_plot_geometry_data
3247 end
3348
3449 def configure_x_ticks
35-
50+ @axes . num_x_ticks = @num_max_slots
51+ labels = @axes . x_ticks || Array . new ( @num_max_slots ) { |i | i . to_s }
52+ if labels . size != @axes . num_x_ticks
53+ labels = labels [ 0 ...@axes . num_x_ticks ]
54+ end
55+ @axes . x_ticks = labels . map . with_index do |label , i |
56+ Rubyplot ::Artist ::XTick . new (
57+ @axes ,
58+ abs_x : @axes . abs_x + @axes . y_axis_margin + i * @max_slot_width + @max_slot_width / 2 ,
59+ abs_y : @axes . origin [ 1 ] ,
60+ label : label ,
61+ length : 6 ,
62+ label_distance : 10
63+ )
64+ end
3665 end
3766
3867 def set_bar_dims bar , plot_index
3968 bar . bar_width = @max_bars_width
69+ plots_below = @stacked_bars [ 0 ...plot_index ]
4070 bar . num_bars . times do |i |
71+ pedestal_height = plots_below . map { |p | p . member_height ( i ) } . inject ( :+ ) || 0
4172 bar . abs_x_left [ i ] = @axes . abs_x + @axes . y_axis_margin +
42- i * @max_bars_width + @padding / 2
43- bar . abs_y_left [ i ] =
73+ i * @max_slot_width + @padding / 2
74+ bar . abs_y_left [ i ] = ( @axes . abs_y + @axes . y_axis . length ) - pedestal_height
4475 end
4576 end
4677 end # class StackedBar
0 commit comments