Class: ChartBase
Direct Known Subclasses
AgingWorkBarChart, AgingWorkInProgressChart, AgingWorkTable, CycletimeHistogram, CycletimeScatterplot, DailyWipChart, DataQualityReport, DependencyChart, ExpeditedChart, HierarchyTable, SprintBurndown, StoryPointAccuracyChart, ThroughputChart
Constant Summary
collapse
- @@chart_counter =
0
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#aggregated_project? ⇒ Boolean
-
#canvas(width:, height:, responsive: true) ⇒ Object
-
#canvas_responsive? ⇒ Boolean
-
#chart_format(object) ⇒ Object
-
#collapsible_issues_panel(issue_descriptions, *args) ⇒ Object
-
#color_for(type:, shade: :dark) ⇒ Object
-
#completed_issues_in_range(include_unstarted: false) ⇒ Object
-
#current_board ⇒ Object
Return only the board columns for the current board.
-
#daily_chart_dataset(date_issues_list:, color:, label:, positive: true) ⇒ Object
-
#description_text(text) ⇒ Object
-
#filter_issues(&block) ⇒ Object
-
#format_integer(number) ⇒ Object
-
#format_status(name_or_id, board:, is_category: false) ⇒ Object
-
#header_text(text) ⇒ Object
-
#holidays(date_range: @date_range) ⇒ Object
-
#initialize ⇒ ChartBase
constructor
A new instance of ChartBase.
-
#label_days(days) ⇒ Object
-
#label_issues(count) ⇒ Object
-
#link_to_issue(issue, args = {}) ⇒ Object
-
#next_id ⇒ Object
-
#random_color ⇒ Object
-
#render(caller_binding, file) ⇒ Object
-
#sprints_in_time_range(board) ⇒ Object
-
#status_category_color(status) ⇒ Object
-
#wrap_and_render(caller_binding, file) ⇒ Object
Render the file and then wrap it with standard headers and quality checks.
Constructor Details
Returns a new instance of ChartBase.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/jirametrics/chart_base.rb', line 11
def initialize
@chart_colors = {
'dark:Story' => 'green',
'dark:Task' => 'blue',
'dark:Bug' => 'orange',
'dark:Defect' => 'orange',
'dark:Spike' => '#9400D3', 'light:Story' => '#90EE90',
'light:Task' => '#87CEFA',
'light:Bug' => '#ffdab9',
'light:Defect' => 'orange',
'light:Epic' => '#fafad2',
'light:Spike' => '#DDA0DD' }
@canvas_width = 800
@canvas_height = 200
@canvas_responsive = true
end
|
Instance Attribute Details
#aggregated_project=(value) ⇒ Object
Sets the attribute aggregated_project
6
7
8
|
# File 'lib/jirametrics/chart_base.rb', line 6
def aggregated_project=(value)
@aggregated_project = value
end
|
#all_boards ⇒ Object
Returns the value of attribute all_boards.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def all_boards
@all_boards
end
|
Returns the value of attribute board_id.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def board_id
@board_id
end
|
#canvas_height ⇒ Object
Returns the value of attribute canvas_height.
7
8
9
|
# File 'lib/jirametrics/chart_base.rb', line 7
def canvas_height
@canvas_height
end
|
#canvas_width ⇒ Object
Returns the value of attribute canvas_width.
7
8
9
|
# File 'lib/jirametrics/chart_base.rb', line 7
def canvas_width
@canvas_width
end
|
#data_quality ⇒ Object
Returns the value of attribute data_quality.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def data_quality
@data_quality
end
|
#date_range ⇒ Object
Returns the value of attribute date_range.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def date_range
@date_range
end
|
#holiday_dates ⇒ Object
Returns the value of attribute holiday_dates.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def holiday_dates
@holiday_dates
end
|
Returns the value of attribute issues.
7
8
9
|
# File 'lib/jirametrics/chart_base.rb', line 7
def issues
@issues
end
|
Returns the value of attribute settings.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def settings
@settings
end
|
#time_range ⇒ Object
Returns the value of attribute time_range.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def time_range
@time_range
end
|
#timezone_offset ⇒ Object
Returns the value of attribute timezone_offset.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def timezone_offset
@timezone_offset
end
|
Instance Method Details
#aggregated_project? ⇒ Boolean
30
31
32
|
# File 'lib/jirametrics/chart_base.rb', line 30
def aggregated_project?
@aggregated_project
end
|
#canvas(width:, height:, responsive: true) ⇒ Object
218
219
220
221
222
|
# File 'lib/jirametrics/chart_base.rb', line 218
def canvas width:, height:, responsive: true
@canvas_width = width
@canvas_height = height
@canvas_responsive = responsive
end
|
#canvas_responsive? ⇒ Boolean
224
225
226
|
# File 'lib/jirametrics/chart_base.rb', line 224
def canvas_responsive?
@canvas_responsive
end
|
167
168
169
170
171
172
173
174
|
# File 'lib/jirametrics/chart_base.rb', line 167
def chart_format object
if object.is_a? Time
object.strftime '%Y-%m-%dT%H:%M:%S%z'
else
object.to_s
end
end
|
#collapsible_issues_panel(issue_descriptions, *args) ⇒ Object
98
99
100
101
102
103
104
105
|
# File 'lib/jirametrics/chart_base.rb', line 98
def collapsible_issues_panel issue_descriptions, *args
link_id = next_id
issues_id = next_id
issue_descriptions.sort! { |a, b| a[0].key_as_i <=> b[0].key_as_i }
erb = ERB.new File.read "#{@html_directory}/collapsible_issues_panel.erb"
erb.result(binding)
end
|
#color_for(type:, shade: :dark) ⇒ Object
60
61
62
|
# File 'lib/jirametrics/chart_base.rb', line 60
def color_for type:, shade: :dark
@chart_colors["#{shade}:#{type}"] ||= random_color
end
|
#completed_issues_in_range(include_unstarted: false) ⇒ Object
144
145
146
147
148
149
150
151
152
153
154
|
# File 'lib/jirametrics/chart_base.rb', line 144
def completed_issues_in_range include_unstarted: false
issues.select do |issue|
cycletime = issue.board.cycletime
stopped_time = cycletime.stopped_time(issue)
started_time = cycletime.started_time(issue)
stopped_time &&
date_range.include?(stopped_time.to_date) && (include_unstarted || (started_time && (stopped_time >= started_time)))
end
end
|
#current_board ⇒ Object
Return only the board columns for the current board.
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/jirametrics/chart_base.rb', line 129
def current_board
if @board_id.nil?
case @all_boards.size
when 0
raise 'Couldn\'t find any board configurations. Ensure one is set'
when 1
return @all_boards.values[0]
else
raise "Must set board_id so we know which to use. Multiple boards found: #{@all_boards.keys.inspect}"
end
end
@all_boards[@board_id]
end
|
#daily_chart_dataset(date_issues_list:, color:, label:, positive: true) ⇒ Object
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/jirametrics/chart_base.rb', line 72
def daily_chart_dataset date_issues_list:, color:, label:, positive: true
{
type: 'bar',
label: label,
data: date_issues_list.collect do |date, issues|
issues.sort! { |a, b| a.key_as_i <=> b.key_as_i }
title = "#{label} (#{label_issues issues.size})"
{
x: date,
y: positive ? issues.size : -issues.size,
title: [title] + issues.collect { |i| "#{i.key} : #{i.summary.strip}#{" #{yield date, i}" if block_given?}" }
}
end,
backgroundColor: color,
borderRadius: positive ? 0 : 5
}
end
|
#description_text(text) ⇒ Object
180
181
182
|
# File 'lib/jirametrics/chart_base.rb', line 180
def description_text text
@description_text = text
end
|
#filter_issues(&block) ⇒ Object
228
229
230
|
# File 'lib/jirametrics/chart_base.rb', line 228
def filter_issues &block
@filter_issues_block = block
end
|
184
185
186
|
# File 'lib/jirametrics/chart_base.rb', line 184
def format_integer number
number.to_s.reverse.scan(/.{1,3}/).join(',').reverse
end
|
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
# File 'lib/jirametrics/chart_base.rb', line 188
def format_status name_or_id, board:, is_category: false
begin
statuses = board.possible_statuses.expand_statuses([name_or_id])
rescue RuntimeError => e
return "<span style='color: red'>#{name_or_id}</span>" if e.message =~ /^Status not found:/
throw e
end
raise "Expected exactly one match and got #{statuses.inspect} for #{name_or_id.inspect}" if statuses.size > 1
status = statuses.first
color = status_category_color status
text = is_category ? status.category_name : status.name
"<span style='color: #{color}'>#{text}</span>"
end
|
176
177
178
|
# File 'lib/jirametrics/chart_base.rb', line 176
def text
@header_text = text
end
|
#holidays(date_range: @date_range) ⇒ Object
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/jirametrics/chart_base.rb', line 107
def holidays date_range: @date_range
result = []
start_date = nil
end_date = nil
date_range.each do |date|
if date.saturday? || date.sunday? || holiday_dates.include?(date)
if start_date.nil?
start_date = date
else
end_date = date
end
elsif start_date
result << (start_date..(end_date || start_date))
start_date = nil
end_date = nil
end
end
result
end
|
#label_days(days) ⇒ Object
64
65
66
|
# File 'lib/jirametrics/chart_base.rb', line 64
def label_days days
"#{days} day#{'s' unless days == 1}"
end
|
#label_issues(count) ⇒ Object
68
69
70
|
# File 'lib/jirametrics/chart_base.rb', line 68
def label_issues count
"#{count} issue#{'s' unless count == 1}"
end
|
#link_to_issue(issue, args = {}) ⇒ Object
90
91
92
93
94
95
96
|
# File 'lib/jirametrics/chart_base.rb', line 90
def link_to_issue issue, args = {}
attributes = { class: 'issue_key' }
.merge(args)
.collect { |key, value| "#{key}='#{value}'" }
.join(' ')
"<a href='#{issue.url}' #{attributes}>#{issue.key}</a>"
end
|
56
57
58
|
# File 'lib/jirametrics/chart_base.rb', line 56
def next_id
@@chart_counter += 1
end
|
#random_color ⇒ Object
214
215
216
|
# File 'lib/jirametrics/chart_base.rb', line 214
def random_color
"\##{Random.bytes(3).unpack1('H*')}"
end
|
#render(caller_binding, file) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
|
# File 'lib/jirametrics/chart_base.rb', line 34
def render caller_binding, file
pathname = Pathname.new(File.realpath(file))
basename = pathname.basename.to_s
raise "Unexpected filename #{basename.inspect}" unless basename =~ /^(.+)\.rb$/
caller_binding.eval "chart_id='chart#{next_id}'"
@html_directory = "#{pathname.dirname}/html"
erb = ERB.new File.read "#{@html_directory}/#{$1}.erb"
erb.result(caller_binding)
end
|
#sprints_in_time_range(board) ⇒ Object
156
157
158
159
160
161
162
163
164
165
|
# File 'lib/jirametrics/chart_base.rb', line 156
def sprints_in_time_range board
board.sprints.select do |sprint|
sprint_end_time = sprint.completed_time || sprint.end_time
sprint_start_time = sprint.start_time
next false if sprint_start_time.nil?
time_range.include?(sprint_start_time) || time_range.include?(sprint_end_time) ||
(sprint_start_time < time_range.begin && sprint_end_time > time_range.end)
end || []
end
|
#status_category_color(status) ⇒ Object
205
206
207
208
209
210
211
212
|
# File 'lib/jirametrics/chart_base.rb', line 205
def status_category_color status
case status.category_name
when nil then 'black'
when 'To Do' then 'gray'
when 'In Progress' then 'blue'
when 'Done' then 'green'
end
end
|
#wrap_and_render(caller_binding, file) ⇒ Object
Render the file and then wrap it with standard headers and quality checks.
48
49
50
51
52
53
54
|
# File 'lib/jirametrics/chart_base.rb', line 48
def wrap_and_render caller_binding, file
result = String.new
result << "<h1>#{@header_text}</h1>" if @header_text
result << ERB.new(@description_text).result(caller_binding) if @description_text
result << render(caller_binding, file)
result
end
|