jirametrics 2.0.1 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jirametrics/aging_work_bar_chart.rb +17 -9
  3. data/lib/jirametrics/aging_work_in_progress_chart.rb +8 -6
  4. data/lib/jirametrics/aging_work_table.rb +8 -15
  5. data/lib/jirametrics/anonymizer.rb +6 -5
  6. data/lib/jirametrics/chart_base.rb +19 -17
  7. data/lib/jirametrics/css_variable.rb +33 -0
  8. data/lib/jirametrics/cycletime_scatterplot.rb +9 -7
  9. data/lib/jirametrics/daily_wip_by_age_chart.rb +9 -9
  10. data/lib/jirametrics/daily_wip_by_blocked_stalled_chart.rb +22 -14
  11. data/lib/jirametrics/daily_wip_chart.rb +2 -2
  12. data/lib/jirametrics/dependency_chart.rb +18 -14
  13. data/lib/jirametrics/downloader.rb +6 -7
  14. data/lib/jirametrics/examples/aggregated_project.rb +3 -1
  15. data/lib/jirametrics/examples/standard_project.rb +10 -4
  16. data/lib/jirametrics/expedited_chart.rb +5 -2
  17. data/lib/jirametrics/exporter.rb +26 -20
  18. data/lib/jirametrics/grouping_rules.rb +7 -1
  19. data/lib/jirametrics/html/aging_work_bar_chart.erb +12 -6
  20. data/lib/jirametrics/html/aging_work_in_progress_chart.erb +8 -2
  21. data/lib/jirametrics/html/aging_work_table.erb +1 -1
  22. data/lib/jirametrics/html/cycletime_histogram.erb +9 -3
  23. data/lib/jirametrics/html/cycletime_scatterplot.erb +10 -4
  24. data/lib/jirametrics/html/daily_wip_chart.erb +10 -5
  25. data/lib/jirametrics/html/expedited_chart.erb +11 -5
  26. data/lib/jirametrics/html/hierarchy_table.erb +1 -1
  27. data/lib/jirametrics/html/index.css +174 -0
  28. data/lib/jirametrics/html/index.erb +8 -36
  29. data/lib/jirametrics/html/sprint_burndown.erb +11 -6
  30. data/lib/jirametrics/html/story_point_accuracy_chart.erb +9 -4
  31. data/lib/jirametrics/html/throughput_chart.erb +11 -5
  32. data/lib/jirametrics/html_report_config.rb +17 -2
  33. data/lib/jirametrics/issue.rb +3 -2
  34. data/lib/jirametrics/jira_gateway.rb +1 -1
  35. data/lib/jirametrics/project_config.rb +13 -18
  36. data/lib/jirametrics/settings.json +7 -0
  37. data/lib/jirametrics/sprint_burndown.rb +2 -2
  38. data/lib/jirametrics/status_collection.rb +1 -1
  39. data/lib/jirametrics/story_point_accuracy_chart.rb +8 -4
  40. data/lib/jirametrics/throughput_chart.rb +4 -1
  41. data/lib/jirametrics.rb +1 -0
  42. metadata +6 -3
@@ -3,11 +3,14 @@
3
3
  require 'jirametrics/chart_base'
4
4
 
5
5
  class ExpeditedChart < ChartBase
6
- EXPEDITED_SEGMENT = Object.new.tap do |segment|
6
+ EXPEDITED_SEGMENT = ChartBase.new.tap do |segment|
7
7
  def segment.to_json *_args
8
+ expedited = CssVariable.new('--expedited-color').to_json
9
+ not_expedited = CssVariable.new('--expedited-chart-no-longer-expedited').to_json
10
+
8
11
  <<~SNIPPET
9
12
  {
10
- borderColor: ctx => expedited(ctx, 'red') || notExpedited(ctx, 'gray'),
13
+ borderColor: ctx => expedited(ctx, #{expedited}) || notExpedited(ctx, #{not_expedited}),
11
14
  borderDash: ctx => notExpedited(ctx, [6, 6])
12
15
  }
13
16
  SNIPPET
@@ -3,9 +3,9 @@
3
3
  require 'fileutils'
4
4
 
5
5
  class Object
6
- def deprecated message:
6
+ def deprecated message:, date:
7
7
  text = +''
8
- text << 'Deprecated:'
8
+ text << "Deprecated(#{date}):"
9
9
  text << message
10
10
  text << "\n-> Called from #{caller(1..1).first}"
11
11
  warn text
@@ -16,7 +16,14 @@ class Exporter
16
16
  attr_reader :project_configs, :file_system
17
17
 
18
18
  def self.configure &block
19
- exporter = Exporter.new
19
+ logfile_name = 'jirametrics.log'
20
+ logfile = File.open logfile_name, 'w'
21
+ file_system = FileSystem.new
22
+ file_system.logfile = logfile
23
+ file_system.logfile_name = logfile_name
24
+
25
+ exporter = Exporter.new file_system: file_system
26
+
20
27
  exporter.instance_eval(&block)
21
28
  @@instance = exporter
22
29
  end
@@ -41,25 +48,24 @@ class Exporter
41
48
 
42
49
  def download name_filter:
43
50
  @downloading = true
44
- logfile_name = 'downloader.log'
45
- File.open logfile_name, 'w' do |logfile|
46
- file_system.logfile = logfile
47
- file_system.logfile_name = logfile_name
48
-
49
- each_project_config(name_filter: name_filter) do |project|
50
- project.evaluate_next_level
51
- next if project.aggregated_project?
52
-
53
- project.download_config.run
54
- downloader = Downloader.new(
55
- download_config: project.download_config,
56
- file_system: file_system,
57
- jira_gateway: JiraGateway.new(file_system: file_system)
58
- )
59
- downloader.run
51
+ each_project_config(name_filter: name_filter) do |project|
52
+ project.evaluate_next_level
53
+ next if project.aggregated_project?
54
+
55
+ unless project.download_config
56
+ raise "Project #{project.name.inspect} is missing a download section in the config. " \
57
+ 'That is required in order to download'
60
58
  end
59
+
60
+ project.download_config.run
61
+ downloader = Downloader.new(
62
+ download_config: project.download_config,
63
+ file_system: file_system,
64
+ jira_gateway: JiraGateway.new(file_system: file_system)
65
+ )
66
+ downloader.run
61
67
  end
62
- puts "Full output from downloader in #{logfile_name}"
68
+ puts "Full output from downloader in #{file_system.logfile_name}"
63
69
  end
64
70
 
65
71
  def each_project_config name_filter:
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class GroupingRules < Rules
4
- attr_accessor :label, :color
4
+ attr_accessor :label
5
+ attr_reader :color
5
6
 
6
7
  def eql? other
7
8
  other.label == @label && other.color == @color
@@ -10,4 +11,9 @@ class GroupingRules < Rules
10
11
  def group
11
12
  [@label, @color]
12
13
  end
14
+
15
+ def color= color
16
+ color = CssVariable[color] unless color.is_a?(CssVariable)
17
+ @color = color
18
+ end
13
19
  end
@@ -1,4 +1,4 @@
1
- <div>
1
+ <div class="chart">
2
2
  <canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
3
3
  </div>
4
4
  <script>
@@ -19,14 +19,20 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
19
19
  stacked: false,
20
20
  title: {
21
21
  display: false
22
- }
22
+ },
23
+ grid: {
24
+ color: <%= CssVariable['--grid-line-color'].to_json %>
25
+ },
23
26
  },
24
27
  y: {
25
28
  stacked: true,
26
29
  position: 'right',
27
30
  ticks: {
28
31
  display: true
29
- }
32
+ },
33
+ grid: {
34
+ color: <%= CssVariable['--grid-line-color'].to_json %>
35
+ },
30
36
  }
31
37
  },
32
38
  plugins: {
@@ -38,8 +44,8 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
38
44
  type: 'box',
39
45
  xMin: '<%= range.begin %>T00:00:00',
40
46
  xMax: '<%= range.end %>T23:59:59',
41
- backgroundColor: '#F0F0F0',
42
- borderColor: '#F0F0F0'
47
+ backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
48
+ borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
43
49
  },
44
50
  <% end %>
45
51
 
@@ -48,7 +54,7 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
48
54
  type: 'line',
49
55
  xMin: '<%= percentage_line_x %>',
50
56
  xMax: '<%= percentage_line_x %>',
51
- borderColor: 'red',
57
+ borderColor: <%= CssVariable.new('--aging-work-bar-chart-percentage-line-color').to_json %>,
52
58
  borderWidth: 1,
53
59
  drawTime: 'afterDraw'
54
60
  }
@@ -1,4 +1,4 @@
1
- <div>
1
+ <div class="chart">
2
2
  <canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
3
3
  </div>
4
4
  <script>
@@ -20,7 +20,10 @@ new Chart(document.getElementById(<%= chart_id.inspect %>).getContext('2d'),
20
20
  scaleLabel: {
21
21
  display: true,
22
22
  labelString: 'Date Completed'
23
- }
23
+ },
24
+ grid: {
25
+ color: <%= CssVariable['--grid-line-color'].to_json %>
26
+ },
24
27
  },
25
28
  y: {
26
29
  scaleLabel: {
@@ -31,6 +34,9 @@ new Chart(document.getElementById(<%= chart_id.inspect %>).getContext('2d'),
31
34
  display: true,
32
35
  text: 'Age in days'
33
36
  },
37
+ grid: {
38
+ color: <%= CssVariable['--grid-line-color'].to_json %>
39
+ },
34
40
  }
35
41
  },
36
42
  plugins: {
@@ -38,7 +38,7 @@
38
38
  <td><%= blocked_text(issue) %></td>
39
39
  <td>
40
40
  <% parent_hierarchy(issue).each_with_index do |parent, index| %>
41
- <% color = (parent == issue ? 'black' : 'gray') %>
41
+ <% color = parent != issue ? "var(--hierarchy-table-inactive-item-text-color)" : 'var(--default-text-color)' %>
42
42
  <div style="padding-left: <%= index %>em; color: <%= color %>">
43
43
  <span style="white-space: nowrap;">
44
44
  <img src="<%= parent.type_icon_url %>" title="<%= parent.type %>"/>
@@ -1,4 +1,4 @@
1
- <div>
1
+ <div class="chart">
2
2
  <canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
3
3
  </div>
4
4
  <script>
@@ -17,14 +17,20 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
17
17
  title: {
18
18
  display: true,
19
19
  text: 'Cycletime in days'
20
- }
20
+ },
21
+ grid: {
22
+ color: <%= CssVariable['--grid-line-color'].to_json %>
23
+ },
21
24
  },
22
25
  y: {
23
26
  stacked: true,
24
27
  title: {
25
28
  display: true,
26
29
  text: 'Number of items that had that cycletime'
27
- }
30
+ },
31
+ grid: {
32
+ color: <%= CssVariable['--grid-line-color'].to_json %>
33
+ },
28
34
  }
29
35
  },
30
36
  plugins: {
@@ -1,4 +1,4 @@
1
- <div>
1
+ <div class="chart">
2
2
  <canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
3
3
  </div>
4
4
  <script>
@@ -20,6 +20,9 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
20
20
  display: true,
21
21
  labelString: 'Date Completed'
22
22
  },
23
+ grid: {
24
+ color: <%= CssVariable['--grid-line-color'].to_json %>
25
+ },
23
26
  min: "<%= date_range.begin.to_s %>",
24
27
  max: "<%= (date_range.end + 1).to_s %>"
25
28
  },
@@ -34,6 +37,9 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
34
37
  display: true,
35
38
  text: 'Cycle time in days'
36
39
  },
40
+ grid: {
41
+ color: <%= CssVariable['--grid-line-color'].to_json %>
42
+ },
37
43
  }
38
44
  },
39
45
  plugins: {
@@ -53,8 +59,8 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
53
59
  type: 'box',
54
60
  xMin: '<%= range.begin %>T00:00:00',
55
61
  xMax: '<%= range.end %>T23:59:59',
56
- backgroundColor: '#F0F0F0',
57
- borderColor: '#F0F0F0'
62
+ backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
63
+ borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
58
64
  },
59
65
  <% end %>
60
66
 
@@ -64,7 +70,7 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
64
70
  type: 'line',
65
71
  yMin: <%= percent %>,
66
72
  yMax: <%= percent %>,
67
- borderColor: '<%= color %>',
73
+ borderColor: <%= color.to_json %>,
68
74
  borderWidth: 1,
69
75
  drawTime: 'beforeDraw'
70
76
  },
@@ -1,4 +1,4 @@
1
- <div>
1
+ <div class="chart">
2
2
  <canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
3
3
  </div>
4
4
  <script>
@@ -20,7 +20,10 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
20
20
  time: {
21
21
  unit: 'day'
22
22
  },
23
- stacked: true
23
+ stacked: true,
24
+ grid: {
25
+ color: <%= CssVariable['--grid-line-color'].to_json %>
26
+ },
24
27
  },
25
28
  y: {
26
29
  stacked: true,
@@ -32,7 +35,9 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
32
35
  display: true,
33
36
  text: 'Count of items'
34
37
  },
35
-
38
+ grid: {
39
+ color: <%= CssVariable['--grid-line-color'].to_json %>
40
+ },
36
41
  }
37
42
  },
38
43
  plugins: {
@@ -51,8 +56,8 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
51
56
  type: 'box',
52
57
  xMin: '<%= range.begin %>T00:00:00',
53
58
  xMax: '<%= range.end %>T23:59:59',
54
- backgroundColor: '#F0F0F0',
55
- borderColor: '#F0F0F0'
59
+ backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
60
+ borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
56
61
  },
57
62
  <% end %>
58
63
  }
@@ -1,4 +1,4 @@
1
- <div>
1
+ <div class="chart">
2
2
  <canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
3
3
  </div>
4
4
  <script>
@@ -24,7 +24,10 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
24
24
  labelString: 'Date Completed'
25
25
  },
26
26
  min: "<%= date_range.begin.to_s %>",
27
- max: "<%= date_range.end.to_s %>"
27
+ max: "<%= date_range.end.to_s %>",
28
+ grid: {
29
+ color: <%= CssVariable['--grid-line-color'].to_json %>
30
+ },
28
31
  },
29
32
  y: {
30
33
  scaleLabel: {
@@ -35,7 +38,10 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
35
38
  display: true,
36
39
  text: 'Age in days'
37
40
  },
38
- min: 0
41
+ min: 0,
42
+ grid: {
43
+ color: <%= CssVariable['--grid-line-color'].to_json %>
44
+ },
39
45
  }
40
46
  },
41
47
  plugins: {
@@ -55,8 +61,8 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
55
61
  type: 'box',
56
62
  xMin: '<%= range.begin %>T00:00:00',
57
63
  xMax: '<%= range.end %>T23:59:59',
58
- backgroundColor: '#F0F0F0',
59
- borderColor: '#F0F0F0'
64
+ backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
65
+ borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
60
66
  },
61
67
  <% end %>
62
68
  }
@@ -14,7 +14,7 @@
14
14
  <tr>
15
15
  <td style="text-align: right;"><%= issue.board.cycletime.age(issue, today: @today) || 'Not started' %></td>
16
16
  <td>
17
- <% color = (node.children? ? 'gray' : 'black') %>
17
+ <% color = "var(--hierarchy-table-#{ 'in' if node.children? }active-item-text-color)" %>
18
18
  <span style="padding-left: <%= depth - 1 %>em;" />
19
19
  <span style="white-space: nowrap;">
20
20
  <img src="<%= issue.type_icon_url %>" title="<%= issue.type %>"/>
@@ -0,0 +1,174 @@
1
+ :root {
2
+ --body-background: white;
3
+ --default-text-color: black;
4
+ --grid-line-color: lightgray;
5
+
6
+ --cycletime-scatterplot-overall-trendline-color: gray;
7
+
8
+ --non-working-days-color: #F0F0F0;
9
+ --expedited-color: red;
10
+ --blocked-color: #FF7400;
11
+ --stalled-color: orange;
12
+ --dead-color: black;
13
+
14
+ --type-story-color: #4bc14b;
15
+ --type-task-color: blue;
16
+ --type-bug-color: orange;
17
+ --type-spike-color: #9400D3;
18
+
19
+ --status-category-todo-color: gray;
20
+ --status-category-inprogress-color: #2663ff;
21
+ --status-category-done-color: #00ff00;
22
+
23
+ --aging-work-bar-chart-percentage-line-color: red;
24
+ --aging-work-bar-chart-separator-color: white;
25
+
26
+ --throughput_chart_total_line_color: gray;
27
+
28
+ --aging-work-in-progress-chart-shading-color: lightgray;
29
+
30
+ --hierarchy-table-inactive-item-text-color: gray;
31
+
32
+ --wip-chart-completed-color: #00ff00;
33
+ --wip-chart-completed-but-not-started-color: #99FF99;
34
+ --wip-chart-duration-less-than-day-color: #ffef41;
35
+ --wip-chart-duration-week-or-less-color: #dcc900;
36
+ --wip-chart-duration-two-weeks-or-less-color: #dfa000;
37
+ --wip-chart-duration-four-weeks-or-less-color: #eb7200;
38
+ --wip-chart-duration-more-than-four-weeks-color: #e70000;
39
+ --wip-chart-active-color: #326cff;
40
+ --wip-chart-border-color: gray;
41
+
42
+ --estimate-accuracy-chart-completed-fill-color: #00ff00;
43
+ --estimate-accuracy-chart-completed-border-color: green;
44
+ --estimate-accuracy-chart-active-fill-color: #FFCCCB;
45
+ --estimate-accuracy-chart-active-border-color: red;
46
+
47
+ --expedited-chart-no-longer-expedited: gray;
48
+
49
+ --sprint-burndown-sprint-color-1: blue;
50
+ --sprint-burndown-sprint-color-2: orange;
51
+ --sprint-burndown-sprint-color-3: green;
52
+ --sprint-burndown-sprint-color-4: red;
53
+ --sprint-burndown-sprint-color-5: brown;
54
+ }
55
+
56
+ body {
57
+ background-color: var(--body-background);
58
+ color: var(--default-text-color);
59
+ }
60
+
61
+ h1 {
62
+ border: 1px solid black;
63
+ background: lightgray;
64
+ padding-left: 0.2em;
65
+ }
66
+ dl, dd, dt {
67
+ padding: 0;
68
+ margin: 0;
69
+ }
70
+ dd {
71
+ margin-bottom: 0.4em;
72
+ }
73
+ span.highlight {
74
+ background: #FDD5B1;
75
+ }
76
+ a.issue_key {
77
+ white-space: nowrap;
78
+ }
79
+ table.standard {
80
+ th {
81
+ border-bottom: 1px solid gray;
82
+ position: sticky;
83
+ top: 0;
84
+ background: white;
85
+ }
86
+ td {
87
+ padding-left: 0.5em;
88
+ padding-right: 0.5em;
89
+ vertical-align: top;
90
+ }
91
+ tr:nth-child(odd){
92
+ background-color: #eee;
93
+ }
94
+ }
95
+ .quality_note_bullet {
96
+ color: red;
97
+ }
98
+
99
+ .chart {
100
+ background-color: white;
101
+ }
102
+
103
+ div.color_block {
104
+ display: inline-block;
105
+ width: 0.9em;
106
+ height: 0.9em;
107
+ border: 1px solid black;
108
+ }
109
+
110
+ @media screen and (prefers-color-scheme: dark) {
111
+ :root {
112
+ --non-working-days-color: #2f2f2f;
113
+ --type-story-color: #6fb86f;
114
+ --type-task-color: #0021b3;
115
+ --type-bug-color: #bb5603;
116
+
117
+ --body-background: #343434;
118
+ --default-text-color: #aaa;
119
+ --grid-line-color: #424242;
120
+
121
+ --expedited-color: #b90000;
122
+ --blocked-color: #c75b02;
123
+ --stalled-color: #ae7202;
124
+ --dead-color: black;
125
+ --wip-chart-active-color: #2551c1;
126
+
127
+ --aging-work-in-progress-chart-shading-color: #b4b4b4;
128
+
129
+ --status-category-inprogress-color: #1c49bb;
130
+
131
+ --cycletime-scatterplot-overall-trendline-color: gray;
132
+
133
+ --hierarchy-table-inactive-item-text-color: #939393;
134
+
135
+ --wip-chart-completed-color: #03cb03;
136
+ --wip-chart-completed-but-not-started-color: #99FF99;
137
+ --wip-chart-duration-less-than-day-color: #d2d988;
138
+ --wip-chart-duration-week-or-less-color: #dfcd00;
139
+ --wip-chart-duration-two-weeks-or-less-color: #cf9400;
140
+ --wip-chart-duration-four-weeks-or-less-color: #c25e00;
141
+ --wip-chart-duration-more-than-four-weeks-color: #8e0000;
142
+ }
143
+
144
+ h1 {
145
+ color: #e0e0e0;
146
+ background-color: #656565;
147
+ }
148
+
149
+ a[href] {
150
+ color: #1e8ad6;
151
+ }
152
+
153
+ a[href]:hover {
154
+ color: #3ba0e6;
155
+ }
156
+
157
+ .chart {
158
+ background: var(--body-background);
159
+ }
160
+
161
+ table.standard {
162
+ th {
163
+ border-bottom: 1px solid gray;
164
+ background: var(--body-background);
165
+ }
166
+ tr:nth-child(odd){
167
+ background-color: #656565;
168
+ }
169
+ }
170
+
171
+ div.color_block {
172
+ border: 1px solid lightgray;
173
+ }
174
+ }
@@ -17,44 +17,16 @@
17
17
  document.getElementById(issues_id).style.display = 'none'
18
18
  }
19
19
  }
20
+ // If we switch between light/dark mode then force a refresh so all charts will redraw correctly
21
+ // in the other colour scheme.
22
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
23
+ location.reload()
24
+ })
25
+
20
26
  </script>
21
27
  <style>
22
- h1 {
23
- border: 1px solid black;
24
- background: lightgray;
25
- padding-left: 0.2em;
26
- }
27
- dl, dd, dt {
28
- padding: 0;
29
- margin: 0;
30
- }
31
- dd {
32
- margin-bottom: 0.4em;
33
- }
34
- span.highlight {
35
- background: #FDD5B1;
36
- }
37
- a.issue_key {
38
- white-space: nowrap;
39
- }
40
- table.standard thead tr th {
41
- border-bottom: 1px solid gray;
42
- position: sticky;
43
- top: 0;
44
- background: white;
45
- }
46
- table.standard tbody tr td {
47
- padding-left: 0.5em;
48
- padding-right: 0.5em;
49
- vertical-align: top;
50
- }
51
- table.standard tbody tr:nth-child(odd){
52
- background-color: #eee;
53
- }
54
- .quality_note_bullet {
55
- color: red;
56
- }
57
- </style>
28
+ <%= css %>
29
+ </style>
58
30
  </head>
59
31
  <body>
60
32
  <div>
@@ -1,6 +1,6 @@
1
1
  <h2>Burndown by <%= y_axis_title %></h2>
2
2
 
3
- <div>
3
+ <div class="chart">
4
4
  <canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
5
5
  </div>
6
6
  <script>
@@ -26,8 +26,10 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
26
26
  labelString: 'Date'
27
27
  },
28
28
  min: "<%= date_range.begin.to_s %>",
29
- max: "<%= (date_range.end + 1).to_s %>"
30
-
29
+ max: "<%= (date_range.end + 1).to_s %>",
30
+ grid: {
31
+ color: <%= CssVariable['--grid-line-color'].to_json %>
32
+ },
31
33
  },
32
34
  y: {
33
35
  scaleLabel: {
@@ -38,7 +40,10 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
38
40
  display: true,
39
41
  text: "<%= y_axis_title %>"
40
42
  },
41
- min: 0.0
43
+ min: 0.0,
44
+ grid: {
45
+ color: <%= CssVariable['--grid-line-color'].to_json %>
46
+ },
42
47
  }
43
48
  },
44
49
  plugins: {
@@ -57,8 +62,8 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
57
62
  type: 'box',
58
63
  xMin: '<%= range.begin %>T00:00:00',
59
64
  xMax: '<%= range.end %>T23:59:59',
60
- backgroundColor: '#F0F0F0',
61
- borderColor: '#F0F0F0'
65
+ backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
66
+ borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
62
67
  },
63
68
  <% end %>
64
69
  }
@@ -1,4 +1,4 @@
1
- <div>
1
+ <div class="chart">
2
2
  <canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
3
3
  </div>
4
4
  <script>
@@ -24,8 +24,10 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
24
24
  display: true,
25
25
  text: "Cycletime (days)"
26
26
  },
27
- min: 0
28
-
27
+ min: 0,
28
+ grid: {
29
+ color: <%= CssVariable['--grid-line-color'].to_json %>
30
+ },
29
31
  },
30
32
  y: {
31
33
  type: "<%= @y_axis_type %>",
@@ -40,7 +42,10 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
40
42
  display: true,
41
43
  text: "<%= @y_axis_label %>"
42
44
  },
43
- min: 0.0
45
+ min: 0.0,
46
+ grid: {
47
+ color: <%= CssVariable['--grid-line-color'].to_json %>
48
+ },
44
49
  }
45
50
  },
46
51
  plugins: {