I had previously developed a demo minimalist Shiny app that relies on the RuODK
package that @Florian_May has developed to retrieve the data in real-time from ODK Central. The data retrieval takes a bit of time on my test database (~10s for 6 forms, the largest database having 20 submissions with 219 columns), but I have not tried to optimise it and I did not develop specific performance tests, so I cannot tell you how the Shiny app will behave with larger databases. Shiny apps are something I would like to investigate more (with Flask, Dash or Django apps in Python), but I unfortunately just do not have enough time to dedicate to this and had to prioritise the generation of markdown reports over shiny dashboards, since this is a much simpler and quicker way to visualise data.
In practice what I had done is to create a R package in which I defined generic core Shiny components (modules). This way you can create several Shiny apps building from these core components and store the server and user interface definition of each app in a specific folder in the inst/shiny/
folder of my package, e.g., inst/shiny/app1
, inst/shiny/app2
. ruODK
is only called in in the server definition of the Shiny app. When a package is installed, everything in the inst/
folder is copied into the top-level package directory. About the core Shiny components themselves, you can have a look at a few examples (..._module.R
files). The file run_app.R
contains the calls to the different Shiny apps, so that when the package is installed you can simply use timci::run_mini_app()
to launch your app.
run_mini_app <- function() {
appDir <- system.file("shiny", "mini", package = "timci")
if (appDir == "") {
stop("Could not find `mini` directory. Try re-installing `timci`.", call. = FALSE)
}
shiny::runApp(appDir,
launch.browser = TRUE,
display.mode = "normal")
}
server.R
# Defines the server logic for the minimalist Shiny web application
#
# Find out more about building applications with Shiny here:
# http://shiny.rstudio.com/
library(ruODK)
library(hash)
server <- function(input, output) {
#######################################
# ODK CENTRAL SERVER CONNECTION SETUP #
#######################################
# Connect to the ODK Central server using ruODK
ruODK::ru_setup(
svc = Sys.getenv("ODKC_SVC"),
un = Sys.getenv("ODKC_UN"),
pw = Sys.getenv("ODKC_PW"),
tz = Sys.getenv("TZ"),
verbose = FALSE # Can be switched to TRUE for demo or debugging
)
################
# RAW ODK DATA #
################
# Load ODK forms that have at least 1 submission
odk_form_list <- ruODK::form_list()
valid_odk_forms <- subset(odk_form_list, submissions > 0, select = c(fid))
valid_odk_form_list <- valid_odk_forms$fid
# Load ODK data
odk_data <- hash::hash()
for (form in valid_odk_form_list) {
odk_data[[form]] <- ruODK::odata_submission_get(fid = form)
}
# Execute the form selection module
current_odk_form <- timci::select_list_item_server("select_odk_form",
valid_odk_form_list,
odk_data)
# Execute the info module about the raw ODK data
timci::reactive_odk_data_info_server("raw_odk_info", current_odk_form)
# Execute the table module that displays the raw ODK data
timci::reactive_data_table_server("raw_odk_table", current_odk_form)
# Execute the CSV and Excel download modules
timci::reactive_csv_download_server("raw_odk_csv_export", current_odk_form)
timci::reactive_xlsx_download_server("raw_odk_xlsx_export", current_odk_form)
}
ui.R
# Defines the UI for the minimalist Shiny web application
#
# Find out more about building applications with Shiny here:
# http://shiny.rstudio.com/
# Define UI
ui <- shiny::fluidPage(
shiny::navbarPage("TIMCI Dashboard", id="nav",
shiny::navbarMenu("Data",
# Raw ODK data panel (will be hidden / access restricted)
shiny::tabPanel("ODK data",
# Sidebar layout with input and output definitions
shiny::sidebarLayout(
# Sidebar panel for inputs
shiny::sidebarPanel(
# Help text
shiny::helpText("ODK form selection"),
# Display the list item selection module
timci::select_list_item_ui("select_odk_form"),
# Info text
shiny::p(shiny::strong("Database information")),
# Study data info
timci::odk_data_info_ui("raw_odk_info"),
# Export study data in *.csv format
timci::csv_download_ui("raw_odk_csv_export"),
# Export study data in *.xlsx format
timci::xlsx_download_ui("raw_odk_xlsx_export")),
# Display the table module
shiny::mainPanel(
shiny::fluidRow(
timci::data_table_ui("raw_odk_table"))))
)
)
)
)
Minimalist Shiny app (obviously the real interest is in adding more modules to this minimalist example)