rshinyshinydashboardrpivottable

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)

Solution

  • 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)