Class: Timet::TagDistribution::Context

Inherits:
Struct
  • Object
show all
Includes:
Timet::TagDistributionFormatting
Defined in:
lib/timet/tag_distribution.rb

Overview

Context object for tag distribution formatting

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Timet::TagDistributionFormatting

build_average_part, build_duration_part, build_major_summary, calculate_value_and_bar_length, generate_horizontal_bar, generate_stats, high_sd_message, introduction, low_sd_message, moderate_sd_message

Instance Attribute Details

#colorsObject

Returns the value of attribute colors

Returns:

  • (Object)

    the current value of colors



85
86
87
# File 'lib/timet/tag_distribution.rb', line 85

def colors
  @colors
end

#time_statsObject

Returns the value of attribute time_stats

Returns:

  • (Object)

    the current value of time_stats



85
86
87
# File 'lib/timet/tag_distribution.rb', line 85

def time_stats
  @time_stats
end

#totalObject

Returns the value of attribute total

Returns:

  • (Object)

    the current value of total



85
86
87
# File 'lib/timet/tag_distribution.rb', line 85

def total
  @total
end

Instance Method Details

#build_category_explanation(tag, duration) ⇒ Object



123
124
125
126
127
128
129
130
131
# File 'lib/timet/tag_distribution.rb', line 123

def build_category_explanation(tag, duration)
  metrics = tag_metrics(tag, duration)
  [
    "#{tag.capitalize.to_s.bold}:",
    " This category consumed #{"#{metrics[:percentage]}%".bold} of the total tracked time.",
    build_duration_part(duration), build_average_part(metrics),
    sd_variation_message(metrics)
  ].join
end

#build_sorted_categoriesObject



142
143
144
145
146
# File 'lib/timet/tag_distribution.rb', line 142

def build_sorted_categories
  time_stats.sorted_duration_by_tag.map do |tag, duration|
    [tag, tag_metrics(tag, duration)[:percentage]]
  end.sort_by(&:last).reverse
end

#category_breakdownObject



117
118
119
120
121
# File 'lib/timet/tag_distribution.rb', line 117

def category_breakdown
  time_stats.sorted_duration_by_tag.each_with_object(['Category Breakdown'.bold]) do |(tag, duration), parts|
    parts << build_category_explanation(tag, duration).white
  end
end

#format_avgHash

Formats the overall average and standard deviation from the time statistics.

Returns:

  • (Hash)

    A hash with :avg and :sd keys, values in minutes rounded to 1 decimal place.



90
91
92
# File 'lib/timet/tag_distribution.rb', line 90

def format_avg
  time_stats.totals.slice(:avg, :sd).transform_values { |val| (val / 60.0).round(1) }
end

#format_total_hoursFloat

Formats the total duration in hours.

Returns:

  • (Float)

    Total duration in hours rounded to 1 decimal place.



96
97
98
# File 'lib/timet/tag_distribution.rb', line 96

def format_total_hours
  (total / 3600.0).round(1)
end

#overall_summaryObject



148
149
150
151
152
153
154
155
# File 'lib/timet/tag_distribution.rb', line 148

def overall_summary
  return [] unless time_stats.sorted_duration_by_tag.any?

  major_categories = build_sorted_categories.select { |_, pct| pct > 10 }
  return [] if major_categories.size <= 1

  build_major_summary(major_categories)
end


164
165
166
167
168
169
170
# File 'lib/timet/tag_distribution.rb', line 164

def print_explanation
  parts = []
  parts << introduction(total)
  parts << category_breakdown
  parts << overall_summary
  puts parts.flatten.join("\n")
end


157
158
159
160
161
162
# File 'lib/timet/tag_distribution.rb', line 157

def print_summary
  f_avg = format_avg
  summary = "#{' ' * TAG_SIZE} #{'Summary'.underline}: "
  summary += "[T: #{format_total_hours}, AVG: #{f_avg[:avg]}min SD: #{f_avg[:sd]}min]".white
  puts summary
end


172
173
174
175
176
177
178
179
180
181
182
# File 'lib/timet/tag_distribution.rb', line 172

def print_tags_info
  stats = time_stats
  stats.sorted_duration_by_tag.each do |tag, duration|
    value, bar_length = calculate_value_and_bar_length(duration, total)
    horizontal_bar = generate_horizontal_bar(bar_length, colors[tag])
    formatted_tag = tag[0...TAG_SIZE].rjust(TAG_SIZE)
    tag_stats = generate_stats(tag, stats)

    puts "#{formatted_tag}: #{value.to_s.rjust(5)}%  #{horizontal_bar} [#{tag_stats}]"
  end
end

#renderObject



184
185
186
187
# File 'lib/timet/tag_distribution.rb', line 184

def render
  print_summary
  print_tags_info
end

#sd_variation_message(metrics) ⇒ Object



133
134
135
136
137
138
139
140
# File 'lib/timet/tag_distribution.rb', line 133

def sd_variation_message(metrics)
  sd_min = metrics[:sd_minutes]
  avg_hour = metrics[:avg_minutes] / 60.0
  return high_sd_message(sd_min) if sd_min > avg_hour * 0.5
  return moderate_sd_message(sd_min) if sd_min > avg_hour * 0.2

  low_sd_message(sd_min)
end

#tag_metrics(tag, duration) ⇒ Hash

Calculates metrics for a specific tag.

Parameters:

  • tag (String)

    The tag name.

  • duration (Numeric)

    The duration for the tag.

Returns:

  • (Hash)

    A hash of metrics for the tag.



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/timet/tag_distribution.rb', line 104

def tag_metrics(tag, duration)
  stats = time_stats
  value = duration.to_f / total
  avg_sec = stats.average_by_tag[tag]
  sd_sec = stats.standard_deviation_by_tag[tag]

  {
    tag: tag, duration: duration, percentage: (value * 100).round(1),
    avg_minutes: (avg_sec / 60.0).round(1), sd_minutes: (sd_sec / 60.0).round(1),
    avg_seconds: avg_sec, sd_seconds: sd_sec, value: value
  }
end