Class: FactDb::Temporal::Timeline
- Inherits:
-
Object
- Object
- FactDb::Temporal::Timeline
- Includes:
- Enumerable
- Defined in:
- lib/fact_db/temporal/timeline.rb
Overview
Builds and analyzes temporal timelines of facts for an entity
Provides methods to view an entity’s history, group events by time periods, find overlapping facts, and compare states at different points in time. Includes Enumerable for easy iteration over timeline events.
Instance Attribute Summary collapse
-
#events ⇒ Array<TimelineEvent>
readonly
The timeline events.
Instance Method Summary collapse
-
#active ⇒ Array<TimelineEvent>
Returns currently active (valid) events.
-
#between(from, to) ⇒ Array<TimelineEvent>
Returns events in a specific date range.
-
#build(entity_id:, from: nil, to: nil) ⇒ Timeline
Builds a timeline of facts for an entity.
-
#by_month ⇒ Hash<String, Array<TimelineEvent>>
Groups events by month.
-
#by_year ⇒ Hash<Integer, Array<TimelineEvent>>
Groups events by year.
-
#changes_summary ⇒ Array<Hash>
Generates a summary of changes between consecutive events.
-
#each {|Hash| ... } ⇒ Enumerator
Iterates over timeline event hashes.
-
#historical ⇒ Array<TimelineEvent>
Returns historical (no longer valid) events.
-
#initialize ⇒ Timeline
constructor
Initializes a new empty Timeline.
-
#overlapping ⇒ Array<Array<TimelineEvent, TimelineEvent>>
Finds pairs of overlapping events.
-
#state_at(date) ⇒ Array<TimelineEvent>
Returns the state (valid events) at a specific point in time.
-
#to_a ⇒ Array<TimelineEvent>
Returns events sorted by valid_at date.
-
#to_hash ⇒ Array<Hash>
Returns events as an array of hashes.
Constructor Details
#initialize ⇒ Timeline
Initializes a new empty Timeline
25 26 27 |
# File 'lib/fact_db/temporal/timeline.rb', line 25 def initialize @events = [] end |
Instance Attribute Details
#events ⇒ Array<TimelineEvent> (readonly)
Returns the timeline events.
22 23 24 |
# File 'lib/fact_db/temporal/timeline.rb', line 22 def events @events end |
Instance Method Details
#active ⇒ Array<TimelineEvent>
Returns currently active (valid) events
89 90 91 |
# File 'lib/fact_db/temporal/timeline.rb', line 89 def active to_a.select(&:currently_valid?) end |
#between(from, to) ⇒ Array<TimelineEvent>
Returns events in a specific date range
82 83 84 |
# File 'lib/fact_db/temporal/timeline.rb', line 82 def between(from, to) to_a.select { |event| event.valid_at >= from && event.valid_at <= to } end |
#build(entity_id:, from: nil, to: nil) ⇒ Timeline
Builds a timeline of facts for an entity
43 44 45 46 47 |
# File 'lib/fact_db/temporal/timeline.rb', line 43 def build(entity_id:, from: nil, to: nil) facts = fetch_facts(entity_id, from, to) @events = facts.map { |fact| TimelineEvent.new(fact) } self end |
#by_month ⇒ Hash<String, Array<TimelineEvent>>
Groups events by month
73 74 75 |
# File 'lib/fact_db/temporal/timeline.rb', line 73 def by_month to_a.group_by { |event| event.valid_at.strftime("%Y-%m") } end |
#by_year ⇒ Hash<Integer, Array<TimelineEvent>>
Groups events by year
66 67 68 |
# File 'lib/fact_db/temporal/timeline.rb', line 66 def by_year to_a.group_by { |event| event.valid_at.year } end |
#changes_summary ⇒ Array<Hash>
Generates a summary of changes between consecutive events
129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/fact_db/temporal/timeline.rb', line 129 def changes_summary sorted = to_a sorted.each_cons(2).map do |prev_event, next_event| { from: prev_event, to: next_event, gap_days: (next_event.valid_at.to_date - (prev_event.invalid_at || prev_event.valid_at).to_date).to_i } end end |
#each {|Hash| ... } ⇒ Enumerator
Iterates over timeline event hashes
33 34 35 |
# File 'lib/fact_db/temporal/timeline.rb', line 33 def each(&block) to_hash.each(&block) end |
#historical ⇒ Array<TimelineEvent>
Returns historical (no longer valid) events
96 97 98 |
# File 'lib/fact_db/temporal/timeline.rb', line 96 def historical to_a.reject(&:currently_valid?) end |
#overlapping ⇒ Array<Array<TimelineEvent, TimelineEvent>>
Finds pairs of overlapping events
Two events overlap if their validity periods intersect.
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/fact_db/temporal/timeline.rb', line 105 def overlapping result = [] sorted = to_a sorted.each_with_index do |event, i| sorted[(i + 1)..].each do |other| result << [event, other] if events_overlap?(event, other) end end result end |
#state_at(date) ⇒ Array<TimelineEvent>
Returns the state (valid events) at a specific point in time
122 123 124 |
# File 'lib/fact_db/temporal/timeline.rb', line 122 def state_at(date) to_a.select { |event| event.valid_at?(date) } end |
#to_a ⇒ Array<TimelineEvent>
Returns events sorted by valid_at date
52 53 54 |
# File 'lib/fact_db/temporal/timeline.rb', line 52 def to_a @events.sort_by(&:valid_at) end |
#to_hash ⇒ Array<Hash>
Returns events as an array of hashes
59 60 61 |
# File 'lib/fact_db/temporal/timeline.rb', line 59 def to_hash to_a.map(&:to_hash) end |