--- title: "Adding third party plots" author: - name: Samuel Wieczorek - name: Thomas Burger package: omXplore abstract: > The package `omXplore` is able to embed third party plots. This vignette aims to explain how to add an external plot to the main UI of `omXplore`. date: "`r Sys.Date()`" output: BiocStyle::html_document: toc_float: true vignette: > %\VignetteIndexEntry{Adding third party plots} %%\VignetteKeywords{Softmware} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} editor_options: markdown: wrap: 72 --- ```{r style, echo = FALSE, results = 'asis'} BiocStyle::markdown() ``` ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE) ``` ```{r env, message = FALSE, warning = FALSE, echo = FALSE} library("omXplore") ``` # Introduction An interesting feature about `omXplore` is the capacity to insert custom plots into the collection of vignettes of the Shiny app `view_dataset()`. This is useful to complete the panel of built-in plots of `omXplore` and the main UI (See ?view_dataset). This vignette aims to describe how to (i) develop a plot function compliant with `omXplore` and (ii) add a new plot in the main app of the package `omXplore`. # Develop a plot module for `omXplore` Any plot function, to be compatible with `omXplore`, must be written as a [shiny module](https://shiny.posit.co/r/articles/improve/modules/) to allow for better code organisation and re-usability. Let suppose one wants to write a plot called "myFirstPlot". As usual, the code of this shiny app is divided into two parts: - User interface (UI): function "myFirstPlot_ui()" - Server: function "myFirstPlot_server()" Moreover, the parameters of these two functions must have the same name and class as the built-in plot functions in `omXplore` . For more details, see ?extFoo1 which is a simple example of what a generic plot function should looks like. Following Bioconductor's recommendations about [Running shiny apps](https://contributions.bioconductor.org/shiny.html#running-app), the source code for this plot function should look as follows: ```{r, eval=FALSE} myFirstPlot <- function(obj, i) { ui <- myFirstPlot_ui(id) server <- myFirstPlot_server(id, obj, i) app <- shinyApp(ui = ui, server = server) } ``` These three functions (myFirstPlot_ui(), myFirstPlot_server() and myFirstPlot()) can be written in the same source file (e.g. myFirstPlot.R) # Adding an existing module ## From a R package When one wants to add an external plot from a R package, it is by means of the parameter 'addons' of the function `view_dataset()`. This parameter is a list structured as follows: - the name of each slot is the name of a R package in which a plot module is implemented, - the content of the slot is a vector of modules names. It is necessary that the functions \*_ui() and \*_server are defined outside the global app function myFirstPlot(). This is because the function "view_dataset" cannot use the function myFirstPlot() and it must use the two functions myFirstPlot_ui(), myFirstPlot_server(). Thus, the following code **will not work**: ```{r, eval=FALSE} myFirstPlot <- function(obj, i) { ui <- function(id) { ... } server <- function(id, obj, i) { moduleServer(id, function(input, output, session) { ... }) } app <- shinyApp(ui = ui, server = server) } ``` A functional code is as follows: ```{r, eval=FALSE} myFirstPlot_ui <- function(id) { ... } myFirstPlot_server <- function(id, obj, i) { moduleServer(id, function(input, output, session) { ... }) } myFirstPlot <- function(obj, i) { ui <- myFirstPlot_ui(id) server <- myFirstPlot_server(id, obj, i) app <- shinyApp(ui = ui, server = server) } ``` As an example, the code below will add three external plots: - package `myPkgA`: the plot functions "extFoo1" and "extFoo2", - package `myPkgB`: the plot function "extFoo1". The corresponding R code is the following: ```{r eval = FALSE} addons <- list( myPkgA = c("extFoo1", "extFoo2"), myPkgB = c("extFoo1") ) view_dataset(myData, addons) ``` Functions can have same names if they are part of different packages. With this procedure, it is not necessary to load the entire package in order to user the plot module. `omXplore` loads only the necessary code for the plot fucntions. **Icon for clickable vignette** If the plot function is part of a R package, it is possible to store a \*.png image that serves as icon for the clickable vignette displayed in the (B) area of the main app of `omXplore`. For that purpose, the file should be stored in the 'images' directory of the corresponding package and its name should be the same as the function it refers to. The global file structure for the plot function of the example is the following: ``` MyPackage/ |-- R/ | |-- myFirstPlot.R |-- inst/ | |-- images/ | |-- myFirstPlot.png ``` ## From R console If the plot function is written in a R script nor console, the same rules are used to write the three functions described in the previous section. However, there are two important modifications: - the name of the three functions must be prefixed by "omXplore_' - so as to let `omXplore` find the plot function, it must already be loaded in the global R environment before running the app `view_dataset()`. Please note that in this case, there is to need to set the parameter "addons". ```{r, eval=FALSE} omXplore_mySecondPlot <- function(obj, i) { ui <- omXplore_mySecondPlot_ui(id) server <- omXplore_mySecondPlot_server(id, obj, i) app <- shinyApp(ui = ui, server = server) } ``` ## Session information ```{r} sessionInfo() ```