Class: RailsDataExplorer::DataSeries

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_data_explorer/data_series.rb

Overview

NOTE: DataSeries values are immutable once instantiated.

Responsibilities:

* Represent a data series
* Compute statistics
* Compute chart attributes
* Cache computed properties like values, statistics
* Provide modified versions of values
  (e.g., :limit_distinct_values, :compress_quantitative_values)

Collaborators:

* DataType

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(_name, _values, options = {}) ⇒ DataSeries

options: :chart_roles, :data_type (all optional)



41
42
43
44
45
46
47
48
# File 'lib/rails_data_explorer/data_series.rb', line 41

def initialize(_name, _values, options={})
  options = { chart_roles: [], data_type: nil }.merge(options)
  @name = _name
  @values = _values
  @data_type = init_data_type(options[:data_type])
  @chart_roles = init_chart_roles(options[:chart_roles]) # after data_type!
  @options = options.symbolize_keys
end

Instance Attribute Details

#chart_rolesObject (readonly)

TODO: Add concept of significant figures for rounding values when displaying them en.wikipedia.org/wiki/Significant_figures



23
24
25
# File 'lib/rails_data_explorer/data_series.rb', line 23

def chart_roles
  @chart_roles
end

#data_typeObject (readonly)

TODO: Add concept of significant figures for rounding values when displaying them en.wikipedia.org/wiki/Significant_figures



23
24
25
# File 'lib/rails_data_explorer/data_series.rb', line 23

def data_type
  @data_type
end

#nameObject (readonly)

TODO: Add concept of significant figures for rounding values when displaying them en.wikipedia.org/wiki/Significant_figures



23
24
25
# File 'lib/rails_data_explorer/data_series.rb', line 23

def name
  @name
end

#optionsObject (readonly)

TODO: Add concept of significant figures for rounding values when displaying them en.wikipedia.org/wiki/Significant_figures



23
24
25
# File 'lib/rails_data_explorer/data_series.rb', line 23

def options
  @options
end

Class Method Details

.large_dynamic_range_thresholdObject

Any data series with a dynamic range greater than this is considered having a large dynamic range We consider dynamic range the ratio between the largest and the smallest value.



30
31
32
# File 'lib/rails_data_explorer/data_series.rb', line 30

def self.large_dynamic_range_threshold
  10000.0
end

.many_uniq_vals_thresholdObject

Any data series with more than this uniq vals is considered having many uniq values.



36
37
38
# File 'lib/rails_data_explorer/data_series.rb', line 36

def self.many_uniq_vals_threshold
  20
end

Instance Method Details

#axis_scale(d3_or_vega, modification = {}) ⇒ Object

@param d3_or_vega :d3 or :vega



148
149
150
# File 'lib/rails_data_explorer/data_series.rb', line 148

def axis_scale(d3_or_vega, modification = {})
  data_type.axis_scale(self, modification, d3_or_vega)
end

#axis_tick_format(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



143
144
145
# File 'lib/rails_data_explorer/data_series.rb', line 143

def axis_tick_format(modification = {})
  data_type.axis_tick_format(values(modification))
end

#descriptive_statistics(modification = {}) ⇒ Object

Returns descriptive_statistics as a flat Array (see #values)



52
53
54
55
56
57
# File 'lib/rails_data_explorer/data_series.rb', line 52

def descriptive_statistics(modification = {})
  @cached_descriptive_statistics ||= {}
  @cached_descriptive_statistics[modification] ||= (
    data_type.descriptive_statistics(values(modification))
  )
end

#descriptive_statistics_table(modification = {}) ⇒ Object

Returns descriptive_statistics as a renderable table structure (see #values)



61
62
63
64
65
66
# File 'lib/rails_data_explorer/data_series.rb', line 61

def descriptive_statistics_table(modification = {})
  @cached_descriptive_statistics_table ||= {}
  @cached_descriptive_statistics_table[modification] ||= (
    data_type.descriptive_statistics_table(values(modification))
  )
end

#dynamic_range(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



177
178
179
180
181
182
183
# File 'lib/rails_data_explorer/data_series.rb', line 177

def dynamic_range(modification = {})
  @cached_dynamic_range ||= {}
  @cached_dynamic_range[modification] ||= (
    divisor = [min_val(modification), max_val(modification)].min.to_f
    0 == divisor ? 0.0 : max_val / divisor
  )
end

#has_large_dynamic_range?(modification = {}) ⇒ Boolean

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.

Returns:

  • (Boolean)


186
187
188
189
190
191
# File 'lib/rails_data_explorer/data_series.rb', line 186

def has_large_dynamic_range?(modification = {})
  @cached_has_large_dynamic_range ||= {}
  @cached_has_large_dynamic_range[modification] ||= (
    dynamic_range(modification) > self.class.large_dynamic_range_threshold
  )
end

#inspect(indent = 1, recursive = 1000) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/rails_data_explorer/data_series.rb', line 128

def inspect(indent=1, recursive=1000)
  r = %(#<#{ self.class.to_s }\n)
  r << [
    "@name=#{ name.inspect }",
    "@data_type=#{ data_type.inspect }",
    "@chart_roles=#{ chart_roles.inspect }",
    "@values=<count: #{ values.count }, items: #{ values_summary }>",
  ].map { |e| "#{ '  ' * indent }#{ e }\n"}.join
  if recursive > 0
    # nothing to recurse
  end
  r << %(#{ '  ' * (indent-1) }>\n)
end

#label_sorter(label_val_key, value_sorter) ⇒ Object



193
194
195
# File 'lib/rails_data_explorer/data_series.rb', line 193

def label_sorter(label_val_key, value_sorter)
  data_type.label_sorter(label_val_key, self, value_sorter)
end

#max_val(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



171
172
173
174
# File 'lib/rails_data_explorer/data_series.rb', line 171

def max_val(modification = {})
  @cached_max_val ||= {}
  @cached_max_val[modification] ||= values(modification).compact.max
end

#min_val(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



165
166
167
168
# File 'lib/rails_data_explorer/data_series.rb', line 165

def min_val(modification = {})
  @cached_min_val ||= {}
  @cached_min_val[modification] ||= values(modification).compact.min
end

#number_of_values(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



69
70
71
72
73
74
# File 'lib/rails_data_explorer/data_series.rb', line 69

def number_of_values(modification = {})
  @cached_number_of_values ||= {}
  @cached_number_of_values[modification] ||= (
    values(modification).length
  )
end

#uniq_vals(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



153
154
155
156
# File 'lib/rails_data_explorer/data_series.rb', line 153

def uniq_vals(modification = {})
  @cached_uniq_vals ||= {}
  @cached_uniq_vals[modification] ||= values(modification).uniq
end

#uniq_vals_count(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



159
160
161
162
# File 'lib/rails_data_explorer/data_series.rb', line 159

def uniq_vals_count(modification = {})
  @cached_uniq_vals_count ||= {}
  @cached_uniq_vals_count[modification] ||= uniq_vals(modification).length
end

#values(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/rails_data_explorer/data_series.rb', line 99

def values(modification = {})
  @cached_values ||= {}
  @cached_values[modification] ||= (
    case modification[:name]
    when NilClass
      @values
    when :limit_distinct_values
      # Returns variant of self's values with number of distinct values limited
      # to :max_num_distinct_values. Less frequent values are mapped to
      # :val_for_others.
      # @param max_num_distinct_values [Integer, optional]
      data_type.limit_distinct_values(
        @values,
        (
          modification[:max_num_distinct_values] ||
          @options[:max_num_distinct_values] ||
          self.class.many_uniq_vals_threshold
        ),
        (
          modification[:val_for_others] ||
          @options[:val_for_others]
        )
      )
    else
      raise "Handle this modification: #{ modification.inspect }"
    end
  )
end

#values_summary(modification = {}) ⇒ Object

Returns the values for this data series with an optional modification

name: :limit_distinct_values,
max_num_distinct_values: 20,
val_for_others: '[Other]',

name: :compress_quantitative_values,

Parameters:

  • modification (Hash, optional) (defaults to: {})

    type of modification.



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rails_data_explorer/data_series.rb', line 77

def values_summary(modification = {})
  @cached_values_summary ||= {}
  @cached_values_summary[modification] ||= (
    v = values(modification)
    if v.length < 3 || v.inspect.length < 80
      v.inspect
    else
      "[#{ v.first } ... #{ v.last }]"
    end
  )
end