Class: RVGP::Plot::Gnuplot::ChartBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/rvgp/plot/gnuplot.rb

Overview

This base class offers some helpers, used by our Element classes to handle common options, and keep things DRY.

Direct Known Subclasses

AreaChart, ColumnAndLineChart

Constant Summary collapse

ONE_MONTH_IN_SECONDS =

30 days

2_592_000

Instance Method Summary collapse

Constructor Details

#initialize(opts, gnuplot) ⇒ ChartBuilder

Create a chart

Parameters:

Options Hash (opts):

  • :domain (Symbol)

    This option specifies the ‘type’ of the domain. Currently, the only supported type is :monthly

  • :xrange_start (Integer, Date)

    The plot domain origin, either the number 1, or a date

  • :xrange_end (Date)

    The end of the plot domain

  • :axis (Hash<Symbol, String>)

    Axis labels. At the moment, :bottom and :left are supported keys.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rvgp/plot/gnuplot.rb', line 91

def initialize(opts, gnuplot)
  # TODO: At some point, we probably want to support inverting the key order.
  #       which, as best I can tell, will involve writing a 'fake' chart,
  #       that's not displayed. But which will create a key, which is
  #       displayed, in the order we want
  @gnuplot = gnuplot

  if opts[:domain]
    @domain = opts[:domain].to_sym
    case @domain
    when :monthly
      # This is mostly needed, because gnuplot doesn't always do the best
      # job of automatically detecting the domain bounds...
      gnuplot.set 'xdata', 'time'
      gnuplot.set 'xtics', ONE_MONTH_IN_SECONDS

      dates = gnuplot.column(0).map { |xtic| Date.strptime xtic, '%m-%y' }.sort
      is_multiyear = dates.first.year != dates.last.year

      unless dates.empty?
        opts[:xrange_start] ||= is_multiyear ? dates.first : Date.new(dates.first.year, 1, 1)
        opts[:xrange_end] ||= is_multiyear ? dates.last : Date.new(dates.last.year, 12, 31)
      end
    else
      raise StandardError, format('Unsupported domain %s', @domain.inspect)
    end
  end

  gnuplot.set 'xrange', format_xrange(opts) if xrange? opts
  gnuplot.set 'xlabel', opts[:axis][:bottom] if opts[:axis] && opts[:axis][:bottom]
  gnuplot.set 'ylabel', opts[:axis][:left] if opts[:axis] && opts[:axis][:left]
end

Instance Method Details

#format_num(num) ⇒ String

Returns the column number specifier, a string, for use by Plot#plot_command, when building charts. In some charts, this is as simple as num + 1. In others, this line can contain more complex gnuplot code.

Returns:

  • (String)

    Returns the gnuplot formatted series_num, for the series at position num.



135
136
137
# File 'lib/rvgp/plot/gnuplot.rb', line 135

def format_num(num)
  (num + 1).to_s
end

#series_range(num_cols) ⇒ Enumerator

Returns a enumerator, for use by Plot#plot_command, when building charts. Mostly, this method is what determines if the series are started from one, going up to numcols. Or, are started from num_cols, and go down to one.

Returns:

  • (Enumerator)

    An enumerator to progress through the chart’s series



128
129
130
# File 'lib/rvgp/plot/gnuplot.rb', line 128

def series_range(num_cols)
  reverse_series_range? ? (num_cols - 1).downto(1) : 1.upto(num_cols - 1)
end