Class: WipByColumnChart
- Defined in:
- lib/jirametrics/wip_by_column_chart.rb
Defined Under Namespace
Classes: ColumnStats
Constant Summary
Constants inherited from ChartBase
Instance Attribute Summary collapse
-
#board_id ⇒ Object
Returns the value of attribute board_id.
-
#possible_statuses ⇒ Object
Returns the value of attribute possible_statuses.
Attributes inherited from ChartBase
#aggregated_project, #all_boards, #atlassian_document_format, #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
- #column_stats ⇒ Object
-
#initialize(block) ⇒ WipByColumnChart
constructor
A new instance of WipByColumnChart.
- #run ⇒ Object
- #show_recommendations ⇒ Object
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, #label_days, #label_hours, #label_issues, #label_minutes, #link_to_issue, #next_id, #normalize_annotation_datetime, #not_visible_text, #random_color, #render, #render_axis_title, #render_top_text, #seam_end, #seam_start, #stagger_label_positions, #status_category_color, #to_human_readable, #working_days_annotation, #wrap_and_render
Constructor Details
#initialize(block) ⇒ WipByColumnChart
Returns a new instance of WipByColumnChart.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/jirametrics/wip_by_column_chart.rb', line 10 def initialize block super() header_text 'WIP by column' description_text <<-HTML <p> This chart shows how much time each board column has spent at different WIP (Work in Progress) levels. </p> <p> Each row on the Y axis is a WIP level (the number of items in that column at the same time). Each column on the X axis is a board column. The horizontal bars show what percentage of the total time that column spent at that WIP level — a wider bar means more time was spent there. </p> <p> A column whose widest bar is at WIP 1 was almost always working on one item at a time, often called single-piece-flow. This team is likely collaborating very well and might have been <a href="https://blog.mikebowler.ca/2021/06/19/pair-programming/">pairing</a> or <a href="https://blog.mikebowler.ca/2023/04/22/ensemble-programming/">mobbing/ensembling</a> and these teams tend to be very effective. </p> <p> A column with wide bars at high WIP levels usually indicates a team that is highly siloed. Where each person is working by themselves. </p> <p> The dashed lines show the minimum and maximum WIP limits configured on the board. If the widest bar sits well above the maximum limit, the limit may be set too low or not being respected. If the widest bar sits below the minimum limit, consider whether that limit is still meaningful. </p> <p> Hover over any bar to see the exact percentage. </p> <% if @all_boards[@board_id].team_managed_kanban? %> <p> If the data looks a bit off then that's probably because you're using a Team Managed project in "kanban mode". For this specific case, we are unable to tell if an item is actually visible on the board and so we may be reporting more items started than you actually see on the board. See <a href="https://jirametrics.org/faq/#team-managed-kanban-backlog">the FAQ</a>. </p> <% end %> HTML instance_eval(&block) end |
Instance Attribute Details
#board_id ⇒ Object
Returns the value of attribute board_id.
6 7 8 |
# File 'lib/jirametrics/wip_by_column_chart.rb', line 6 def board_id @board_id end |
#possible_statuses ⇒ Object
Returns the value of attribute possible_statuses.
6 7 8 |
# File 'lib/jirametrics/wip_by_column_chart.rb', line 6 def possible_statuses @possible_statuses end |
Instance Method Details
#column_stats ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/jirametrics/wip_by_column_chart.rb', line 79 def column_stats board = current_board columns = board.visible_columns status_to_column = build_status_to_column_map(columns) relevant_issues = @issues.select { |issue| issue.board.id == @board_id } current_column = initial_column_state(relevant_issues, status_to_column) events = events_within_range(relevant_issues, status_to_column) column_wip_seconds = compute_wip_seconds(columns, current_column, events) columns.collect.with_index do |column, index| ColumnStats.new( name: column.name, min_wip_limit: column.min, max_wip_limit: column.max, wip_history: column_wip_seconds[index].sort.to_a ) end end |
#run ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/jirametrics/wip_by_column_chart.rb', line 59 def run @header_text += " on board: #{current_board.name}" stats = column_stats @column_names = stats.collect(&:name) @wip_data = stats.collect do |stat| total = stat.wip_history.sum { |_wip, seconds| seconds }.to_f next [] if total.zero? stat.wip_history.collect { |wip, seconds| { 'wip' => wip, 'pct' => format_pct(seconds, total) } } end @max_wip = stats.flat_map { |s| s.wip_history.collect { |wip, _| wip } }.max || 0 @wip_limits = stats.collect { |s| { 'min' => s.min_wip_limit, 'max' => s.max_wip_limit } } @recommendations = @show_recommendations ? compute_recommendations(stats) : Array.new(stats.size) trim_zero_end_columns @recommendation_texts = @show_recommendations ? build_recommendation_texts : [] wrap_and_render(binding, __FILE__) end |
#show_recommendations ⇒ Object
55 56 57 |
# File 'lib/jirametrics/wip_by_column_chart.rb', line 55 def show_recommendations @show_recommendations = true end |