Skip to content

Commit 0d8982b

Browse files
committed
WIP rethinking ratios and proportions
1 parent 722ada5 commit 0d8982b

6 files changed

Lines changed: 114 additions & 63 deletions

File tree

CONTRIBUTING.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Developer notes
2+
3+
## Co-ordinate system
4+
Each Artist contains a `(abs_x, abs_y)` pair that denotes the absolute position of the
5+
Artist on the canvas. For `Figure` and `Axes` this pair denotes the top left corner.
6+
7+
During the data collection phase (anything before calling `draw`), all the co-ordinates
8+
exist in the form of ratios. The absolute co-ordinates are calculated during the draw
9+
phase. Therefore there should be no code except in the `draw` methods where actual
10+
co-ordinates are calcualted.
11+
12+
Varible naming conventions:
13+
* All values that are absolute values will be prefixed with `abs_`.
14+
* Variables relating to positioning of the graph other than the absolute
15+
variables are always ratios.

lib/rubyplot/artist.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require_relative 'artist/base'
2+
require_relative 'artist/figure'
23
require_relative 'artist/legend'
34
require_relative 'artist/line2d'
45
require_relative 'artist/tick'

lib/rubyplot/artist/axes.rb

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@ class Axes < Base
3838
attr_reader :figure
3939
# Array of plots contained in this Axes.
4040
attr_reader :plots
41-
# Position of this Axes object in the subplots.
42-
attr_reader :position
43-
# Width in pixels of the graph
44-
attr_reader :width
45-
# Height in pixels of the graph
46-
attr_reader :height
4741
# data variables for something
4842
attr_reader :raw_rows
4943
attr_reader :backend
@@ -54,19 +48,12 @@ class Axes < Base
5448

5549
attr_reader :label_stagger_height
5650
# FIXME: possibly disposable attrs
57-
attr_reader :graph_height, :title_caps_height, :graph_bottom
58-
# left margin of the actual plot
59-
attr_reader :graph_left
60-
# top margin of the actual plot to leave space for the title
61-
attr_reader :graph_top
62-
# total width of the actual graph
63-
attr_reader :graph_width
51+
attr_reader :title_caps_height
52+
attr_reader :top_spacing
6453

6554
# @param figure [Rubyplot::Figure] Figure object to which this Axes belongs.
66-
# @param position [Integer] Position among the rest of the Axes in the Figure.
67-
def initialize figure, width, height, position
55+
def initialize figure
6856
@figure = figure
69-
@position = position
7057

7158
@x_title = ''
7259
@y_title = ''
@@ -86,8 +73,6 @@ def initialize figure, width, height, position
8673
@y_axis_padding = :default
8774
@x_ticks = {}
8875
@plots = []
89-
@width = width
90-
@height = height
9176

9277
@raw_rows = @width * (@height/@width)
9378

@@ -162,6 +147,25 @@ def stacked_bar! *args, &block
162147
def write file_name
163148
@plots[0].write file_name
164149
end
150+
151+
# Absolute X co-ordinate of the Axes. Top left corner.
152+
def abs_x
153+
@figure.top_spacing * @figure.abs_height + @figure.abs_x
154+
end
155+
156+
# Absolute Y co-ordinate of the Axes. Top left corner.
157+
def abs_y
158+
@figure.top_spacing * @figure.abs_height + @figure.abs_y
159+
end
160+
# Absolute width of the Axes in pixels.
161+
def abs_width
162+
(@figure.left_spacing + @figure.right_spacing) * @figure.abs_width
163+
end
164+
165+
# Absolute height of the Axes in pixels.
166+
def abs_height
167+
(@figure.top_spacing + @figure.bottom_spacing) * @figure.abs_height
168+
end
165169

166170
private
167171

@@ -241,7 +245,7 @@ def setup_default_theme
241245
# * X/Y offsets
242246
def setup_drawing
243247
calculate_spread
244-
normalize
248+
normalize # FIXME: maybe doesnt need to go here.
245249
setup_graph_measurements
246250
end
247251

@@ -267,6 +271,11 @@ def normalize
267271
# It calcuates the measurments in pixels to figure out the positioning
268272
# gap pixels of Legends, Labels and Titles from the picture edge.
269273
def setup_graph_measurements
274+
calculate_font_spaces
275+
calculate_top_spacing
276+
calculate_left_spacing
277+
calculate_bottom_spacing
278+
calculate_right_spacing
270279
@marker_caps_height = @backend.caps_height @font, @marker_font_size
271280
@title_caps_height = @geometry.hide_title || @title.nil? ? 0 :
272281
@backend.caps_height(@font, @title_font_size) * @title.lines.to_a.size
@@ -328,6 +337,12 @@ def setup_graph_measurements
328337
@graph_height = @graph_bottom - @graph_top
329338
end
330339

340+
# Consider the various fonts that in use in this graph and calculate the
341+
# ratio of the space that they will occupy w.r.t the Axes.
342+
def calculate_font_spaces
343+
344+
end
345+
331346
# Return a formatted string representing a number value that should be
332347
# printed as a label.
333348
def label_string(value, increment)

lib/rubyplot/artist/base.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module Rubyplot
22
module Artist
33
class Base
44
attr_reader :backend
5+
# Absolute X co-ordinate of this Aritist on the canvas.
6+
attr_reader :abs_x
7+
# Absolute Y co-ordinate of this Aritist on the canvas.
8+
attr_reader :abs_y
59
end
610
end
711
end

lib/rubyplot/artist/figure.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module Rubyplot
2+
module Artist
3+
class Figure < Artist::Base
4+
DEFAULT_TARGET_WIDTH = 800
5+
6+
# Title on the figure.
7+
attr_reader :title
8+
# Number of Axes objects in the rows.
9+
attr_reader :nrows
10+
# Number of Axes objects in the cols.
11+
attr_reader :ncols
12+
# Total width of the Figure in pixels.
13+
attr_reader :abs_width
14+
# Total height of the Figure in pixels.
15+
attr_reader :abs_height
16+
# Ratio of the total height that is the spacing between the top of the
17+
# Figure and the top of the Axes.
18+
attr_reader :top_spacing
19+
# Ratio of the total width that is the spacing between the left of the
20+
# Figure and the left of the Axes.
21+
attr_reader :left_spacing
22+
# Ratio of the total width that is the spacing between the right of the
23+
# Figure and the right of the Axes.
24+
attr_reader :right_spacing
25+
# Ratio of the total width that is the spacing between the bottom of the
26+
# Figure and the bottom of the Axes.
27+
attr_reader :bottom_spacing
28+
def initialize
29+
@title = ''
30+
@nrows = 1
31+
@ncols = 1
32+
@backend = Rubyplot::Backend::MagickWrapper.new
33+
@abs_width = DEFAULT_TARGET_WIDTH
34+
@abs_height = @width * 0.75
35+
@abs_x = 0
36+
@abs_y = 0
37+
@top_spacing = 0.05
38+
@bottom_spacing = 0.05
39+
@left_spacing = 0.05
40+
@right_spacing = 0.05
41+
add_subplots @nrows, @ncols
42+
end
43+
44+
def add_subplots nrows, ncols
45+
@subplots = Array.new(nrows) { Array.new(ncols) { nil } }
46+
end
47+
48+
def add_subplot nrow, ncol
49+
@subplots[nrow][ncol] = Rubyplot::Artist::Axes.new(self)
50+
end
51+
52+
def write file_name
53+
@subplots.each { |i| i.each { |j| j.draw } }
54+
@backend.write(file_name)
55+
end
56+
end # class Figure
57+
end # module Artist
58+
end # module Rubyplot

lib/rubyplot/figure.rb

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,2 @@
1-
module Rubyplot
2-
class Figure
3-
DEFAULT_TARGET_WIDTH = 800
4-
5-
# Title on the figure.
6-
attr_reader :title
7-
# Number of Axes objects in the rows.
8-
attr_reader :nrows
9-
# Number of Axes objects in the cols.
10-
attr_reader :ncols
11-
# Drawing backend.
12-
attr_reader :backend
13-
# Total width of the Figure in pixels.
14-
attr_reader :width
15-
# Total height of the Figure in pixels.
16-
attr_reader :height
17-
18-
def initialize
19-
@title = ''
20-
@nrows = 1
21-
@ncols = 1
22-
@backend = Rubyplot::Backend::MagickWrapper.new
23-
@width = DEFAULT_TARGET_WIDTH
24-
@height = @width * 0.75
25-
@x = 0
26-
@y = 0
27-
add_subplots @nrows, @ncols
28-
end
29-
30-
def add_subplots nrows, ncols
31-
@subplots = Array.new(nrows) { Array.new(ncols) { nil } }
32-
end
33-
34-
def add_subplot nrow, ncol
35-
@subplots[nrow][ncol] = Rubyplot::Artist::Axes.new(
36-
self, @width, @height, nrow*@ncols + ncol)
37-
end
38-
39-
def write file_name
40-
@subplots.each { |i| i.each { |j| j.draw } }
41-
@backend.write(file_name)
42-
end
43-
end # class Figure
44-
end # module Rubyplot
1+
# Alias meant for easy class initialization without knowing Artist details.
2+
Rubyplot::Figure = Rubyplot::Artist::Figure

0 commit comments

Comments
 (0)