Class: UnicodePlot::GridCanvas

Inherits:
Plot
  • Object
show all
Defined in:
lib/unicode_plot/lineplot.rb

Direct Known Subclasses

Lineplot

Constant Summary collapse

MIN_WIDTH =
5
DEFAULT_WIDTH =
40
MIN_HEIGHT =
2
DEFAULT_HEIGHT =
15

Constants inherited from Plot

Plot::COLOR_CYCLE, Plot::DEFAULT_BORDER, Plot::DEFAULT_MARGIN, Plot::DEFAULT_PADDING

Constants included from StyledPrinter

StyledPrinter::COLOR_DECODE, StyledPrinter::COLOR_ENCODE, StyledPrinter::DISABLE_TEXT_STYLE, StyledPrinter::TEXT_COLORS

Instance Attribute Summary

Attributes inherited from Plot

#border, #colors_deco, #colors_left, #colors_right, #decorations, #labels_left, #labels_right, #margin, #padding, #title, #xlabel, #ylabel

Instance Method Summary collapse

Methods inherited from Plot

#annotate!, #annotate_row!, #next_color, #render, #show_labels?, #title_given?, #to_s, #xlabel_given?, #ylabel_given?, #ylabel_length

Methods included from StyledPrinter

#color?, #print_color, #print_styled

Constructor Details

#initialize(x, y, canvas, width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT, xlim: [0, 0], ylim: [0, 0], grid: true, **kw) ⇒ GridCanvas

Returns a new instance of GridCanvas.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/unicode_plot/lineplot.rb', line 10

def initialize(x, y, canvas,
               width: DEFAULT_WIDTH,
               height: DEFAULT_HEIGHT,
               xlim: [0, 0], 
               ylim: [0, 0],
               grid: true,
               **kw)
  unless xlim.length == 2 && ylim.length == 2
    raise ArgumentError, "xlim and ylim must be 2-length arrays"
  end
  width = [width, MIN_WIDTH].max
  height = [height, MIN_HEIGHT].max
  min_x, max_x = extend_limits(x, xlim)
  min_y, max_y = extend_limits(y, ylim)
  origin_x = min_x
  origin_y = min_y
  plot_width = max_x - origin_x
  plot_height = max_y - origin_y
  @canvas = Canvas.create(canvas, width, height,
                          origin_x: origin_x,
                          origin_y: origin_y,
                          plot_width: plot_width,
                          plot_height: plot_height)
  super(**kw)

  min_x_str = (roundable?(min_x) ? min_x.round : min_x).to_s
  max_x_str = (roundable?(max_x) ? max_x.round : max_x).to_s
  min_y_str = (roundable?(min_y) ? min_y.round : min_y).to_s
  max_y_str = (roundable?(max_y) ? max_y.round : max_y).to_s

  annotate_row!(:l, 0, max_y_str, color: :light_black)
  annotate_row!(:l, height-1, min_y_str, color: :light_black)
  annotate!(:bl, min_x_str, color: :light_black)
  annotate!(:br, max_x_str, color: :light_black)

  if grid
    if min_y < 0 && 0 < max_y
      step = plot_width.fdiv(width * @canvas.x_pixel_per_char - 1)
      min_x.step(max_x, by: step) do |i|
        @canvas.point!(i, 0, :normal)
      end
    end
    if min_x < 0 && 0 < max_x
      step = plot_height.fdiv(height * @canvas.y_pixel_per_char - 1)
      min_y.step(max_y, by: step) do |i|
        @canvas.point!(0, i, :normal)
      end
    end
  end
end

Instance Method Details

#ceil_neg_log10(x) ⇒ Object



141
142
143
144
145
146
147
# File 'lib/unicode_plot/lineplot.rb', line 141

def ceil_neg_log10(x)
  if roundable?(-Math.log10(x))
    (-Math.log10(x)).ceil
  else
    (-Math.log10(x)).floor
  end
end

#extend_limits(values, limits) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/unicode_plot/lineplot.rb', line 97

def extend_limits(values, limits)
  mi, ma = limits.minmax.map(&:to_f)
  if mi == 0 && ma == 0
    mi, ma = values.minmax.map(&:to_f)
  end
  diff = ma - mi
  if diff == 0
    ma = mi + 1
    mi = mi - 1
  end
  if limits == [0, 0]
    plotting_range_narrow(mi, ma)
  else
    [mi, ma]
  end
end

#lines!(x, y, color) ⇒ Object



89
90
91
# File 'lib/unicode_plot/lineplot.rb', line 89

def lines!(x, y, color)
  @canvas.lines!(x, y, color)
end

#n_columnsObject



81
82
83
# File 'lib/unicode_plot/lineplot.rb', line 81

def n_columns
  @canvas.width
end

#n_rowsObject



77
78
79
# File 'lib/unicode_plot/lineplot.rb', line 77

def n_rows
  @canvas.height
end

#origin_xObject



61
62
63
# File 'lib/unicode_plot/lineplot.rb', line 61

def origin_x
  @canvas.origin_x
end

#origin_yObject



65
66
67
# File 'lib/unicode_plot/lineplot.rb', line 65

def origin_y
  @canvas.origin_y
end

#plot_heightObject



73
74
75
# File 'lib/unicode_plot/lineplot.rb', line 73

def plot_height
  @canvas.plot_height
end

#plot_widthObject



69
70
71
# File 'lib/unicode_plot/lineplot.rb', line 69

def plot_width
  @canvas.plot_width
end

#plotting_range_narrow(xmin, xmax) ⇒ Object



114
115
116
117
118
119
# File 'lib/unicode_plot/lineplot.rb', line 114

def plotting_range_narrow(xmin, xmax)
  diff = xmax - xmin
  xmax = round_up_subtick(xmax, diff)
  xmin = round_down_subtick(xmin, diff)
  [xmin.to_f, xmax.to_f]
end

#points!(x, y, color) ⇒ Object



85
86
87
# File 'lib/unicode_plot/lineplot.rb', line 85

def points!(x, y, color)
  @canvas.points!(x, y, color)
end


93
94
95
# File 'lib/unicode_plot/lineplot.rb', line 93

def print_row(out, row_index)
  @canvas.print_row(out, row_index)
end

#round_down_subtick(x, m) ⇒ Object



131
132
133
134
135
136
137
138
139
# File 'lib/unicode_plot/lineplot.rb', line 131

def round_down_subtick(x, m)
  if x == 0
    0.0
  elsif x > 0
    x.floor(ceil_neg_log10(m) + 1)
  else
    -(-x).ceil(ceil_neg_log10(m) + 1)
  end
end

#round_up_subtick(x, m) ⇒ Object



121
122
123
124
125
126
127
128
129
# File 'lib/unicode_plot/lineplot.rb', line 121

def round_up_subtick(x, m)
  if x == 0
    0.0
  elsif x > 0
    x.ceil(ceil_neg_log10(m) + 1)
  else
    -(-x).floor(ceil_neg_log10(m) + 1)
  end
end

#roundable?(x) ⇒ Boolean

Returns:

  • (Boolean)


149
150
151
# File 'lib/unicode_plot/lineplot.rb', line 149

def roundable?(x)
  x.to_i == x
end