|
1 | 1 | module Rubyplot |
2 | 2 | module Artist |
3 | 3 | class Legend < Artist::Base |
| 4 | + TOP_MARGIN = 2.5 |
| 5 | + BOTTOM_MARGIN = 2.5 |
| 6 | + # Space between the color box and the legend text. |
| 7 | + BOX_AND_TEXT_SPACE = 5.0 |
4 | 8 | attr_reader :legend_box_size, :font, :font_size, :font_color |
5 | | - |
6 | | - # text - [String] String containing name of this legend. |
7 | | - # colors - [String] String of corresponding color. |
8 | | - def initialize(axes, text:, color:,abs_x:,abs_y:) |
9 | | - super(axes.backend, abs_x, abs_y) |
| 9 | + |
| 10 | + def initialize(legend_box, axes, text:, color:,abs_x:,abs_y:) |
| 11 | + super(legend_box.backend, abs_x, abs_y) |
| 12 | + @legend_box = legend_box |
10 | 13 | @axes = axes |
11 | 14 | @text = text |
12 | 15 | @color = color |
13 | | - @legend_box_size = 20.0 # size of the color box of the legend. |
| 16 | + @legend_box_size = @legend_box.per_legend_height - |
| 17 | + (TOP_MARGIN + BOTTOM_MARGIN) # size of the color box of the legend. |
14 | 18 | @font_size = 20.0 |
15 | 19 | @font = @axes.font |
16 | 20 | @font_color = @axes.font_color |
17 | 21 | configure_legend_color_box |
18 | 22 | configure_legend_text |
19 | | - calculate_legend_size |
20 | | - calculate_offsets |
21 | 23 | end |
22 | 24 |
|
23 | 25 | def draw |
24 | | - draw_legend_text |
25 | | - draw_legend_color_indicator # FIXME: make a new Artist::Rectangle object. |
| 26 | + @legend_color_box.draw |
| 27 | + @text.draw |
26 | 28 | end |
27 | 29 |
|
28 | 30 | private |
29 | 31 |
|
30 | 32 | def configure_legend_color_box |
31 | | - |
| 33 | + @legend_color_box = Rubyplot::Artist::Rectangle.new( |
| 34 | + self, |
| 35 | + abs_x: @abs_x, |
| 36 | + abs_y: @abs_y + TOP_MARGIN, |
| 37 | + width: @legend_box_size, |
| 38 | + height: @legend_box_size, |
| 39 | + border_color: @color, |
| 40 | + fill_color: @color |
| 41 | + ) |
32 | 42 | end |
33 | 43 |
|
34 | 44 | def configure_legend_text |
35 | | - |
36 | | - end |
37 | | - |
38 | | - def draw_legend_text |
39 | | - scaled_width = @axes.geometry.raw_columns * @axes.scale |
40 | | - scaled_width = scaled_width >=1 ? scaled_width : 1 |
41 | | - @axes.backend.draw_text(@text, |
42 | | - font_color: @font_color, |
43 | | - font: @font, |
44 | | - pointsize: @font_size * @axes.scale, |
45 | | - stroke: 'transparent', |
46 | | - width: scaled_width, |
47 | | - height: 1.0, |
48 | | - x: @current_x_offset + (@legend_box_size * 1.7), |
49 | | - y: @current_y_offset |
50 | | - ) |
51 | | - end |
52 | | - |
53 | | - def draw_legend_color_indicator |
54 | | - @axes.backend.draw_rectangle(x1: @current_x_offset, |
55 | | - y1: @current_y_offset - @legend_box_size/2.0, |
56 | | - x2: @current_x_offset + @legend_box_size, |
57 | | - y2: @current_y_offset + @legend_box_size/2.0, |
58 | | - color: @color, |
59 | | - stroke: 'transparent' |
60 | | - ) |
61 | | - end |
62 | | - |
63 | | - # FIXME: should work for multiple legeuidends. |
64 | | - def calculate_offsets |
65 | | - @current_x_offset = (@axes.geometry.raw_columns - |
66 | | - @label_widths.first.inject(:+))/2 |
67 | | - @current_y_offset = if @axes.geometry.legend_at_bottom |
68 | | - @axes.graph_height + @axes.title_margin |
69 | | - else |
70 | | - if @axes.geometry.hide_title |
71 | | - @axes.geometry.top_margin + @axes.title_margin |
72 | | - else |
73 | | - @axes.geometry.top_margin + |
74 | | - @axes.title_margin + @axes.title_caps_height |
75 | | - end |
76 | | - end |
77 | | - end |
78 | | - |
79 | | - def calculate_legend_size |
80 | | - # FIXME: below array consists of two arrays. If the legend overflows into another line, |
81 | | - # it removes the element from the first array and put it in the second array. |
82 | | - # so basically first array is for legends which have not overflowed and the second |
83 | | - # is one which have. possibly rethink this data structure. |
84 | | - @label_widths = [[]] # for calculating line wrap |
85 | | - width, _ = @axes.backend.get_text_width_height @text |
86 | | - label_width = width + @legend_box_size * 2.7 # FIXME: make value a global constant |
87 | | - @label_widths.last.push label_width |
88 | | - |
89 | | - if @label_widths.last.inject(:+) > (@axes.geometry.raw_columns * 0.9) |
90 | | - @label_widths.push [@label_widths.last.pop] |
91 | | - end |
| 45 | + @text = Rubyplot::Artist::Text.new( |
| 46 | + @text, |
| 47 | + self, |
| 48 | + abs_x: @abs_x + @legend_box_size + BOX_AND_TEXT_SPACE, |
| 49 | + abs_y: @legend_color_box.abs_y + @legend_box_size - 2.5, |
| 50 | + font: @font, |
| 51 | + color: @font_color, |
| 52 | + pointsize: @font_size |
| 53 | + ) |
92 | 54 | end |
93 | 55 | end # class Legend |
94 | 56 | end # class Artist |
|
0 commit comments