---
title: "Observable"
format:
html:
toc: true
echo: false
warning: false
messages: false
code-summary: "Show the code"
code-tools: true
---
```{r}
library (crosstalk)
library (reactable)
library (dplyr)
ae_att <- NHSRdatasets:: ae_attendances
distinct_ae <- ae_att |>
dplyr:: filter (type == 1 ,
period == "2017-03-01" )
ojs_define (data = ae_att)
organisations <- sort (unique (distinct_ae$ org_code))
ojs_define (orgCodes = organisations)
subset_df <- ae_att |>
filter (org_code == "RRF" , type == 1 ) |>
arrange (period)
ojs_define (subset_aeatt = subset_df)
```
::: panel-tabset
## SPC Plot - WIP
Built with the help of Observable notebooks (see README).
<https://observablehq.com/@training/replicating-nhsrplotthedots-spcs>
Calculating mean used a function from D3:
<https://talk.observablehq.com/t/histogram-with-average-line/7099>
<https://observablehq.com/@d3/d3-mean-d3-median-and-friends>
```{ojs}
d3 = require("d3@7")
```
```{ojs}
Inputs.table(transpose(subset_aeatt), { sort: "period", reverse: false })
Plot.plot({
title: "A and E Attendances",
x: { label: "Dates" },
y: { label: "Breaches" },
marks: [
Plot.frame({ strokeOpacity: 0.1, marginRight: 25 }),
Plot.dot(transpose(subset_aeatt), {
x: "period",
y: "breaches",
fill: "gray",
r: 6
}),
Plot.dot(
transpose(subset_aeatt),
Plot.pointer({
x: "period",
y: "breaches",
fill: "gray",
stroke: "type",
opacity: 0.6,
r: 8,
tip: true,
// title: (d) => `Breaches: ${d.breaches}\nDate: ${d.period.toISOString().slice(0, 10)}`
}),
),
Plot.tip(transpose(subset_aeatt), Plot.selectMaxY({
x: "period",
y: "breaches"
})),
Plot.crosshair(transpose(subset_aeatt), {
x: "period",
y: "breaches"
}),
Plot.lineY(transpose(subset_aeatt), {
x: "period",
y: "breaches"
}),
Plot.ruleY([d3.mean(transpose(subset_aeatt).map(d => d.breaches))], {
stroke: "red",
tip: true,
title: (d) => `Breaches: ${d3.mean(transpose(subset_aeatt).map(d => d.breaches))}`
}),
Plot.text(
transpose(subset_aeatt),
Plot.selectLast({
x: "period",
y: "breaches",
text: "org_code",
dx: 12,
fontSize: 12
})
)
]
})
```
## Facet attempt
```{ojs}
//| panel: input
//| layout-ncol: 1
viewof attendances = Inputs.checkbox(
["1", "2", "other"],
{value: ["1", "2"],
label: "Attendance type:"}
)
viewof code = Inputs.checkbox(
["R1H", "RRK", "RF4"],
{value: ["R1H", "RF4"],
label: "Hospitals:"
}
)
```
```{ojs}
filtered = transpose(data).filter(function(hospital){
return attendances.includes(hospital.type) &&
code.includes(hospital.org_code);
})
```
```{ojs}
//| code-fold: true
Plot.plot({
grid: true,
marginRight: 60,
facet: {label: null},
marks: [
Plot.frame(),
Plot.lineY(filtered, {
x: "period",
y: "breaches",
fx: "type",
fy: "org_code",
sort: "period",
tip: true
})
]
})
```
## SPC
This uses `NHSRplotthedots` for the `plotly` chart and is the development version (not CRAN).
The only interactivity is from `plotly` itself.
It might be that the data needs to be pre calculated (using `NHSRplotthedots` to get that possibly) but would mean that there is potentially a huge dataset needed to be manipulated at the output side.
```{r}
library (NHSRdatasets)
library (NHSRplotthedots)
library (dplyr)
NHSRdatasets:: ae_attendances |>
dplyr:: filter (org_code == "RQM" ,
type == 1 ) |>
NHSRplotthedots:: ptd_spc (
value_field = breaches,
date_field = period,
improvement_direction = "decrease"
) |>
NHSRplotthedots:: ptd_create_plotly (
)
```
## reactable link - WIP
Trying out code to link the codes to a reactable from the [ timelyportfolio blog ](https://timelyportfolio.github.io/quarto_tests/examples/quarto_observable_crosstalk/quarto_observable_crosstalk.html)
```{ojs}
// use Observable select input to allow user to pick states
viewof selectedCodes = Inputs.select(orgCodes, {label: "NHS hospitals", multiple: true})
```
```{r}
# Note since we do not supply a key in SharedData$new() the keys will be rownames(state.x77) which are the state names that populate the Observable selection output.
dat <- SharedData$ new (distinct_ae, ~ org_code)
reactable (dat)
```
:::