class Friends::Graph
Constants
- COLORS
Originally generated by executing the code in Minitest's Pride plugin (the PrideLOL class), and then pulling the unique values out and doubling them to create a more even distribution of colors.
- DATE_FORMAT
- SCALED_SIZE
Public Class Methods
@param filtered_activities [Array<Friends::Activity>] a list of activities to highlight in
the graph (may be the same as `all_activities`)
@param all_activities [Array<Friends::Activity>] a list of activities to graph @param unscaled [Boolean] true iff we should show the absolute size of bars in the graph
rather than a scaled version
# File lib/friends/graph.rb, line 15 def initialize(filtered_activities:, all_activities:, unscaled:) @filtered_activities = filtered_activities @all_activities = all_activities @unscaled = unscaled return if @all_activities.empty? @start_date = @all_activities.last.date @end_date = @all_activities.first.date end
Public Instance Methods
@return [Array<String>] the output to print, with colors
# File lib/friends/graph.rb, line 27 def output hash = to_h global_total = hash.max_by { |_, (_, val)| val }.last.last unless @unscaled || hash.empty? hash.map do |month, (filtered_count, total_count)| unless @unscaled # We want to use rationals for math so we can round up as well # as down (instead of int division), for more accurate graphing. # Floats are less trustworthy and could give results < 0 or > total_count filtered_count = Rational(filtered_count * SCALED_SIZE, global_total).round total_count = SCALED_SIZE end str = "#{month} |" str += Array.new(filtered_count) do |count| Paint["█", color(count)] end.join if total_count > filtered_count str += Array.new(total_count - filtered_count) do |count| Paint["∙", color(filtered_count + count)] end.join + Paint["|", color(total_count + 1)] end str end.reverse! end
Private Instance Methods
@param x_coord [Integer] the x coordinate we want to color; x >= 0 @return [Array<Integer>] the color we should use to paint
a point on the graph at the given x coordinate
# File lib/friends/graph.rb, line 101 def color(x_coord) COLORS[x_coord % COLORS.size] end
Render an empty graph as a hash in the format:
{ "Jan 2015" => [0, 0] # [# filtered activities, # total activities] "Feb 2015" => [0, 0] "Mar 2015" => [0, 0] }
@return [Hash{String => Integer}]
# File lib/friends/graph.rb, line 85 def empty_graph Hash[(@start_date && @end_date ? (@start_date..@end_date) : []).map do |date| [format_date(date), [0, 0]] end] end
Format a date for use in the graph label @param date [Date] the date to format @return [String]
# File lib/friends/graph.rb, line 94 def format_date(date) date.strftime(DATE_FORMAT) end
Render the graph as a hash in the format:
{ "Jan 2015" => [3, 4], # [# filtered activities, # total activities] "Feb 2015" => [0, 0], "Mar 2015" => [0, 9] }
@return [Hash{String => Integer}]
# File lib/friends/graph.rb, line 65 def to_h empty_graph.tap do |graph| @filtered_activities.each do |activity| graph[format_date(activity.date)][0] += 1 end @all_activities.each do |activity| graph[format_date(activity.date)][1] += 1 end end end