R Shiny navbarPage; values not loading from server - r

Help! For the life of me, I can't get values to populate from the server to the infoBox in the UI.
I've tried to define the infoboxes from the server section, but the infoboxes will only appear if I construct them in the UI (as shown below).
The goal is to populate the boxes with filtered data based on user inputs, but I've abandoned this at this stage because I can't even pass a value from the server to the UI infobox here:
infoBox("Participants Trained",
value = renderText("AYval"), # tried every combo here
width = 12,color = "blue", # tried width = NULL
icon = icon("fa-solid fa-people-group"), fill = F)
A value shows when I hardcode a value in "value = ", but none of the render options, renderText, verbatimText, output$AYval, valueTextbox, listen(),react() will get a value that is hard-coded in the server side to show up in this infobox.
To get the dashboard to display boxes, I'm using header = tagList(useShinydashboard()). My guess is this useShinydashboard() is the culprit.
I thought this comment might be relevant:
Your code using lapply and the navbarPage doesn't generate the UI in
the proper namespace, since when using the navbarPage construct your
modules are "one level deeper".
The script:
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
#library(shinyjs)
side_width <- 5
#completing the ui part with dashboardPage
ui <- navbarPage(fluid = TRUE,
theme = shinythemes::shinytheme("flatly"),
collapsible = TRUE,
header = tagList(
useShinydashboard()
),
tabPanel("START"),
tabPanel("Home Dashboard",
value = "Tab1",
# useShinyjs(),
fluidRow(
column(4,
# Selection Input ---------------------------------------------------------
selectInput(inputId = "AY","Academic Year",
multiple = T,
choices = unique(INDGEN$AcademicYear),
selected = unique(INDGEN$AcademicYear)
)),
column(4,
selectInput(inputId = "State","Select State",
choices = c("State","States"))),
column(4,
selectInput(inputId = "Program","Select Program",
choices = c("Program","Programs")))
),
fluidRow(column(12,
box(width = 4,
infoBox("Who?",
width = 12,color = "blue",
fill = F)
),
box(width = 4,
infoBox("Where?", width = 12,color = "blue",
fill = F)
),
box(width = 4,
infoBox("What?", width = 12,color = "blue",
fill = F))
)),
# UI Box R1 ---------------------------------------------------------------
fluidRow(column(12,
box(width = 4,
# uiOutput(infoBoxOutput("BOX1",width = NULL)),
infoBox("Participants Trained", value =
renderText("AYval"),
width = 12,color = "blue",
icon = icon("fa-solid fa-people-group"), fill = F)
),box(width = 4,
infoBox("Training Sites", nrow(data), width = 12,color = "blue",
icon = icon("fa-solid fa-school"), fill = F)
),box(width = 4,
infoBox("Training Programs Offered", nrow(data), width = 12,color = "blue",
icon = icon("fa-solid fa-book-open-reader"), fill = F))
)),
server <- function(input, output,session) {
output$AYval <- renderText({
textInput(13)
})
output$BOX1 <- renderInfoBox({
infoBox(title = "Participants Trained",
value = 13,
width = NULL,color = "blue",
icon = icon("fa-solid fa-people-group"), fill = T)
})
}#Server End
shinyApp(ui = ui,server = server,options = list(height = 1440))
Notice the "participant trained" box is empty. That's because that value isn't hard-coded. The rest are.

Here's a small reproducible example of how to change the value contents dynamically:
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
data(iris)
ui <- navbarPage(
fluid = TRUE,
theme = shinythemes::shinytheme("flatly"),
collapsible = TRUE,
header = tagList(
useShinydashboard()
),
tabPanel("START"),
tabPanel(
title = "Home Dashboard",
value = "Tab1",
selectInput("column",
label = "Select a column",
choices = c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")
),
box(
width = 4,
infoBoxOutput("test")
)
)
)
server <- function(input, output, session) {
iris_sum <- reactive({
sum(iris[input$column])
})
output$test <- shinydashboard::renderInfoBox({
infoBox(
title = "Where?",
value = iris_sum(),
width = 12,
color = "blue",
fill = F
)
})
}
shinyApp(ui, server)

Related

Dynamic left menu listing items downward instead of to the right

I am trying to create a dynamic left menu (header), but the items are listed downward instead of to the right. I guess it has to do with the tagList wrapper when defining the UI.
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
library(stringr)
ui = dashboardPage(
dashboardHeader(
leftUi = tagList(uiOutput("filter"))
),
dashboardSidebar(
pickerInput(
"inputParameters",
"Parameters:",
choices = c("a", "b", "c"),
multiple = TRUE,
options = list(
`actions-box` = TRUE,
size = 10,
`selected-text-format` = "count > 1"
)
)
),
dashboardBody(),
title = "DashboardPage"
)
server = function(input, output) {
params <- reactive(input$inputParameters)
output$filter = renderUI(
lapply(seq_along(params()), function(i) {
dropdownButton(
inputId = paste0("mydropdown", i),
label = params()[i],
icon = icon("sliders"),
status = "primary",
circle = FALSE,
selectizeInput(
paste0("input", paste0(str_to_title(params()[i]))),
paste0(paste0(str_to_title(params()[i]), ":")),
choices = 1:3,
multiple = TRUE,
selected = 1:3
)
)
})
)
}
shinyApp(ui, server)
Not tested, I would try:
output$filter = renderUI({
ddbuttons <- lapply(seq_along(params()), function(i) {
dropdownButton(
inputId = paste0("mydropdown", i),
label = params()[i],
icon = icon("sliders"),
status = "primary",
circle = FALSE,
selectizeInput(
paste0("input", paste0(str_to_title(params()[i]))),
paste0(paste0(str_to_title(params()[i]), ":")),
choices = 1:3,
multiple = TRUE,
selected = 1:3
)
)
})
do.call(splitLayout, ddbuttons)
})
And don't use tagList, just uiOutput("filter").

Issue with UI side of Shiny app with data table

I am in the process of creating a shiny app for a process at work and am struggling to figure something out on the UI side of the app. I would like to display a data table next to a sidebar menu containing options for the app. The issue is that when I do so, the data table is pushed down below the sidebar panel instead of beside it (see the original data tab).
I found a work around as seen in the suggested tab, but that comes with its own issues. I need to be able to lock the column headers while scrolling through the app and when the data table is inside the box element, I am unable to find a way to do so.
Here is the code to a simplified version of the app.
library(shiny)
library(lubridate)
library(tidyverse)
library(DT)
library(shinydashboard)
library(shinythemes)
library(sortable)
library(reactlog)
ui<- dashboardPage(
#this gives you the name displayed on the tab
dashboardHeader(title = "HHS Resin Purchasing 0.99"),
#this gives you your sidebar (page) options
dashboardSidebar(
sidebarMenu(
menuItem("Original Data", tabName = "original"),
menuItem("Suggested", tabName = "suggested")
)
),
#this is the body of the webpages
dashboardBody(
#this gives you the body options that are displayed on every page
sidebarPanel(width = 2,
h2("Menu Options"),
h4(strong("Upload Data:")),
fileInput("file", "Data", buttonLabel = "Upload..."),
textInput("delim", "Delimiter (leave blank to guess)", ""),
numericInput("skip", "Rows to skip", 0, min = 0),
h4(strong("User Options:")),
selectInput("plant", "Select a Plant", choices =
c("All")),
dateInput("latest_date", "Select the latest W_LEAD date in the data",
value = Sys.Date()),
numericInput("avg_multiple", "Multiple of Daily Useage for Cuttoff",21, min = 1, max = 50),
h4(strong("Download Options:")),
actionButton("complete_orders", "Analysis for plant orders complete"),
actionButton("complete_checks", "Mid month check complete"),
downloadButton("downloadData1", label = "Download Suggested Orders...", class = "btn-block"),
downloadButton("downloadData2", label = "Download Flags...", class = "btn-block"),
downloadButton("downloadData3", label = "Download Full Suggested Orders Data...", class = "btn-block")
),
#This is the actual data that fills those page options listed above
tabItems(
tabItem(tabName = "original",
DT::dataTableOutput(outputId = "preview1")
),
tabItem(tabName = "suggested",
box(title = "Suggested Orders",width = 9, status = "primary", height = "auto",
solidHeader = T, dataTableOutput("preview2"), style = "max-height:800px; overflow-y: scroll;overflow-x: scroll;")
)
)
)
)
server <- function(input, output) {
output$preview1 <- renderDataTable({
DT::datatable(iris, options = list(searching = T, pageLength = 20, lengthMenu = c(5,10,15, 20))
})
output$preview2 <- renderDataTable({
DT::datatable(iris, options = list(searching = T, pageLength = 20, lengthMenu = c(5,10,15, 20))
})
}
shinyApp(ui, server)
Help in fixing either of the issues outlined above would be very appreciated! Thanks in advance.
I think using the column() function will support your first question of the datatable moving under the sidebar sidebarPanel. Please see example below.
I think the second request of freezing the row header in the datatable can be resolved with the advice found at Freezing header and first column using data.table in Shiny
library(shiny)
library(lubridate)
library(tidyverse)
library(DT)
library(shinydashboard)
library(shinythemes)
library(sortable)
library(reactlog)
ui<- dashboardPage(
#this gives you the name displayed on the tab
dashboardHeader(title = "HHS Resin Purchasing 0.99"),
#this gives you your sidebar (page) options
dashboardSidebar(
sidebarMenu(
menuItem("Original Data", tabName = "original"),
menuItem("Suggested", tabName = "suggested")
)
),
#this is the body of the webpages
dashboardBody(
#this gives you the body options that are displayed on every page
fluidRow(
column(width = 2,
sidebarPanel(width = 2,
h2("Menu Options"),
h4(strong("Upload Data:")),
fileInput("file", "Data", buttonLabel = "Upload..."),
textInput("delim", "Delimiter (leave blank to guess)", ""),
numericInput("skip", "Rows to skip", 0, min = 0),
h4(strong("User Options:")),
selectInput("plant", "Select a Plant", choices =
c("All")),
dateInput("latest_date", "Select the latest W_LEAD date in the data",
value = Sys.Date()),
numericInput("avg_multiple", "Multiple of Daily Useage for Cuttoff",21, min = 1, max = 50),
h4(strong("Download Options:")),
actionButton("complete_orders", "Analysis for plant orders complete"),
actionButton("complete_checks", "Mid month check complete"),
downloadButton("downloadData1", label = "Download Suggested Orders...", class = "btn-block"),
downloadButton("downloadData2", label = "Download Flags...", class = "btn-block"),
downloadButton("downloadData3", label = "Download Full Suggested Orders Data...", class = "btn-block")
)
),
#This is the actual data that fills those page options listed above
column(width = 6,
tabItems(
tabItem(
tabName = "original",
DT::dataTableOutput("preview1",
options = list(dom = 't',
scrollX = TRUE,
paging=FALSE,
fixedHeader=TRUE,
fixedColumns = list(leftColumns = 1, rightColumns = 0)))
),
tabItem(tabName = "suggested",
box(title = "Suggested Orders",width = 9, status = "primary", height = "auto",
solidHeader = T, dataTableOutput("preview2"), style = "max-height:800px; overflow-y: scroll;overflow-x: scroll;")
)
)
)
)
)
)
server <- function(input, output) {
output$preview1 <- renderDataTable({
DT::datatable(iris, options = list(searching = T, pageLength = 20, lengthMenu = c(5,10,15, 20)))
})
output$preview2 <- renderDataTable({
DT::datatable(iris, options = list(searching = T, pageLength = 20, lengthMenu = c(5,10,15, 20)))
})
}
shinyApp(ui, server)

R shiny: slickROutput disappears when switching tabpanel()

I am making a Shiny app with tabPanels embedded in a navbarPage.
In each tabPanel, I generate a serie of image. When switching from one panel to the other one, the image loaded in one of them disappear.
I have to "refresh" manually the page to see it again. The problem seems similar than the one posted here but I cannot really subset my tabPanels, even though I gave $id and value to them.
Here is a reproducible example:
library(shiny)
library(shinythemes)
library(slickR)
## ui ----
# Image list
imgs <- list(
stackoverflow =
"https://upload.wikimedia.org/wikipedia/fr/9/95/Stack_Overflow_website_logo.png",
stackexchange =
"https://upload.wikimedia.org/wikipedia/commons/6/6f/Stack_Exchange_Logo.png"
)
ui <- navbarPage(title = div(
HTML('<span style="font-size:180%;color:white;font-weight:bold;"> Navbarpage</span></a>'),
tags$style(style = 'position:absolute; right:42px;'),
tags$style(HTML("#panel1{font-size: 25px}")),
tags$style(HTML("#panel2{font-size: 25px}")),
tags$style(HTML("#panel_about{font-size: 25px}"))
),
theme = shinytheme("flatly"),
windowTitle = "Navbarpage",
id = "navbar",
## First tabpanel ----
tabPanel(h1(id = "panel1", "Panel 1"), value = 1, fluid = TRUE,
fluidRow(column(4,
selectInput("img_list", "Image list",
choices = imgs,
selected = imgs[1])),
column(8,
slickROutput("plot_panel1"))),
),
tabPanel(h1(id = "panel2", "Panel 2"), value = 2, fluid = TRUE,
fluidRow(column(4,
selectInput("img_list", "Image list",
choices = imgs,
selected = imgs[1])),
column(8,
slickROutput("plot_panel2"))),
)
) # closes navbarpage
## server ----
server <- function(input, output, session){
observe({
output$plot_panel1 <- renderSlickR({
slick1 <- slick_list(slick_div(
input$img_list,
css = htmltools::css(width = "100%", margin.left = "auto",
margin.right = "auto"),
type = "img", links = NULL))
slickR(slick1)
})
})
observe({
output$plot_panel2 <- renderSlickR({
slick2 <- slick_list(slick_div(
input$img_list,
css = htmltools::css(width = "100%", margin.left = "auto",
margin.right = "auto"),
type = "img", links = NULL))
slickR(slick2)
})
})
}
shinyApp(ui, server)
And what it produces:
When there are multiple slickR objects to be rendered, you need to use a unique slideId for each. Furthermore you should not wrap render* functions in observe and use the same id for two selectInputs.
Please check the following:
library(shiny)
library(shinythemes)
library(slickR)
## ui ----
# Image list
imgs <- list(
stackoverflow =
"https://upload.wikimedia.org/wikipedia/fr/9/95/Stack_Overflow_website_logo.png",
stackexchange =
"https://upload.wikimedia.org/wikipedia/commons/6/6f/Stack_Exchange_Logo.png"
)
ui <- navbarPage(title = div(
HTML('<span style="font-size:180%;color:white;font-weight:bold;"> Navbarpage</span></a>'),
tags$style(style = 'position:absolute; right:42px;'),
tags$style(HTML("#panel1{font-size: 25px}")),
tags$style(HTML("#panel2{font-size: 25px}")),
tags$style(HTML("#panel_about{font-size: 25px}"))
),
theme = shinytheme("flatly"),
windowTitle = "Navbarpage",
id = "navbar",
## First tabpanel ----
tabPanel(h1(id = "panel1", "Panel 1"), value = 1, fluid = TRUE,
fluidRow(column(4,
selectInput("img_list1", "Image list",
choices = imgs,
selected = imgs[1])),
column(8,
slickROutput("plot_panel1"))),
),
tabPanel(h1(id = "panel2", "Panel 2"), value = 2, fluid = TRUE,
fluidRow(column(4,
selectInput("img_list2", "Image list",
choices = imgs,
selected = imgs[1])),
column(8,
slickROutput("plot_panel2"))),
)
) # closes navbarpage
## server ----
server <- function(input, output, session){
output$plot_panel1 <- renderSlickR({
slick1 <- slick_list(slick_div(
input$img_list1,
css = htmltools::css(width = "100%", margin.left = "auto",
margin.right = "auto"),
type = "img", links = NULL))
slickR(slick1, slideId = "slide1")
})
output$plot_panel2 <- renderSlickR({
slick2 <- slick_list(slick_div(
input$img_list2,
css = htmltools::css(width = "100%", margin.left = "auto",
margin.right = "auto"),
type = "img", links = NULL))
slickR(slick2, slideId = "slide2")
})
}
shinyApp(ui, server)

How to fix the layout of semantic.dashboard?

I am trying to build a dashboard using semantic.dashboard library. I see that all the components are aligned at the center. How can I change the layout?
I have taken the following code from examples in the semantic.dashboard repo. It works absolutely fine when I run it. I see that there is a space between the sidebar menu and boxes in the main body. I want the components to be aligned without any space from the side bar menu. Is there any way I could achieve this?
library(shiny)
library(shiny.semantic)
library(semantic.dashboard)
library(ggplot2)
library(plotly)
library(DT)
ui <- dashboardPage(
dashboardHeader(
dropdownMenuOutput("dropdown"),
dropdownMenu(type = "notifications",
taskItem("Project progress...", 50.777, color = "red")),
dropdownMenu(
icon = uiicon("red warning sign"),
notificationItem("This is an important notification!", color = "red")
)
),
dashboardSidebar(side = "left",
sidebarMenu(
menuItem(
tabName = "plot_tab",
text = "My plot",
icon = icon("home")
),
menuItem(
tabName = "table_tab",
text = "My table",
icon = icon("smile")
)
)),
dashboardBody(tabItems(
tabItem(tabName = "plot_tab",
fluidRow(
valueBox(
"Unread Mail",
44,
icon("mail"),
color = "blue",
width = 5
)
),
fluidRow(
box(
title = "Sample box",
color = "blue",
width = 11,
selectInput(
inputId = "variable1",
choices = names(mtcars),
label = "Select first variable",
selected = "mpg"
),
selectInput(
inputId = "variable2",
choices = names(mtcars),
label = "Select second variable",
selected = "cyl"
),
plotlyOutput("mtcars_plot")
),
tabBox(
title = "Sample box",
color = "blue",
width = 5,
collapsible = FALSE,
tabs = list(
list(menu = "First Tab", content = "Some text..."),
list(menu = "Second Tab", content = plotlyOutput("mtcars_plot2"))
)
)
)),
tabItem(
tabName = "table_tab",
fluidRow(
valueBox(
"Unread Mail",
144,
icon("mail"),
color = "blue",
width = 6,
size = "small"
),
valueBox(
"Spam",
20,
icon("mail"),
color = "red",
width = 5,
size = "small"
),
valueBox(
"Readed Mail",
666,
icon("mail"),
color = "green",
width = 5,
size = "small"
)
),
fluidRow(
box(
title = "Classic box",
color = "blue",
ribbon = FALSE,
title_side = "top left",
width = 14,
tags$div(
dataTableOutput("mtcars_table")
,
style = paste0("color:", semantic_palette[["blue"]], ";")
)
)
)
)
)),
theme = "slate"
)
server <- function(input, output) {
output$mtcars_plot <-
renderPlotly(plot_ly(
mtcars,
x = ~ mtcars[, input$variable1],
y = ~ mtcars[, input$variable2],
type = "scatter",
mode = "markers"
))
output$mtcars_plot2 <-
renderPlotly(plot_ly(
mtcars,
x = ~ mtcars[, input$variable1],
y = ~ mtcars[, input$variable2],
type = "scatter",
mode = "markers"
))
output$mtcars_table <-
renderDataTable(mtcars, options = list(dom = 't'))
output$dropdown <- renderDropdownMenu({
dropdownMenu(
messageItem("User", "Test message", color = "teal", style = "min-width: 200px"),
messageItem("Users", "Test message", color = "teal", icon = "users"),
messageItem(
"See this",
"Another test",
icon = "warning",
color = "red"
)
)
})
}
shinyApp(ui, server)
It looks like the issue is behind the dashboardBody function. It uses a ui stackable container grid for each tab which is causing the large amount of padding.
There are two ways around it:
Hack around the dashboardBody function and remove "container" from the class:
dash_body <- function (...) {
shiny::div(
class = "pusher container", style = "min-height: 100vh;",
shiny::div(
class = "ui segment", style = "min-height: 100vh;",
shiny::tags$div(class = "ui stackable grid", ...)
),
semantic.dashboard:::body_js
)
}
Add CSS to remove the padding for this class (add first row in the dashboardBody arguments):
tags$style(".pusher.container .ui.segment .ui.stackable.container.grid {margin:0px!important;}")

rCharts in shiny : width with 2 charts

I have an app with two Highcharts plot, when I start the app the width of the two plots are correct, but everytime I change the mean input, the width of the first plot is set to the width of the second, like this :
When I start the app :
When I change the input :
My code to produce the app :
library(rCharts)
library(shiny)
runApp(list(
ui = fluidPage(
title = "App title",
titlePanel(strong("App title", style="color: steelblue")),
sidebarLayout(
sidebarPanel(width = 2,
br()),
mainPanel(width = 10,
tabsetPanel(
tabPanel("Tab 1",
selectInput(inputId = "input_mean", label = "Mean : ", choices = c(20:30)),
fluidRow(
column(8,
showOutput(outputId = "chart1", lib = "highcharts")
, br(), br(), br(), br(), br(), br(), br(), br(), br(), br(), br()),
column(4,
showOutput(outputId = "chart2", lib = "highcharts"))
)
)
)
)
)
),
server = function(input, output) {
my_data <- reactive({
rnorm(n = 30, mean = as.numeric(input$input_mean))
})
output$chart1 <- renderChart2({
my_data = my_data()
h2 <- Highcharts$new()
h2$chart(type="line")
h2$series(data=my_data, name = "One", marker = list(symbol = 'circle'), color = "lightblue")
h2$set(width = 800, height = 400)
return(h2)
})
output$chart2 <- renderChart2({
my_data = my_data()
my_mean = as.numeric(input$input_mean)
part = data.frame(V1 = c("Sup", "Inf"), V2 = c(sum(my_data>my_mean), sum(my_data<my_mean)))
p = hPlot(x = "V1", y = "V2", data = part, type = "pie")
p$tooltip(pointFormat = "{series.name}: <b>{point.percentage:.1f}%</b>")
p$params$width <- 200
p$params$height <- 200
return(p)
})
}
))
I use rCharts_0.4.5 and shiny_0.9.1.
Thanks !
Replace these lines:
h2$chart(type="line")
h2$set(width = 800, height = 400)
as follows:
h2$chart(type="line", width = 800, height = 400)
This should help.

Resources