@beauraines/sprint-tracker 0.6.13 → 0.6.15
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.
- package/.github/workflows/test.yaml +1 -1
- package/CHANGELOG.md +14 -1
- package/R/combinedStats.R +345 -0
- package/R/commitmentVarianceCli.R +76 -42
- package/cmds/stats.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
-
### [0.6.
|
|
5
|
+
### [0.6.15](https://github.com/beauraines/sprint-tracker/compare/v0.6.14...v0.6.15) (2024-05-17)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* combines stats and visualization plots ([#71](https://github.com/beauraines/sprint-tracker/issues/71)) ([34f1237](https://github.com/beauraines/sprint-tracker/commit/34f1237d4cbcaaa80c97392e9f494369377980ba))
|
|
11
|
+
|
|
12
|
+
### [0.6.14](https://github.com/beauraines/sprint-tracker/compare/v0.6.12...v0.6.14) (2024-05-06)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* improves sprint statistics with patchwork ([#69](https://github.com/beauraines/sprint-tracker/issues/69)) ([a36c75b](https://github.com/beauraines/sprint-tracker/commit/a36c75ba68631b1e28b7f3970c77d126a0e16fa3))
|
|
6
18
|
|
|
7
19
|
|
|
8
20
|
### Bug Fixes
|
|
9
21
|
|
|
22
|
+
* **deps:** bump cli-markdown from 3.2.2 to 3.2.3 ([#65](https://github.com/beauraines/sprint-tracker/issues/65)) ([bc3c912](https://github.com/beauraines/sprint-tracker/commit/bc3c912a331678a9e880939c7555257983a4f4c3))
|
|
10
23
|
* **deps:** bump cli-table3 from 0.6.3 to 0.6.4 ([#63](https://github.com/beauraines/sprint-tracker/issues/63)) ([1487e95](https://github.com/beauraines/sprint-tracker/commit/1487e9531782b0575ad27664814461856c454ea4))
|
|
11
24
|
|
|
12
25
|
### [0.6.12](https://github.com/beauraines/sprint-tracker/compare/v0.6.9...v0.6.12) (2024-03-27)
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
library(tidyverse)
|
|
2
|
+
library(zoo)
|
|
3
|
+
library(DBI)
|
|
4
|
+
library(RSQLite)
|
|
5
|
+
library(ggrepel)
|
|
6
|
+
library(patchwork)
|
|
7
|
+
|
|
8
|
+
args = commandArgs(trailingOnly=TRUE)
|
|
9
|
+
if (length(args)==0) {
|
|
10
|
+
stop("At least one argument must be supplied, the key", call.=FALSE)
|
|
11
|
+
}
|
|
12
|
+
project_id = if_else(is.na(args[1]),"4",args[1])
|
|
13
|
+
|
|
14
|
+
con <- dbConnect(RSQLite::SQLite(),"~/projects/sprint-tracker/tracker.db")
|
|
15
|
+
|
|
16
|
+
#TODO simplify this sql and build the data set in R, maybe
|
|
17
|
+
res <- dbSendQuery(con, str_c("WITH commitment as (
|
|
18
|
+
select
|
|
19
|
+
p.name,
|
|
20
|
+
s.id sprint_id,
|
|
21
|
+
s.sprint_name,
|
|
22
|
+
s.start_date,
|
|
23
|
+
s.end_date,
|
|
24
|
+
so.story_points,
|
|
25
|
+
o.name as outcome,
|
|
26
|
+
o.id
|
|
27
|
+
from
|
|
28
|
+
sprint_outcomes so
|
|
29
|
+
JOIN sprints s on sprint_id = s.id
|
|
30
|
+
JOIN projects p on project_id = p.id and p.id = ",project_id,
|
|
31
|
+
" JOIN outcomes o on outcome_id = o.id and outcome_id in (6) -- 1 Delivered, 6 Committment
|
|
32
|
+
),
|
|
33
|
+
completed as
|
|
34
|
+
(
|
|
35
|
+
select
|
|
36
|
+
p.name,
|
|
37
|
+
s.id sprint_id,
|
|
38
|
+
s.sprint_name,
|
|
39
|
+
s.start_date,
|
|
40
|
+
s.end_date,
|
|
41
|
+
so.story_points,
|
|
42
|
+
o.name as outcome,
|
|
43
|
+
o.id
|
|
44
|
+
from
|
|
45
|
+
sprint_outcomes so
|
|
46
|
+
JOIN sprints s on sprint_id = s.id
|
|
47
|
+
JOIN projects p on project_id = p.id and p.id = ",project_id,
|
|
48
|
+
" JOIN outcomes o on outcome_id = o.id and outcome_id in (1) -- 1 Delivered, 6 Committment
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
select
|
|
52
|
+
commitment.name,
|
|
53
|
+
commitment.sprint_id,
|
|
54
|
+
commitment.sprint_name,
|
|
55
|
+
commitment.start_date,
|
|
56
|
+
commitment.end_date,
|
|
57
|
+
commitment.story_points commitment,
|
|
58
|
+
completed.story_points completed
|
|
59
|
+
from
|
|
60
|
+
commitment
|
|
61
|
+
LEFT JOIN completed on completed.sprint_id = commitment.sprint_id
|
|
62
|
+
where
|
|
63
|
+
1 =1
|
|
64
|
+
order by commitment.name,commitment.start_date
|
|
65
|
+
|
|
66
|
+
;
|
|
67
|
+
"))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# TODO query sqlite directly
|
|
71
|
+
sprintData <- dbFetch(res)
|
|
72
|
+
|
|
73
|
+
# Clear the result
|
|
74
|
+
dbClearResult(res)
|
|
75
|
+
|
|
76
|
+
# Disconnect from the database
|
|
77
|
+
dbDisconnect(con)
|
|
78
|
+
|
|
79
|
+
## Clean data
|
|
80
|
+
# Remove Foo and Abe's project
|
|
81
|
+
sprintData = sprintData %>%
|
|
82
|
+
filter(!name %in% c('Foo','Abe\'s projct'))
|
|
83
|
+
|
|
84
|
+
# How to deal with outliers
|
|
85
|
+
|
|
86
|
+
## Add numbering
|
|
87
|
+
sprintData = sprintData %>%
|
|
88
|
+
group_by(name) %>%
|
|
89
|
+
mutate(sprint_number = row_number()) %>%
|
|
90
|
+
add_count(name="project_sprint_count") %>%
|
|
91
|
+
mutate(project_percent_completed = sprint_number/project_sprint_count)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## Add velocity
|
|
95
|
+
|
|
96
|
+
sprintData = sprintData %>%
|
|
97
|
+
group_by(name) %>%
|
|
98
|
+
mutate(velocity = cumsum(completed)/sprint_number)
|
|
99
|
+
|
|
100
|
+
## Add Completion Percentage
|
|
101
|
+
sprintData = sprintData %>%
|
|
102
|
+
group_by(name) %>%
|
|
103
|
+
mutate(commitment_percentage = completed/commitment)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
f_labels <- sprintData %>% summarise(
|
|
108
|
+
Velocity = sd(velocity, na.rm=TRUE) %>% formatC(digits = 3),
|
|
109
|
+
"Commitment Percentage" = sd(commitment_percentage, na.rm=TRUE) %>% formatC(digits = 3)
|
|
110
|
+
) %>%
|
|
111
|
+
select(!"name") %>%
|
|
112
|
+
pivot_longer(
|
|
113
|
+
cols = c("Velocity", "Commitment Percentage"),
|
|
114
|
+
values_to = "label",
|
|
115
|
+
names_to = "measure" )
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
sprintDataPivot = sprintData %>%
|
|
119
|
+
select(!c(completed,commitment,sprint_id,project_sprint_count,project_percent_completed)) %>%
|
|
120
|
+
pivot_longer(
|
|
121
|
+
c(velocity,commitment_percentage),
|
|
122
|
+
names_to = "measure",
|
|
123
|
+
values_to = "value"
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
projectName = unique(sprintDataPivot$name)
|
|
127
|
+
|
|
128
|
+
velocity <- sprintDataPivot %>%
|
|
129
|
+
filter(measure == 'velocity') %>%
|
|
130
|
+
ggplot(aes(x = reorder(str_wrap(sprint_name,15),sprint_number),
|
|
131
|
+
y = value
|
|
132
|
+
)) +
|
|
133
|
+
geom_line(group=1,color = "#b9b9b9") +
|
|
134
|
+
geom_point(color = "#b9b9b9") +
|
|
135
|
+
# Add point values
|
|
136
|
+
geom_text_repel(
|
|
137
|
+
aes(label=round(value,2)),
|
|
138
|
+
direction = "y",
|
|
139
|
+
family = "roboto",
|
|
140
|
+
size = 10 * 5/14 * 0.8) +
|
|
141
|
+
# plot labels
|
|
142
|
+
labs(title=str_c(projectName,"Velocity", sep =" "),
|
|
143
|
+
x ="",
|
|
144
|
+
y = "") +
|
|
145
|
+
#themes
|
|
146
|
+
theme(
|
|
147
|
+
plot.title = element_text(family = "roboto"),
|
|
148
|
+
# NO x-axis labels
|
|
149
|
+
axis.title.x = element_blank(),
|
|
150
|
+
axis.text.x = element_blank(),
|
|
151
|
+
axis.title.y = element_text(family = "roboto"),
|
|
152
|
+
panel.grid.major.y = element_line(colour = "#D9D9D9"),
|
|
153
|
+
panel.grid.minor.y = element_line(colour = "#D9D9D9"),
|
|
154
|
+
panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank(),
|
|
155
|
+
# background color
|
|
156
|
+
panel.background = element_rect(fill = "#D9D9D920", colour = NA),
|
|
157
|
+
legend.position = "bottom",
|
|
158
|
+
plot.background = element_rect(colour = "#D9D9D9", fill=NA)
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
commitmentPercentage <- sprintDataPivot %>%
|
|
162
|
+
filter(measure == 'commitment_percentage') %>%
|
|
163
|
+
ggplot(aes(x = reorder(str_wrap(sprint_name,15),sprint_number),
|
|
164
|
+
y = value
|
|
165
|
+
)) +
|
|
166
|
+
geom_hline(yintercept = 1, color = "green") +
|
|
167
|
+
geom_hline(yintercept = .8, color = "yellow") +
|
|
168
|
+
geom_hline(yintercept = .6, color = "red") +
|
|
169
|
+
geom_line(group=1,color = "#b9b9b9") +
|
|
170
|
+
geom_point(color = "#b9b9b9") +
|
|
171
|
+
# Add point values
|
|
172
|
+
geom_text_repel(
|
|
173
|
+
aes(label=scales::label_percent()(round(value,2))),
|
|
174
|
+
direction = "y",
|
|
175
|
+
family = "roboto",
|
|
176
|
+
size = 10 * 5/14 * 0.8) +
|
|
177
|
+
# plot labels
|
|
178
|
+
labs(title=str_c(projectName,"Commitment Percentage", sep =" "),
|
|
179
|
+
x ="",
|
|
180
|
+
y = "") +
|
|
181
|
+
scale_y_continuous (labels = scales::percent) +
|
|
182
|
+
#themes
|
|
183
|
+
theme(
|
|
184
|
+
plot.title = element_text(family = "roboto"),
|
|
185
|
+
# has x-axis labels because this is the bottom plot
|
|
186
|
+
# TODO are these axis labels actually needed with the columns below
|
|
187
|
+
# axis.title.x = element_text(family = "roboto"),
|
|
188
|
+
# axis.text.x = element_text(angle = 45, vjust = 1, hjust=1),
|
|
189
|
+
axis.title.x = element_blank(),
|
|
190
|
+
axis.text.x = element_blank(),
|
|
191
|
+
axis.title.y = element_text(family = "roboto"),
|
|
192
|
+
panel.grid.major.y = element_line(colour = "#D9D9D9"),
|
|
193
|
+
panel.grid.minor.y = element_line(colour = "#D9D9D9"),
|
|
194
|
+
panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank(),
|
|
195
|
+
# background color
|
|
196
|
+
panel.background = element_rect(fill = "#D9D9D920", colour = NA),
|
|
197
|
+
legend.position = "bottom",
|
|
198
|
+
plot.background = element_rect(colour = "#D9D9D9", fill=NA)
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# Add StdDeviation to each plot
|
|
205
|
+
velocity <- velocity +
|
|
206
|
+
geom_label(
|
|
207
|
+
x = 1,
|
|
208
|
+
y = Inf,
|
|
209
|
+
aes(label = str_c("St Dev = ",label), hjust = "left", vjust = 1.3),
|
|
210
|
+
data = f_labels %>% filter(measure == 'Velocity')
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
commitmentPercentage <- commitmentPercentage +
|
|
214
|
+
geom_label(
|
|
215
|
+
x = 1,
|
|
216
|
+
y = Inf,
|
|
217
|
+
aes(label = str_c("St Dev = ",label), hjust = "left", vjust = 1.3),
|
|
218
|
+
data = f_labels %>% filter(measure == 'Commitment Percentage')
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# Add shading to commitment percentage plots
|
|
224
|
+
commitmentPercentage <- commitmentPercentage +
|
|
225
|
+
annotate(geom ="rect",xmin=-Inf,xmax=Inf,ymin=-Inf,ymax=0.6,fill=alpha(c("red"),0.1)) +
|
|
226
|
+
annotate(geom ="rect",xmin=-Inf,xmax=Inf,ymin=0.6,ymax=0.8,fill=alpha("yellow",0.1)) +
|
|
227
|
+
annotate(geom ="rect",xmin=-Inf,xmax=Inf,ymin=0.8,ymax=Inf,fill=alpha(c("green"),0.1))
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
### Generate Sprint Outcomes
|
|
232
|
+
|
|
233
|
+
# TODO - pull in the SQL here
|
|
234
|
+
outcomes = read_csv(str_c(Sys.getenv("HOME"),"/","outcomes.csv"))
|
|
235
|
+
|
|
236
|
+
outcomes <- outcomes %>%
|
|
237
|
+
tibble() %>%
|
|
238
|
+
filter(story_points != 0) %>%
|
|
239
|
+
mutate(
|
|
240
|
+
end_date = as.Date(end_date)
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# compute velocity statistics
|
|
244
|
+
|
|
245
|
+
entire_project_velocity = (outcomes %>%
|
|
246
|
+
filter(outcome == 'B-Delivered' ) %>%
|
|
247
|
+
summarize( average_velocity = mean(story_points)))$average_velocity
|
|
248
|
+
|
|
249
|
+
average_velocity = (outcomes %>%
|
|
250
|
+
filter(outcome == 'B-Delivered') %>%
|
|
251
|
+
filter(!sprint_name %in% c('Accessibility Improvement 0','Accessibility Improvements 1')) %>%
|
|
252
|
+
summarize( average_velocity = mean(story_points)))$average_velocity
|
|
253
|
+
|
|
254
|
+
# Compute 95% band velocity
|
|
255
|
+
|
|
256
|
+
outcomeColors = c("A-Commitment" = "#0B4F6C",
|
|
257
|
+
"Carryover" = "#D34E24",
|
|
258
|
+
"Carryover - External" = "#d3248d",
|
|
259
|
+
"Descoped" ="#A39BA8",
|
|
260
|
+
"Unplanned - Bug" ="#F28123",
|
|
261
|
+
"Unplanned - Story" = "#F7F052",
|
|
262
|
+
"B-Delivered" ="#00A878")
|
|
263
|
+
outcomeFills = c("A-Commitment" = "#0B4F6C",
|
|
264
|
+
"Carryover" = "#D34E24",
|
|
265
|
+
"Carryover - External" = "#d3248d",
|
|
266
|
+
"Descoped" ="#A39BA8",
|
|
267
|
+
"Unplanned - Bug" ="#F28123",
|
|
268
|
+
"Unplanned - Story" = "#F7F052",
|
|
269
|
+
"B-Delivered" ="#00A878")
|
|
270
|
+
|
|
271
|
+
chartTitle = str_c("Sprint Outcomes - ",unique(outcomes$project_name))
|
|
272
|
+
|
|
273
|
+
outcomePlot <-ggplot(outcomes,
|
|
274
|
+
aes(fill=outcome,
|
|
275
|
+
y=story_points,
|
|
276
|
+
# x=end_date
|
|
277
|
+
#x = str_wrap(sprint_name,15)
|
|
278
|
+
x = reorder(str_wrap(sprint_name,15),end_date)
|
|
279
|
+
)
|
|
280
|
+
)+
|
|
281
|
+
geom_bar(position="dodge", stat="identity",color = "black") +
|
|
282
|
+
# add bar labels
|
|
283
|
+
geom_text(data = outcomes %>% mutate(story_points = na_if(story_points,0)),
|
|
284
|
+
aes(label=story_points, y = story_points + .5),
|
|
285
|
+
position = position_dodge(0.9)) +
|
|
286
|
+
# trendline
|
|
287
|
+
geom_smooth(aes(#x=factor(end_date),
|
|
288
|
+
x=factor(reorder(str_wrap(sprint_name,15),end_date)),
|
|
289
|
+
y=story_points,group=outcome),
|
|
290
|
+
data = outcomes%>%filter(outcome=="B-Delivered"),
|
|
291
|
+
#method = "lm", # no method = curved line
|
|
292
|
+
se=FALSE,
|
|
293
|
+
show.legend = FALSE,
|
|
294
|
+
linetype = "dashed",
|
|
295
|
+
color = "#00A878") +
|
|
296
|
+
# TODO better position this annotation
|
|
297
|
+
annotate(geom="text",
|
|
298
|
+
x=length(unique(outcomes$sprint_name))+.25,
|
|
299
|
+
y=average_velocity + 1.5,
|
|
300
|
+
label="Trend Line") +
|
|
301
|
+
# average velocity line
|
|
302
|
+
geom_hline(yintercept=average_velocity,linetype = "dotted", color = "#00A878") +
|
|
303
|
+
annotate(geom="text", x=.75, y=average_velocity + 1.5, label="Average\nVelocity") +
|
|
304
|
+
# plot labels
|
|
305
|
+
labs(title=chartTitle,
|
|
306
|
+
# subtitle = 'Excluding the Data Science, Product Ownership and QA Teams',
|
|
307
|
+
x ="",
|
|
308
|
+
y = "Story Points",
|
|
309
|
+
fill='Outcomes') +
|
|
310
|
+
#colors
|
|
311
|
+
scale_colour_manual(values = outcomeColors) +
|
|
312
|
+
scale_fill_manual(values = outcomeFills) +
|
|
313
|
+
#themes
|
|
314
|
+
theme(
|
|
315
|
+
plot.title = element_text(family = "roboto"),
|
|
316
|
+
axis.title.x = element_text(family = "roboto"),
|
|
317
|
+
axis.text.x = element_text(angle = 45, vjust = 1, hjust=1),
|
|
318
|
+
axis.title.y = element_text(family = "roboto"),
|
|
319
|
+
panel.grid.major.y = element_line(colour = "#D9D9D9"), panel.grid.minor.y = element_line(colour = "#D9D9D9"),
|
|
320
|
+
panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank(),
|
|
321
|
+
# background color
|
|
322
|
+
panel.background = element_rect(fill = "#D9D9D920", colour = NA),
|
|
323
|
+
legend.position = "bottom",
|
|
324
|
+
plot.background = element_rect(colour = "#D9D9D9", fill=NA)
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
statsPlot <- velocity /
|
|
334
|
+
commitmentPercentage /
|
|
335
|
+
outcomePlot
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
# plot
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
ggsave(str_c(Sys.getenv("HOME"),"/",str_replace(projectName," ",""),"SprintStats.png"),plot=statsPlot,bg="white", width = 2882, height = 1700, units = "px")
|
|
344
|
+
|
|
345
|
+
print(str_c("Saving to ",str_c(Sys.getenv("HOME"),"/",str_replace(projectName," ",""),"SprintStats.png"),sep = " "))
|
|
@@ -3,6 +3,7 @@ library(zoo)
|
|
|
3
3
|
library(DBI)
|
|
4
4
|
library(RSQLite)
|
|
5
5
|
library(ggrepel)
|
|
6
|
+
library(patchwork)
|
|
6
7
|
|
|
7
8
|
args = commandArgs(trailingOnly=TRUE)
|
|
8
9
|
if (length(args)==0) {
|
|
@@ -54,8 +55,7 @@ select
|
|
|
54
55
|
commitment.start_date,
|
|
55
56
|
commitment.end_date,
|
|
56
57
|
commitment.story_points commitment,
|
|
57
|
-
completed.story_points completed
|
|
58
|
-
(completed.story_points*1.0 - commitment.story_points*1.0)/commitment.story_points * 100.0 commitment_variance
|
|
58
|
+
completed.story_points completed
|
|
59
59
|
from
|
|
60
60
|
commitment
|
|
61
61
|
LEFT JOIN completed on completed.sprint_id = commitment.sprint_id
|
|
@@ -106,54 +106,27 @@ sprintData = sprintData %>%
|
|
|
106
106
|
|
|
107
107
|
f_labels <- sprintData %>% summarise(
|
|
108
108
|
Velocity = sd(velocity, na.rm=TRUE) %>% formatC(digits = 3),
|
|
109
|
-
"Commitment Variance" = sd(commitment_variance, na.rm=TRUE) %>% formatC(digits = 3),
|
|
110
109
|
"Commitment Percentage" = sd(commitment_percentage, na.rm=TRUE) %>% formatC(digits = 3)
|
|
111
110
|
) %>%
|
|
112
111
|
select(!"name") %>%
|
|
113
112
|
pivot_longer(
|
|
114
|
-
cols = c("Velocity", "Commitment
|
|
113
|
+
cols = c("Velocity", "Commitment Percentage"),
|
|
115
114
|
values_to = "label",
|
|
116
115
|
names_to = "measure" )
|
|
117
116
|
|
|
118
117
|
|
|
119
|
-
# commitment_variance
|
|
120
|
-
# sprintData %>%
|
|
121
|
-
# ggplot(aes(x = sprint_number,
|
|
122
|
-
# y = commitment_variance,
|
|
123
|
-
# colour = name)) +
|
|
124
|
-
# geom_line() +
|
|
125
|
-
# geom_point()
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
# Sprint Velocity
|
|
130
|
-
# sprintData %>%
|
|
131
|
-
# ggplot(aes(x = sprint_number,
|
|
132
|
-
# y = velocity,
|
|
133
|
-
# colour = name)) +
|
|
134
|
-
# geom_line() +
|
|
135
|
-
# geom_point()
|
|
136
|
-
|
|
137
|
-
# Commitment Percentage
|
|
138
|
-
# sprintData %>%
|
|
139
|
-
# ggplot(aes(x = commitment_percentage,
|
|
140
|
-
# y = velocity,
|
|
141
|
-
# colour = name)) +
|
|
142
|
-
# geom_line() +
|
|
143
|
-
# geom_point()
|
|
144
|
-
|
|
145
|
-
|
|
146
118
|
sprintDataPivot = sprintData %>%
|
|
147
119
|
select(!c(completed,commitment,sprint_id,project_sprint_count,project_percent_completed)) %>%
|
|
148
120
|
pivot_longer(
|
|
149
|
-
c(velocity,commitment_percentage
|
|
121
|
+
c(velocity,commitment_percentage),
|
|
150
122
|
names_to = "measure",
|
|
151
123
|
values_to = "value"
|
|
152
124
|
)
|
|
153
125
|
|
|
154
126
|
projectName = unique(sprintDataPivot$name)
|
|
155
127
|
|
|
156
|
-
|
|
128
|
+
velocity <- sprintDataPivot %>%
|
|
129
|
+
filter(measure == 'velocity') %>%
|
|
157
130
|
ggplot(aes(x = reorder(str_wrap(sprint_name,15),sprint_number),
|
|
158
131
|
y = value
|
|
159
132
|
)) +
|
|
@@ -166,12 +139,50 @@ plot <- sprintDataPivot %>%
|
|
|
166
139
|
family = "roboto",
|
|
167
140
|
size = 10 * 5/14 * 0.8) +
|
|
168
141
|
# plot labels
|
|
169
|
-
labs(title=str_c(projectName,"
|
|
142
|
+
labs(title=str_c(projectName,"Velocity", sep =" "),
|
|
170
143
|
x ="",
|
|
171
144
|
y = "") +
|
|
172
145
|
#themes
|
|
173
146
|
theme(
|
|
174
147
|
plot.title = element_text(family = "roboto"),
|
|
148
|
+
# NO x-axis labels
|
|
149
|
+
axis.title.x = element_blank(),
|
|
150
|
+
axis.text.x = element_blank(),
|
|
151
|
+
axis.title.y = element_text(family = "roboto"),
|
|
152
|
+
panel.grid.major.y = element_line(colour = "#D9D9D9"),
|
|
153
|
+
panel.grid.minor.y = element_line(colour = "#D9D9D9"),
|
|
154
|
+
panel.grid.major.x = element_blank(), panel.grid.minor.x = element_blank(),
|
|
155
|
+
# background color
|
|
156
|
+
panel.background = element_rect(fill = "#D9D9D920", colour = NA),
|
|
157
|
+
legend.position = "bottom",
|
|
158
|
+
plot.background = element_rect(colour = "#D9D9D9", fill=NA)
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
commitmentPercentage <- sprintDataPivot %>%
|
|
162
|
+
filter(measure == 'commitment_percentage') %>%
|
|
163
|
+
ggplot(aes(x = reorder(str_wrap(sprint_name,15),sprint_number),
|
|
164
|
+
y = value
|
|
165
|
+
)) +
|
|
166
|
+
geom_hline(yintercept = 1, color = "green") +
|
|
167
|
+
geom_hline(yintercept = .8, color = "yellow") +
|
|
168
|
+
geom_hline(yintercept = .6, color = "red") +
|
|
169
|
+
geom_line(group=1,color = "#b9b9b9") +
|
|
170
|
+
geom_point(color = "#b9b9b9") +
|
|
171
|
+
# Add point values
|
|
172
|
+
geom_text_repel(
|
|
173
|
+
aes(label=scales::label_percent()(round(value,2))),
|
|
174
|
+
direction = "y",
|
|
175
|
+
family = "roboto",
|
|
176
|
+
size = 10 * 5/14 * 0.8) +
|
|
177
|
+
# plot labels
|
|
178
|
+
labs(title=str_c(projectName,"Commitment Percentage", sep =" "),
|
|
179
|
+
x ="",
|
|
180
|
+
y = "") +
|
|
181
|
+
scale_y_continuous (labels = scales::percent) +
|
|
182
|
+
#themes
|
|
183
|
+
theme(
|
|
184
|
+
plot.title = element_text(family = "roboto"),
|
|
185
|
+
# has x-axis labels because this is the bottom plot
|
|
175
186
|
axis.title.x = element_text(family = "roboto"),
|
|
176
187
|
axis.text.x = element_text(angle = 45, vjust = 1, hjust=1),
|
|
177
188
|
axis.title.y = element_text(family = "roboto"),
|
|
@@ -184,23 +195,46 @@ plot <- sprintDataPivot %>%
|
|
|
184
195
|
plot.background = element_rect(colour = "#D9D9D9", fill=NA)
|
|
185
196
|
)
|
|
186
197
|
|
|
187
|
-
plot <- plot + facet_wrap(
|
|
188
|
-
vars(str_to_title(sub("_"," ",measure))),
|
|
189
|
-
ncol = 1,
|
|
190
|
-
scales = "free_y"
|
|
191
|
-
)
|
|
192
198
|
|
|
193
|
-
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
# Add StdDeviation to each plot
|
|
202
|
+
velocity <- velocity +
|
|
194
203
|
geom_label(
|
|
195
204
|
x = 1,
|
|
196
205
|
y = Inf,
|
|
197
206
|
aes(label = str_c("St Dev = ",label), hjust = "left", vjust = 1.3),
|
|
198
|
-
data = f_labels
|
|
207
|
+
data = f_labels %>% filter(measure == 'Velocity')
|
|
199
208
|
)
|
|
200
209
|
|
|
210
|
+
commitmentPercentage <- commitmentPercentage +
|
|
211
|
+
geom_label(
|
|
212
|
+
x = 1,
|
|
213
|
+
y = Inf,
|
|
214
|
+
aes(label = str_c("St Dev = ",label), hjust = "left", vjust = 1.3),
|
|
215
|
+
data = f_labels %>% filter(measure == 'Commitment Percentage')
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
# Add shading to commitment percentage plots
|
|
221
|
+
commitmentPercentage <- commitmentPercentage +
|
|
222
|
+
annotate(geom ="rect",xmin=-Inf,xmax=Inf,ymin=-Inf,ymax=0.6,fill=alpha(c("red"),0.1)) +
|
|
223
|
+
annotate(geom ="rect",xmin=-Inf,xmax=Inf,ymin=0.6,ymax=0.8,fill=alpha("yellow",0.1)) +
|
|
224
|
+
annotate(geom ="rect",xmin=-Inf,xmax=Inf,ymin=0.8,ymax=Inf,fill=alpha(c("green"),0.1))
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
statsPlot <- velocity /
|
|
230
|
+
commitmentPercentage
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
201
235
|
# plot
|
|
202
236
|
|
|
203
237
|
|
|
204
|
-
ggsave(str_c(Sys.getenv("HOME"),"/",str_replace(projectName," ",""),"SprintStats.png"),plot=
|
|
238
|
+
ggsave(str_c(Sys.getenv("HOME"),"/",str_replace(projectName," ",""),"SprintStats.png"),plot=statsPlot,bg="white", width = 2882, height = 1700, units = "px")
|
|
205
239
|
|
|
206
240
|
print(str_c("Saving to ",str_c(Sys.getenv("HOME"),"/",str_replace(projectName," ",""),"SprintStats.png"),sep = " "))
|
package/cmds/stats.js
CHANGED
|
@@ -45,7 +45,7 @@ const handler = async function () {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
console.log('Making statistics visualizations')
|
|
48
|
-
const cmd = `Rscript ${__dirname}/../R/
|
|
48
|
+
const cmd = `Rscript ${__dirname}/../R/combinedStats.R ${project_id}`
|
|
49
49
|
exec(cmd, function(err, stdout, stderr) {
|
|
50
50
|
if (err) {
|
|
51
51
|
console.log(stderr);
|