Class: Charting::Highcharts::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/ar_to_chart/charting/highcharts/base.rb

Overview

Base class for chart renderers. Chart renderers should subclass rather than instantiate Base directly.

Direct Known Subclasses

Area, Pie

Constant Summary collapse

WEEKEND =

The days of the week that are the weekend (Sun, Sat)

[0,6]
AXIS_START_UNIT =

Where highcharts starts its x-axis in axis units

0.5
MAX_X_LABELS =

Display no more than this number of category labels

10
DEFAULT_OPTIONS =
{

}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data_source, category_column, data_columns, options = {}) ⇒ Base

Initialize a new chart.

Parameters

data_source:      Array of ActiveRecord objects for rendering as a chart
category_column:  The name of the column which is the category (X) axis
data_columns:     The name (or array of names) of the columns which are
                  the data series.
options:          Options hash

Options

title:            Chart title (default: none)
subtitle:         Subtitle (default: none)
x_axis_title:     X-Axis title (default: none)
y_axis_title:     Y-Axis title (defualt: none)
x_step:           X-Axis labels are printed every 'x' steps
                  Requires Highcharts beta 2.1
x_plot_bands:     Plot bands in Ruby Hash format according to the
                  Highcharts documented format
linearize:        Linearize the data to ensure continuous
                  series on the X-Axis.
weekend_plot_bands:   Creates plot-bands for the weekends (Saturday/Sunday)
container:        DOM id for the container div.  Default is to generate one.


40
41
42
43
44
45
46
47
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 40

def initialize(data_source, category_column, data_columns, options = {})
  @options          = DEFAULT_OPTIONS.merge(options)
  @category_column  = category_column
  @data_columns     = data_columns
  @data_source      = data_source
  @data_source      = linearize if @options.delete(:linearize)       
  @options[:x_step] ||= (@data_source.size.to_f / MAX_X_LABELS.to_f).round
end

Instance Attribute Details

#category_columnObject (readonly)

Returns the value of attribute category_column.



6
7
8
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 6

def category_column
  @category_column
end

#data_columnsObject (readonly)

Returns the value of attribute data_columns.



6
7
8
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 6

def data_columns
  @data_columns
end

#data_sourceObject (readonly)

Returns the value of attribute data_source.



6
7
8
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 6

def data_source
  @data_source
end

#optionsObject (readonly)

Returns the value of attribute options.



6
7
8
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 6

def options
  @options
end

Instance Method Details

#categoriesObject

Define in concrete subclass



66
67
68
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 66

def categories
  nil
end

#chart_optionsObject



49
50
51
52
53
54
55
56
57
58
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 49

def chart_options
  {
    :title        => options[:title],
    :subtitle     => options[:subtitle],
    :x_axis       => options[:x_axis_title], 
    :y_axis       => options[:y_axis_title], 
    :x_step       => options[:x_step],
    :x_plot_bands => weekend_plot_bands
  }
end

#chart_typeObject



86
87
88
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 86

def chart_type
  @chart_type ||= self.class.name.split('::').last.downcase
end

#containerObject



90
91
92
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 90

def container
  options[:container]
end

#linearizeObject

When we retrieve datat from the data base it may have gaps where not results are available. For charting we want to have a linearized series of data so here we plug the gaps.

Punt that the categeory column tells us enough to know what the data should be.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 110

def linearize
  return data_source unless range = Charting::Period.range_from(options)
  range = data_source.first[category_column]..range.last if range.first > data_source.first[category_column]
  klass = data_source.first.class
  index = 0
  range.inject(Array.new) do |linear_data, data_point|
    if data_source[index] && data_source[index][category_column] == data_point
      linear_data << data_source[index]
      index += 1
    else
      new_row = klass.new(category_column => data_point)
      data_columns.each {|column| new_row[column] = 0 }
      yield new_row if block_given?
      linear_data << new_row
    end
    linear_data
  end
end

#seriesObject

Define in concrete subclass



61
62
63
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 61

def series
  nil
end

#series_name(column) ⇒ Object



82
83
84
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 82

def series_name(column)
  data_source.first.class.human_attribute_name(column)
end

#to_jsObject



94
95
96
97
98
99
100
101
102
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 94

def to_js
  "    chart.\#{chart_type}('\#{container}', \n      \#{categories.to_json}, \n      \#{series.to_json},\n      \#{chart_options.to_json}\n    );\n  EOF\nend\n"

#weekend_plot_bandsObject

Returns a plotbands definition for the data source Only if the category column is a date or datetime



72
73
74
75
76
77
78
79
80
# File 'lib/ar_to_chart/charting/highcharts/base.rb', line 72

def weekend_plot_bands
  return unless options[:weekend_plot_bands] && data_source.first[category_column].respond_to?(:to_date)
  x_plot_bands = data_source.inject_with_index([]) do |plot_bands, row, index|
    if WEEKEND.include?(row[category_column].to_date.wday)
      plot_bands << {:from => (index + AXIS_START_UNIT - 1), :to => (index + AXIS_START_UNIT)}
    end
    plot_bands
  end
end