knitr::opts_chunk$set( echo = TRUE, collapse = TRUE, comment = "#>" ) library(shiny) library(shiny.semantic) library(shiny.layouts)
Two main things shiny.layouts
provides is pre-defined app layouts (like app with a sidebar and a main panel) and easy interface to put elements in a custom grid (based on CSS grid).
In this article we will see how to use these two features.
To make examples look better and shorten their code, we will use shiny.semantic, but shiny.layouts works with any UI framework.
Let's start by defining a page wtih a sidebar layout (sidebar_layout()
) with a sidebar panel (sidebar_panel()
) and main panel (main_panel()
). The sidebar is displayed with a distinct background color and typically contains input controls. The main area occupies 2/3 of the horizontal width and typically contains outputs.
ui <- semanticPage( title = "My first page", h1("My page"), sidebar_layout( sidebar_panel(), main_panel() ) ) server <- function(input, output, session) {} shinyApp(ui, server)
Next let's fill in the main panel main_panel()
with a Semantic UI segment containing 2 cards.
ui <- semanticPage( title = "My first page", h1("My page"), sidebar_layout( sidebar_panel(), main_panel( segment( cards( class = "two", card(class = "red", div(class = "content", div(class = "header", "Main title card 1"), div(class = "meta", "Sub title card 1"), div(class = "description", "More detail description card 1") ) ), card(class = "blue", div(class = "content", div(class = "header", "Main title card 2"), div(class = "meta", "Sub title card 2"), div(class = "description", "More detail description card 2") ) ) ) ) ) ) ) server <- function(input, output, session) {} shinyApp(ui, server)
Time to fill in sidebar sidebar_panel()
, so let's add a dropdown. We create it input using dropdown_input()
.
ui <- semanticPage( title = "My first page", h1("My page"), sidebar_layout( sidebar_panel( dropdown_input("mtcars_dropdown", c("mpg", "cyl", "disp", "hp"), value = "mpg"), textOutput("dropdown") ), main_panel( segment( cards( class = "two", card(class = "red", div(class = "content", div(class = "header", "Main title card 1"), div(class = "meta", "Sub title card 1"), div(class = "description", "More detail description card 1") ) ), card(class = "blue", div(class = "content", div(class = "header", "Main title card 2"), div(class = "meta", "Sub title card 2"), div(class = "description", "More detail description card 2") ) ) ) ) ) ) ) server <- function(input, output, session) { output$dropdown <- renderText(input$mtcars_dropdown) } shinyApp(ui, server)
Let's make dropdown do something and generate a histogram and a simple plot from a selected mtcars
column using dropdown.
ui <- semanticPage( title = "My first page", h1("My page"), sidebar_layout( sidebar_panel( p("Select variable for plots:"), dropdown_input("mtcars_dropdown", c("mpg", "cyl", "disp", "hp"), value = "mpg") ), main_panel( segment( cards( class = "two", card(class = "red", div(class = "content", div(class = "header", "Main title card 1"), div(class = "meta", "Sub title card 1"), div(class = "description", "More detail description card 1") ) ), card(class = "blue", div(class = "content", div(class = "header", "Main title card 2"), div(class = "meta", "Sub title card 2"), div(class = "description", "More detail description card 2") ) ) ) ), plotOutput("histogram"), plotOutput("plot") ) ) ) server <- function(input, output, session) { output$dropdown <- renderText(input$mtcars_dropdown) output$histogram <- renderPlot(hist(mtcars[[input$mtcars_dropdown]])) output$plot <- renderPlot(plot(mtcars[[input$mtcars_dropdown]])) } shinyApp(ui, server)
There is more layouts that you can use. Just check the documentation of: split_layout
,
flow_layout
, vertical_layout
and more.
Finally let's change the layout of the plots on the page and make them appear next to each other. We will use grid()
for it and define a grid template using grid_template()
with 1 row and 2 columns of the same size. Our grid template will contain 2 areas chart1
and chart2
grid_charts <- grid_template( default = list(areas = rbind(c("chart1", "chart2")), rows_height = c("100%"), cols_width = c("50%", "50%")) )
We assign plots' outputs plotOutput()
to both areas inside the grid
function.
This is the final effect of our work:
ui <- semanticPage( title = "My first page", h1("My page"), sidebar_layout( sidebar_panel( p("Select variable for plots:"), dropdown_input("mtcars_dropdown", c("mpg", "cyl", "disp", "hp"), value = "mpg") ), main_panel( segment( cards( class = "two", card(class = "red", div(class = "content", div(class = "header", "Main title card 1"), div(class = "meta", "Sub title card 1"), div(class = "description", "More detail description card 1") ) ), card(class = "blue", div(class = "content", div(class = "header", "Main title card 2"), div(class = "meta", "Sub title card 2"), div(class = "description", "More detail description card 2") ) ) ) ), grid(grid_charts, chart1 = plotOutput("histogram"), chart2 = plotOutput("plot") ) ) ) ) server <- function(input, output, session) { output$dropdown <- renderText(input$mtcars_dropdown) output$histogram <- renderPlot(hist(mtcars[[input$mtcars_dropdown]])) output$plot <- renderPlot(plot(mtcars[[input$mtcars_dropdown]])) } shinyApp(ui, server)
You can define grids for different screen sizes. Here is an example on how to define it for mobile.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.