Skip to content

Commit fb143f3

Browse files
authored
Merge pull request #100 from ropensci-review-tools/quarto-org
start of org dashboard for #99
2 parents 1079e89 + a9dc09d commit fb143f3

File tree

6 files changed

+320
-2
lines changed

6 files changed

+320
-2
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: repometrics
22
Title: Metrics for Your Code Repository
3-
Version: 0.1.6.006
3+
Version: 0.1.6.020
44
Authors@R:
55
person("Mark", "Padgham", , "mark.padgham@email.com", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0003-2172-5265"))

R/quarto-dashboard-org.R

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#' Start quarto dashboard with results of
2+
#' `repometrics_collate_org_data` function for collation of data across orgs.
3+
#'
4+
#' @param data_org Data on GitHub organization as returned from
5+
#' `repometrics_collate_org_data` function.
6+
#' @param action One of "preview", to start and open a live preview of the
7+
#' dashboard website, or "render" to render a static version without previewing
8+
#' or opening.
9+
#' @return (Invisibly) Path to main "index.html" document of quarto site. Note
10+
#' that the site must be served with `action = "preview"`, and will not work by
11+
#' simply opening this "index.html" file.
12+
#' @export
13+
orgmetrics_dashboard <- function (data_org, data_users, action = "preview") {
14+
15+
data_all <- data_org_preprocess (data_org) |>
16+
dplyr::select (-org, -date) |>
17+
tidyr::pivot_longer (-package)
18+
19+
requireNamespace ("brio")
20+
requireNamespace ("jsonlite")
21+
requireNamespace ("quarto")
22+
requireNamespace ("withr")
23+
24+
action <- match.arg (action, c ("preview", "render"))
25+
quarto_action <- paste0 ("quarto::quarto_", action)
26+
27+
path_src <- system.file ("extdata", "quarto-org", package = "repometrics")
28+
path_dest <- fs::path (fs::path_temp (), "quarto-org")
29+
dir <- fs::dir_copy (path_src, path_dest, overwrite = TRUE)
30+
saveRDS (data_all, fs::path (dir, "results-org.Rds"))
31+
32+
withr::with_dir (dir, {
33+
do.call (eval (parse (text = quarto_action)), list ())
34+
})
35+
}
36+
37+
#' Pre-process organization data by converting all model values to standard
38+
#' z-scores, retrieving the latest value only for each package, and generating
39+
#' a "final" score from the sum across all model scores. Higher values of this
40+
#' final score are better than lower values.
41+
#' @noRd
42+
data_org_preprocess <- function (data_org) {
43+
44+
data_org |>
45+
dplyr::mutate (
46+
dplyr::across (dplyr::where (is.numeric), ~ scale (.) [, 1])
47+
) |>
48+
dplyr::group_by (package) |>
49+
dplyr::slice_head (n = 1L) |>
50+
dplyr::mutate (org = gsub ("\\/.*$", "", package), .after = package) |>
51+
dplyr::mutate (package = gsub ("^.*\\/", "", package)) |>
52+
dplyr::mutate (
53+
final = sum (dplyr::across (dplyr::where (is.numeric))),
54+
.after = "date"
55+
) |>
56+
dplyr::arrange (dplyr::desc (final))
57+
}

codemeta.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"codeRepository": "https://github.com/ropensci-review-tools/repometrics",
99
"issueTracker": "https://github.com/ropensci-review-tools/repometrics/issues",
1010
"license": "https://spdx.org/licenses/GPL-3.0",
11-
"version": "0.1.6.006",
11+
"version": "0.1.6.020",
1212
"programmingLanguage": {
1313
"@type": "ComputerLanguage",
1414
"name": "R",

inst/extdata/quarto-org/_quarto.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
project:
2+
type: website
3+
4+
website:
5+
title: "Organization"
6+
cookie-consent:
7+
type: express
8+
navbar:
9+
left:
10+
- models.qmd
11+
right:
12+
- icon: "github"
13+
menu:
14+
- text: Source Code
15+
url: https://github.com/ropensci-review-tools/repometrics
16+
- text: Request a Feature
17+
url: https://github.com/ropensci-review-tools/repometrics/issues/new
18+
19+
format:
20+
html:
21+
theme: cosmo
22+
toc: true

inst/extdata/quarto-org/index.qmd

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
title: "Organization-level Metrics and Models"
3+
---

inst/extdata/quarto-org/models.qmd

+236
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
---
2+
title: "Community Models"
3+
execute:
4+
echo: false
5+
format:
6+
html:
7+
fig-width: 8
8+
fig-height: 4
9+
code-fold: false
10+
---
11+
12+
```{r load-pkg, echo = FALSE, message = FALSE}
13+
library (repometrics)
14+
```
15+
This page shows aggregate community health scores for all repositories within
16+
the "reconhub" and "epiverse-trace" organizations. Higher values describe
17+
repositories with greater community health scores.
18+
19+
```{r load-data}
20+
dat_models <- readRDS ("results-org.Rds") |>
21+
as.data.frame ()
22+
```
23+
```{r ojs-in-models, echo = FALSE}
24+
ojs_define (models_in = dat_models)
25+
```
26+
```{ojs}
27+
models_all = {
28+
return transpose(models_in).map(row => ({
29+
...row,
30+
}));
31+
}
32+
models_final = models_all.filter(function(mod) {
33+
return mod.name.includes("final")
34+
})
35+
models_len = models_final.length
36+
```
37+
38+
39+
```{ojs plot-all-community-health-vars}
40+
Plot.plot({
41+
height: 20 * models_len,
42+
marginLeft: 60,
43+
marginRight: 160,
44+
marginTop: 50,
45+
marginBottom: 50,
46+
axis: null,
47+
x: {
48+
axis: "top",
49+
grid: true,
50+
label: "Community Health"
51+
},
52+
y: { grid: true },
53+
marks: [
54+
Plot.barX(models_final, {
55+
y: "package",
56+
x: "value",
57+
sort: {y: "-x" },
58+
fill: "value",
59+
}),
60+
Plot.barX(models_final,
61+
Plot.pointer(
62+
{
63+
y: "package",
64+
x: "value",
65+
sort: {y: "-x" },
66+
stroke: "gray",
67+
fill: "value",
68+
strokeWidth: 2,
69+
})
70+
),
71+
Plot.text(models_final, {
72+
x: (d) => d.value < 0 ? 0 : d.value,
73+
y: "package",
74+
text: "package",
75+
textAnchor: "start",
76+
fontSize: 16,
77+
dx: 5
78+
})
79+
],
80+
color: {
81+
scheme: "Cool",
82+
type: "ordinal"
83+
}
84+
})
85+
```
86+
87+
## Individual components of community health
88+
89+
The following section shows the individual components of community health for
90+
all repositories.
91+
92+
```{ojs comm-health-vars}
93+
commHealthVars = [
94+
"collab_devel_index",
95+
"comm_serv_support",
96+
"comm_welcoming",
97+
"community_activity",
98+
"dev_responsiveness",
99+
"oss_compliance",
100+
"proj_awareness",
101+
"proj_engagement",
102+
"starter_health",
103+
"viability_community",
104+
"viability_gov",
105+
"viability_starter",
106+
"viability_strategy"
107+
]
108+
viewof commHealthVar = Inputs.select(
109+
commHealthVars,
110+
{ multiple: "false", label: "Community Health Variable" }
111+
);
112+
```
113+
114+
```{ojs}
115+
models_filtered = models_all.filter(function(mod) {
116+
return mod.name.includes(commHealthVar)
117+
})
118+
```
119+
120+
121+
```{ojs plot-filtered-community-health-var}
122+
Plot.plot({
123+
height: 20 * models_len,
124+
marginLeft: 60,
125+
marginRight: 160,
126+
marginTop: 50,
127+
marginBottom: 50,
128+
axis: null,
129+
x: {
130+
axis: "top",
131+
grid: true,
132+
label: "Community Health"
133+
},
134+
y: { grid: true },
135+
marks: [
136+
Plot.barX(models_filtered, {
137+
y: "package",
138+
x: "value",
139+
sort: {y: "-x" },
140+
fill: "value",
141+
}),
142+
Plot.barX(models_filtered,
143+
Plot.pointer(
144+
{
145+
y: "package",
146+
x: "value",
147+
sort: {y: "-x" },
148+
stroke: "gray",
149+
fill: "value",
150+
strokeWidth: 2,
151+
})
152+
),
153+
Plot.text(models_filtered, {
154+
x: (d) => d.value < 0 ? 0 : d.value,
155+
y: "package",
156+
text: "package",
157+
textAnchor: "start",
158+
fontSize: 16,
159+
dx: 5
160+
})
161+
],
162+
color: {
163+
scheme: "Cool",
164+
type: "ordinal"
165+
}
166+
})
167+
```
168+
169+
## Community health for individual repositories
170+
171+
The following section all components of community health for a selected
172+
repository.
173+
174+
```{ojs get-all-models}
175+
// Get array of unique repo names for input selector:
176+
reposAll = models_all.map(function(item) {
177+
return item.package;
178+
});
179+
repos = Array.from(new Set(reposAll));
180+
viewof repo = Inputs.select(repos, {multiple: false, label: "Repository:"})
181+
```
182+
183+
```{ojs}
184+
model_repo = models_all.filter(function(mod) {
185+
return mod.package.includes(repo) && mod.name !== "final"
186+
})
187+
model_repo_len = model_repo.length
188+
```
189+
190+
```{ojs plot-filtered-repo}
191+
Plot.plot({
192+
height: 40 * model_repo_len,
193+
marginLeft: 60,
194+
marginRight: 160,
195+
marginTop: 50,
196+
marginBottom: 50,
197+
axis: null,
198+
x: {
199+
axis: "top",
200+
grid: true,
201+
label: "Community Health"
202+
},
203+
y: { grid: true },
204+
marks: [
205+
Plot.barX(model_repo, {
206+
y: "name",
207+
x: "value",
208+
sort: {y: "-x" },
209+
fill: "value",
210+
}),
211+
Plot.barX(model_repo,
212+
Plot.pointer(
213+
{
214+
y: "name",
215+
x: "value",
216+
sort: {y: "-x" },
217+
stroke: "gray",
218+
fill: "value",
219+
strokeWidth: 2,
220+
})
221+
),
222+
Plot.text(model_repo, {
223+
x: (d) => d.value < 0 ? 0 : d.value,
224+
y: "name",
225+
text: "name",
226+
textAnchor: "start",
227+
fontSize: 16,
228+
dx: 5
229+
})
230+
],
231+
color: {
232+
scheme: "Cool",
233+
type: "ordinal"
234+
}
235+
})
236+
```

0 commit comments

Comments
 (0)