Class: TimeBasedHistogram
- Inherits:
-
TimeBasedChart
- Object
- ChartBase
- TimeBasedChart
- TimeBasedHistogram
- Includes:
- GroupableIssueChart
- Defined in:
- lib/jirametrics/time_based_histogram.rb
Direct Known Subclasses
Constant Summary
Constants inherited from TimeBasedChart
TimeBasedChart::VALUE_AXIS_LABELS
Constants inherited from ChartBase
ChartBase::LABEL_POSITIONS, ChartBase::OKABE_ITO_PALETTE
Instance Attribute Summary collapse
-
#show_stats ⇒ Object
readonly
Returns the value of attribute show_stats.
Attributes included from GroupableIssueChart
#group_by_block, #issue_hints, #issue_periods
Attributes inherited from ChartBase
#aggregated_project, #all_boards, #atlassian_document_format, #board_id, #canvas_height, #canvas_width, #data_quality, #date_range, #file_system, #fix_versions, #holiday_dates, #issues, #settings, #time_range, #timezone_offset, #x_axis_title, #y_axis_title
Instance Method Summary collapse
- #average_for(histogram_data, total_values) ⇒ Object
- #data_set_for(histogram_data:, label:, color:) ⇒ Object
- #disable_stats ⇒ Object
- #histogram_data_for(items:) ⇒ Object
-
#initialize ⇒ TimeBasedHistogram
constructor
A new instance of TimeBasedHistogram.
- #label_for_item(item, hint:) ⇒ Object
-
#modes_for(histogram_data) ⇒ Object
Every value that ties for the highest frequency, so a flat or multi-modal distribution returns them all.
- #percentiles(percs = nil) ⇒ Object
- #percentiles_for(histogram_data, percentiles, total_values) ⇒ Object
- #run ⇒ Object
- #sort_items(items) ⇒ Object
- #stats_for(histogram_data:, percentiles:) ⇒ Object
-
#value_axis_title=(title) ⇒ Object
On a histogram the cycle time is plotted along the x-axis (count is on the y-axis).
Methods included from GroupableIssueChart
#group_issues, #grouping_rules, #init_configuration_block
Methods inherited from TimeBasedChart
#cycletime_unit, #duration_in_unit, #label_cycletime
Methods inherited from ChartBase
#aggregated_project?, #before_run, #call_before_run, #canvas, #canvas_responsive?, #chart_format, #collapsible_issues_panel, #color_block, #color_for, #completed_issues_in_range, #current_board, #cycletime, #cycletime_for_issue, #daily_chart_dataset, #date_annotation, #describe_non_working_days, #description_text, #format_integer, #format_status, #header_text, #holidays, #html_directory, #icon_span, #link_to_issue, #next_id, #non_working_day?, #normalize_annotation_datetime, #not_visible_icon, #not_visible_text, #random_color, #render, #render_axis_title, #render_top_text, #resolve_status, #stagger_label_positions, #status_category_color, #to_human_readable, #working_days_annotation, #wrap_and_render
Constructor Details
#initialize ⇒ TimeBasedHistogram
Returns a new instance of TimeBasedHistogram.
11 12 13 14 15 16 |
# File 'lib/jirametrics/time_based_histogram.rb', line 11 def initialize super percentiles [50, 85, 98] @show_stats = true end |
Instance Attribute Details
#show_stats ⇒ Object (readonly)
Returns the value of attribute show_stats.
9 10 11 |
# File 'lib/jirametrics/time_based_histogram.rb', line 9 def show_stats @show_stats end |
Instance Method Details
#average_for(histogram_data, total_values) ⇒ Object
87 88 89 90 91 92 |
# File 'lib/jirametrics/time_based_histogram.rb', line 87 def average_for histogram_data, total_values return 0 if total_values.zero? weighted_sum = histogram_data.reduce(0) { |sum, (value, frequency)| sum + (value * frequency) } weighted_sum.to_f / total_values end |
#data_set_for(histogram_data:, label:, color:) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/jirametrics/time_based_histogram.rb', line 124 def data_set_for histogram_data:, label:, color: { type: 'bar', label: label, data: histogram_data.keys.sort.filter_map do |days| items = histogram_data[days] next if items.empty? { x: days, y: items.size, title: [title_for_item(count: items.size, value: days)] + sort_items(items).collect do |item| hint = @issue_hints&.fetch(item, nil) label_for_item(item, hint: hint) end } end, backgroundColor: color, borderRadius: 0 } end |
#disable_stats ⇒ Object
28 29 30 |
# File 'lib/jirametrics/time_based_histogram.rb', line 28 def disable_stats @show_stats = false end |
#histogram_data_for(items:) ⇒ Object
64 65 66 67 68 69 70 71 |
# File 'lib/jirametrics/time_based_histogram.rb', line 64 def histogram_data_for items: items_hash = {} items.each do |item| days = value_for_item item (items_hash[days] ||= []) << item if days.positive? end items_hash end |
#label_for_item(item, hint:) ⇒ Object
120 121 122 |
# File 'lib/jirametrics/time_based_histogram.rb', line 120 def label_for_item item, hint: raise NotImplementedError, "#{self.class} must implement label_for_item" end |
#modes_for(histogram_data) ⇒ Object
Every value that ties for the highest frequency, so a flat or multi-modal distribution returns them all.
95 96 97 98 99 |
# File 'lib/jirametrics/time_based_histogram.rb', line 95 def modes_for histogram_data sorted_by_frequency = histogram_data.sort_by { |_value, frequency| frequency } max_frequency = sorted_by_frequency[-1][1] sorted_by_frequency.select { |_value, frequency| frequency == max_frequency }.collect(&:first).sort end |
#percentiles(percs = nil) ⇒ Object
23 24 25 26 |
# File 'lib/jirametrics/time_based_histogram.rb', line 23 def percentiles percs = nil @percentiles = percs unless percs.nil? @percentiles end |
#percentiles_for(histogram_data, percentiles, total_values) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/jirametrics/time_based_histogram.rb', line 101 def percentiles_for histogram_data, percentiles, total_values sorted_values = histogram_data.keys.sort cumulative_counts = {} cumulative_sum = 0 sorted_values.each do |value| cumulative_sum += histogram_data[value] cumulative_counts[value] = cumulative_sum end percentiles.to_h do |percentile| rank = (percentile / 100.0) * total_values [percentile, sorted_values.find { |value| cumulative_counts[value] >= rank }] end end |
#run ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/jirametrics/time_based_histogram.rb', line 32 def run histogram_items = all_items rules_to_items = group_issues histogram_items the_stats = {} overall_histogram = histogram_data_for(items: histogram_items).transform_values(&:size) the_stats[:all] = stats_for histogram_data: overall_histogram, percentiles: @percentiles data_sets = rules_to_items.keys.collect do |rules| the_label = rules.label the_histogram = histogram_data_for(items: rules_to_items[rules]) if @show_stats the_stats[the_label] = stats_for( histogram_data: the_histogram.transform_values(&:size), percentiles: @percentiles ) end data_set_for( histogram_data: the_histogram, label: the_label, color: rules.color ) end if data_sets.empty? return "<h1 class='foldable'>#{@header_text}</h1>" \ '<div>No data matched the selected criteria. Nothing to show.</div>' end wrap_and_render(binding, __FILE__) end |
#sort_items(items) ⇒ Object
116 117 118 |
# File 'lib/jirametrics/time_based_histogram.rb', line 116 def sort_items items items end |
#stats_for(histogram_data:, percentiles:) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/jirametrics/time_based_histogram.rb', line 73 def stats_for histogram_data:, percentiles: return {} if histogram_data.empty? total_values = histogram_data.values.sum min, max = histogram_data.keys.minmax { average: average_for(histogram_data, total_values), mode: modes_for(histogram_data), min: min, max: max, percentiles: percentiles_for(histogram_data, percentiles, total_values) } end |
#value_axis_title=(title) ⇒ Object
On a histogram the cycle time is plotted along the x-axis (count is on the y-axis).
19 20 21 |
# File 'lib/jirametrics/time_based_histogram.rb', line 19 def value_axis_title= title @x_axis_title = title end |