Class: Lyra::Visualization::ActivityHeatmap

Inherits:
Object
  • Object
show all
Defined in:
lib/lyra/visualization/activity_heatmap.rb

Overview

Activity heatmap visualization for D3.js Shows event activity patterns across time (hour of day vs day of week)

Constant Summary collapse

DAYS_OF_WEEK =
%w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday].freeze
HOURS_OF_DAY =
(0..23).to_a.freeze

Instance Method Summary collapse

Constructor Details

#initialize(events) ⇒ ActivityHeatmap

Returns a new instance of ActivityHeatmap.



9
10
11
# File 'lib/lyra/visualization/activity_heatmap.rb', line 9

def initialize(events)
  @events = events.sort_by { |e| event_timestamp(e) }
end

Instance Method Details

#daily_breakdown(model_class = nil) ⇒ Object

Generate daily breakdown



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/lyra/visualization/activity_heatmap.rb', line 49

def daily_breakdown(model_class = nil)
  filtered = model_class ? @events.select { |e| event_model_class(e) == model_class } : @events

  DAYS_OF_WEEK.each_with_index.map do |day, i|
    count = filtered.count { |e| event_timestamp(e).wday == i }
    {
      day: day,
      day_index: i,
      count: count,
      percentage: filtered.empty? ? 0 : (count.to_f / filtered.size * 100).round(2)
    }
  end
end

#hourly_breakdown(model_class = nil) ⇒ Object

Generate hourly breakdown for a specific model



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/lyra/visualization/activity_heatmap.rb', line 34

def hourly_breakdown(model_class = nil)
  filtered = model_class ? @events.select { |e| event_model_class(e) == model_class } : @events

  HOURS_OF_DAY.map do |hour|
    count = filtered.count { |e| event_timestamp(e).hour == hour }
    {
      hour: hour,
      label: format_hour(hour),
      count: count,
      percentage: filtered.empty? ? 0 : (count.to_f / filtered.size * 100).round(2)
    }
  end
end

#model_heatmap ⇒ Object

Generate model-based heatmap



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/lyra/visualization/activity_heatmap.rb', line 78

def model_heatmap
  model_classes = @events.map { |e| event_model_class(e) }.uniq

  model_classes.map do |model_class|
    model_events = @events.select { |e| event_model_class(e) == model_class }
    {
      model_class: model_class,
      hourly: HOURS_OF_DAY.map { |h| model_events.count { |e| event_timestamp(e).hour == h } },
      daily: DAYS_OF_WEEK.each_with_index.map { |_d, i| model_events.count { |e| event_timestamp(e).wday == i } },
      total: model_events.count
    }
  end
end

#operation_heatmap ⇒ Object

Generate operation-based heatmap



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/lyra/visualization/activity_heatmap.rb', line 64

def operation_heatmap
  operations = @events.map { |e| event_operation(e) }.uniq

  operations.map do |operation|
    op_events = @events.select { |e| event_operation(e) == operation }
    {
      operation: operation.to_s,
      hourly: HOURS_OF_DAY.map { |h| op_events.count { |e| event_timestamp(e).hour == h } },
      total: op_events.count
    }
  end
end

#to_d3_json ⇒ Object

Generate heatmap data for D3.js



14
15
16
17
18
19
20
21
# File 'lib/lyra/visualization/activity_heatmap.rb', line 14

def to_d3_json
  {
    data: build_heatmap_data,
    x_labels: hour_labels,
    y_labels: DAYS_OF_WEEK,
    metadata: 
  }.to_json
end

#to_data ⇒ Object

Generate data hash (for API responses)



24
25
26
27
28
29
30
31
# File 'lib/lyra/visualization/activity_heatmap.rb', line 24

def to_data
  {
    data: build_heatmap_data,
    x_labels: hour_labels,
    y_labels: DAYS_OF_WEEK,
    metadata: 
  }
end