Periodically switch tab in shinydashboard - r

In a shinydashboard with several tabs like here
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Sample Shiny"),
dashboardSidebar(
sidebarMenu(
menuItem("Tab 1", tabName = "tab1"),
menuItem("Tab 2", tabName = "tab2")
)
),
dashboardBody(
tabItems(
tabItem(
"tab1",
fluidRow(
box(title = "Foo")
)
),
tabItem(
"tab2",
fluidRow(
box(title = "Bar")
)
)
)
)
)
server <- function(input, output) { }
shinyApp(ui = ui, server = server)
is it possible to let the application switch the active tab periodically? I want to have the dashboard on my screen with switching the active tab every x minutes.
I already checked the Shiny docs for a solution but haven't found an appropriate function. But maybe I simply overlooked such a feature. If Shiny does not offer a suitable feature, is it possible to include some custom JavaScript that does the job?

Here's a way to do it, using invalidateLater and updateTabItems:
app.R:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Sample Shiny"),
dashboardSidebar(
sidebarMenu(
id = 'tabs',
menuItem("Tab 1", tabName = "tab1"),
menuItem("Tab 2", tabName = "tab2")
)
),
dashboardBody(
tabItems(
tabItem(
"tab1",
fluidRow(
box(title = "Foo")
)
),
tabItem(
"tab2",
fluidRow(
box(title = "Bar")
)
)
)
)
)
tabnames = c('tab1', 'tab2')
server <- function(input, output, session) {
#keep track of active tab
active <- reactiveValues(tab = 1)
observe({
#Change every 5 secs, you can set this to whatever you want
invalidateLater(5000,session)
#update tab
isolate(active$tab <- active$tab%%length(tabnames) + 1)
updateTabItems(session,'tabs',tabnames[active$tab])
})
}
shinyApp(ui = ui, server = server)

Related

R Shiny dashboard loading tabs only once

I started building my first shiny app but am now struggling with a strange behaviour. First, when I initially load the app, no tab is selected by default. Second, when clicking on any menu on the sidebar it shows the body only on the first time. When I go from "Overview" to "Pivot-Tabelle" and back, the body is blank. What am I missing? Below is the code I used.
library(shiny)
library(shinydashboard)
df<-data.frame(a=c(1,2,3,4),
b=c("A","B","C","D"))
###################Beginn der App################
ui <- dashboardPage(
# Application title
dashboardHeader(),
##----DashboardSidebar----
dashboardSidebar(
menuItem("Overview", tabName = "overview",selected=TRUE),
menuItem("Pivot-Tabelle", tabName = "pivot"),
menuItem("Test", tabName = "farmer")
),
##----DashboardBody----
dashboardBody(
tabItems(
##----TabItem: Overview----
tabItem(tabName="overview",
fluidRow(
valueBoxOutput("A"),
valueBoxOutput("B")
)
),
###----TabItem:Pivot----
tabItem(tabName = "pivot",
##Pivot
column(6,offset=4,titlePanel("Daten-Explorer")),
column(12,
mainPanel(
rpivotTableOutput("pivot")
)
)
),
##----TabItem:Test----
tabItem(tabName = "Test",
h2("In Progress"))
)
)
)
server <- function(input, output) {
##----server:overview----
output$A<-renderValueBox({
valueBox(
paste0(25, "%"), "Landwirte in der Datenbank", icon = icon("Person"),
color = "purple"
)
})
output$B<-renderValueBox({
valueBox(
paste0(55, "%"), "Landwirte in der Datenbank", icon = icon("Person"),
color = "purple"
)
})
##----server:pivot----
output$pivot <- renderRpivotTable({
rpivotTable(data = df)
})
}
# Run the application
shinyApp(ui = ui, server = server)
This seems to work. You need to have sidebarMenu for your menuItems. Also, you need to change tabName to farmer so it matches your menuItem. And I don't think you need mainPanel in there (you can use mainPanel with sidebarPanel as part of a sidebarLayout if you wanted that layout - see layout options). See if this works for you.
library(shiny)
library(shinydashboard)
library(rpivotTable)
df<-data.frame(a=c(1,2,3,4),
b=c("A","B","C","D"))
###################Beginn der App################
ui <- dashboardPage(
# Application title
dashboardHeader(),
##----DashboardSidebar----
dashboardSidebar(
sidebarMenu(
menuItem("Overview", tabName = "overview",selected=TRUE),
menuItem("Pivot-Tabelle", tabName = "pivot"),
menuItem("Test", tabName = "farmer")
)
),
##----DashboardBody----
dashboardBody(
tabItems(
##----TabItem: Overview----
tabItem(tabName="overview",
fluidRow(
valueBoxOutput("A"),
valueBoxOutput("B")
)
),
###----TabItem:Pivot----
tabItem(tabName = "pivot",
##Pivot
column(6,offset=4,titlePanel("Daten-Explorer")),
column(12,
#mainPanel(
rpivotTableOutput("pivot")
#)
)
),
##----TabItem:Test----
tabItem(tabName = "farmer",
h2("In Progress"))
)
)
)
server <- function(input, output) {
##----server:overview----
output$A<-renderValueBox({
valueBox(
paste0(25, "%"), "Landwirte in der Datenbank", icon = icon("Person"),
color = "purple"
)
})
output$B<-renderValueBox({
valueBox(
paste0(55, "%"), "Landwirte in der Datenbank", icon = icon("Person"),
color = "purple"
)
})
##----server:pivot----
output$pivot <- renderRpivotTable({
rpivotTable(data = df)
})
}
# Run the application
shinyApp(ui = ui, server = server)

Shiny: Re-using the same plot in multiple tabs is not working

I am trying to create a shiny dashboard that has two tabs.
First tab (called: dashboard) shows two graphs, and the other one (called: widgets) is intended to show the first graph from the first tab (called: mpg) and below it is the rpivottable.
Problem is that the moment I add graphs/rpivottable to the second tab, all the graphs disappear.
I figured that the moment I take away the content of the second tab, the dashboard starts displaying the first tab content. Any idea why it is happening and how to fix it ?
Sample code:
library(shiny)
library(shinydashboard)
library(rhandsontable)
library(writexl)
library(readxl)
library(stringr)
library(ggplot2)
library(rpivotTable)
ui <- dashboardPage(skin = 'green',
dashboardHeader( title = "Test", titleWidth = 280),
dashboardSidebar(width = 280,
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
menuItem("Pivot", tabName = "widgets", icon = icon("th"))
)),
dashboardBody(
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
column(5, 'Mpg Table') ),
br(),
fluidRow(
rHandsontableOutput ('mpg')),
br(),
fluidRow(
column(5,'mtcars Summary')),
br(),
fluidRow(
column(3),column(6, tableOutput ('mtcars')),column(3))
),
# Second tab content
tabItem(tabName = "widgets",
fluidRow(
column(5,'Mpg table')),
br(),
fluidRow(
rHandsontableOutput ('mpg')),
br(),
fluidRow(
rpivotTableOutput('pivot')
)
)
)
)
)
server <- shinyServer(function(input, output) {
#mpg
output$mpg <- renderRHandsontable ({ rhandsontable({
mpg[1,] })
})
#mtcars
output$mtcars <-renderTable ({
head(mtcars)})
# pivot table
output$pivot <- renderRpivotTable({ rpivotTable(mtcars)})
})
shinyApp(ui, server)
You cannot re-use the same id to bind multiple outputs (Look here). So one option would be to give the mpg table a unique id in both tabs and render the table output twice in the server with: output$mpg1 <- output$mpg2 <- renderRHandsontable ({}).
Working example:
library(shiny)
library(shinydashboard)
library(rhandsontable)
library(writexl)
library(readxl)
library(stringr)
library(ggplot2)
library(rpivotTable)
ui <- dashboardPage(skin = 'green',
dashboardHeader(title = "Test", titleWidth = 280),
dashboardSidebar(width = 280,
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
menuItem("Pivot", tabName = "widgets", icon = icon("th"))
)),
dashboardBody(
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
column(5, 'Mpg Table') ),
br(),
fluidRow(
rHandsontableOutput ('mpg1')),
br(),
fluidRow(
column(5, 'mtcars Summary')),
br(),
fluidRow(
column(3),
column(6, tableOutput ('mtcars')),column(3))
),
# Second tab content
tabItem(tabName = "widgets",
fluidRow(
column(5,'Mpg table')),
br(),
fluidRow(
rHandsontableOutput ('mpg2')),
br(),
fluidRow(
rpivotTableOutput('pivot'))
)
)
)
)
server <- shinyServer(function(input, output) {
#mpg
output$mpg1 <-output$mpg2<- renderRHandsontable ({
rhandsontable({
mpg[1,]})
})
#mtcars
output$mtcars <-renderTable ({
head(mtcars)})
# pivot table
output$pivot <- renderRpivotTable({rpivotTable(mtcars)})
})
shinyApp(ui, server)
simple example:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(skin = 'green',
dashboardHeader( title = "Test", titleWidth = 280),
dashboardSidebar(width = 280,
sidebarMenu(
menuItem(text = "Dashboard", tabName = "dashboard", icon = icon("dashboard")),
menuItem(text = "Pivot", tabName = "widgets", icon = icon("th"))
)),
dashboardBody(
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
column(5, 'Mpg Table') ),
br(),
fluidRow(column(width = 12, plotOutput("plot1")
)
)),
# Second tab content
tabItem(tabName = "widgets",
fluidRow(
column(5,'Mpg table')),
br(),
fluidRow(column(width = 6, plotOutput("plot2")),
column(width = 6, plotOutput("plot3"))
),
br(),
fluidRow(column(width = 12, plotOutput("plot4"))
)
)
)
)
)
server <- shinyServer(function(input, output) {
output$plot1 <- renderPlot({
hist(rnorm(1000))
})
output$plot2 <- renderPlot({
plot(rnorm(1000), rnorm(1000))
})
output$plot3 <- renderPlot({
boxplot(rnorm(100))
})
output$plot4 <- renderPlot({
ts.plot(rnorm(100))
})
})
shinyApp(ui, server)

shinydashboard: menuSubItem not rendering at start in case of several menuSubItems

I found that menuSubItem content is not rendering in case of several (more than one) tabItems.
Minimal example demonstrating this behavior is below.
The desired behavior is to show content of the tabItem marked as selected = TRUE on startup. Now, the content shows up only after switching between menuSubItems in the sidebar.
How can I make it work?
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "MINIMAL EXAMPLE"),
dashboardSidebar(
sidebarMenuOutput("menu")
),
dashboardBody(
uiOutput("body")
)
)
server <- function(input, output, session) {
output$menu <- renderMenu(
sidebarMenu(
menuItem(text = "TABS", tabName = "TABS", startExpanded = T,
menuSubItem(text = "tab1", tabName="tab1",
icon = icon("cube"), selected = TRUE),
menuSubItem(text = "tab2", tabName="tab2",
icon = icon("cube"), selected = FALSE)
)
)
)
output$body <- renderUI({
tabItems(
tabItem(tabName = "tab1",
h4("MY TEXT 1")
),
tabItem(tabName = "tab2",
h4("MY TEXT 2")
))
})
}
shinyApp(ui = ui, server = server)
Indeed, putting ui elements directly in UI solves it.
But the approach of putting everything inside ui is limited to situations that do not involve using reactive values. As I understand passing reactive value from server to ui is not possible in general (or limited to special cases). Please correct if I am wrong... Thanks
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "MINIMAL EXAMPLE"),
dashboardSidebar(
sidebarMenuOutput("menu")
),
dashboardBody(
tabItems(
tabItem(tabName = "tab1",
h4("MY TEXT 1")
),
tabItem(tabName = "tab2",
h4("MY TEXT 2")
))
)
)
server <- function(input, output, session) {
output$menu <- renderMenu(
sidebarMenu(
menuItem(text = "TABS", tabName = "TABS", startExpanded = T,
menuSubItem(text = "tab1", tabName="tab1",
icon = icon("cube"), selected = TRUE),
menuSubItem(text = "tab2", tabName="tab2",
icon = icon("cube"), selected = FALSE)
)
)
)
}
shinyApp(ui = ui, server = server)
Renaming your output to something other than "body" helps - please see this.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "MINIMAL EXAMPLE"),
dashboardSidebar(
sidebarMenuOutput("menu")
),
dashboardBody(
uiOutput("myBodyOutput")
)
)
server <- function(input, output, session) {
output$myBodyOutput <- renderUI({
tabItems(
tabItem(tabName = "tab1",
h4("MY TEXT 1")
),
tabItem(tabName = "tab2",
h4("MY TEXT 2")
))
})
output$menu <- renderMenu(
sidebarMenu(id = "sidebarID",
menuItem(text = "TABS", tabName = "TABS", startExpanded = T,
menuSubItem(text = "tab1", tabName="tab1",
icon = icon("cube"), selected = TRUE),
menuSubItem(text = "tab2", tabName="tab2",
icon = icon("cube"), selected = FALSE)
)
)
)
}
shinyApp(ui = ui, server = server)

Using shiny plotOutput in multiple places in R

I am trying to use plotOutput in R shiny in multiple sub-menu items. However, I believe it is not possible for plotOutput to be used at multiple places with same id. Please help me if it is possible somehow. attaching the snapshot for reference.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("Charts", icon = icon("bar-chart-o"),
menuSubItem("Sub-item 1", tabName = "subitem1"),
menuSubItem("Sub-item 2", tabName = "subitem2")
))),
dashboardBody(
tabItems(tabItem("subitem1", 3),
tabItem("subitem2", plotOutput("brand_selector")))
))
server <- shinyServer(function(input, output) {
output$brand_selector <- renderPlot({
plot(iris$Sepal.Length)
})
})
shinyApp(ui = ui, server = server)
Update
library(shiny)
library(shinydashboard)
submenuUI <- function(id) {
ns <- NS(id)
# return a list of tags
tagList(
column(2,offset = 0, style='padding:1px;',
selectInput(ns("select1"),"select1",c("A1","A2","A3","A2","A1","A3","A1"))),
column(2,offset = 0, style='padding:1px;',
selectInput(ns("select2"),"select2",c("B3","B4","B5","B3","B6","B2","B3")))
)
}
submenu <- function(input,output,session){}
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("Charts", icon = icon("bar-chart-o"),
menuSubItem("Sub-item 1", tabName = "subitem1"),
menuSubItem("Sub-item 2", tabName = "subitem2"),
menuSubItem("Sub-item 3", tabName = "subitem3"),
menuSubItem("Sub-item 4", tabName = "subitem4")
))),
dashboardBody(
tabItems(tabItem("subitem1", submenuUI('submenu1')),
tabItem("subitem2", submenuUI('submenu2')),
tabItem("subitem3", submenuUI('submenu3')),
tabItem("subitem4", "Sub-item 2 tab content"))))
server <- function(input, output, session) {
observeEvent(input$Select1,{
updateSelectInput(session,'Select2',
choices= input$select2[input$Select1 == "A1"] )
})
callModule(submenu, "submenu")
}
shinyApp(ui, server)
Please help me to update the second selectInput based on input from the previous selectInput.
This is the modularized code for multiple plotting: Very similar to the selectInput one.
library(shiny)
library(shinydashboard)
plotopUI <- function(id) {
ns <- NS(id)
# return a list of tags
tagList(
plotOutput(ns('plt'))
)
}
plotop <- function(input,output,session){
ns <- session$ns
output$plt <- renderPlot({
plot(iris$Sepal.Length)
})
}
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("Charts", icon = icon("bar-chart-o"),
menuSubItem("Sub-item 1", tabName = "subitem1"),
menuSubItem("Sub-item 2", tabName = "subitem2")
))),
dashboardBody(
tabItems(tabItem("subitem1", plotopUI('plt1')),
tabItem("subitem2", plotopUI('plt2')))))
server <- function(input, output, session) {
callModule(plotop, "plt1")
callModule(plotop, "plt2")
}
shinyApp(ui, server)

Embed weather iframe into Shiny Dashboard

I am trying to embed the weather forecast from forecast.io in a Shiny dashboard. I originally had trouble with the ampersand but saw a post that provided an example of how to format HTML code with special characters. However, when I run the app I see a simple "Not Found", even though I know that the link works and is being formatted correctly. I'm not sure what I'm missing.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Dashboard"),
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard"))
)
),
dashboardBody(
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
column(12,
mainPanel(htmlOutput("frame")
)
)
)
)
)
)
)
server <- shinyServer(function(input, output) {
output$frame <- renderUI({
tags$iframe(id = 'app', src = url("https://forecast.io/embed/#lat=42.3583&lon=-71.0603&name=Downtown Boston"), width = '100%')
})
})
shinyApp(ui,server)
Screen capture of error in Shiny Dashboard
Update with inserted dashboard
I transfered url from server to ui:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Dashboard"),
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard",
tabName = "dashboard",
icon = icon("dashboard")
)
)
),
dashboardBody(
tabItems(
tabItem(
tabName = "dashboard",
fluidRow(
tags$iframe(
seamless = "seamless",
src = "https://forecast.io/embed/#lat=42.3583&lon=-71.0603&name=Downtown Boston",
height = 800, width = 1400
)
)
)
)
)
)
server <- function(input, output) {}
shinyApp(ui, server)

Resources