Title: | Enterprise Streamlined 'shiny' Application Framework Using 'bs4Dash' |
---|---|
Description: | A framework for building enterprise, scalable and UI-standardized 'shiny' applications. It brings enhanced features such as 'bootstrap' v4 <https://getbootstrap.com/docs/4.0/getting-started/introduction/>, additional and enhanced 'shiny' modules, customizable UI features, as well as an enhanced application file organization paradigm. This update allows developers to harness the ability to build powerful applications and enriches the 'shiny' developers' experience when building and maintaining applications. |
Authors: | Mohammed Ali [aut, cre], Constance Brett [ctb], Aggregate Genius Inc [spn] |
Maintainer: | Mohammed Ali <[email protected]> |
License: | GPL-3 |
Version: | 0.2.3 |
Built: | 2024-11-16 05:51:50 UTC |
Source: | https://github.com/aggregate-genius/periscope2 |
Builds application body with given configurations and elements. It is called within "ui_body.R". Check example application for detailed example
add_ui_body(body_elements = NULL, append = FALSE)
add_ui_body(body_elements = NULL, append = FALSE)
body_elements |
List of UI elements to be displayed in application body |
append |
Add elements to current body elements or remove previous body elements (default = FALSE) |
list of both shiny UI elements and html div tags for alert and linking app JS and CSS files
Call this function from program/ui_body.R
to set body parameters
periscope2:add_ui_left_sidebar()
periscope2:add_ui_right_sidebar()
periscope2:get_url_parameters()
library(shiny) library(bs4Dash) # Inside ui_body.R about_box <- jumbotron(title = "periscope2: Test Example", lead = p("periscope2 is a scalable and UI-standardized 'shiny' framework including a variety of developer convenience functions"), status = "info", href = "https://periscopeapps.org/") # -- Register Elements in the ORDER SHOWN in the UI add_ui_body(list(about_box))
library(shiny) library(bs4Dash) # Inside ui_body.R about_box <- jumbotron(title = "periscope2: Test Example", lead = p("periscope2 is a scalable and UI-standardized 'shiny' framework including a variety of developer convenience functions"), status = "info", href = "https://periscopeapps.org/") # -- Register Elements in the ORDER SHOWN in the UI add_ui_body(list(about_box))
Builds application header with given configurations and elements. It is called within "ui_header.R". These elements will be displayed in the header beside application title and application busy indicator.
add_ui_header( ui_elements = NULL, ui_position = "right", title = NULL, title_position = "center", left_menu = NULL, right_menu = NULL, border = TRUE, compact = FALSE, right_sidebar_icon = shiny::icon("bars"), fixed = FALSE, left_sidebar_icon = shiny::icon("th"), skin = "light", status = "white" )
add_ui_header( ui_elements = NULL, ui_position = "right", title = NULL, title_position = "center", left_menu = NULL, right_menu = NULL, border = TRUE, compact = FALSE, right_sidebar_icon = shiny::icon("bars"), fixed = FALSE, left_sidebar_icon = shiny::icon("th"), skin = "light", status = "white" )
ui_elements |
It can be any UI element but mostly used for navbarMenu. NULL by default.
Check |
ui_position |
Location of UI elements in the header. Must be either of 'center', 'left' or 'right' Default value is 'right'. |
title |
Sets application title. If it is not NULL, it will override "title" value that is set in
|
title_position |
Location of the title in the header. Must be either of 'center', 'left' or 'right' Default value is 'Center'. If there are no UI elements, this param will be ignored. |
left_menu |
Left menu. bs4DropdownMenu object (or similar dropdown menu).
Check |
right_menu |
Right menu. bs4DropdownMenu object (or similar dropdown menu).
Check |
border |
Whether to separate the navbar and body by a border. TRUE by default |
compact |
Whether items should be compacted. FALSE by default |
right_sidebar_icon |
Right sidebar toggle icon |
fixed |
Whether to fix the navbar to the top. FALSE by default |
left_sidebar_icon |
Left sidebar toggle icon |
skin |
Sidebar skin. "dark" or "light" |
status |
Sidebar status. Check |
An automatic wait indicator that are shown when the shiny server session is busy
Display application title
Optional header menu to switch between application different tabs
Header elements can be arranged via ui_position
and title_position
parameters.
Header elements look and feel can also be configured in "www\css\custom.css" file under
"Application Header" section.
Check example application for detailed example
list of both shiny UI elements and named header properties
Call this function from program/ui_header.R
to set header parameters
periscope2:set_app_parameters()
periscope2:add_ui_left_sidebar()
periscope2:add_ui_right_sidebar()
periscope2:get_url_parameters()
library(shiny) library(bs4Dash) # Inside ui_header.R # Custom left UI menu left_menu <- tagList(dropdownMenu(badgeStatus = "info", type = "notifications", notificationItem(inputId = "triggerAction2", text = "Error!", status = "danger")), dropdownMenu(badgeStatus = "info", type = "tasks", taskItem(inputId = "triggerAction3", text = "My progress", color = "orange", value = 10))) # Custom right UI menu right_menu <- dropdownMenu(badgeStatus = "danger", type = "messages", messageItem(inputId = "triggerAction1", message = "message 1", from = "Divad Nojnarg", time = "today", color = "lime")) # -- Register Header Elements in the ORDER SHOWN in the UI add_ui_header(left_menu = left_menu, right_menu = right_menu)
library(shiny) library(bs4Dash) # Inside ui_header.R # Custom left UI menu left_menu <- tagList(dropdownMenu(badgeStatus = "info", type = "notifications", notificationItem(inputId = "triggerAction2", text = "Error!", status = "danger")), dropdownMenu(badgeStatus = "info", type = "tasks", taskItem(inputId = "triggerAction3", text = "My progress", color = "orange", value = 10))) # Custom right UI menu right_menu <- dropdownMenu(badgeStatus = "danger", type = "messages", messageItem(inputId = "triggerAction1", message = "message 1", from = "Divad Nojnarg", time = "today", color = "lime")) # -- Register Header Elements in the ORDER SHOWN in the UI add_ui_header(left_menu = left_menu, right_menu = right_menu)
This function adds left sidebar configurations and UI elements. It is called within "ui_left_sidebar.R". Check example application for detailed example
add_ui_left_sidebar( sidebar_elements = NULL, sidebar_menu = NULL, collapsed = FALSE, custom_area = NULL, elevation = 4, expand_on_hover = TRUE, fixed = TRUE, minified = FALSE, status = "primary", skin = "light" )
add_ui_left_sidebar( sidebar_elements = NULL, sidebar_menu = NULL, collapsed = FALSE, custom_area = NULL, elevation = 4, expand_on_hover = TRUE, fixed = TRUE, minified = FALSE, status = "primary", skin = "light" )
sidebar_elements |
List of regular shiny UI elements (inputText, textArea, etc..) |
sidebar_menu |
|
collapsed |
If TRUE, the sidebar will be collapsed on app start up |
custom_area |
List of regular shiny UI elements but for sidebar bottom space area only. Only works if sidebar is fixed |
elevation |
A number between 0 and 5, which applies a shadow to the sidebar to add a shadow effect. |
expand_on_hover |
When |
fixed |
Whether to see all menus at once without scrolling up and down.(default = TRUE) |
minified |
Whether to slightly close the sidebar but still show item icons (default = FALSE) |
status |
Determines which color menu items (if exist) will have Check |
skin |
Sidebar skin. "dark" or "light" (default = "light") |
list of both shiny UI elements and named left sidebar properties
Call this function from program/ui_left_sidebar.R
to set left sidebar parameters
periscope2:add_ui_right_sidebar()
periscope2:get_url_parameters()
library(shiny) library(bs4Dash) # Inside ui_left_sidebar.R # sidebar menu items sidebar_elements <- textInput("text_id", "Test", "Test Data") sidebar_menu <- sidebarMenu(sidebarHeader("Main Menu"), menuItem("menu item 1", tabName = "item_1 page"), menuItem("menu item 2", tabName = "item_2 page")) add_ui_left_sidebar(sidebar_elements = sidebar_elements, sidebar_menu = sidebar_menu)
library(shiny) library(bs4Dash) # Inside ui_left_sidebar.R # sidebar menu items sidebar_elements <- textInput("text_id", "Test", "Test Data") sidebar_menu <- sidebarMenu(sidebarHeader("Main Menu"), menuItem("menu item 1", tabName = "item_1 page"), menuItem("menu item 2", tabName = "item_2 page")) add_ui_left_sidebar(sidebar_elements = sidebar_elements, sidebar_menu = sidebar_menu)
Builds application right sidebar with given configurations and elements. It is called within "ui_right_sidebar.R". Check example application for detailed example
add_ui_right_sidebar( sidebar_elements = NULL, sidebar_menu = NULL, collapsed = TRUE, overlay = TRUE, pinned = FALSE, skin = "light" )
add_ui_right_sidebar( sidebar_elements = NULL, sidebar_menu = NULL, collapsed = TRUE, overlay = TRUE, pinned = FALSE, skin = "light" )
sidebar_elements |
List of regular shiny UI elements (inputText, textArea, etc..) |
sidebar_menu |
|
collapsed |
If TRUE, the sidebar will be collapsed on app startup (default = TRUE) |
overlay |
Whether the sidebar covers the content when expanded (default = TRUE) |
pinned |
If TRUE, allows right sidebar to remain open even after a click outside (default = FALSE) |
skin |
Sidebar skin. "dark" or "light" (default = "light") |
list of both shiny UI elements and named right sidebar properties
Call this function from program/ui_right_sidebar.R
to set right sidebar parameters
periscope2:add_ui_left_sidebar()
periscope2:set_app_parameters()
periscope2:get_url_parameters()
library(shiny) library(bs4Dash) # Inside ui_right_sidebar.R sidebar_elements <- list(div(checkboxInput("checkMe", "Example Check"))) sidebar_menu <- controlbarMenu(id = "controlbarmenu", controlbarItem("Item 2", "Simple text")) # -- Register Right Sidebar Elements in the ORDER SHOWN in the UI add_ui_right_sidebar(sidebar_elements = sidebar_elements, sidebar_menu = sidebar_menu)
library(shiny) library(bs4Dash) # Inside ui_right_sidebar.R sidebar_elements <- list(div(checkboxInput("checkMe", "Example Check"))) sidebar_menu <- controlbarMenu(id = "controlbarmenu", controlbarItem("Item 2", "Simple text")) # -- Register Right Sidebar Elements in the ORDER SHOWN in the UI add_ui_right_sidebar(sidebar_elements = sidebar_elements, sidebar_menu = sidebar_menu)
Call this as an addin to build valid yaml file that is needed for running announcements module. The generated file can be used in periscope2 app using load_announcements.
announcementConfigurationsAddin()
announcementConfigurationsAddin()
The method can be called directly via R
console or via RStudio addins menu
launch gadget window
periscope2:load_announcements()
if (interactive()) { periscope2:::announcementConfigurationsAddin() }
if (interactive()) { periscope2:::announcementConfigurationsAddin() }
Server-side function for the appResetButton This is a custom high-functionality button for session reload. The server function is used to provide module configurations.
appReset(id, reset_wait = 5000, alert_location = "bodyAlert", logger)
appReset(id, reset_wait = 5000, alert_location = "bodyAlert", logger)
id |
Character represents the ID of the Module's UI element (the same id used in |
reset_wait |
Integer represents the period to wait before session reload in milliseconds (default = 5000) |
alert_location |
Character represents div ID or selector to display module related messages (default = "bodyAlert") |
logger |
logger to use |
nothing, function will display a warning message in the app then reload the whole application
This function is not called directly by consumers - it is accessed in
server_local.R (or similar file) using the same id provided in appResetButton
:
appReset(id = "appResetId", logger = ss_userAction.Log)
if (interactive()) { library(shiny) library(periscope2) shinyApp( ui = fluidPage(fluidRow(column(12, appResetButton(id = "appResetId")))), server = function(input, output) { appReset(id = "appResetId", logger = "") }) }
if (interactive()) { library(shiny) library(periscope2) shinyApp( ui = fluidPage(fluidRow(column(12, appResetButton(id = "appResetId")))), server = function(input, output) { appReset(id = "appResetId", logger = "") }) }
Creates a toggle button to reset application session. Upon pressing on the button, its state is flipped to cancel application reload with application and console warning messages indicating that the application will be reloaded.
appResetButton(id)
appResetButton(id)
id |
character id for the object |
User can either resume reloading application session or cancel reloading process which will also generate application and console messages to indicate reloading status and result.
an html div with prettyToggle button
Initial state label is "Application Reset" with warning status
Reloading state label is "Cancel Application Reset" with danger status
Call this function at any place in UI section.
It is paired with a call to appReset(id, ...)
in server
if (interactive()) { library(shiny) library(periscope2) shinyApp( ui = fluidPage(fluidRow(column(12, appResetButton(id = "appResetId")))), server = function(input, output) { appReset(id = "appResetId", logger = "") }) }
if (interactive()) { library(shiny) library(periscope2) shinyApp( ui = fluidPage(fluidRow(column(12, appResetButton(id = "appResetId")))), server = function(input, output) { appReset(id = "appResetId", logger = "") }) }
Creates ready-to-use templated application files using the periscope2
framework. The application can be created either empty (default) or with a
sample/documented example application.
create_application( name, location, sample_app = FALSE, left_sidebar = TRUE, right_sidebar = FALSE )
create_application( name, location, sample_app = FALSE, left_sidebar = TRUE, right_sidebar = FALSE )
name |
name for the new application and directory |
location |
base path for creation of |
sample_app |
whether to create a sample shiny application |
left_sidebar |
whether the left sidebar should be enabled. It can be TRUE/FALSE |
right_sidebar |
parameter to set the right sidebar. It can be TRUE/FALSE |
no return value, creates application folder structure and files
The name
directory must not exist in location
. If the code
detects that this directory exists it will abort the creation process with
a warning and will not create an application template.
Use only filesystem-compatible characters in the name (ideally w/o spaces)
name -- log (log files) -- program (user application) -- -- config (application configuration files) -- -- data (user application data) -- -- fxn (user application function) -- -- modules (application modules files) -- www (supporting shiny files) -- -- css (application css files) -- -- img (application image files) -- -- js (application js files)
All user application creation and modifications will be done in
the program directory. The names & locations
of the framework-provided .R files should not be changed or the framework
will fail to work as expected.
name/program/config directory :
Use this location for configuration files.
name/program/data directory :
Use this location for data files. There is a .gitignore file
included in this directory to prevent accidental versioning of data
name/program/fxn directory :
Use this location for supporting and helper R files.
name/program/modules directory :
Use this location for application new modules files.
name/program/global.R :
Use this location for code that would have previously resided in global.R
and for setting application parameters using
set_app_parameters. Anything placed in this file will
be accessible across all user sessions as well as within the UI context.
name/program/server_global.R :
Use this location for code that would have previously resided in server.R
above (i.e. outside of) the call to shinyServer(...)
. Anything placed
in this file will be accessible across all user sessions.
name/program/server_local.R :
Use this location for code that would have previously resided in server.R
inside of the call to shinyServer(...)
. Anything placed in this
file will be accessible only within a single user session.
name/program/ui_body.R :
Create body UI elements in this file and register them with the
framework using a call to add_ui_body
name/program/ui_footer.R :
Create footer UI elements in this file and register them with the
framework using a call to add_ui_footer
name/program/ui_header.R :
Create header UI elements in this file and register them with the
framework using a call to add_ui_header
name/program/ui_left_sidebar.R :
Create sidebar UI elements in this file and register them with the
framework using a call to add_ui_left_sidebar
name/program/ui_right_sidebar.R :
Create right sidebar UI elements in this file and register them with the
framework using a call to add_ui_right_sidebar
name/www/css/custom.css :
This is the application custom styling css file. User can update
application different parts style using this file.
name/www/js/custom.js :
This is the application custom javascript file.
name/www/periscope_style.yaml :
This is the application custom styling yaml file. User can update
application different parts style using this file.
Do not modify the following files:
name\global.R name\server.R name\ui.R name\www\img\loader.gif name\www\img\tooltip.png
# sample app named 'mytestapp' created in a temp dir location <- tempdir() create_application(name = 'mytestapp', location = location, sample_app = TRUE) unlink(paste0(location,'/mytestapp'), TRUE) # sample app named 'mytestapp' with a right sidebar using a custom icon created in a temp dir location <- tempdir() create_application(name = 'mytestapp', location = location, sample_app = TRUE, right_sidebar = TRUE) unlink(paste0(location,'/mytestapp'), TRUE) # blank app named 'myblankapp' created in a temp dir location <- tempdir() create_application(name = 'myblankapp', location = location) unlink(paste0(location,'/myblankapp'), TRUE) # blank app named 'myblankapp' without a left sidebar created in a temp dir location <- tempdir() create_application(name = 'myblankapp', location = location, left_sidebar = FALSE) unlink(paste0(location,'/myblankapp'), TRUE)
# sample app named 'mytestapp' created in a temp dir location <- tempdir() create_application(name = 'mytestapp', location = location, sample_app = TRUE) unlink(paste0(location,'/mytestapp'), TRUE) # sample app named 'mytestapp' with a right sidebar using a custom icon created in a temp dir location <- tempdir() create_application(name = 'mytestapp', location = location, sample_app = TRUE, right_sidebar = TRUE) unlink(paste0(location,'/mytestapp'), TRUE) # blank app named 'myblankapp' created in a temp dir location <- tempdir() create_application(name = 'myblankapp', location = location) unlink(paste0(location,'/myblankapp'), TRUE) # blank app named 'myblankapp' without a left sidebar created in a temp dir location <- tempdir() create_application(name = 'myblankapp', location = location, left_sidebar = FALSE) unlink(paste0(location,'/myblankapp'), TRUE)
User can update an existing application that does not have a left side bar and add a new empty one using this function.
create_left_sidebar(location)
create_left_sidebar(location)
location |
path of the existing periscope2 application |
If conversion is successful, the following message will be returned "Add left sidebar conversion was successful. File(s) updated: ui.R, ui_left_sidebar.R"
If the function called on an application with an existing left bar, message "Left sidebar already available, no conversion needed" will be returned with no conversion
If the passed location is invalid, empty, not exist or not a valid periscope2 application, nothing will be added and a related error message will be printed in console
no return value, creates left sidebar related UI R file and updates related source call in ui.R
User can update an existing application that does not have a right side bar and add a new empty one using this function.
create_right_sidebar(location)
create_right_sidebar(location)
location |
path of the existing periscope2 application. |
If conversion is successful, the following message will be returned "Add right sidebar conversion was successful. File(s) updated: ui.R, ui_right_sidebar.R"
If the function called on an application with an existing right bar, message "Right sidebar already available, no conversion needed" will be returned with no conversion
If the passed location is invalid, empty, not exist or not a valid periscope2 application, nothing will be added and a related error message will be printed in console
no return value, creates right sidebar related UI R file and updates related source call in ui.R
Create an alert panel in server code to be displayed in the specified UI selector location
createPSAlert( session = shiny::getDefaultReactiveDomain(), id = NULL, selector = NULL, options )
createPSAlert( session = shiny::getDefaultReactiveDomain(), id = NULL, selector = NULL, options )
session |
Shiny session object |
id |
Anchor id (either id or selector only should be set) |
selector |
Character vector represents jQuery selector to add the alert to is (i.e ".alertClass", div.badge-danger.navbar-badge). If 'id' is specified, this parameter will be neglected |
options |
List of options to pass to the alert |
html div and inserts it in the app DOM
Call this function from program/server_local.R
or any other server file to setup the needed alert
periscope2:set_app_parameters()
periscope2:get_url_parameters()
library(shiny) library(bs4Dash) # Inside server_local.R createPSAlert(id = "sidebarRightAlert", options = list(title = "Right Side", status = "success", closable = TRUE, content = "Example Basic Sidebar Alert")) # Test se ## a div with class "badge-danger.navbar-badge" must be exist in UI to display alert selector <- "div.badge-danger.navbar-badge" createPSAlert(selector = selector, options = list(title = "Selector Title", status = "danger", closable = TRUE, content = "Selector Alert"))
library(shiny) library(bs4Dash) # Inside server_local.R createPSAlert(id = "sidebarRightAlert", options = list(title = "Right Side", status = "success", closable = TRUE, content = "Example Basic Sidebar Alert")) # Test se ## a div with class "badge-danger.navbar-badge" must be exist in UI to display alert selector <- "div.badge-danger.navbar-badge" createPSAlert(selector = selector, options = list(title = "Selector Title", status = "danger", closable = TRUE, content = "Selector Alert"))
Server-side function for the downloadablePlotUI. This is a custom plot output paired with a linked downloadFile button.
downloadablePlot( id, logger = NULL, filenameroot = "download", aspectratio = 1, downloadfxns = NULL, visibleplot )
downloadablePlot( id, logger = NULL, filenameroot = "download", aspectratio = 1, downloadfxns = NULL, visibleplot )
id |
the ID of the Module's UI element |
logger |
logger to use |
filenameroot |
the base text used for user-downloaded file - can be either a character string or a reactive expression returning a character string |
aspectratio |
the downloaded chart image width:height ratio (ex: 1 = square, 1.3 = 4:3, 0.5 = 1:2). Where not applicable for a download type it is ignored (e.g. data, html downloads) |
downloadfxns |
a named list of functions providing download images or data tables as return values. The names for the list should be the same names that were used when the plot UI was created. |
visibleplot |
function or reactive expression providing the plot to display as a return value. This function should require no input parameters. |
downloadFile button will be hidden if downloadablePlot
parameter downloadfxns
or
downloadablePlotUI
parameter downloadtypes
is empty
Reactive expression containing the currently selected plot to be available for display and download
When there are no values to download in any of the linked downloadfxns the button will be hidden as there is nothing to download.
This function is not called directly by consumers - it is accessed in
server.R using the same id provided in downloadablePlotUI
:
downloadablePlot(id, logger, filenameroot,
downloadfxns, visibleplot)
if (interactive()) { library(shiny) library(ggplot2) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 12, downloadablePlotUI("object_id1", downloadtypes = c("png", "csv"), download_hovertext = "Download plot and data", height = "500px", btn_halign = "left")))), server = function(input, output) { download_plot <- function() { ggplot(data = mtcars, aes(x = wt, y = mpg)) + geom_point(aes(color = cyl)) + theme(legend.justification = c(1, 1), legend.position = c(1, 1), legend.title = element_blank()) + ggtitle("GGPlot Example ") + xlab("wt") + ylab("mpg") } downloadablePlot(id = "object_id1", logger = "", filenameroot = "mydownload1", downloadfxns = list(png = download_plot, csv = reactiveVal(mtcars)), aspectratio = 1.33, visibleplot = download_plot) }) }
if (interactive()) { library(shiny) library(ggplot2) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 12, downloadablePlotUI("object_id1", downloadtypes = c("png", "csv"), download_hovertext = "Download plot and data", height = "500px", btn_halign = "left")))), server = function(input, output) { download_plot <- function() { ggplot(data = mtcars, aes(x = wt, y = mpg)) + geom_point(aes(color = cyl)) + theme(legend.justification = c(1, 1), legend.position = c(1, 1), legend.title = element_blank()) + ggtitle("GGPlot Example ") + xlab("wt") + ylab("mpg") } downloadablePlot(id = "object_id1", logger = "", filenameroot = "mydownload1", downloadfxns = list(png = download_plot, csv = reactiveVal(mtcars)), aspectratio = 1.33, visibleplot = download_plot) }) }
Creates a custom plot output that is paired with a linked downloadFile button. This module is compatible with ggplot2, grob and lattice produced graphics.
downloadablePlotUI( id, downloadtypes = c("png"), download_hovertext = NULL, width = "100%", height = "400px", btn_halign = "right", btn_valign = "bottom", btn_overlap = TRUE, clickOpts = NULL, hoverOpts = NULL, brushOpts = NULL )
downloadablePlotUI( id, downloadtypes = c("png"), download_hovertext = NULL, width = "100%", height = "400px", btn_halign = "right", btn_valign = "bottom", btn_overlap = TRUE, clickOpts = NULL, hoverOpts = NULL, brushOpts = NULL )
id |
character id for the object |
downloadtypes |
vector of values for download types |
download_hovertext |
download button tooltip hover text |
width |
plot width (any valid css size value) |
height |
plot height (any valid css size value) |
btn_halign |
horizontal position of the download button ("left", "center", "right") |
btn_valign |
vertical position of the download button ("top", "bottom") |
btn_overlap |
whether the button should appear on top of the bottom of the plot area to save on vertical space (there is often a blank area where a button can be overlayed instead of utilizing an entire horizontal row for the button below the plot area) |
clickOpts |
NULL or an object created by the clickOpts function |
hoverOpts |
NULL or an object created by the hoverOpts function |
brushOpts |
NULL or an object created by the brushOpts function |
downloadFile button will be hidden if downloadablePlot
parameter downloadfxns
or
downloadablePlotUI
parameter downloadtypes
is empty
list of downloadFileButton UI and plot object
downloadablePlotUI("myplotID", c("png", "csv"),
"Download Plot or Data", "300px")
When there is nothing to download in any of the linked downloadfxns the button will be hidden as there is nothing to download.
This module is NOT compatible with the built-in (base) graphics (such as basic plot, etc.) because they cannot be saved into an object and are directly output by the system at the time of creation.
Call this function at the place in ui.R where the plot should be placed.
Paired with a call to downloadablePlot(id, ...)
in server.R
if (interactive()) { library(shiny) library(ggplot2) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 12, downloadablePlotUI("object_id1", downloadtypes = c("png", "csv"), download_hovertext = "Download plot and data", height = "500px", btn_halign = "left")))), server = function(input, output) { download_plot <- function() { ggplot(data = mtcars, aes(x = wt, y = mpg)) + geom_point(aes(color = cyl)) + theme(legend.justification = c(1, 1), legend.position = c(1, 1), legend.title = element_blank()) + ggtitle("GGPlot Example ") + xlab("wt") + ylab("mpg") } downloadablePlot(id = "object_id1", logger = "", filenameroot = "mydownload1", downloadfxns = list(png = download_plot, csv = reactiveVal(mtcars)), aspectratio = 1.33, visibleplot = download_plot) }) }
if (interactive()) { library(shiny) library(ggplot2) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 12, downloadablePlotUI("object_id1", downloadtypes = c("png", "csv"), download_hovertext = "Download plot and data", height = "500px", btn_halign = "left")))), server = function(input, output) { download_plot <- function() { ggplot(data = mtcars, aes(x = wt, y = mpg)) + geom_point(aes(color = cyl)) + theme(legend.justification = c(1, 1), legend.position = c(1, 1), legend.title = element_blank()) + ggtitle("GGPlot Example ") + xlab("wt") + ylab("mpg") } downloadablePlot(id = "object_id1", logger = "", filenameroot = "mydownload1", downloadfxns = list(png = download_plot, csv = reactiveVal(mtcars)), aspectratio = 1.33, visibleplot = download_plot) }) }
Server-side function for the downloadableTableUI. This is a custom high-functionality table paired with a linked downloadFile button.
downloadableTable( id, logger = NULL, filenameroot = "download", downloaddatafxns = NULL, tabledata, selection = NULL, table_options = list() )
downloadableTable( id, logger = NULL, filenameroot = "download", downloaddatafxns = NULL, tabledata, selection = NULL, table_options = list() )
id |
the ID of the Module's UI element |
logger |
logger to use |
filenameroot |
the text used for user-downloaded file - can be either a character string, a reactive expression or a function returning a character string |
downloaddatafxns |
a named list of functions providing the data as return values. The names for the list should be the same names that were used when the table UI was created. |
tabledata |
function or reactive expression providing the table display data as a return value. This function should require no input parameters. |
selection |
function or reactive expression providing the row_ids of the rows that should be selected |
table_options |
optional table formatting parameters check |
downloadFile button will be hidden if downloadableTable
parameter downloaddatafxn
or
downloadableTableUI
parameter downloadtypes
is empty
Generated table can highly customized using function ?DT::datatable
same arguments
except for options
and selection
parameters.
For options
user can pass the same ?DT::datatable
options using the same names and
values one by one separated by comma.
For selection
parameter it can be either a function or reactive expression providing the row_ids of the
rows that should be selected.
Also, user can apply the same provided ?DT::formatCurrency
columns formats on passed
dataset using format functions names as keys and their options as a list.
Reactive expression containing the currently selected rows in the display table
When there are no rows to download in any of the linked downloaddatafxns the button will be hidden as there is nothing to download.
selection
parameter has different usage than DT::datatable selection
option.
See parameters usage section.
DT::datatable options editable
, width
and height
are not supported
This function is not called directly by consumers - it is accessed in
server.R using the same id provided in downloadableTableUI
:
downloadableTable(id, logger, filenameroot,
downloaddatafxns, tabledata, rownames, caption, selection)
Note: calling module server returns the reactive expression containing the currently selected rows in the display table.
if (interactive()) { library(shiny) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 12, downloadableTableUI("object_id1", downloadtypes = c("csv", "tsv"), hovertext = "Download the data here!", contentHeight = "300px", singleSelect = FALSE)))), server = function(input, output) { mydataRowIds <- function(){ rownames(head(mtcars))[c(2, 5)] } selectedrows <- downloadableTable( id = "object_id1", logger = "", filenameroot = "mydownload1", downloaddatafxns = list(csv = reactiveVal(mtcars), tsv = reactiveVal(mtcars)), tabledata = reactiveVal(mtcars), selection = mydataRowIds, table_options = list(rownames = TRUE, caption = "This is a great table!")) observeEvent(selectedrows(), { print(selectedrows()) })}) }
if (interactive()) { library(shiny) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 12, downloadableTableUI("object_id1", downloadtypes = c("csv", "tsv"), hovertext = "Download the data here!", contentHeight = "300px", singleSelect = FALSE)))), server = function(input, output) { mydataRowIds <- function(){ rownames(head(mtcars))[c(2, 5)] } selectedrows <- downloadableTable( id = "object_id1", logger = "", filenameroot = "mydownload1", downloaddatafxns = list(csv = reactiveVal(mtcars), tsv = reactiveVal(mtcars)), tabledata = reactiveVal(mtcars), selection = mydataRowIds, table_options = list(rownames = TRUE, caption = "This is a great table!")) observeEvent(selectedrows(), { print(selectedrows()) })}) }
Creates a custom high-functionality table paired with a linked downloadFile button. The table has search and highlight functionality, infinite scrolling, sorting by columns and returns a reactive dataset of selected items.
downloadableTableUI( id, downloadtypes = NULL, hovertext = NULL, contentHeight = "200px", singleSelect = FALSE )
downloadableTableUI( id, downloadtypes = NULL, hovertext = NULL, contentHeight = "200px", singleSelect = FALSE )
id |
character id for the object |
downloadtypes |
vector of values for data download types |
hovertext |
download button tooltip hover text |
contentHeight |
viewable height of the table (any valid css size value) |
singleSelect |
whether the table should only allow a single row to be selected at a time (FALSE by default allows multi-select). |
downloadFile button will be hidden if downloadableTable
parameter downloaddatafxn
or
downloadableTableUI
parameter downloadtypes
is empty
list of downloadFileButton UI and DT datatable
Consistent styling of the table
downloadFile module button functionality built-in to the table (it will be shown only if downloadtypes is defined)
Ability to show different data from the download data
Table is automatically fit to the window size with infinite y-scrolling
Table search functionality including highlighting built-in
Multi-select built in, including reactive feedback on which table items are selected
downloadableTableUI("mytableID", c("csv", "tsv"),
"Click Here", "300px")
When there are no rows to download in any of the linked downloaddatafxns the button will be hidden as there is nothing to download.
Call this function at the place in ui.R where the table should be placed.
Paired with a call to downloadableTable(id, ...)
in server.R
if (interactive()) { library(shiny) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 12, downloadableTableUI("object_id1", downloadtypes = c("csv", "tsv"), hovertext = "Download the data here!", contentHeight = "300px", singleSelect = FALSE)))), server = function(input, output) { mydataRowIds <- function(){ rownames(head(mtcars))[c(2, 5)] } selectedrows <- downloadableTable( id = "object_id1", logger = "", filenameroot = "mydownload1", downloaddatafxns = list(csv = reactiveVal(mtcars), tsv = reactiveVal(mtcars)), tabledata = reactiveVal(mtcars), selection = mydataRowIds, table_options = list(rownames = TRUE, caption = "This is a great table!")) observeEvent(selectedrows(), { print(selectedrows()) })}) }
if (interactive()) { library(shiny) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 12, downloadableTableUI("object_id1", downloadtypes = c("csv", "tsv"), hovertext = "Download the data here!", contentHeight = "300px", singleSelect = FALSE)))), server = function(input, output) { mydataRowIds <- function(){ rownames(head(mtcars))[c(2, 5)] } selectedrows <- downloadableTable( id = "object_id1", logger = "", filenameroot = "mydownload1", downloaddatafxns = list(csv = reactiveVal(mtcars), tsv = reactiveVal(mtcars)), tabledata = reactiveVal(mtcars), selection = mydataRowIds, table_options = list(rownames = TRUE, caption = "This is a great table!")) observeEvent(selectedrows(), { print(selectedrows()) })}) }
Server-side function for the downloadFileButton. This is a custom high-functionality button for file downloads supporting single or multiple download types. The server function is used to provide the data for download.
downloadFile( id, logger = NULL, filenameroot = "download", datafxns = NULL, aspectratio = 1 )
downloadFile( id, logger = NULL, filenameroot = "download", datafxns = NULL, aspectratio = 1 )
id |
ID of the Module's UI element |
logger |
logger to use |
filenameroot |
the base text used for user-downloaded file - can be either a character string or a reactive expression that returns a character string |
datafxns |
a named list of functions providing the data as return values. The names for the list should be the same names that were used when the button UI was created. |
aspectratio |
the downloaded chart image width:height ratio (ex: 1 = square, 1.3 = 4:3, 0.5 = 1:2). Where not applicable for a download type it is ignored (e.g. data downloads). |
no return value, called for downloading selected file type
This function is not called directly by consumers - it is accessed in
server.R using the same id provided in downloadFileButton
:
downloadFile(id, logger, filenameroot, datafxns)
if (interactive()) { library(shiny) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 6, # single download type downloadFileButton("object_id1", downloadtypes = c("csv"), hovertext = "Button 1 Tooltip")), column(width = 6, # multiple download types downloadFileButton("object_id2", downloadtypes = c("csv", "tsv"), hovertext = "Button 2 Tooltip")))), server = function(input, output) { # single download type downloadFile(id = "object_id1", logger = "", filenameroot = "mydownload1", datafxns = list(csv = reactiveVal(iris)), aspectratio = 1) # multiple download types downloadFile(id = "object_id2", logger = "", filenameroot = "mydownload2", datafxns = list(csv = reactiveVal(mtcars), tsv = reactiveVal(mtcars))) }) }
if (interactive()) { library(shiny) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 6, # single download type downloadFileButton("object_id1", downloadtypes = c("csv"), hovertext = "Button 1 Tooltip")), column(width = 6, # multiple download types downloadFileButton("object_id2", downloadtypes = c("csv", "tsv"), hovertext = "Button 2 Tooltip")))), server = function(input, output) { # single download type downloadFile(id = "object_id1", logger = "", filenameroot = "mydownload1", datafxns = list(csv = reactiveVal(iris)), aspectratio = 1) # multiple download types downloadFile(id = "object_id2", logger = "", filenameroot = "mydownload2", datafxns = list(csv = reactiveVal(mtcars), tsv = reactiveVal(mtcars))) }) }
Returns a list of all supported types
downloadFile_AvailableTypes()
downloadFile_AvailableTypes()
a vector of all supported types
It is a downloadFile module helper to return periscope2 defined file types list and warns user if an invalid type is included
downloadFile_ValidateTypes(types)
downloadFile_ValidateTypes(types)
types |
list of types to test |
the list input given in types
#inside console ## Check valid types result <- periscope2::downloadFile_AvailableTypes() identical(result, c("csv", "xlsx", "tsv", "txt", "png", "jpeg", "tiff", "bmp")) ## check invalid type testthat::expect_warning(downloadFile_ValidateTypes(types = "csv_invalid"), "file download list contains an invalid type <csv_invalid>")
#inside console ## Check valid types result <- periscope2::downloadFile_AvailableTypes() identical(result, c("csv", "xlsx", "tsv", "txt", "png", "jpeg", "tiff", "bmp")) ## check invalid type testthat::expect_warning(downloadFile_ValidateTypes(types = "csv_invalid"), "file download list contains an invalid type <csv_invalid>")
Creates a custom high-functionality button for file downloads with two states - single download type or multiple-download types. The button image and pop-up menu (if needed) are set accordingly. A tooltip can also be set for the button.
downloadFileButton(id, downloadtypes = c("csv"), hovertext = NULL)
downloadFileButton(id, downloadtypes = c("csv"), hovertext = NULL)
id |
character id for the object |
downloadtypes |
vector of values for data download types |
hovertext |
tooltip hover text |
html span with tooltip and either shiny downloadButton in case of single download or shiny actionButton otherwise
Consistent styling of the button, including a hover tooltip
Single or multiple types of downloads
Ability to download different data for each type of download
downloadFileUI("mybuttonID1", c("csv", "tsv"), "Click Here")
downloadFileUI("mybuttonID2", "csv", "Click to download")
Call this function at the place in ui.R where the button should be placed.
It is paired with a call to downloadFile(id, ...)
in server.R
if (interactive()) { library(shiny) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 6, # single download type downloadFileButton("object_id1", downloadtypes = c("csv"), hovertext = "Button 1 Tooltip")), column(width = 6, # multiple download types downloadFileButton("object_id2", downloadtypes = c("csv", "tsv"), hovertext = "Button 2 Tooltip")))), server = function(input, output) { # single download type downloadFile(id = "object_id1", logger = "", filenameroot = "mydownload1", datafxns = list(csv = reactiveVal(iris)), aspectratio = 1) # multiple download types downloadFile(id = "object_id2", logger = "", filenameroot = "mydownload2", datafxns = list(csv = reactiveVal(mtcars), tsv = reactiveVal(mtcars))) }) }
if (interactive()) { library(shiny) library(periscope2) shinyApp(ui = fluidPage(fluidRow(column(width = 6, # single download type downloadFileButton("object_id1", downloadtypes = c("csv"), hovertext = "Button 1 Tooltip")), column(width = 6, # multiple download types downloadFileButton("object_id2", downloadtypes = c("csv", "tsv"), hovertext = "Button 2 Tooltip")))), server = function(input, output) { # single download type downloadFile(id = "object_id1", logger = "", filenameroot = "mydownload1", datafxns = list(csv = reactiveVal(iris)), aspectratio = 1) # multiple download types downloadFile(id = "object_id2", logger = "", filenameroot = "mydownload2", datafxns = list(csv = reactiveVal(mtcars), tsv = reactiveVal(mtcars))) }) }
This function returns any url parameters passed to the application as a named list. Keep in mind url parameters are always user-session scoped
get_url_parameters(session)
get_url_parameters(session)
session |
shiny session object |
named list of url parameters and values. List may be empty if no URL parameters were passed when the application instance was launched
Call this function from program/server_local.R
or any other server file
periscope2:set_app_parameters()
periscope2:add_ui_left_sidebar()
periscope2:add_ui_right_sidebar()
library(shiny) library(periscope2) # Display application info observeEvent(input$app_info, { url_params <- get_url_parameters(session) show_alert(html = TRUE, showCloseButton = FALSE, animation = "slide-from-top", closeOnClickOutside = TRUE, text = url_params[["passed_paramter"]], title = "alert title") })
library(shiny) library(periscope2) # Display application info observeEvent(input$app_info, { url_params <- get_url_parameters(session) show_alert(html = TRUE, showCloseButton = FALSE, animation = "slide-from-top", closeOnClickOutside = TRUE, text = url_params[["passed_paramter"]], title = "alert title") })
Reads and parses application announcements configurations in config/announce.yaml
, then display announcements in
application header.
load_announcements( announcements_file_path = NULL, announcement_location_id = "announceAlert" )
load_announcements( announcements_file_path = NULL, announcement_location_id = "announceAlert" )
announcements_file_path |
The path to announcements configuration file. |
announcement_location_id |
Announcement target location div id (default = "announceAlert") |
If announce.yaml does not exist or contains invalid configurations. Nothing will be displayed. Closing announcements is caller application responsibility
number of seconds an announcement should be staying in caller application
periscope2:announcementConfigurationsAddin()
load_announcements(system.file("fw_templ/announce.yaml", package = "periscope2"))
load_announcements(system.file("fw_templ/announce.yaml", package = "periscope2"))
Generate a log record and pass it to the logging system.
logdebug(msg, ..., logger = "") loginfo(msg, ..., logger = "") logwarn(msg, ..., logger = "") logerror(msg, ..., logger = "")
logdebug(msg, ..., logger = "") loginfo(msg, ..., logger = "") logwarn(msg, ..., logger = "") logerror(msg, ..., logger = "")
msg |
the textual message to be output, or the format for the ... arguments |
... |
if present, msg is interpreted as a format and the ... values are passed to it to form the actual message. |
logger |
the name of the logger to which we pass the record |
A log record gets timestamped and will be independently formatted by each
of the handlers handling it.
Leading and trailing whitespace is stripped from the final message.
no return value, prints log contents into R console and app log file
Creates a shiny table with table containing logged user actions. Table contents are auto updated whenever a user action is
logged. The id must match the same id configured in server.R file upon calling fw_server_setup
method
logViewerOutput(id = "logViewer")
logViewerOutput(id = "logViewer")
id |
character id for the object(default = "logViewer") |
shiny tableOutput instance
action - the action that id logged in any place in app
time - action time
logViewerOutput('logViewer')
Add the log viewer box to your box list
It is paired with a call to fw_server_setup
method in server.R file
# Inside ui_body add the log viewer box to your box list logViewerOutput('logViewerId')
# Inside ui_body add the log viewer box to your box list logViewerOutput('logViewerId')
Periscope2 is the next-generation package following the paradigm of the 'periscope' package to support a UI-standardized and rail-guarded enterprise quality application environment. This package also includes a variety of convenience functions for 'shiny' applications in a more modernized way. Base reusable functionality as well as UI paradigms are included to ensure a consistent user experience regardless of application or developer.
'periscope2' differs from the 'periscope' package as follows:
Upgraded dependency on bootstrap v4 instead of bootstrap v3
New user modules (i.e. announcements)
More functionality and finer control over existing modules such as alert and reset
More control over customizing different application parts (header, footer, left sidebar, right sidebar and body)
Enhanced file structure to organize application UI, shiny modules, app configuration, .. etc
A gallery of 'periscope' and 'periscope2' example apps is hosted at http://periscopeapps.org
Create a new framework application instance:
create_application
Set application parameters in program/global.R:
set_app_parameters
Get any url parameters passed to the application:
get_url_parameters
Update an existing application with a needed sidebar:
create_left_sidebar
create_right_sidebar
Register user-created UI objects to the requisite application locations:
add_ui_body
add_ui_footer
add_ui_header
add_ui_left_sidebar
add_ui_right_sidebar
Included shiny modules with a customized UI:
downloadFileButton
downloadableTableUI
downloadablePlotUI
appResetButton
logViewerOutput
High-functionality standardized tooltips:
ui_tooltip
browseVignettes(package = 'periscope2')
This function sets global parameters customizing the shiny application.
set_app_parameters( title = NULL, app_info = NULL, log_level = "DEBUG", app_version = "1.0.0", loading_indicator = NULL, announcements_file = NULL )
set_app_parameters( title = NULL, app_info = NULL, log_level = "DEBUG", app_version = "1.0.0", loading_indicator = NULL, announcements_file = NULL )
title |
Use add_ui_header to configure application title text |
app_info |
Application detailed information. It can be character string, HTML value or NULL
|
log_level |
Designating the log level to use for the user log as 'DEBUG','INFO', 'WARN' or 'ERROR' (default = 'DEBUG') |
app_version |
Character string designating the application version (default = '1.0.0') |
loading_indicator |
It uses waiter (see https://waiter.john-coene.com/#/). |
announcements_file |
. Use load_announcements to configure announcement. |
no return value, called for setting new application global properties
Call this function from program/global.R
to set the application
parameters.
periscope2:announcementConfigurationsAddin()
periscope2:load_announcements()
periscope2:add_ui_left_sidebar()
periscope2:add_ui_right_sidebar()
periscope2:get_url_parameters()
library(shiny) library(waiter) library(periscope2) # Inside program/global.R set_app_parameters(app_info = HTML("Example info"), log_level = "DEBUG", app_version = "1.0.0", loading_indicator = list(html = tagList(spin_1(), "Loading ...")))
library(shiny) library(waiter) library(periscope2) # Inside program/global.R set_app_parameters(app_info = HTML("Example info"), log_level = "DEBUG", app_version = "1.0.0", loading_indicator = list(html = tagList(spin_1(), "Loading ...")))
Call this as an addin to build valid yaml file that is needed for creating application periscope_style.yaml file. The generated file can be used in periscope2 app by putting it inside generated app www folder.
themeConfigurationsAddin()
themeConfigurationsAddin()
The method can be called directly via R
console or via RStudio addins menu
launch gadget window
periscope2:create_application()
if (interactive()) { periscope2:::themeConfigurationsAddin() }
if (interactive()) { periscope2:::themeConfigurationsAddin() }
This function inserts a standardized tooltip image, label (optional), and hovertext into the application UI
ui_tooltip(id, label = "", text = "", placement = "top")
ui_tooltip(id, label = "", text = "", placement = "top")
id |
The id for the tooltip object |
label |
Text label to appear to the left of the tooltip image |
text |
Tooltip text shown when the user hovers over the image |
placement |
Where to display tooltip label. Available places are "top", "bottom", "left", "right" (default is "top") |
html span with the label, tooltip image and tooltip text
Call this function from program/ui_body.R
to set tooltip parameters
periscope2:add_ui_left_sidebar()
periscope2:add_ui_right_sidebar()
periscope2:set_app_parameters()
periscope2:get_url_parameters()
library(shiny) library(periscope2) # Inside ui_body.R or similar UI file ui_tooltip(id = "top_tip", label = "Top Tooltips", text = "Top tooltip")
library(shiny) library(periscope2) # Inside ui_body.R or similar UI file ui_tooltip(id = "top_tip", label = "Top Tooltips", text = "Top tooltip")