class ReportsKits::Reports::Data::AggregateComposite

Constants

OPERATORS_METHODS

Attributes

composite_series[RW]
context_record[RW]

Public Class Methods

new(properties, context_record:) click to toggle source
# File lib/reports_kits/reports/data/aggregate_composite.rb, line 22
def initialize(properties, context_record:)
  self.composite_series = CompositeSeries.new(properties, context_record: context_record)
  self.context_record = context_record
end

Public Instance Methods

perform() click to toggle source
# File lib/reports_kits/reports/data/aggregate_composite.rb, line 27
def perform
  return serieses_results_for_one_dimension if dimension_count == 1
  return serieses_results_for_two_dimensions if dimension_count == 2
  raise ArgumentError.new("Composite aggregations' series can only have 1-2 dimensions")
end

Private Instance Methods

composite_method() click to toggle source
# File lib/reports_kits/reports/data/aggregate_composite.rb, line 79
def composite_method
  composite_method = OPERATORS_METHODS[composite_operator]
  raise ArgumentError.new("Invalid composite_operator: #{composite_operator}") unless composite_method
  composite_method
end
dimension_count() click to toggle source
# File lib/reports_kits/reports/data/aggregate_composite.rb, line 85
def dimension_count
  unique_dimension_counts = serieses.map { |series| series.dimensions.length }.uniq
  raise ArgumentError.new('All series must have the same number of dimensions') if unique_dimension_counts.length > 1
  unique_dimension_counts.first
end
reduce(values) click to toggle source
# File lib/reports_kits/reports/data/aggregate_composite.rb, line 69
def reduce(values)
  if composite_method.is_a?(Symbol)
    values.reduce(&composite_method)
  elsif composite_method.is_a?(Proc)
    values = composite_method.call(values)
  else
    raise ArgumentError.new("Invalid composite method type: #{composite_method.class}")
  end
end
serieses() click to toggle source
# File lib/reports_kits/reports/data/aggregate_composite.rb, line 91
def serieses
  @serieses ||= Series.new_from_properties!(properties, context_record: context_record)
end
serieses_results_for_one_dimension() click to toggle source
# File lib/reports_kits/reports/data/aggregate_composite.rb, line 35
def serieses_results_for_one_dimension
  serieses_results = Hash[serieses.map { |series| [series, AggregateOneDimension.new(series).perform] }]
  serieses_results = Data::PopulateOneDimension.new(serieses_results, context_record: context_record, properties: properties).perform
  sorted_dimension_keys_values = sort_dimension_keys_values(serieses_results)
  value_lists = sorted_dimension_keys_values.map(&:values)
  composited_values = value_lists.transpose.map { |data| reduce(data) }
  dimension_keys = sorted_dimension_keys_values.first.keys
  composited_keys_values = dimension_keys.zip(composited_values)
  Hash[composited_keys_values]
end
serieses_results_for_two_dimensions() click to toggle source
# File lib/reports_kits/reports/data/aggregate_composite.rb, line 46
def serieses_results_for_two_dimensions
  serieses_results = Hash[serieses.map { |series| [series, AggregateTwoDimensions.new(series).perform] }]
  serieses_results = Data::PopulateTwoDimensions.new(serieses_results).perform
  value_lists = serieses_results.values.map(&:values)
  composited_values = value_lists.transpose.map { |data| reduce(data) }
  dimension_keys = serieses_results.values.first.keys
  composited_keys_values = dimension_keys.zip(composited_values)
  Hash[composited_keys_values]
end
sort_dimension_keys_values(serieses_results) click to toggle source

Before performing a composition of values, we need to make sure that the values are sorted by the same dimension key.

# File lib/reports_kits/reports/data/aggregate_composite.rb, line 57
def sort_dimension_keys_values(serieses_results)
  dimension_keys_values_list = serieses_results.values
  sorted_dimension_keys_values = dimension_keys_values_list.map do |dimension_keys_values|
    dimension_keys_values = dimension_keys_values.sort_by do |dimension_key, value|
      is_boolean = dimension_key.is_a?(TrueClass) || dimension_key.is_a?(FalseClass)
      is_boolean ? (dimension_key ? 0 : 1) : dimension_key
    end
    Hash[dimension_keys_values]
  end
  sorted_dimension_keys_values
end