The Report previewer is an advanced shiny module designed for
visualization, editing, and downloading of report cards. It extended the
base modules introduced in the simpleReporter
vignette,
enhancing interactivity and user engagement with report content.
The report previewer is now implemented as a modal dialog that opens when a preview button is clicked, providing a streamlined user experience without requiring separate tabs.
The five essential steps for implementing the report previewer
include integrating it within a shiny application. Key code segments are
highlighted in ### REPORTER
code blocks.
- Add the preview button UI component to your app’s interface.
- Integrate the UI components of the modules into the app’s UI.
- Initialize reporter instance.
- Create a reactive that must return a
teal_card
object. Theteal_card
object should be built step by step, assuming that it is empty at the beginning. Please note that the document page’s design is up to the developer’s imagination. - Invoke the servers with the
Reporter
instance and the function to create theteal_card
instance.
The code added to introduce the reporter is wrapped in the
### REPORTER
code blocks.
First, load the required packages:
A basic shiny
app with the previewer module:
ui <- bslib::page_fluid(
sidebarLayout(
sidebarPanel(
uiOutput("encoding")
),
mainPanel(
tabsetPanel(
id = "tabs",
tabPanel("Plot", plotOutput("dist_plot")),
tabPanel("Table", verbatimTextOutput("table")),
tabPanel("Table DataFrame", verbatimTextOutput("table2")),
tabPanel("Table DataTable", DTOutput("table3"))
)
)
)
)
server <- function(input, output, session) {
output$encoding <- renderUI({
shiny::tagList(
### REPORTER
teal.reporter::add_card_button_ui("add_reporter", label = "Add Report Card"),
tags$div(style = "margin-bottom: 0.5em;"), # empty separator
teal.reporter::preview_report_button_ui("previewer"),
###
if (input$tabs == "Plot") {
sliderInput(
"binwidth",
"binwidth",
min = 2,
max = 10,
value = 8
)
} else if (input$tabs %in% c("Table", "Table DataFrame", "Table DataTable")) {
selectInput(
"stat",
label = "Statistic",
choices = c("mean", "median", "sd"),
"mean"
)
} else {
NULL
}
)
})
plot <- reactive({
req(input$binwidth)
x <- mtcars$mpg
ggplot(data = mtcars, aes(x = mpg)) +
geom_histogram(binwidth = input$binwidth)
})
output$dist_plot <- renderPlot(plot())
table <- reactive({
req(input$stat)
lyt <- basic_table() %>%
split_rows_by("Month", label_pos = "visible") %>%
analyze("Ozone", afun = eval(str2expression(input$stat)))
build_table(lyt, airquality)
})
output$table <- renderPrint(table())
table2 <- reactive({
req(input$stat)
data <- aggregate(
airquality[, c("Ozone"), drop = FALSE], list(Month = airquality$Month), get(input$stat),
na.rm = TRUE
)
colnames(data) <- c("Month", input$stat)
data
})
output$table2 <- renderPrint(print.data.frame(table2()))
output$table3 <- renderDT(table2())
### REPORTER
reporter <- Reporter$new()
# Optionally set reporter id to e.g. secure report reload only for the same app
# The id is added to the downloaded file name.
reporter$set_id("myappid")
card_r <- reactive({
card <- teal_card()
card <- if (input$tabs == "Plot") {
metadata(card, "title") <- "Plot Module"
c(
card,
"## My plot",
plot(),
code_chunk(
paste(
"x <- mtcars$mpg",
"ggplot2::ggplot(data = mtcars, ggplot2::aes(x = mpg)) +",
paste0("ggplot2::geom_histogram(binwidth = ", input$binwidth, ")"),
sep = "\n"
)
)
)
} else if (input$tabs == "Table") {
metadata(card, "title") <- "Table Module rtables"
c(
card,
"## My rtables",
table,
code_chunk(
paste(
"lyt <- rtables::basic_table() %>%",
'rtables::split_rows_by("Month", label_pos = "visible") %>%',
paste0('rtables::analyze("Ozone", afun = ', input$stat, ")"),
"rtables::build_table(lyt, airquality)",
sep = "\n"
)
)
)
} else if (input$tabs %in% c("Table DataFrame", "Table DataTable")) {
metadata(card, "title") <- "Table Module DF"
c(
card,
"## My Table DF",
table2(),
paste(
"```",
paste0(
'data <- aggregate(airquality[, c("Ozone"), drop = FALSE], list(Month = airquality$Month), ',
input$stat,
", na.rm = TRUE)"
),
sprintf('colnames(data) <- c("Month", "%s")', input$stat),
"data",
"```",
sep = "\n"
)
)
}
})
teal.reporter::add_card_button_srv("add_reporter", reporter = reporter, card_fun = card_r)
teal.reporter::preview_report_button_srv("previewer", reporter)
###
}
shinyApp(ui = ui, server = server)