mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 13:19:39 +02:00
65 lines
1.4 KiB
Ruby
65 lines
1.4 KiB
Ruby
class TimeSeries
|
|
DIRECTIONS = %w[up down].freeze
|
|
|
|
attr_reader :values, :favorable_direction
|
|
|
|
def self.from_collection(collection, value_method, favorable_direction: "up")
|
|
collection.map do |obj|
|
|
{
|
|
date: obj.date,
|
|
value: obj.public_send(value_method),
|
|
original: obj
|
|
}
|
|
end.then { |data| new(data, favorable_direction: favorable_direction) }
|
|
end
|
|
|
|
def initialize(data, favorable_direction: "up")
|
|
@favorable_direction = (favorable_direction.presence_in(DIRECTIONS) || "up").inquiry
|
|
@values = initialize_values data.sort_by { |d| d[:date] }
|
|
end
|
|
|
|
def first
|
|
values.first
|
|
end
|
|
|
|
def last
|
|
values.last
|
|
end
|
|
|
|
def on(date)
|
|
values.find { |v| v.date == date }
|
|
end
|
|
|
|
def trend
|
|
TimeSeries::Trend.new \
|
|
current: last&.value,
|
|
previous: first&.value,
|
|
series: self
|
|
end
|
|
|
|
def empty?
|
|
values.empty?
|
|
end
|
|
|
|
def has_current_day_value?
|
|
values.any? { |v| v.date == Date.current }
|
|
end
|
|
|
|
# `as_json` returns the data shape used by D3 charts
|
|
def as_json
|
|
{
|
|
values: values.map(&:as_json),
|
|
trend: trend.as_json,
|
|
favorable_direction: favorable_direction
|
|
}.as_json
|
|
end
|
|
|
|
private
|
|
def initialize_values(data)
|
|
[ nil, *data ].each_cons(2).map do |previous, current|
|
|
TimeSeries::Value.new **current,
|
|
previous_value: previous.try(:[], :value),
|
|
series: self
|
|
end
|
|
end
|
|
end
|