Skip to content

Commit 71d1f6d

Browse files
committed
WIP stacked bar
1 parent 9ec40c7 commit 71d1f6d

5 files changed

Lines changed: 139 additions & 55 deletions

File tree

lib/rubyplot/artist/axes.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,13 @@ def consolidate_plots
331331
@plots.delete_if { |p| p.is_a?(Rubyplot::Artist::Plot::Bar) }
332332
@plots << Rubyplot::Artist::Plot::MultiBars.new(self, bar_plots: bars)
333333
end
334+
335+
stacked_bars = @plots.grep(Rubyplot::Artist::Plot::StackedBar)
336+
if !stacked_bars.empty?
337+
@plots.delete_if { |p| p.is_a?(Rubyplot::Artist::Plot::StackedBar) }
338+
@plots << Rubyplot::Artist::Plot::MultiStackedBar.new(
339+
self, stacked_bars: stacked_bars)
340+
end
334341
end
335342

336343
# FIXME: replace x_range and y_range with XAxis::max/min_value and YAxis::max/min_value.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module Rubyplot
2+
module Artist
3+
module Plot
4+
class BarType < Artist::Plot::Base
5+
6+
def initialize(*)
7+
super
8+
@spacing_ratio = 0.1
9+
@abs_x_left = []
10+
@abs_y_left = []
11+
@rectangles = []
12+
end
13+
14+
def data y_values
15+
super(Array(0...(y_values.size)), y_values)
16+
end
17+
18+
def num_bars
19+
@data[:y_values].size
20+
end
21+
22+
def draw
23+
setup_bar_rectangles
24+
@rectangles.each(&:draw)
25+
end
26+
27+
protected
28+
29+
30+
end # class BarType
31+
end # module Plot
32+
end # module Artist
33+
end # module Rubyplot
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
module Rubyplot
2+
module Artist
3+
module Plot
4+
class MultiStackedBar < Artist::Plot::Base
5+
def initialize(*, stacked_bars:)
6+
super
7+
@stacked_bars = stacked_bars
8+
@x_min = @stacked_bars.map(&:x_min).min
9+
@y_min = @stacked_bars.map(&:y_min).min
10+
@x_max = @stacked_bars.map(&:x_max).max
11+
@y_max = @stacked_bars.map(&:y_max).max
12+
configure_plot_geometry_data
13+
configure_x_ticks
14+
end
15+
16+
def draw
17+
18+
end
19+
20+
private
21+
22+
def configure_plot_geometry_data
23+
@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
25+
@spacing_ratio = @stacked_bars[0].spacing_ratio
26+
@padding = @spacing_ratio * @max_slot_width
27+
@max_bars_width = @max_slot_width - @padding
28+
@num_max_stacks = @stacked_bars.size
29+
@stacked_bars.each_with_index do |bar, index|
30+
set_bar_dims bar, index
31+
end
32+
end
33+
34+
def configure_x_ticks
35+
36+
end
37+
38+
def set_bar_dims bar, plot_index
39+
bar.bar_width = @max_bars_width
40+
bar.num_bars.times do |i|
41+
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] =
44+
end
45+
end
46+
end # class StackedBar
47+
end # module Plot
48+
end # module Artist
49+
end # module Rubyplot
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module Rubyplot
2+
module Artist
3+
module Plot
4+
class StackedBar < Artist::Plot::Base
5+
# Ratio of the total avialable width that is left as padding space.
6+
attr_accessor :spacing_ratio
7+
# Array of X co-ordinates of the lower left corner of each stacked bar.
8+
attr_accessor :abs_x_left
9+
# Array of Y co-ordinates of the lower left corner of each stacked bar.
10+
attr_accessor :abs_y_left
11+
# Width in pixels of each bar.
12+
attr_accessor :bar_width
13+
14+
def initialize(*)
15+
super
16+
@spacing_ratio = 0.1
17+
@abs_x_left = []
18+
@abs_y_left = []
19+
end
20+
21+
def data y_values
22+
super(Array(0...(y_values.size)), y_values)
23+
end
24+
25+
def num_bars
26+
@data[:y_values].size
27+
end
28+
29+
def draw
30+
setup_bar_rectangles
31+
@rectangles.each(&:draw)
32+
end
33+
34+
private
35+
36+
def setup_bar_rectangles
37+
end
38+
end # class StackedBar
39+
end # module Plot
40+
end # module Artist
41+
end # module Rubyplot

spec/axes_spec.rb

Lines changed: 9 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,7 @@
2020
FileUtils.mkdir_p @temp_dir
2121
end
2222

23-
it "plots a single stacked bar graph with default colors" do
24-
fig = Rubyplot::Figure.new
25-
axes = fig.add_subplot 0,0
26-
axes.stacked_bar! do |p|
27-
p.data [25, 36, 86, 39]
28-
p.label = "moon"
29-
end
30-
axes.title = "net earnings in different months."
31-
axes.x_ticks = {
32-
0 => 'Jan',
33-
1 => 'Feb',
34-
2 => 'March',
35-
3 => 'April',
36-
4 => 'May',
37-
5 => 'June',
38-
6 => 'July',
39-
7 => 'August',
40-
8 => 'September',
41-
9 => 'October',
42-
10 => 'November',
43-
11 => 'December'
44-
}
45-
46-
file = "/#{Rubyplot.backend}_simple_stacked_bar.png"
47-
fig.write(@temp_dir + file)
48-
49-
#expect("temp/stacked_bar" + file).to eq_image("fixtures/stacked_bar" + file)
50-
end
51-
52-
it "plots multiple stacked bar graphs with default colors" do
23+
it "plots multiple stacked bar graphs with default colors", hell: true do
5324
fig = Rubyplot::Figure.new
5425
axes = fig.add_subplot 0,0
5526
[
@@ -63,20 +34,8 @@
6334
end
6435
end
6536
axes.title = "net earnings in different months."
66-
axes.x_ticks = {
67-
0 => 'Jan',
68-
1 => 'Feb',
69-
2 => 'March',
70-
3 => 'April',
71-
4 => 'May',
72-
5 => 'June',
73-
6 => 'July',
74-
7 => 'August',
75-
8 => 'September',
76-
9 => 'October',
77-
10 => 'November',
78-
11 => 'December'
79-
}
37+
axes.x_ticks = ['Jan', 'Feb', 'March', 'April', 'May', 'June', 'July',
38+
'August', 'September', 'October', 'November', 'December']
8039

8140
file = "/#{Rubyplot.backend}_multiple_stacked_bar.png"
8241
fig.write(@temp_dir + file)
@@ -85,14 +44,14 @@
8544
end
8645

8746
it "plots stacked bar in a small size" do
88-
fig = Rubyplot::Figure.new
47+
fig = Rubyplot::Figure.new(height: 400, width: 400)
8948
axes = fig.add_subplot 0,0
9049
[
9150
["Car", [25, 36, 86, 39]],
9251
["Bus", [80, 54, 67, 54]],
9352
["Train", [22, 29, 35, 38]]
9453
].each do |label, data|
95-
axes.stacked_bar!(400) do |p|
54+
axes.stacked_bar! do |p|
9655
p.data data
9756
p.label = label
9857
end
@@ -113,29 +72,24 @@
11372
FileUtils.mkdir_p @temp_dir
11473
end
11574

116-
it "plots a single dot plot" do
75+
skip "plots a single dot plot" do
11776
fig = Rubyplot::Figure.new
11877
axes = fig.add_subplot 0,0
11978
axes.dot! do |p|
12079
p.data [0,5,8,15]
12180
p.label = "Car"
12281
p.color = :maroon
123-
p.minimum_value = 0 # FIXME: change this!
12482
end
125-
axes.y_ticks = {
126-
0 => '5/6',
127-
1 => '5/15',
128-
2 => '5/24',
129-
3 => '5/30'
130-
}
83+
axes.num_y_ticks = 4
84+
axes.y_ticks = ['5/6', '5/15', '5/24', '5/30']
13185

13286
file = "/#{Rubyplot.backend}_simple_dot.png"
13387
fig.write(@temp_dir + file)
13488

13589
#expect("temp/dot" + file).to eq_image("fixtures/dot" + file)
13690
end
13791

138-
it "plots multiple dot plots" do
92+
skip "plots multiple dot plots" do
13993
fig = Rubyplot::Figure.new
14094
axes = fig.add_subplot 0,0
14195
[

0 commit comments

Comments
 (0)