This framework was created for the express purpose of making it easy for shiny developers to create consistent-looking and functioning applications. This is important because it reduces the time a user must spend to learn the interface for new applications (thus reducing application support time and increasing the user’s satisfaction across applications).
In addition to creating a consistent UI experience this framework reduces development time for new applications by removing some of the boilerplate aspects of new applications such as alerting, logging, etc.
1: Left Sidebar
The left sidebar is reserved for configuration options, settings, and general user application controls and functionality that will affect the body of the application.
There are two tabs in the sidebar Basic and Advanced. The Basic tab is intended to be used for commonly accessed options and settings whereas the Advanced tab is reserved for less-common options and settings. The tab names (or labels) can be changed. Both tabs are optional and if one of them or both are missing there will be no tabs shown (the sidebar will not have tabbed areas).
The left sidebar can be collapsed in desktop mode to maximize the user’s view of the application body when they do not immediately need the configuration options and settings. Also, it is possible to create an application without a left sidebar.
2: Body
This is the main body area for applications where charts and figures, tables, etc. are placed by the application developer. If desired the developer can add tabbed pages, etc.
3: Right Sidebar
The right sidebar is, like the left sidebar, reserved for configuration options, settings, and general user application controls and functionality that will affect the body of the application.
Users can create their own tabs in the right sidebar up to a maximum of 5.
The right sidebar is collapsed by default, it can be opened by clicking on the (customizable) icon.
Note: The blue area running across the top of
the application is the header bar. This area is reserved for framework
use.
The application layout will adapt to user device size automatically
This indicator shows in the header bar automatically when the shiny application is busy. There is no application developer code necessary to tie into this functionality.
There is a button placed by the framework at the bottom of the Advanced sidebar tab. This button is automatically wired to reset the application to the initial session state. The user is given a warning (as an alert on the Advanced tab) and the reset is delayed (default = 5s) to allow the user to cancel the reset. Reset requests and cancellations are logged automatically.
The framework makes it easy to log user actions. Framework user interactions are automatically logged. The user interaction log is automatically shown in a (collapsed) box at the bottom of the application body but can be turned off by setting userlog = FALSE in set_app_parameters in program/global.R.
There are four standardized locations for user-alerts: the top of the basic sidebar tab, the top of the advanced sidebar tab, the top of the body and at the top of the right sidebar. All the alerts are dismissible by the user and can be colored by setting the status.
Alerts can accumulate (i.e. append to each other) or replace previous alerts.
# Alert on Sidebar>Basic tab
createAlert(session, "sidebarBasicAlert",
style = "info",
content = "Basic Alert Text")
# Alert on Sidebar>Advanced tab
createAlert(session, "sidebarAdvancedAlert",
style = "danger",
content = "Advanced Alert Text")
# Alert in the Body Area
createAlert(session, "bodyAlert", style = "success",
content = "Body Alert Text", append = FALSE)
# Alert on Right Sidebar
createAlert(session, "sidebarRightAlert",
style = "error",
content = "Error Alert Text")
Different parts of the generated application can be customized with a custom yaml file called periscope_style.yaml located under www folder as follow:
custom_theme_file
parameter in
create_new_application
method.See the Creating a Sample Application and Creating your Application sections for an example
This is a high-functionality set of custom-styled buttons with the built-in ability to download data in different file formats.
See the downloadFile Vignette for more detailed information
This is a high-functionality custom styled table that includes a downloadFileButton linked to the data.
See the downloadableTable Vignette for more detailed information
This is a custom plot output that is paired with a linked downloadFile button which allows the user to download the plot in different file formats.
See the downloadablePlot Vignette for more detailed information
library(periscope)
app_dir = tempdir()
create_new_application(name = 'mytestapp', location = app_dir, sampleapp = TRUE)
# application without a left sidebar
create_new_application(name = 'mytestapp', location = app_dir, sampleapp = TRUE, leftsidebar = FALSE)
# application without a reset button
create_new_application(name = 'mytestapp', location = app_dir, sampleapp = TRUE, resetbutton = FALSE)
# application with a right sidebar using the default icon
create_new_application(name = 'mytestapp', location = app_dir, sampleapp = TRUE, rightsidebar = TRUE)
# application with a right sidebar using a custom icon
create_new_application(name = 'mytestapp', location = app_dir, sampleapp = TRUE, rightsidebar = "table")
# application with a custom style file
create_new_application(name = 'mytestapp', location = app_dir, sampleapp = TRUE, custom_theme_file = "periscope_style.yaml")
This generates a default sample application optionally with a left/right sidebar in a subdirectory named mytestapp at the specified location. The location must exist when calling this function.
Note: If the mytestapp directory in this location already exists it will not be overwritten - the function will give a warning and exit without modifying the user’s system.
The application should run in either the viewer or browser (depending on system preferences/settings). It will contain help text, test buttons, a sample log, etc. You can use this sample application to explore the functionality and code!
library(periscope)
app_dir = tempdir()
create_new_application(name = 'mytestapp', location = app_dir)
# application without a left sidebar
create_new_application(name = 'mytestapp', location = app_dir, leftsidebar = FALSE)
# application without a reset button
create_new_application(name = 'mytestapp', location = app_dir, resetbutton = FALSE)
# application with a right sidebar using the default icon
create_new_application(name = 'mytestapp', location = app_dir, rightsidebar = TRUE)
# application with a right sidebar using a custom icon
create_new_application(name = 'mytestapp', location = app_dir, rightsidebar = "table")
# application with a custom style file
create_new_application(name = 'mytestapp', location = app_dir, custom_theme_file = "periscope_style.yaml")
This generates a default blank application optionally with a left/right sidebar in a subdirectory named mytestapp at the specified location. The location must exist when calling this function.
Note: If the mytestapp directory in this location already exists it will not be overwritten - the function will give a warning and exit without modifying the user’s system.
It is recommended to run the empty application after creation to ensure a proper setup before beginning to customize the application.
All user customization is done in the files in the program subdirectory. We’ll walk through a few examples of how to add components and functionality as in a typical shiny application but using this framework.
Set your application title, application version, titleinfo, change the loglevel and optionally turn off the userlog using set_app_parameters().
The app_version parameter in this function has a default value of “1.0.0”. It is recommended to follow the best practice in R’s packaging versioning. This means that a version consists of 3 numbers, <major>.<minor>.<patch>.
The titleinfo parameter in this function can be:
Important: Any variables or functions placed into this file are globally scoped and will be available to ui and server functions across all user sessions.
# Plain text title
set_app_parameters(title = "My Application Title")
# Application Title links to an external url
set_app_parameters(title = "My Application Title",
titleinfo = "http://www.somelocation.com")
# Application Title links to a modal window with HTML content
set_app_parameters(title = "My Application Title",
titleinfo = HTML("<h3>This is information about this application</h3>",
"<p><b>Author: </b>Me</p>",
"<p><b>Date: </b>", Sys.Date(), "</p>"))
Create UI components for the body and register them with the framework using a call to add_ui_body(). Use box elements for consistent presentation of your UI sections. Remember that there are 12 “blocks” across in the body.
body1 <- box( id = "bodyElement1",
title = "Box 1",
width = 8, #2/3 of the width
status = "primary", #colored bar at the top
collapsible = TRUE,
collapsed = FALSE,
htmlOutput("example1") )
body2 <- box( id = "bodyElement2",
title = "Box 2",
width = 4, #1/3 of the width
status = "danger", #colored bar at the top
collapsible = FALSE,
p("Some great text in paragraph format"),
pre("A pre-formatted (e.g. code) block"),
actionButton("exButton", label = "Example") )
add_ui_body(list(body1, body2))
In the above example UI elements are being added in 2 different ways. body1 uses an htmlOutput element to set a placeholder for the id “example1” which will be setup in the server file. This is commonly used when there is need for a dynamic UI element that cannot be setup ahead of the session (for example it is dependent on data at runtime). body2 defines the UI elements in place here.
This illustrates the two most common paradigms for creating shiny UI elements. For more information see the Shiny documentation.
Create your application functionality in this file. This corresponds to the inside of the shinyServer(…) call in a traditional Shiny application and is where the majority of your application code will reside. The variables and functions in this file are isolated to a single application session.
Variables Available
You can also call the get_url_parameters(session) function to retrieve anything passed at the end of the URL.
source("program/fxn/makeplot.R")
#build the deferred UI from ui_body.R
output$example1 <- renderUI({
list(downloadFileButton("ex_d1", c("csv"), "Download CSV"),
hr(),
p("Some great explanatory text in my application"))
})
downloadFile("ex_d1", ss_userAction.Log, "mydownload", list(csv=get_ref_data))
observeEvent(input$exButton, {
loginfo("exButton Pressed!", logger = ss_userAction.Log)
createAlert(session, "bodyAlert",
style = "success",
content = "Example Button Pressed!")
})
Create variables and functions in this file that are the same for all sessions and users of your application. It corresponds to the area above the shinyServer(…) call in a traditional Shiny application and generally there will not be a lot of usage of this file because of its global scoping. However, one of the common uses is to load reference data sets that are the same for all users of the application.
Use this directory to store data for your application. Note that a .gitignore file has been added so that data is not accidentally versioned. If you want to version files in this directory you will need to modify this file accordingly.
Use this directory to store your .R files containing helper functions. Don’t forget to source these files in the appropriate place according to your scoping needs. (i.e. you would source a file in server_local.R to scope by user session, server_global.R to scope across all sessions, and global.R to scope across all sessions and UI)
Updated this file values and restart app to customize application different parts styles.
Application Gallery
There is a gallery of example applications using the periscope framework at http://periscopeapps.org
Vignettes