The Countdown apps (cd2030.rmncah,
cd2030.vaxx, cd2030.pooled) are Shiny front ends to this package.
cd2030.core holds everything they share: the app frame, the Load Data
screen, the analysis pages, the filters and the report content. An app
is a small package that says what is particular to it. This guide
describes the parts and how they fit;
cd2030.rmncah::run_app() is the complete example.
DataSuite
└─ countdown-analytics the DataSuite extension: lists the apps
└─ cd2030.rmncah / cd2030.vaxx / cd2030.pooled one R package per app: run_app()
└─ cd2030.core analysis, pages, Load Data screen, report content
└─ datasuite.ui interface kit, chart options, report builder
datasuite.ui knows nothing about Countdown: it has the components, the page frame and the report engine. cd2030.core plugs Countdown into it. An app adds its indicator group, its pages and its text.
An app’s run_app() does five things, in this order.
set_selected_group("rmncah")
options(
cd2030.app_group = "rmncah",
cd2030.config = list(
nat_cov_indicators = c("anc4", "instlivebirths", "penta3", "measles1"),
consistency_pairs = list(c("anc1", "penta1"), c("penta1", "penta3")),
has_maternal = TRUE
)
)cd2030.config is what the shared pages read to know what
to show for this app: which indicators a page offers, which pairs the
consistency check compares, whether there is a maternal denominator. A
page reads a setting with cd_cfg(), and
?cd_cfg lists the keys.
The Load Data screen is the same in every app. The fields it asks for
(which surveys, which rates) come from
options(cd2030.wizard = ...);
?cd_upload_data_ui describes them and the builders for an
app’s own fields.
Every label is a translation key. The app’s own file is merged with datasuite.ui’s and cd2030.core’s.
A page is a _ui function and a _server
function. The app lists every page it has, shared or its own, with the
kit’s cd_page_def(): the id, the two functions, and the
keys of its title and subtitle.
my_pages <- function() list(
cd_page_def(
id = "reporting_rate",
ui = reporting_rate_ui, server = reporting_rate_server, # a shared page, from cd2030.core
title = "title_rr_main", section = "lbl_nav_section_quality", subtitle = "sub_rr_main"
),
cd_page_def(
id = "my_page",
ui = my_page_ui, server = my_page_server, # a page of the app's own
title = "title_my_page", section = "lbl_nav_section_analysis", subtitle = "sub_my_page"
)
)
pages <- my_pages()
cd_use_pages(pages)The shared pages are listed in the reference under “App: pages”.
A page’s _ui function builds its layout from the kit’s
components and the shared pieces in this package. Its
_server function receives the dataset as a reactive
cache and draws from it.
my_page_ui <- function(id, i18n) {
ns <- shiny::NS(id)
cd_page_ui(id, i18n = i18n, cd_table_ui(ns("table")))
}
my_page_server <- function(id, cache, i18n) {
shiny::moduleServer(id, function(input, output, session) {
cd_table_server("table", data = shiny::reactive(cache()$reporting_rate_national), i18n = i18n)
})
}The pieces a page is built from each have a help page, grouped in the reference:
| Group | What is in it | Start at |
|---|---|---|
| App: building an app | cd_app(), the settings, the guide to the interface |
?cd_app, ?"countdown-pages" |
| App: pages | the shared analysis pages, each a _ui /
_server pair |
?reporting_rate_ui |
| App: Load Data wizard | the Load Data screen, its steps and field builders | ?cd_upload_data_ui |
| App: filters | indicator, administrative level, denominator, years | ?cd_admin_level_ui |
| App: layout | the dataset header, sidebar sections, scoped pages, tabbed charts | ?cd_scope |
| App: charts and tables | chart and table cards with their downloads | ?cd_table_ui |
Read the source of a shared page that resembles yours before writing
one: R/page-reporting_rate.R is a short one. The kit’s own
components are described in datasuite.ui
(docs/COMPONENTS.md).
A page should read results from the dataset object, not compute them.
Each result is computed once, kept, and cleared when something it
depends on changes, so two pages showing the same table do not compute
it twice. ?CacheConnection lists them, and
cache_definition() says for any of them what it depends on
and which pages show it.
During development, load the app package and call its
run_app():
In DataSuite, the countdown-analytics extension names each app’s
package; DataSuite installs the package from r-universe with the
extension, and starts run_app() with the chosen file and
language. An app’s DESCRIPTION must require the cd2030.core
version it needs (cd2030.core (>= 1.4.0)), because
DataSuite only updates a package when a newer version is required.