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}{