diff --git a/DESCRIPTION b/DESCRIPTION index 27648b22..efbdf40d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -50,6 +50,7 @@ Suggests: withr (>= 3.0.0) Remotes: insightsengineering/osprey + insightsengineering/teal Config/Needs/verdepcheck: insightsengineering/osprey, rstudio/shiny, insightsengineering/teal, insightsengineering/teal.slice, insightsengineering/teal.transform, mllg/checkmate, tidyverse/dplyr, diff --git a/NEWS.md b/NEWS.md index f0d8b7be..275c5a6e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # teal.osprey 0.4.0.9002 +### Enhancements +- All `tm_g_*` modules accept `transformators` (input data transforms in the filter sidebar) and `decorators` (plot output transforms in the encoding panel). + # teal.osprey 0.4.0 diff --git a/R/argument_convention.R b/R/argument_convention.R index 277ddbb5..c749ad7b 100644 --- a/R/argument_convention.R +++ b/R/argument_convention.R @@ -36,6 +36,15 @@ #' @param plot_width (`numeric(3)`)\cr #' vector to indicate default value, minimum and maximum values. #' +#' @param transformators (`list` of `teal_transform_module`) optional, +#' input data transforms applied after filtering (UI in the filter sidebar under +#' **Transform Data**). See `vignette("transform-input-data", package = "teal")`. +#' +#' @param decorators `r lifecycle::badge("experimental")` +#' (named `list` of `teal_transform_module`) optional, +#' decorators for the module `plot` output. See [decorate_module_section] for which +#' object types are supported per module. +#' #' @return the [teal::module()] object. #' #' @name argument_convention diff --git a/R/decorate_module_section.R b/R/decorate_module_section.R new file mode 100644 index 00000000..b92b6e32 --- /dev/null +++ b/R/decorate_module_section.R @@ -0,0 +1,64 @@ +#' Decorating and transforming `teal.osprey` modules +#' +#' @description +#' Documentation for the `transformators` and `decorators` arguments accepted by all +#' `tm_g_*` modules in this package. +#' +#' @section Decorating Module: +#' +#' All `teal.osprey` plot modules expose a single decoratable output object named `plot`. +#' Decorators are passed as a named `list` of [`teal::teal_transform_module()`] objects; +#' the name of each list element must match the output object name (`"plot"`). +#' +#' ```r +#' tm_g_waterfall( +#' ..., +#' decorators = list( +#' plot = teal::teal_transform_module(...) # applied only to `plot` +#' ) +#' ) +#' ``` +#' +#' Decorator UI controls appear in the module **encoding** panel. Decorators run in the +#' module server after the plot is created and before it is rendered. +#' +#' **Important:** decorators must not change the class of `plot`. Use transformations +#' appropriate to the object type returned by the underlying [osprey] function. +#' +#' | Module | Output | Typical class of `plot` | +#' |--------|--------|-------------------------| +#' | `tm_g_spiderplot` | `plot` | `ggplot` | +#' | `tm_g_butterfly` | `plot` | `grob` / `gtable` | +#' | `tm_g_waterfall` | `plot` | `grob` / `gtable` | +#' | `tm_g_swimlane` | `plot` | `grob` / `gtable` | +#' | `tm_g_patient_profile` | `plot` | `grob` (`cowplot` layout) | +#' | `tm_g_ae_oview` | `plot` | `grob` | +#' | `tm_g_ae_sub` | `plot` | `grob` | +#' | `tm_g_events_term_id` | `plot` | `grob` | +#' | `tm_g_heat_bygrade` | `plot` | `grob` / `gtable` | +#' +#' - For **`ggplot`** outputs (`tm_g_spiderplot` only), use `ggplot2` modifiers +#' (for example via [`teal::make_teal_transform_server()`]). +#' - For **`grob`** outputs (all other modules), use [`tern::decorate_grob()`] or +#' other grid-compatible adjustments. Applying `ggplot2` layers to `plot` in +#' those modules will fail silently or break rendering. +#' +#' Four modules (`tm_g_ae_oview`, `tm_g_ae_sub`, `tm_g_events_term_id`, `tm_g_heat_bygrade`) +#' also provide built-in title and footnote controls via [`ui_g_decorate()`] and +#' [`srv_g_decorate()`]. User-defined decorators run **before** that built-in decoration step. +#' +#' @section Transforming input data: +#' +#' All `tm_g_*` modules also accept `transformators`, a named `list` of +#' [`teal::teal_transform_module()`] objects that modify module **input** data after +#' filtering. Their UI appears in the app filter sidebar under **Transform Data**. +#' +#' See `vignette("transform-input-data", package = "teal")` for transformators and +#' `vignette("transform-module-output", package = "teal")` for decorators. +#' +#' A demo app using every module with both mechanisms is in +#' `system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")`. +#' +#' @name decorate_module_section +#' @keywords internal +NULL diff --git a/R/tm_g_ae_oview.R b/R/tm_g_ae_oview.R index 67126e8d..02710edf 100644 --- a/R/tm_g_ae_oview.R +++ b/R/tm_g_ae_oview.R @@ -12,6 +12,8 @@ #' sub-groups (e.g. Serious events, Related events, etc.) #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' #' @export @@ -80,7 +82,8 @@ tm_g_ae_oview <- function(label, fontsize = c(5, 3, 7), plot_height = c(600L, 200L, 2000L), plot_width = NULL, - transformators = list()) { + transformators = list(), + decorators = list()) { message("Initializing tm_g_ae_oview") checkmate::assert_class(arm_var, classes = "choices_selected") checkmate::assert_class(flag_var_anl, classes = "choices_selected") @@ -103,6 +106,8 @@ tm_g_ae_oview <- function(label, plot_width[1], lower = plot_width[2], upper = plot_width[3], null.ok = TRUE, .var.name = "plot_width" ) + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") args <- as.list(environment()) @@ -113,7 +118,8 @@ tm_g_ae_oview <- function(label, label = label, dataname = dataname, plot_height = plot_height, - plot_width = plot_width + plot_width = plot_width, + decorators = decorators ), ui = ui_g_ae_oview, ui_args = args, @@ -180,6 +186,10 @@ ui_g_ae_oview <- function(id, ...) { selected = "left", multiple = FALSE ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(args$decorators, "plot") + ), ui_g_decorate( ns(NULL), fontsize = args$fontsize, @@ -195,7 +205,8 @@ srv_g_ae_oview <- function(id, dataname, label, plot_height, - plot_width) { + plot_width, + decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(isolate(data()), "teal_data") @@ -226,12 +237,7 @@ srv_g_ae_oview <- function(id, iv }) - decorate_output <- srv_g_decorate( - id = NULL, plt = plot_r, - plot_height = plot_height, plot_width = plot_width - ) - font_size <- decorate_output$font_size - pws <- decorate_output$pws + font_size <- reactive(input$fontsize) observeEvent(list(input$diff_ci_method, input$conf_level), { req(!is.null(input$diff_ci_method) && !is.null(input$conf_level)) @@ -332,7 +338,21 @@ srv_g_ae_oview <- function(id, }) ) - plot_r <- reactive(output_q()[["plot"]]) - set_chunk_dims(pws, output_q) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) + + decorate_output <- srv_g_decorate( + id = NULL, + plt = plot_r, + plot_height = plot_height, + plot_width = plot_width + ) + pws <- decorate_output$pws + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/tm_g_ae_sub.R b/R/tm_g_ae_sub.R index d0b2c7dd..122e1c92 100644 --- a/R/tm_g_ae_sub.R +++ b/R/tm_g_ae_sub.R @@ -13,6 +13,8 @@ #' @author Molly He (hey59) \email{hey59@gene.com} #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' #' @export @@ -56,7 +58,8 @@ tm_g_ae_sub <- function(label, plot_height = c(600L, 200L, 2000L), plot_width = NULL, fontsize = c(5, 3, 7), - transformators = list()) { + transformators = list(), + decorators = list()) { message("Initializing tm_g_ae_sub") checkmate::assert_class(arm_var, classes = "choices_selected") checkmate::assert_class(group_var, classes = "choices_selected") @@ -76,6 +79,8 @@ tm_g_ae_sub <- function(label, plot_width[1], lower = plot_width[2], upper = plot_width[3], null.ok = TRUE, .var.name = "plot_width" ) + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") module( label = label, @@ -84,13 +89,15 @@ tm_g_ae_sub <- function(label, label = label, dataname = dataname, plot_height = plot_height, - plot_width = plot_width + plot_width = plot_width, + decorators = decorators ), ui = ui_g_ae_sub, ui_args = list( arm_var = arm_var, group_var = group_var, - fontsize = fontsize + fontsize = fontsize, + decorators = decorators ), transformators = transformators, datanames = c("ADSL", dataname) @@ -156,6 +163,10 @@ ui_g_ae_sub <- function(id, ...) { max = 1, value = 0.95 ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(args$decorators, "plot") + ), ui_g_decorate( ns(NULL), fontsize = args$fontsize, @@ -172,7 +183,8 @@ srv_g_ae_sub <- function(id, dataname, label, plot_height, - plot_width) { + plot_width, + decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(shiny::isolate(data()), "teal_data") @@ -206,14 +218,7 @@ srv_g_ae_sub <- function(id, iv }) - decorate_output <- srv_g_decorate( - id = NULL, - plt = plot_r, - plot_height = plot_height, - plot_width = plot_width - ) - font_size <- decorate_output$font_size - pws <- decorate_output$pws + font_size <- reactive(input$fontsize) observeEvent(input$arm_var, ignoreNULL = TRUE, { arm_var <- input$arm_var @@ -374,7 +379,21 @@ srv_g_ae_sub <- function(id, }) ) - plot_r <- reactive(output_q()[["plot"]]) - set_chunk_dims(pws, output_q) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) + + decorate_output <- srv_g_decorate( + id = NULL, + plt = plot_r, + plot_height = plot_height, + plot_width = plot_width + ) + pws <- decorate_output$pws + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/tm_g_butterfly.R b/R/tm_g_butterfly.R index 2fb5d8fa..48f5ec0c 100644 --- a/R/tm_g_butterfly.R +++ b/R/tm_g_butterfly.R @@ -33,6 +33,8 @@ #' used directly as filter. #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' #' @export @@ -121,7 +123,8 @@ tm_g_butterfly <- function(label, plot_width = NULL, pre_output = NULL, post_output = NULL, - transformators = list()) { + transformators = list(), + decorators = list()) { message("Initializing tm_g_butterfly") checkmate::assert_string(label) checkmate::assert_string(dataname) @@ -144,6 +147,8 @@ tm_g_butterfly <- function(label, null.ok = TRUE, .var.name = "plot_width" ) + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") args <- as.list(environment()) @@ -151,7 +156,13 @@ tm_g_butterfly <- function(label, label = label, datanames = c("ADSL", dataname), server = srv_g_butterfly, - server_args = list(dataname = dataname, label = label, plot_height = plot_height, plot_width = plot_width), + server_args = list( + dataname = dataname, + label = label, + plot_height = plot_height, + plot_width = plot_width, + decorators = decorators + ), ui = ui_g_butterfly, ui_args = args, transformators = transformators @@ -251,6 +262,10 @@ ui_g_butterfly <- function(id, ...) { ns("legend_on"), "Add legend", value = a$legend_on + ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(a$decorators, "plot") ) ), pre_output = a$pre_output, @@ -258,7 +273,7 @@ ui_g_butterfly <- function(id, ...) { ) } -srv_g_butterfly <- function(id, data, dataname, label, plot_height, plot_width) { +srv_g_butterfly <- function(id, data, dataname, label, plot_height, plot_width, decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(shiny::isolate(data()), "teal_data") @@ -520,7 +535,13 @@ srv_g_butterfly <- function(id, data, dataname, label, plot_height, plot_width) }) ) - plot_r <- reactive(output_q()[["plot"]]) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) # Insert the plot into a plot_with_settings module from teal.widgets pws <- teal.widgets::plot_with_settings_srv( @@ -530,6 +551,6 @@ srv_g_butterfly <- function(id, data, dataname, label, plot_height, plot_width) width = plot_width ) - set_chunk_dims(pws, output_q) + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/tm_g_events_term_id.R b/R/tm_g_events_term_id.R index 5a9cea52..14e35052 100644 --- a/R/tm_g_events_term_id.R +++ b/R/tm_g_events_term_id.R @@ -11,6 +11,8 @@ #' and pre-selected option names that can be used to specify the term for events #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' #' @export @@ -59,7 +61,8 @@ tm_g_events_term_id <- function(label, fontsize = c(5, 3, 7), plot_height = c(600L, 200L, 2000L), plot_width = NULL, - transformators = list()) { + transformators = list(), + decorators = list()) { message("Initializing tm_g_events_term_id") checkmate::assert_string(label) checkmate::assert_class(term_var, classes = "choices_selected") @@ -83,13 +86,21 @@ tm_g_events_term_id <- function(label, null.ok = TRUE, .var.name = "plot_width" ) + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") args <- as.list(environment()) module( label = label, server = srv_g_events_term_id, - server_args = list(label = label, dataname = dataname, plot_height = plot_height, plot_width = plot_width), + server_args = list( + label = label, + dataname = dataname, + plot_height = plot_height, + plot_width = plot_width, + decorators = decorators + ), ui = ui_g_events_term_id, ui_args = args, transformators = transformators, @@ -184,6 +195,10 @@ ui_g_events_term_id <- function(id, ...) { value = FALSE ) ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(args$decorators, "plot") + ), ui_g_decorate( ns(NULL), fontsize = args$fontsize, @@ -199,7 +214,8 @@ srv_g_events_term_id <- function(id, dataname, label, plot_height, - plot_width) { + plot_width, + decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(shiny::isolate(data()), "teal_data") @@ -222,11 +238,7 @@ srv_g_events_term_id <- function(id, iv }) - decorate_output <- srv_g_decorate( - id = NULL, plt = plot_r, plot_height = plot_height, plot_width = plot_width - ) - font_size <- decorate_output$font_size - pws <- decorate_output$pws + font_size <- reactive(input$fontsize) observeEvent(list(input$diff_ci_method, input$conf_level), { req(!is.null(input$diff_ci_method) && !is.null(input$conf_level)) @@ -359,7 +371,21 @@ srv_g_events_term_id <- function(id, ) }) - plot_r <- reactive(output_q()[["plot"]]) - set_chunk_dims(pws, output_q) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) + + decorate_output <- srv_g_decorate( + id = NULL, + plt = plot_r, + plot_height = plot_height, + plot_width = plot_width + ) + pws <- decorate_output$pws + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/tm_g_heat_bygrade.R b/R/tm_g_heat_bygrade.R index 3bbbccab..bc33b382 100644 --- a/R/tm_g_heat_bygrade.R +++ b/R/tm_g_heat_bygrade.R @@ -30,6 +30,8 @@ #' specify to `NA` if no concomitant medications data is available #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' #' @export @@ -132,7 +134,8 @@ tm_g_heat_bygrade <- function(label, fontsize = c(5, 3, 7), plot_height = c(600L, 200L, 2000L), plot_width = NULL, - transformators = list()) { + transformators = list(), + decorators = list()) { message("Initializing tm_g_heat_bygrade") args <- as.list(environment()) @@ -166,6 +169,8 @@ tm_g_heat_bygrade <- function(label, null.ok = TRUE, .var.name = "plot_width" ) + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") module( label = label, @@ -177,7 +182,8 @@ tm_g_heat_bygrade <- function(label, ae_dataname = ae_dataname, cm_dataname = cm_dataname, plot_height = plot_height, - plot_width = plot_width + plot_width = plot_width, + decorators = decorators ), ui = ui_g_heatmap_bygrade, ui_args = args, @@ -258,6 +264,10 @@ ui_g_heatmap_bygrade <- function(id, ...) { multiple = TRUE ) ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(args$decorators, "plot") + ), ui_g_decorate( ns(NULL), fontsize = args$fontsize, @@ -277,7 +287,8 @@ srv_g_heatmap_bygrade <- function(id, cm_dataname, label, plot_height, - plot_width) { + plot_width, + decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(shiny::isolate(data()), "teal_data") if (!is.na(sl_dataname)) checkmate::assert_names(sl_dataname, subset.of = names(data)) @@ -361,15 +372,6 @@ srv_g_heatmap_bygrade <- function(id, iv_cm }) - decorate_output <- srv_g_decorate( - id = NULL, - plt = plot_r, - plot_height = plot_height, - plot_width = plot_width - ) - font_size <- decorate_output$font_size - pws <- decorate_output$pws - if (!is.na(cm_dataname)) { observeEvent(input$conmed_var, { ADCM <- data()[[cm_dataname]] @@ -454,7 +456,21 @@ srv_g_heatmap_bygrade <- function(id, }) ) - plot_r <- reactive(output_q()[["plot"]]) - set_chunk_dims(pws, output_q) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) + + decorate_output <- srv_g_decorate( + id = NULL, + plt = plot_r, + plot_height = plot_height, + plot_width = plot_width + ) + pws <- decorate_output$pws + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/tm_g_patient_profile.R b/R/tm_g_patient_profile.R index 99719856..c534ac22 100644 --- a/R/tm_g_patient_profile.R +++ b/R/tm_g_patient_profile.R @@ -47,6 +47,8 @@ #' @template author_qit3 #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' #' @details @@ -155,7 +157,8 @@ tm_g_patient_profile <- function(label = "Patient Profile Plot", plot_width = NULL, pre_output = NULL, post_output = NULL, - transformators = list()) { + transformators = list(), + decorators = list()) { args <- as.list(environment()) checkmate::assert_string(label) checkmate::assert_string(sl_dataname) @@ -186,6 +189,8 @@ tm_g_patient_profile <- function(label = "Patient Profile Plot", null.ok = TRUE, .var.name = "plot_width" ) + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") module( label = label, @@ -203,7 +208,8 @@ tm_g_patient_profile <- function(label = "Patient Profile Plot", ae_line_col_opt = ae_line_col_opt, label = label, plot_height = plot_height, - plot_width = plot_width + plot_width = plot_width, + decorators = decorators ), transformators = transformators, datanames = "all" @@ -325,6 +331,10 @@ ui_g_patient_profile <- function(id, ...) { helpText("Enter TWO numeric values of study days range, separated by comma (eg. -28, 750)") ), value = a$x_limit + ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(a$decorators, "plot") ) ), pre_output = a$pre_output, @@ -345,14 +355,16 @@ srv_g_patient_profile <- function(id, label, ae_line_col_opt, plot_height, - plot_width) { + plot_width, + decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(shiny::isolate(data()), "teal_data") - if (!is.na(ex_dataname)) checkmate::assert_names(ex_dataname, subset.of = names(data)) - if (!is.na(ae_dataname)) checkmate::assert_names(ae_dataname, subset.of = names(data)) - if (!is.na(rs_dataname)) checkmate::assert_names(rs_dataname, subset.of = names(data)) - if (!is.na(lb_dataname)) checkmate::assert_names(lb_dataname, subset.of = names(data)) - if (!is.na(cm_dataname)) checkmate::assert_names(cm_dataname, subset.of = names(data)) + data_names <- names(isolate(data())) + if (!is.na(ex_dataname)) checkmate::assert_names(ex_dataname, subset.of = data_names) + if (!is.na(ae_dataname)) checkmate::assert_names(ae_dataname, subset.of = data_names) + if (!is.na(rs_dataname)) checkmate::assert_names(rs_dataname, subset.of = data_names) + if (!is.na(lb_dataname)) checkmate::assert_names(lb_dataname, subset.of = data_names) + if (!is.na(cm_dataname)) checkmate::assert_names(cm_dataname, subset.of = data_names) checkboxes <- c(ex_dataname, ae_dataname, rs_dataname, lb_dataname, cm_dataname) moduleServer(id, function(input, output, session) { teal.logger::log_shiny_input_changes(input, namespace = "teal.osprey") @@ -900,7 +912,13 @@ srv_g_patient_profile <- function(id, }) ) - plot_r <- reactive(output_q()[["plot"]]) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) pws <- teal.widgets::plot_with_settings_srv( id = "patientprofileplot", @@ -909,6 +927,6 @@ srv_g_patient_profile <- function(id, width = plot_width ) - set_chunk_dims(pws, output_q) + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/tm_g_spiderplot.R b/R/tm_g_spiderplot.R index c941552e..1f7fb7dd 100644 --- a/R/tm_g_spiderplot.R +++ b/R/tm_g_spiderplot.R @@ -19,6 +19,8 @@ #' @param yfacet_var variable for y facets #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' @export #' @@ -96,7 +98,8 @@ tm_g_spiderplot <- function(label, plot_width = NULL, pre_output = NULL, post_output = NULL, - transformators = list()) { + transformators = list(), + decorators = list()) { message("Initializing tm_g_spiderplot") checkmate::assert_class(paramcd, classes = "choices_selected") checkmate::assert_class(x_var, classes = "choices_selected") @@ -119,6 +122,8 @@ tm_g_spiderplot <- function(label, null.ok = TRUE, .var.name = "plot_width" ) + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") args <- as.list(environment()) module( @@ -130,7 +135,8 @@ tm_g_spiderplot <- function(label, paramcd = paramcd, label = label, plot_height = plot_height, - plot_width = plot_width + plot_width = plot_width, + decorators = decorators ), ui = ui_g_spider, ui_args = args, @@ -235,13 +241,17 @@ ui_g_spider <- function(id, ...) { value = a$href_line ) ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(a$decorators, "plot") + ), pre_output = a$pre_output, post_output = a$post_output ) ) } -srv_g_spider <- function(id, data, dataname, paramcd, label, plot_height, plot_width) { +srv_g_spider <- function(id, data, dataname, paramcd, label, plot_height, plot_width, decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(shiny::isolate(data()), "teal_data") @@ -451,7 +461,13 @@ srv_g_spider <- function(id, data, dataname, paramcd, label, plot_height, plot_w ) }) - plot_r <- reactive(output_q()[["plot"]]) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) pws <- teal.widgets::plot_with_settings_srv( id = "spiderplot", @@ -460,6 +476,6 @@ srv_g_spider <- function(id, data, dataname, paramcd, label, plot_height, plot_w width = plot_width ) - set_chunk_dims(pws, output_q) + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/tm_g_swimlane.R b/R/tm_g_swimlane.R index 0df80ca5..e0593fae 100644 --- a/R/tm_g_swimlane.R +++ b/R/tm_g_swimlane.R @@ -29,6 +29,8 @@ #' @param x_label the label of the x axis #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' #' @export @@ -123,7 +125,8 @@ tm_g_swimlane <- function(label, pre_output = NULL, post_output = NULL, x_label = "Time from First Treatment (Day)", - transformators = list()) { + transformators = list(), + decorators = list()) { message("Initializing tm_g_swimlane") args <- as.list(environment()) @@ -149,7 +152,8 @@ tm_g_swimlane <- function(label, .var.name = "plot_width" ) checkmate::assert_string(x_label) - + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") module( label = label, @@ -166,7 +170,8 @@ tm_g_swimlane <- function(label, label = label, plot_height = plot_height, plot_width = plot_width, - x_label = x_label + x_label = x_label, + decorators = decorators ), transformators = transformators, datanames = c("ADSL", dataname) @@ -246,6 +251,10 @@ ui_g_swimlane <- function(id, ...) { helpText("Enter numeric value(s) of reference lines, separated by comma (eg. 100, 200)") ), value = paste(a$vref_line, collapse = ", ") + ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(a$decorators, "plot") ) ), pre_output = a$pre_output, @@ -265,7 +274,8 @@ srv_g_swimlane <- function(id, label, plot_height, plot_width, - x_label) { + x_label, + decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(shiny::isolate(data()), "teal_data") @@ -511,7 +521,13 @@ srv_g_swimlane <- function(id, teal.code::eval_code(q3, code = plot_call) }) - plot_r <- reactive(output_q()[["plot"]]) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) # Insert the plot into a plot_with_settings module from teal.widgets pws <- teal.widgets::plot_with_settings_srv( @@ -521,6 +537,6 @@ srv_g_swimlane <- function(id, width = plot_width ) - set_chunk_dims(pws, output_q) + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/tm_g_waterfall.R b/R/tm_g_waterfall.R index e7f66066..ab4d5c84 100644 --- a/R/tm_g_waterfall.R +++ b/R/tm_g_waterfall.R @@ -40,6 +40,8 @@ #' @param show_value boolean of whether value of bar height is shown, default is `TRUE` #' #' @inherit argument_convention return +#' @inheritSection decorate_module_section Decorating Module +#' @inheritSection decorate_module_section Transforming input data #' @inheritSection teal::example_module Reporting #' #' @export @@ -105,7 +107,8 @@ tm_g_waterfall <- function(label, plot_width = NULL, pre_output = NULL, post_output = NULL, - transformators = list()) { + transformators = list(), + decorators = list()) { message("Initializing tm_g_waterfall") checkmate::assert_string(label) checkmate::assert_string(dataname_tr) @@ -129,6 +132,8 @@ tm_g_waterfall <- function(label, null.ok = TRUE, .var.name = "plot_width" ) + assert_transformators(transformators) + teal::assert_decorators(decorators, "plot") args <- as.list(environment()) @@ -146,7 +151,8 @@ tm_g_waterfall <- function(label, label = label, bar_color_opt = bar_color_opt, plot_height = plot_height, - plot_width = plot_width + plot_width = plot_width, + decorators = decorators ), transformators = transformators, datanames = c("ADSL", dataname_tr, dataname_rs) @@ -256,6 +262,10 @@ ui_g_waterfall <- function(id, ...) { helpText("Enter a numeric value to break very high bars") ), value = a$gap_point_val + ), + teal::ui_transform_teal_data( + ns("decorator"), + transformators = select_decorators(a$decorators, "plot") ) ), pre_output = a$pre_output, @@ -273,7 +283,8 @@ srv_g_waterfall <- function(id, bar_color_opt, label, plot_height, - plot_width) { + plot_width, + decorators) { checkmate::assert_class(data, "reactive") checkmate::assert_class(shiny::isolate(data()), "teal_data") @@ -576,7 +587,13 @@ srv_g_waterfall <- function(id, ) }) - plot_r <- reactive(output_q()[["plot"]]) + decorated_output_q <- teal::srv_transform_teal_data( + id = "decorator", + data = output_q, + transformators = select_decorators(decorators, "plot"), + expr = quote(plot) + ) + plot_r <- reactive(decorated_output_q()[["plot"]]) # Insert the plot into a plot_with_settings module from teal.widgets pws <- teal.widgets::plot_with_settings_srv( @@ -586,6 +603,6 @@ srv_g_waterfall <- function(id, width = plot_width ) - set_chunk_dims(pws, output_q) + set_chunk_dims(pws, decorated_output_q) }) } diff --git a/R/utils.R b/R/utils.R index 1dfcf628..01b8e6fa 100644 --- a/R/utils.R +++ b/R/utils.R @@ -15,6 +15,19 @@ #' NULL +select_decorators <- utils::getFromNamespace("select_decorators", "teal") + +#' Validate module `transformators` argument +#' @param transformators (`list` or `teal_transform_module`) +#' @keywords internal +assert_transformators <- function(transformators) { + if (inherits(transformators, "teal_transform_module")) { + transformators <- list(transformators) + } + checkmate::assert_list(transformators, types = "teal_transform_module") + invisible(transformators) +} + #' Utility function for quick filter #' #' diff --git a/inst/WORDLIST b/inst/WORDLIST index 21a72e78..1779f733 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -17,3 +17,5 @@ pre qit reportable zhanc +decoratable +transformators diff --git a/man/argument_convention.Rd b/man/argument_convention.Rd index a85d149d..ed36f0ad 100644 --- a/man/argument_convention.Rd +++ b/man/argument_convention.Rd @@ -30,6 +30,15 @@ vector to indicate default value, minimum and maximum values.} \item{plot_width}{(\code{numeric(3)})\cr vector to indicate default value, minimum and maximum values.} + +\item{transformators}{(\code{list} of \code{teal_transform_module}) optional, +input data transforms applied after filtering (UI in the filter sidebar under +\strong{Transform Data}). See \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. diff --git a/man/assert_transformators.Rd b/man/assert_transformators.Rd new file mode 100644 index 00000000..5a5fb20d --- /dev/null +++ b/man/assert_transformators.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{assert_transformators} +\alias{assert_transformators} +\title{Validate module \code{transformators} argument} +\usage{ +assert_transformators(transformators) +} +\arguments{ +\item{transformators}{(\code{list} or \code{teal_transform_module})} +} +\description{ +Validate module \code{transformators} argument +} +\keyword{internal} diff --git a/man/decorate_module_section.Rd b/man/decorate_module_section.Rd new file mode 100644 index 00000000..26709e2b --- /dev/null +++ b/man/decorate_module_section.Rd @@ -0,0 +1,69 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/decorate_module_section.R +\name{decorate_module_section} +\alias{decorate_module_section} +\title{Decorating and transforming \code{teal.osprey} modules} +\description{ +Documentation for the \code{transformators} and \code{decorators} arguments accepted by all +\verb{tm_g_*} modules in this package. +} +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + +\keyword{internal} diff --git a/man/plot_decorate_output.Rd b/man/plot_decorate_output.Rd index 67dd48ef..6061a5a2 100644 --- a/man/plot_decorate_output.Rd +++ b/man/plot_decorate_output.Rd @@ -13,5 +13,5 @@ plot_decorate_output(id) An html element. } \description{ -Adds \code{\link[teal.widgets:plot_with_settings]{teal.widgets::plot_with_settings_ui()}} +Adds \code{\link[=plot_with_settings_ui]{plot_with_settings_ui()}} } diff --git a/man/tm_g_ae_oview.Rd b/man/tm_g_ae_oview.Rd index 375f1212..938af011 100644 --- a/man/tm_g_ae_oview.Rd +++ b/man/tm_g_ae_oview.Rd @@ -12,7 +12,8 @@ tm_g_ae_oview( fontsize = c(5, 3, 7), plot_height = c(600L, 200L, 2000L), plot_width = NULL, - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -45,6 +46,11 @@ vector to indicate default value, minimum and maximum values.} \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -52,6 +58,65 @@ the \code{\link[teal:teal_modules]{teal::module()}} object. \description{ Display the \code{AE} overview plot as a shiny module } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{ diff --git a/man/tm_g_ae_sub.Rd b/man/tm_g_ae_sub.Rd index e830c26b..92474bca 100644 --- a/man/tm_g_ae_sub.Rd +++ b/man/tm_g_ae_sub.Rd @@ -12,7 +12,8 @@ tm_g_ae_sub( plot_height = c(600L, 200L, 2000L), plot_width = NULL, fontsize = c(5, 3, 7), - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -43,6 +44,11 @@ plot.} \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -50,6 +56,65 @@ the \code{\link[teal:teal_modules]{teal::module()}} object. \description{ Display the \code{AE} by subgroups plot as a teal module } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{ diff --git a/man/tm_g_butterfly.Rd b/man/tm_g_butterfly.Rd index cc2f0673..8198668b 100644 --- a/man/tm_g_butterfly.Rd +++ b/man/tm_g_butterfly.Rd @@ -21,7 +21,8 @@ tm_g_butterfly( plot_width = NULL, pre_output = NULL, post_output = NULL, - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -68,6 +69,11 @@ into context. For example the \code{\link[shiny:helpText]{shiny::helpText()}} el \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -87,6 +93,65 @@ observations with "Y" value in each and every selected variables will be used for subsequent analysis. Flag variables (from \code{ADaM} datasets) can be used directly as filter. } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{ diff --git a/man/tm_g_events_term_id.Rd b/man/tm_g_events_term_id.Rd index f7745d13..d9e76c7e 100644 --- a/man/tm_g_events_term_id.Rd +++ b/man/tm_g_events_term_id.Rd @@ -12,7 +12,8 @@ tm_g_events_term_id( fontsize = c(5, 3, 7), plot_height = c(600L, 200L, 2000L), plot_width = NULL, - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -44,6 +45,11 @@ vector to indicate default value, minimum and maximum values.} \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -51,6 +57,65 @@ the \code{\link[teal:teal_modules]{teal::module()}} object. \description{ Display Events by Term plot as a shiny module } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{ diff --git a/man/tm_g_heat_bygrade.Rd b/man/tm_g_heat_bygrade.Rd index 9aa0c127..4eb20d68 100644 --- a/man/tm_g_heat_bygrade.Rd +++ b/man/tm_g_heat_bygrade.Rd @@ -19,7 +19,8 @@ tm_g_heat_bygrade( fontsize = c(5, 3, 7), plot_height = c(600L, 200L, 2000L), plot_width = NULL, - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -70,6 +71,11 @@ vector to indicate default value, minimum and maximum values.} \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -77,6 +83,65 @@ the \code{\link[teal:teal_modules]{teal::module()}} object. \description{ Display the heatmap by grade as a shiny module } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{ diff --git a/man/tm_g_patient_profile.Rd b/man/tm_g_patient_profile.Rd index 48ceb14d..89e879b1 100644 --- a/man/tm_g_patient_profile.Rd +++ b/man/tm_g_patient_profile.Rd @@ -26,7 +26,8 @@ tm_g_patient_profile( plot_width = NULL, pre_output = NULL, post_output = NULL, - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -91,6 +92,11 @@ into context. For example the \code{\link[shiny:helpText]{shiny::helpText()}} el \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -109,6 +115,65 @@ is derived for consistency based the start date of user's choice in the app (for the start date } } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{ diff --git a/man/tm_g_spiderplot.Rd b/man/tm_g_spiderplot.Rd index fbda9e0a..2dfb304f 100644 --- a/man/tm_g_spiderplot.Rd +++ b/man/tm_g_spiderplot.Rd @@ -22,7 +22,8 @@ tm_g_spiderplot( plot_width = NULL, pre_output = NULL, post_output = NULL, - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -71,6 +72,11 @@ into context. For example the \code{\link[shiny:helpText]{shiny::helpText()}} el \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -78,6 +84,65 @@ the \code{\link[teal:teal_modules]{teal::module()}} object. \description{ Display spider plot as a shiny module } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{ diff --git a/man/tm_g_swimlane.Rd b/man/tm_g_swimlane.Rd index fac41f64..273dd998 100644 --- a/man/tm_g_swimlane.Rd +++ b/man/tm_g_swimlane.Rd @@ -22,7 +22,8 @@ tm_g_swimlane( pre_output = NULL, post_output = NULL, x_label = "Time from First Treatment (Day)", - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -75,6 +76,11 @@ into context. For example the \code{\link[shiny:helpText]{shiny::helpText()}} el \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -82,6 +88,65 @@ the \code{\link[teal:teal_modules]{teal::module()}} object. \description{ This is teal module that generates a \code{swimlane} plot (bar plot with markers) for \code{ADaM} data } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{ diff --git a/man/tm_g_waterfall.Rd b/man/tm_g_waterfall.Rd index 799b57d3..65f3dd5e 100644 --- a/man/tm_g_waterfall.Rd +++ b/man/tm_g_waterfall.Rd @@ -26,7 +26,8 @@ tm_g_waterfall( plot_width = NULL, pre_output = NULL, post_output = NULL, - transformators = list() + transformators = list(), + decorators = list() ) } \arguments{ @@ -94,6 +95,11 @@ into context. For example the \code{\link[shiny:helpText]{shiny::helpText()}} el \item{transformators}{(\code{list} of \code{teal_transform_module}) that will be applied to transform module's data input. To learn more check \code{vignette("transform-input-data", package = "teal")}.} + +\item{decorators}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +(named \code{list} of \code{teal_transform_module}) optional, +decorators for the module \code{plot} output. See \link{decorate_module_section} for which +object types are supported per module.} } \value{ the \code{\link[teal:teal_modules]{teal::module()}} object. @@ -101,6 +107,65 @@ the \code{\link[teal:teal_modules]{teal::module()}} object. \description{ This is teal module that generates a waterfall plot for \code{ADaM} data } +\section{Decorating Module}{ + + +All \code{teal.osprey} plot modules expose a single decoratable output object named \code{plot}. +Decorators are passed as a named \code{list} of \code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects; +the name of each list element must match the output object name (\code{"plot"}). + +\if{html}{\out{
}}\preformatted{tm_g_waterfall( + ..., + decorators = list( + plot = teal::teal_transform_module(...) # applied only to `plot` + ) +) +}\if{html}{\out{
}} + +Decorator UI controls appear in the module \strong{encoding} panel. Decorators run in the +module server after the plot is created and before it is rendered. + +\strong{Important:} decorators must not change the class of \code{plot}. Use transformations +appropriate to the object type returned by the underlying \link{osprey} function.\tabular{lll}{ + Module \tab Output \tab Typical class of \code{plot} \cr + \code{tm_g_spiderplot} \tab \code{plot} \tab \code{ggplot} \cr + \code{tm_g_butterfly} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_waterfall} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_swimlane} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr + \code{tm_g_patient_profile} \tab \code{plot} \tab \code{grob} (\code{cowplot} layout) \cr + \code{tm_g_ae_oview} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_ae_sub} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_events_term_id} \tab \code{plot} \tab \code{grob} \cr + \code{tm_g_heat_bygrade} \tab \code{plot} \tab \code{grob} / \code{gtable} \cr +} + +\itemize{ +\item For \strong{\code{ggplot}} outputs (\code{tm_g_spiderplot} only), use \code{ggplot2} modifiers +(for example via \code{\link[teal:make_teal_transform_server]{teal::make_teal_transform_server()}}). +\item For \strong{\code{grob}} outputs (all other modules), use \code{\link[tern:decorate_grob]{tern::decorate_grob()}} or +other grid-compatible adjustments. Applying \code{ggplot2} layers to \code{plot} in +those modules will fail silently or break rendering. +} + +Four modules (\code{tm_g_ae_oview}, \code{tm_g_ae_sub}, \code{tm_g_events_term_id}, \code{tm_g_heat_bygrade}) +also provide built-in title and footnote controls via \code{\link[=ui_g_decorate]{ui_g_decorate()}} and +\code{\link[=srv_g_decorate]{srv_g_decorate()}}. User-defined decorators run \strong{before} that built-in decoration step. +} + +\section{Transforming input data}{ + + +All \verb{tm_g_*} modules also accept \code{transformators}, a named \code{list} of +\code{\link[teal:teal_transform_module]{teal::teal_transform_module()}} objects that modify module \strong{input} data after +filtering. Their UI appears in the app filter sidebar under \strong{Transform Data}. + +See \code{vignette("transform-input-data", package = "teal")} for transformators and +\code{vignette("transform-module-output", package = "teal")} for decorators. + +A demo app using every module with both mechanisms is in +\code{system.file("examples", "app_decorators_transformators.R", package = "teal.osprey")}. +} + \section{Reporting}{