Reporter Previewer is a shiny module to visualize and manipulate the
already added report Cards, and eventually downloading a report
document. Reporter Previewer is extended by the base modules introduced
in the simpleReporter
vignette.
For clarity, in the app below the code added to introduce the
reporter is wrapped in the ### REPORTER
code blocks.
The implementation should consist of 5 steps:
- Create a
tabsetPanel
with the main app and the Previewer. - Add modules user interface to the user interface of the app.
- Initialize Reporter instance.
- Create the Report Card function with two optional arguments: card
and comment. This function must return a
ReportCard
object. The function should build the Card step by step and assuming it is empty at the beginning, the optional comment argument is a string provided by the user when the card is added. If the comment argument is not specified then it is added automatically at the end of the Card. If the card argument is added then theReportCard
instance is automatically created for the user, otherwise the function should create the card itself. This part requires the developer to use their imagination as to what the document page should look like. - Invoke the servers with the reporter instance and the function to create the report 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 <- fluidPage(
# please, specify specific bootstrap version and theme
theme = bslib::bs_theme(version = "4"),
titlePanel(""),
tabsetPanel(
tabPanel(
"main App",
tags$br(),
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", DT::dataTableOutput("table3"))
)
)
)
),
### REPORTER
tabPanel(
"Previewer",
reporter_previewer_ui("prev")
)
###
)
)
server <- function(input, output, session) {
output$encoding <- renderUI({
tagList(
### REPORTER
teal.reporter::simple_reporter_ui("simple_reporter"),
###
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
ggplot2::ggplot(data = mtcars, ggplot2::aes(x = mpg)) +
ggplot2::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 <- DT::renderDataTable(table2())
### REPORTER
reporter <- teal.reporter::Reporter$new()
card_fun <- function(card = ReportCard$new(), comment) {
if (input$tabs == "Plot") {
card$set_name("Plot Module")
card$append_text("My plot", "header2")
card$append_plot(plot())
card$append_rcode(
paste(
c(
"x <- mtcars$mpg",
"ggplot2::ggplot(data = mtcars, ggplot2::aes(x = mpg)) +",
paste0("ggplot2::geom_histogram(binwidth = ", input$binwidth, ")")
),
collapse = "\n"
),
echo = TRUE,
eval = FALSE
)
} else if (input$tabs == "Table") {
card$set_name("Table Module rtables")
card$append_text("My rtables", "header2")
card$append_table(table())
card$append_rcode(
paste(
c(
"lyt <- rtables::basic_table() %>%",
'rtables::split_rows_by("Month", label_pos = "visible") %>%',
paste0('rtables::analyze("Ozone", afun = ', input$stat, ")"),
"rtables::build_table(lyt, airquality)"
),
collapse = "\n"
),
echo = TRUE,
eval = FALSE
)
} else if (input$tabs %in% c("Table DataFrame", "Table DataTable")) {
card$set_name("Table Module DF")
card$append_text("My Table DF", "header2")
card$append_table(table2())
# Here r code added as a regular verbatim text
card$append_text(
paste0(
c(
'data <- aggregate(airquality[, c("Ozone"), drop = FALSE], list(Month = airquality$Month), ',
input$stat,
", na.rm = TRUE)\n",
'colnames(data) <- c("Month", ', paste0('"', input$stat, '"'), ")\n",
"data"
),
collapse = ""
), "verbatim"
)
}
if (!comment == "") {
card$append_text("Comment", "header3")
card$append_text(comment)
}
card
}
teal.reporter::simple_reporter_srv("simple_reporter", reporter = reporter, card_fun = card_fun)
teal.reporter::reporter_previewer_srv("prev", reporter)
###
}
if (interactive()) shinyApp(ui = ui, server = server)