I have a dashboard where I would like to show a table, but I cant figure out why my table is not showing. If I replace the table for example with some text, h2(....) it does show. I would like to click on "Species" and have the table show on the right when clicking it.
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
dashboardSidebar(sidebarMenu(
menuItem(
"Species",
tabName = "Species",
icon = NULL,
switchInput(
inputId = "long1",
onLabel = "Go",
offLabel = "NoGo",
value = T
),
actionButton("Gobtn", "Get data"),
menuItem("Specs", tabName = "Specs", icon = NULL)
)
)),
dashboardBody(tabItems(
tabItem(tabName = "Species",
DT::renderDataTable("Table1")),
tabItem(tabName = "Specs",
h2("Hi"))
))
)
server.r
server <- shinyServer(function(input, output, session) {
output$Table1 <- DT::renderDataTable({
iris
})
})
shinyApp(ui, server)
Few things to get your code up and running here. Couple have been noted by other contributors.
We need to use DT::dataTableOutput("Table1") on the UI side as renderDataTable will not work here, that is the server side function.
The other would be that using the switchInput within the menuItem may confused the app, as these are not standard parameters to pass into the function. From what I can see from your code, which is a common challenge, is that you want to be able to show this switchInput only when the 'Species' tab is selected. We can account for this using conditionalPanel. To do this, we can set id = "tabs" within the sidebarMenu and then reference this sidebarMenu within the conditionalPanel:
conditionalPanel(
condition = "input.tabs== 'Species' ",
switchInput(
inputId = "long1",
onLabel = "Go",
offLabel = "NoGo",
value = T
)
)
To finish, I have altered the layouts of the ui.R and server.R, as the shinyApp function was not needed for the app to work with the server and ui files. This is how I lay out my dashboards. It may show you a few other possible ways you can use the app structure within Shiny, but equally you could just align the changes to the basic layout.
ui.R
header <- dashboardHeader(title = "Basic dashboard")
sidebar <- dashboardSidebar(
sidebarMenu(id = "tabs",
menuItem(
"Species",
tabName = "Species",
icon = NULL),
conditionalPanel(
condition = "input.tabs== 'Species' ",
switchInput(
inputId = "long1",
onLabel = "Go",
offLabel = "NoGo",
value = T
)
),
actionButton("Gobtn", "Get data"),
menuItem("Specs", tabName = "Spec", icon = NULL)
)
)
body <- dashboardBody(
tabItems(
tabItem(tabName = "Species",
DT::dataTableOutput("Table1")),
tabItem(tabName = "Spec",
h2("Hi"))
)
)
dashboardPage(skin = "blue", header = header, sidebar = sidebar, body = body)
server.R
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(DT)
shinyServer(function(input, output, session){
output$Table1 <- DT::renderDataTable({
datatable(iris)
})
})
You need to change/add some part of the dashboardBody, see Using shiny modules and shinydashboard: shiny.tag error
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
dashboardSidebar(sidebarMenu(
menuItem(
"Species",
tabName = "Species",
icon = NULL,
switchInput(
inputId = "long1",
onLabel = "Go",
offLabel = "NoGo",
value = T
),
actionButton("Gobtn", "Get data")
)
)),
dashboardBody(tags$div(
tabName = "Species",
fluidRow(box(DT::dataTableOutput("Table1"))), class = "tab-content"
))
)
server.r
server <- shinyServer(function(input, output, session) {
output$Table1 <- DT::renderDataTable({
iris
})
})
shinyApp(ui, server)
Related
I am creating a dashboard which has multiple subItems that have the exact same structure. Is there an easy way to create them rather than hard-coded them one by one? For example,
library(shiny)
library(shinydashboard)
library(DT)
library(dplyr)
library(tibble)
attach(mtcars)
cars <- rownames_to_column(mtcars)[1:8,c("brand","mpg","cyl")]
ui <- dashboardPage(
dashboardHeader(title = "test"),
dashboardSidebar(sidebarMenu(
menuItem("Cars",
tabName = "cars",
shinydashboard::menuSubItem(
text = "Cars1",
tabName = "cars1"
),
shinydashboard::menuSubItem(
text = "Cars2",
tabName = "cars2"
))
)
)
,
dashboardBody(tabItems(
tabItem(
tabName = "cars1",
shiny::selectizeInput(inputId = "brand_filter",
label = "Brand",
choices = cars$brand),
shiny::selectizeInput(inputId = "cyl_filter",
label = "cyl",
choices = c(4,6,8))),
tabItem(tabName = "cars2",
shiny::selectizeInput(inputId = "brand_filter",
label = "Brand",
choices = mtcars$brand),
shiny::selectizeInput(inputId = "cyl_filter",
label = "cyl",
choices = c(4,6,8)))
)
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
tab cars1 and cars2 are exactly the same. Is there a way to create cars2 without code everything again? Thanks!
I am trying to clear what ever is written in the text area but looks like it not working. Based on the below applications, when the user clicks on "click" button, the contents (if written) should get cleared. But it is not. Can anyone help me here please........................................
data(mtcars)
library(shiny)
library(shinydashboard)
library(dplyr)
library(DT)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(title = "Dynamic sidebar"),
dashboardSidebar(sidebarMenu(id = "menu", sidebarMenuOutput("menu"))),
dashboardBody(tabItems
(
tabItem
(tabName = "plots", h2("Dashboard plots"),
fluidRow(column(width = 12, class = "well",
h4("Boxplot"),
plotOutput("bxp")))
),
tabItem(tabName = "dashboard", h2("Dashboard tab content"),
dataTableOutput(outputId = "subdt"),textAreaInput("sd","label1"),textAreaInput("sd1","label2") ,
actionButton("idff","click"))
)
)
)
server <- function(input, output, session) {
output$menu <- renderMenu({
sidebarMenu(
# menuItem("Plots Menu", tabName = "plots", icon = icon("line-chart")),
menuItem("Table Menu", icon = icon("info"),
menuSubItem(
"Dashboard", tabName = "dashboard", icon = icon("calendar")
),
selectInput(
inputId = "mcm", label = "Some label", multiple = TRUE,
choices = unique(mtcars$cyl), selected = unique(mtcars$cyl)
)
)
)
})
observe({
print(input$menu)
})
datsub <- reactive({
mtcars %>%
filter_at(vars("cyl"), all_vars(. %in% input$mcm))
})
output$subdt <- renderDataTable({
datatable(datsub(),selection = if(input$menu == "dashboard"){'single'} else {'none'})
# print(datatable.selection())
})
# datatable(datsub(),selection = if(input$menu == "dashboard"){'single'} else {'none'})
output$bxp <- renderPlot({
hist(rnorm(100))
})
observeEvent(input$idff,{
print("cjec")
shinyjs::reset('sd')
shinyjs::reset('sd1')
})
}
shinyApp(ui, server)
I'd suggest to update the textAreaInput as suggested in the comments. Update the event handler as follows:
observeEvent(input$idff, {
updateTextAreaInput(session = session, inputId = 'sd', value = "")
updateTextAreaInput(session = session, inputId = 'sd1', value = "")
})
There is a wrong display in shiny dashboard for the below code. The title "Yet to do" is getting displayed as soon as i run the app. I need that when I click on Bivariate Analysis. What is the issue here. This happened when I introduced selectinput under menu item. Earlier it was working well
library(shinydashboard)
library(shiny)
ui <- dashboardPage(
dashboardHeader(title = "Data Analysis"),
dashboardSidebar(
sidebarMenu(
menuItem("Univariate Analysis", tabName = "Univariate", icon =
icon("question"),selectInput("Factors",h5("Factors"),choices =
c("","A","B"))),
menuItem("Bivariate Analysis", tabName = "Bivariate", icon =
icon("question")))
),
dashboardBody(
tabItems(
tabItem(tabName = "Univariate",fluidRow(box(plotOutput("Plot1"),width =
1000,height = 1000),
box(plotOutput("Plot2"),width =
1000,height = 1000))),
tabItem(tabName = "Bivariate",h1("Yet to do")))
))
server <- function(input, output) {
}
shinyApp(ui, server)
It is related having selectInput() as menuItem(). I tried some options like creating menuSubItem etc. but couldn't get it to work. This is probably some bug so you may have to look around for a fix. For now, I'd suggest moving the selectInput inside dashboardBody() -
ui <- dashboardPage(
dashboardHeader(title = "Data Analysis"),
dashboardSidebar(
sidebarMenu(
menuItem("Univariate Analysis",
tabName = "Univariate", icon = icon("question")
# removing selectInput from here fixes the issue
# ,selectInput("Factors", h5("Factors"), choices = c("","A","B"))
),
# an option is to have selectInput by itself but probably not the layout you want
# selectInput("Factors", h5("Factors"), choices = c("","A","B")),
menuItem("Bivariate Analysis",
tabName = "Bivariate", icon = icon("question")
)
)
),
dashboardBody(
tabItems(
tabItem(tabName = "Univariate",
fluidRow(
# add selectInput somewhere on Univariate page
selectInput("Factors", h5("Factors"), choices = c("","A","B")),
box(plotOutput("Plot1"), width = "50%", height = "50%"),
box(plotOutput("Plot2"), width = "50%", height = "50%")
)
),
tabItem(tabName = "Bivariate",
h1("Yet to do")
)
)
)
)
server <- function(input, output) {}
shinyApp(ui, server)
I am creating a shiny Dashboard which has two tabs in the side bar. Tab1 is for importing a csv and Tab2 is for showing the plots for the selected variable.
Tab2 has 1 select input option for selecting the variable for plot
Problem: After clicking on sidebar tabs, my dashboard body doesn't change. It is always showing me Tab1 Content i.e csv import results.
So despite of clicking on Tab2 in sidebar, nothing happens
Following is my script
library(shinydashboard)
library(shiny)
library(DT)
#UI
sidebar=dashboardSidebar(width=200,
sidebarMenu( id="sidebar",
menuItem("Data UpLoad", tabName = "dashboard", icon = icon("table"),
fileInput('file1','Choose CSV File',
accept=c('text/csv','text/comma-separated-values,text/plain', '.csv'))),
menuItem("Uni Variate", tabName = "Uni", icon = icon("line-chart"),
fluidRow(
selectInput("options",label=h5("Select Column"),"")))))
body= dashboardBody(
tabItems(
tabItem(tabName="dashboard",class='active',
fluidRow(
box(
title="Data",solidHeader = TRUE, collapsible = TRUE,
div(style='overflow-x: scroll',tableOutput("table1"))))),
tabItem(tabName = "Uni",
fluidRow(box(title="Plot",solidHeader = TRUE,plotOutput("plot1"))),
h2("tab content"))))
dashboardPage(
dashboardHeader(title= "test"),sidebar,body)
#Server
server <- function(input, output,session) {
data_set <- reactive({
req(input$file1)
inFile <- input$file1
data_set1<-read.csv(inFile$datapath)
list(data=data_set1)
})
# updating select input of second tab in shiny side bar
observe({
updateSelectInput(
session,
"options",
choices = names(data_set()$data))})
# tab1
output$table1= renderTable({
de=as.data.frame(data_set()$data[1:7,])})
#tab2
output$plot1 <- renderPlot({ggplot(data_set$data,aes(y=input$options,x=Prediction))+geom_histogram(binwidth=0.50, fill="blue") })
}
Every help is important!
It seems that the problem is related to putting widgets on the sidebar, it takes them as sub-menus. Below are a couple of possible solution to have widgets on the sidebar depending if you want to hide them when are inactive.
Option 1- widgets always visible
library(shinydashboard)
library(shiny)
sidebar <- dashboardSidebar(width=200,
sidebarMenu( id="sidebar",
menuItem("Data UpLoad", icon = icon("table"), tabName = "dashboard"),
div(
fileInput('file1','Choose CSV File',
accept=c('text/csv','text/comma-separated-values,text/plain', '.csv'))
),
menuItem("Uni Variate", icon = icon("line-chart"), tabName = "Uni"),
div(
selectInput("options",label=h5("Select Column"),"")
)
)
)
body <- dashboardBody(
tabItems(
tabItem(tabName="dashboard", class='active',
box( title="Data",solidHeader = TRUE, collapsible = TRUE,
div(style='overflow-x: scroll', p("table1"))
)
),
tabItem(tabName = "Uni",
box(title="Plot", solidHeader = TRUE, p("plot1"))
)
)
)
server <- function(input, output,session) {}
shinyApp(dashboardPage(dashboardHeader(title= "test"), sidebar, body), server = server)
Option 2- widgets only visible when tab is active
Please note that to show the correct tab on the body, the users must click on the sub-item.
library(shinydashboard)
library(shiny)
sidebar <- dashboardSidebar(width=200,
sidebarMenu( id="sidebar",
menuItem("data", icon = icon("table"), tabName = "dashboard",
menuSubItem(tabName = "dashboard",
fileInput('file1','Choose CSV File',
accept=c('text/csv','text/comma-separated-values,text/plain', '.csv'))
)),
menuItem("Uni Variate", icon = icon("line-chart"), tabName = "Uni",
menuSubItem( tabName = "Uni",
selectInput("options",label=h5("Select Column"),"")
))
)
)
body <- dashboardBody(
tabItems(
tabItem(tabName="dashboard", class='active',
box( title="Data",solidHeader = TRUE, collapsible = TRUE,
div(style='overflow-x: scroll', p("table1"))
)
),
tabItem(tabName = "Uni",
box(title="Plot", solidHeader = TRUE, p("plot1"))
)
)
)
server <- function(input, output,session) {}
shinyApp(dashboardPage(dashboardHeader(title= "test"), sidebar, body), server = server)
library(shiny)
library(shinydashboard)
ui <- dashboardPage( skin="blue",title = "asdfasf",
dashboardHeader(title = "Fund Analysis Status Tool",titleWidth=255, .list=NULL),
dashboardSidebar( width = 255, sidebarMenu(menuItem("Analysis", icon = icon("th"),menuSubItem("ME-1", tabName = "Analysis-ME-1"),
menuSubItem("Current", tabName = "Analysis-Current")),menuItem("Post-Analysis1",icon = icon("th"),menuSubItem("ME-1", tabName = "Post_Analysis-ME-1"),menuSubItem("Current", tabName = "Post_Analysis-Current")))), # it gives heading in the left panel
dashboardBody(
tabItems(tabItem(tabName = "Analysis-ME-1",fluidRow(box(dataTableOutput('table')),box(title = "Controls",
sliderInput("slider", "Number of observations:", 1, 100, 50)))),
tabItem(tabName = "Analysis-Current",h2("To be discussed1")),
# Second tab content
tabItem(tabName = "Post_Analysis-ME-1", h2("To be discussed1")),
tabItem(tabName = "Post_Analysis-Current",h2("To be discussed2")))))
server <- function(input, output) {
histdata <- rnorm(500)
output$table <- renderDataTable(iris)
output$plot1 <- renderPlot({
data <- histdata[seq_len(input$slider)]
hist(data)
})
}
shinyApp(ui, server)
This is largely a matter of opinion on how you go about this. I've reorganized your code to how I might approach it below.
In the few applications I've built, my choice of strategy has varied by how large the application is. In smaller applications, I'll source in functions or define them in global.R and then use those functions throughout the application. More recently, I've started just writing each application as a stand alone package.
Either way, the general process is to break your application into small steps, write each of those steps into a function with a descriptive name (brevity isn't necessarily a virtue here), and then call the functions to generate your application.
library(shiny)
library(shinydashboard)
#* Put these in your global.R file, perhaps.
dashboard_header <- function(){
dashboardHeader(
title = "Fund Analysis Status Tool",
titleWidth=255,
.list=NULL
)
}
dashboard_sidebar <- function(){
dashboardSidebar(
width = 255,
sidebarMenu(
menuItem("Analysis", icon = icon("th"),
menuSubItem(
"ME-1",
tabName = "Analysis-ME-1"
),
menuSubItem(
"Current",
tabName = "Analysis-Current"
)
),
menuItem(
"Post-Analysis1",
icon = icon("th"),
menuSubItem(
"ME-1",
tabName = "Post_Analysis-ME-1"
),
menuSubItem(
"Current",
tabName = "Post_Analysis-Current"
)
)
)
)
}
tab_items <- function(){
tabItems(
# First tab content
tabItem(
tabName = "Analysis-ME-1",
fluidRow(
box( dataTableOutput('table') )
),
box(
title = "Controls",
sliderInput(
"slider",
"Number of observations:",
1,
100,
50
)
)
),
tabItem(
tabName = "Analysis-Current",
h2("To be discussed1")
),
# Second tab content
tabItem(
tabName = "Post_Analysis-ME-1",
h2("To be discussed1")
),
tabItem(
tabName = "Post_Analysis-Current",
h2("To be discussed2")
)
)
}
#***************************
#***************************
#* And now the ui and server
ui <-
dashboardPage(
skin="blue",
title = "asdfasf",
dashboard_header(),
dashboard_sidebar(),# it gives heading in the left panel
dashboardBody(
tab_items()
)
)
server <- shinyServer(function(input, output) {
histdata <- rnorm(500)
output$table <- renderDataTable(iris)
output$plot1 <- renderPlot({ data <- histdata[seq_len(input$slider)]
hist(data) })
})
shinyApp(ui, server)