Class: ChartBase
Direct Known Subclasses
AgingWorkBarChart, AgingWorkInProgressChart, AgingWorkTable, CycletimeHistogram, CycletimeScatterplot, DailyWipChart, DataQualityReport, DependencyChart, EstimateAccuracyChart, ExpeditedChart, FlowEfficiencyScatterplot, HierarchyTable, SprintBurndown, 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_block(color, title: nil) ⇒ Object
-
#color_for(type:) ⇒ 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
-
#describe_non_working_days ⇒ Object
-
#description_text(text = nil) ⇒ Object
-
#format_integer(number) ⇒ Object
-
#format_status(name_or_id, board:, is_category: false) ⇒ Object
-
#header_text(text = nil) ⇒ Object
-
#holidays(date_range: @date_range) ⇒ Object
-
#html_directory ⇒ Object
-
#icon_span(title:, icon:) ⇒ 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
-
#render_top_text(caller_binding) ⇒ 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
|
# File 'lib/jirametrics/chart_base.rb', line 11
def initialize
@chart_colors = {
'Story' => CssVariable['--type-story-color'],
'Task' => CssVariable['--type-task-color'],
'Bug' => CssVariable['--type-bug-color'],
'Defect' => CssVariable['--type-bug-color'],
'Spike' => CssVariable['--type-spike-color']
}
@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
|
#file_system ⇒ Object
Returns the value of attribute file_system.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
def file_system
@file_system
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.
4
5
6
|
# File 'lib/jirametrics/chart_base.rb', line 4
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
24
25
26
|
# File 'lib/jirametrics/chart_base.rb', line 24
def aggregated_project?
@aggregated_project
end
|
#canvas(width:, height:, responsive: true) ⇒ Object
224
225
226
227
228
|
# File 'lib/jirametrics/chart_base.rb', line 224
def canvas width:, height:, responsive: true
@canvas_width = width
@canvas_height = height
@canvas_responsive = responsive
end
|
#canvas_responsive? ⇒ Boolean
230
231
232
|
# File 'lib/jirametrics/chart_base.rb', line 230
def canvas_responsive?
@canvas_responsive
end
|
163
164
165
166
167
168
169
170
|
# File 'lib/jirametrics/chart_base.rb', line 163
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
106
107
108
109
110
111
112
113
|
# File 'lib/jirametrics/chart_base.rb', line 106
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_system.load File.join(html_directory, 'collapsible_issues_panel.erb')
erb.result(binding)
end
|
#color_block(color, title: nil) ⇒ Object
234
235
236
237
238
239
240
|
# File 'lib/jirametrics/chart_base.rb', line 234
def color_block color, title: nil
result = +''
result << "<div class='color_block' style='background: var(#{color});'"
result << " title=#{title.inspect}" if title
result << '></div>'
result
end
|
#color_for(type:) ⇒ Object
68
69
70
|
# File 'lib/jirametrics/chart_base.rb', line 68
def color_for type:
@chart_colors[type] ||= random_color
end
|
#completed_issues_in_range(include_unstarted: false) ⇒ Object
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/jirametrics/chart_base.rb', line 152
def completed_issues_in_range include_unstarted: false
issues.select do |issue|
cycletime = issue.board.cycletime
started_time, stopped_time = cycletime.started_stopped_times(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.
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/jirametrics/chart_base.rb', line 137
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/jirametrics/chart_base.rb', line 80
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_by!(&: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
|
#describe_non_working_days ⇒ Object
242
243
244
245
246
247
248
249
|
# File 'lib/jirametrics/chart_base.rb', line 242
def describe_non_working_days
<<-TEXT
<div class='p'>
The #{color_block '--non-working-days-color'} vertical bars indicate non-working days; weekends
and any other holidays mentioned in the configuration.
</div>
TEXT
end
|
#description_text(text = nil) ⇒ Object
177
178
179
180
|
# File 'lib/jirametrics/chart_base.rb', line 177
def description_text text = nil
@description_text = text if text
@description_text
end
|
182
183
184
|
# File 'lib/jirametrics/chart_base.rb', line 182
def format_integer number
number.to_s.reverse.scan(/.{1,3}/).join(',').reverse
end
|
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
# File 'lib/jirametrics/chart_base.rb', line 186
def format_status name_or_id, board:, is_category: false
begin
statuses = board.possible_statuses.expand_statuses([name_or_id])
rescue StatusNotFoundError
return "<span style='color: red'>#{name_or_id}</span>"
end
status = statuses.first
color = status_category_color status
visibility = ''
if is_category == false && board.visible_columns.none? { |column| column.status_ids.include? status.id }
visibility = icon_span(
title: "Not visible: The status #{status.name.inspect} is not mapped to any column and will not be visible",
icon: ' 👀'
)
end
text = is_category ? status.category_name : status.name
"<span title='Category: #{status.category_name}'>#{color_block color.name} #{text}</span>#{visibility}"
end
|
172
173
174
175
|
# File 'lib/jirametrics/chart_base.rb', line 172
def text = nil
@header_text = text if text
@header_text
end
|
#holidays(date_range: @date_range) ⇒ Object
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# File 'lib/jirametrics/chart_base.rb', line 115
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
|
#html_directory ⇒ Object
28
29
30
31
32
33
34
|
# File 'lib/jirametrics/chart_base.rb', line 28
def html_directory
pathname = Pathname.new(File.realpath(__FILE__))
"#{pathname.dirname}/html"
end
|
#icon_span(title:, icon:) ⇒ Object
207
208
209
|
# File 'lib/jirametrics/chart_base.rb', line 207
def icon_span title:, icon:
"<span title='#{title}' style='font-size: 0.8em;'>#{icon}</span>"
end
|
#label_days(days) ⇒ Object
72
73
74
|
# File 'lib/jirametrics/chart_base.rb', line 72
def label_days days
"#{days} day#{'s' unless days == 1}"
end
|
#label_issues(count) ⇒ Object
76
77
78
|
# File 'lib/jirametrics/chart_base.rb', line 76
def label_issues count
"#{count} issue#{'s' unless count == 1}"
end
|
#link_to_issue(issue, args = {}) ⇒ Object
98
99
100
101
102
103
104
|
# File 'lib/jirametrics/chart_base.rb', line 98
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
|
64
65
66
|
# File 'lib/jirametrics/chart_base.rb', line 64
def next_id
@@chart_counter += 1
end
|
#random_color ⇒ Object
220
221
222
|
# File 'lib/jirametrics/chart_base.rb', line 220
def random_color
"##{Random.bytes(3).unpack1('H*')}"
end
|
#render(caller_binding, file) ⇒ Object
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/jirametrics/chart_base.rb', line 36
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}'"
erb = ERB.new file_system.load "#{html_directory}/#{$1}.erb"
erb.result(caller_binding)
end
|
#render_top_text(caller_binding) ⇒ Object
49
50
51
52
53
54
|
# File 'lib/jirametrics/chart_base.rb', line 49
def render_top_text caller_binding
result = +''
result << "<h1>#{@header_text}</h1>" if @header_text
result << ERB.new(@description_text).result(caller_binding) if @description_text
result
end
|
#status_category_color(status) ⇒ Object
211
212
213
214
215
216
217
218
|
# File 'lib/jirametrics/chart_base.rb', line 211
def status_category_color status
case status.category_name
when 'To Do' then CssVariable['--status-category-todo-color']
when 'In Progress' then CssVariable['--status-category-inprogress-color']
when 'Done' then CssVariable['--status-category-done-color']
else 'black' end
end
|
#wrap_and_render(caller_binding, file) ⇒ Object
Render the file and then wrap it with standard headers and quality checks.
57
58
59
60
61
62
|
# File 'lib/jirametrics/chart_base.rb', line 57
def wrap_and_render caller_binding, file
result = +''
result << render_top_text(caller_binding)
result << render(caller_binding, file)
result
end
|