fluidRow won't appear under mainPanel graphic in Shiny - r

I've created a Shiny app using a fluid grid system (i.e., using fluidPage) that utilizes sidebarPanel and tabsetPanel. In addition to the input "control" widgets I put in the sidebar, I would also like to add a series of input widgets below the graphic in my main panel on a specific panel.
My approach was to simply include a fluidRow with multiple columns after the plotOutput command in the first tabPanel.
My code produces no errors, but for some reason nothing shows up under the graphic in my main panel.
Is this just not possible, or am I doing something wrong?
Note: this SO question suggests that my approach to including multiple UI elements within the tab is valid, and this SO question suggests that multiple outputs can be added to the mainPanel (but what about inputs??). So what gives??
Example code with same issue:
library(shiny)
ui <- fluidPage(
titlePanel(
h1("NMS Comparing tool", style = "font-size: 15px")
),
sidebarPanel(width = 3,
div(style = "font-size: 8px;",
sliderInput(inputId = "groups",
label = "No. of Groups",
value = 4, min = 2, max = 12)
),
fluidRow(
column(6,offset=0,
div(style = "height: 105px; padding: 0px 0px",
plotOutput(outputId = "scree")
)
),
column(6,offset=0,
div(style = "font-size: 8px;padding: 0px 10px;height: 105px",
checkboxGroupInput(inputId = "labels",
label = "Labels",
choices = c("SPEC","Plot-End","Plot-Start"),
selected = c("SPEC","Plot-End","Plot-Start")
)
)
)
),
fluidRow(
column(6,offset=0,
div(style = "font-size: 8px; padding: 0px 0px",
radioButtons(inputId = "data",
label = "Data",
choices = c("PSP Only","PSP + MAP"),
selected = "PSP + MAP")
)
),
column(6,offset=0,
div(style = "font-size: 8px;padding: 0px 10px;",
radioButtons(inputId = "freq",
label = "Frequency",
choices = c(0.025,0.05),
selected = 0.05)
)
)
),
fluidRow(
column(6,offset=0,
div(style = "font-size: 8px; padding: 0px 0px; ",
radioButtons(inputId = "arrows",
label = "Vector Choice",
choices = c("Cumulative Change","All Samples","Hurricane"),
selected = "Cumulative Change")
)
),
column(6,offset=0,
div(style = "font-size: 8px;padding: 0px 10px",
selectInput(inputId = "size",
label = "Tree Size",
choices = c("All","Canopy","Subcanopy","Small"),
selected = "All"),
tags$style(type = "text/css",
"#size {height: 4px; }")
)
)
),
fluidRow(
div(style = "font-size: 8px;",
verbatimTextOutput("info")
)
)
,
mainPanel(width = 9,
tabsetPanel(
tabPanel(title = "NMS",
plotOutput(outputId = "nms", click = "plot_click"),
fluidRow(
column(2,offset=0,
div(style = "font-size: 8px; padding: 0px 0px",
actionButton(inputId = "plot.singles", label = "Lookup")
)
),
column(2,offset=0,
div(style = "font-size: 8px; padding: 0px 0px",
textInput(inputId = "individ", label = "Plot(s)")
)
),
column(2,offset=0,
div(style = "font-size: 8px; padding: 0px 0px",
textInput(inputId = "group.choose", label = "Group(s)")
)
),
column(3,offset=0,
div(style = "font-size: 8px; padding: 0px 0px",
sliderInput(inputId = "lwidth.choose", label = "LineWidth",min = 1, max = 6)
)
)
)
),
tabPanel(title = "Silhouette", plotOutput(outputId = "silhouette")),
tabPanel(title = "Indicator Spp", dataTableOutput(outputId = "ind.spp")),
tabPanel(title = "Data", dataTableOutput(outputId = "nms.data.table"))
)
)
)
)
server <- function(input, output) {
output$scree <- renderPlot({
par(mar = c(1.5,1.4,0.1,0.1), mgp = c(0.5,0.01,0), tcl = -0.1)
plot(runif(99),runif(99),cex.axis=0.5,cex.lab=0.5,cex=0.75)
},height = 95, width = 135)
output$nms <- renderPlot({
plot(runif(99),runif(99))
})
}
shinyApp(ui = ui, server = server)

Certainly what you're trying to do is possible. When I run your example code, I actually do see the widgets underneath the plot (Lookup, Plot(s), Group(s), etc.). But I had to fix a couple of small things first--for one thing, you need to give a value to sliderInput. For another, you've got a misplaced bracket that's causing the mainPanel to be shoved into your sidebarPanel.
But there's no problem with your fluidRow itself, as written. Make sure you've put it in the right place in the UI.

Related

Panel output displaying on top of navbarPage and other panel output - R Shiny UI

Despite the navbarPage and tabPanel combo of a Shiny UI appearing to be straightforward, I can't for the life of me get the UI of my Shiny app to display correctly. I simply want a main tabPanel titled "Matchup Finder" that displays the dashboard I've created and then another panel titled "About" that will eventually display some html when clicked that explains what's happening on the dashboard. However, upon running, the About page contents shows up behind the output from the Matchup Finder dashboard, and there's no button for the Matchup Finder tabPanel. I've tried a variety of things (i.e., adding fluidPage, and id for the navbarPage, among others) to no avail.
ui <- navbarPage(
tabPanel("Matchup Finder",
fluidRow(
column(6,
fluidRow(
column(12,
wellPanel(
style = "background-color: ghostwhite; border-color: #2c3e50; height: 360px;",
fluidRow(
column(6,
radioButtons(inputId = "radio",
label = "View",
choices = list(
"By player" = 1,
"By team" = 2)),
selectInput(inputId = "off_player",
label = "Offensive player",
choices = c("Jayson Tatum"),
selectize = TRUE,
selected = c("Jayson Tatum")),
conditionalPanel(
condition = "input.radio == '1'",
selectizeInput(
inputId = "def_players",
label = "Defensive players",
choices = c("Kevin Durant", "Khris Middleton",
"Matisse Thybulle", "OG Anunoby", "Scottie Barnes"),
multiple = TRUE)),
conditionalPanel(
condition = "input.radio == '2'",
selectInput(inputId = "def_team",
label = "Defensive team",
choices = c("ATL", "CHA", "CLE"),
selectize = FALSE,
selected = c("ATL"))),
selectInput(inputId = "metrics",
label = "Select metric:",
choices = c("pts_created_per_100", "off_avg_pts_created_per_100"),
selectize = FALSE,
selected = "pts_created_per_100")),
column(6,
checkboxGroupInput(
inputId = "seasons",
label = "Select season:",
choices = c("2018", "2019", "2020", "2021", "2022"),
selected = c("2018", "2019", "2020", "2021", "2022"),
inline = TRUE),
checkboxGroupInput(inputId = "season_type",
label = "Select type:",
choices = c("playoffs", "reg"),
selected = c("playoffs", "reg"),
inline = TRUE),
sliderInput(inputId = "poss",
label = "Minimum possessions:",
0, 160, 20, step = 20)))))),
fluidRow(
column(12,
wellPanel(
style = "background-color: ghostwhite; border-color: #2c3e50; height: 420px;",
tabsetPanel(type = "tabs",
tabPanel("Selected", DTOutput("selected_table", width = 640)),
tabPanel("Top 5 Defenders", DTOutput("top_perf", width = 640)),
tabPanel("Most Frequent", DTOutput("top_vol", width = 640))))))),
column(6,
wellPanel(
style = "background-color: ghostwhite; border-color: #2c3e50; height: 795px;",
fluidRow(
column(12,
mainPanel(
plotOutput("plot1",
height = 760,
width = 620)))))))),
tabPanel("About", icon = icon("bars"),
fluidRow(
column(12,
wellPanel(
# style = "background-color: #fff; border-color: #2c3e50;",
"This panel is intentionally left blankThis panel is intentionally left blank
This panel is intentionally left blankThis panel is intentionally left blank
This panel is intentionally left blankThis panel is intentionally left blank
This panel is intentionally left blankThis panel is intentionally left blank
This panel is intentionally left blankThis panel is intentionally left blank"))))
)
Individual tabPanel tabs need to be wrapped inside a tabsetPanel (See here for an example):
library(shiny)
library(DT)
ui <- navbarPage(
tabsetPanel(
tabPanel(
"Matchup Finder",
fluidRow(
column(
6,
fluidRow(
column(
12,
wellPanel(
style = "background-color: ghostwhite; border-color: #2c3e50; height: 360px;",
fluidRow(
column(
6,
radioButtons(
inputId = "radio",
label = "View",
choices = list(
"By player" = 1,
"By team" = 2
)
),
selectInput(
inputId = "off_player",
label = "Offensive player",
choices = c("Jayson Tatum"),
selectize = TRUE,
selected = c("Jayson Tatum")
),
conditionalPanel(
condition = "input.radio == '1'",
selectizeInput(
inputId = "def_players",
label = "Defensive players",
choices = c(
"Kevin Durant", "Khris Middleton",
"Matisse Thybulle", "OG Anunoby", "Scottie Barnes"
),
multiple = TRUE
)
),
conditionalPanel(
condition = "input.radio == '2'",
selectInput(
inputId = "def_team",
label = "Defensive team",
choices = c("ATL", "CHA", "CLE"),
selectize = FALSE,
selected = c("ATL")
)
),
selectInput(
inputId = "metrics",
label = "Select metric:",
choices = c("pts_created_per_100", "off_avg_pts_created_per_100"),
selectize = FALSE,
selected = "pts_created_per_100"
)
),
column(
6,
checkboxGroupInput(
inputId = "seasons",
label = "Select season:",
choices = c("2018", "2019", "2020", "2021", "2022"),
selected = c("2018", "2019", "2020", "2021", "2022"),
inline = TRUE
),
checkboxGroupInput(
inputId = "season_type",
label = "Select type:",
choices = c("playoffs", "reg"),
selected = c("playoffs", "reg"),
inline = TRUE
),
sliderInput(
inputId = "poss",
label = "Minimum possessions:",
0, 160, 20, step = 20
)
)
)
)
)
),
fluidRow(
column(
12,
wellPanel(
style = "background-color: ghostwhite; border-color: #2c3e50; height: 420px;",
tabsetPanel(
type = "tabs",
tabPanel("Selected", DTOutput("selected_table", width = 640)),
tabPanel("Top 5 Defenders", DTOutput("top_perf", width = 640)),
tabPanel("Most Frequent", DTOutput("top_vol", width = 640))
)
)
)
)
),
column(
6,
wellPanel(
style = "background-color: ghostwhite; border-color: #2c3e50; height: 795px;",
fluidRow(
column(
12,
mainPanel(
plotOutput("plot1",
height = 760,
width = 620
)
)
)
)
)
)
)
),
tabPanel("About",
icon = icon("bars"),
fluidRow(
column(
12,
wellPanel(
# style = "background-color: #fff; border-color: #2c3e50;",
"This panel is intentionally left blankThis panel is intentionally left blank
This panel is intentionally left blankThis panel is intentionally left blank
This panel is intentionally left blankThis panel is intentionally left blank
This panel is intentionally left blankThis panel is intentionally left blank
This panel is intentionally left blankThis panel is intentionally left blank"
)
)
)
)
)
)
server <- function(input, output, session) {
}
shinyApp(ui, server)

How to replace fluidRow with a horizontally scrollable non-wrapping row in tab panel?

The reproducible code below uses a fluidRow() to house several user selections using radio buttons. Works fine in this limited example of only 2 radio button groupings. But I need to fit more radio button groupings into this row, without any wrapping. To do this, I'd like to replace this combination of fluidRow()/column() with a horizontally scrollable, non-wrapping row that is not subject to the limitations of the 12-wide grid system currently used in this code.
Also, all objects viewed in the scrolling row need to be left aligned without "fluid" expansion. Currently, using this fluidRow()/column() combo, if the viewing pane is expanded, the 2 columns housing each radio button grouping also expanded which doesn't look good. They need to remain fixed width and stay to the left.
Is this possible?
I prefer sticking with this sidebar/main panel/tab panel/conditional panel layout as I find it very user friendly for navigating the type of data we work with.
The image at the bottom further explains.
Reproducible code:
library(dplyr)
library(DT)
library(shiny)
library(shinyWidgets)
ui <-
fluidPage(
titlePanel("Summary"),
sidebarLayout(
sidebarPanel(
selectInput("selectData", h5("Select data to view:"),
choices = list("Beta"),
selected = "Beta"),
),
mainPanel(
tabsetPanel(
tabPanel("Private data", value = 1,
conditionalPanel(condition = "input.selectData == 'Beta'",
fluidRow(div(style = "margin-top:15px"),
column(width = 6, offset = 0,
wellPanel(
radioButtons(inputId = 'group1',
label = NULL,
choiceNames = c('By period','By MOA'),
choiceValues = c('Period','MOA'),
selected = 'Period',
inline = TRUE
),
style = "padding-top: 12px; padding-bottom: 0px;"
)
),
column(width = 6, offset = 0,
wellPanel(
radioButtons(inputId = 'group2',
label = NULL,
choiceNames = c('Exclude CT','Include CT'),
choiceValues = c('Exclude','Include'),
selected = 'Exclude',
inline = TRUE
),
style = "padding-top: 12px; padding-bottom: 0px;"
)
)
),
DTOutput("plants")
)
),
id = "tabselected"
)
)
)
)
server <- function(input, output, session) {
output$plants <- renderDT({iris %>% datatable(rownames = FALSE)})
}
shinyApp(ui, server)
How about using a carousel instead e.g. via shinyglide or slickR:
library(dplyr)
library(DT)
library(shiny)
library(shinyWidgets)
library(shinyglide)
ui <-
fluidPage(
titlePanel("Summary"),
sidebarLayout(
sidebarPanel(
selectInput("selectData", h5("Select data to view:"),
choices = list("Beta"),
selected = "Beta"),
),
mainPanel(
tabsetPanel(
tabPanel("Private data", value = 1,
conditionalPanel(condition = "input.selectData == 'Beta'",
fluidRow(div(style = "margin-top:15px"),
column(12, glide(
height = "25",
controls_position = "top",
screen(
p(strong("Group 1")),
wellPanel(
radioButtons(inputId = 'group1',
label = NULL,
choiceNames = c('By period','By MOA'),
choiceValues = c('Period','MOA'),
selected = 'Period',
inline = TRUE
),
style = "padding-top: 12px; padding-bottom: 0px;"
)
),
screen(
p(strong("Group 2")),
wellPanel(
radioButtons(inputId = 'group2',
label = NULL,
choiceNames = c('Exclude CT','Include CT'),
choiceValues = c('Exclude','Include'),
selected = 'Exclude',
inline = TRUE
),
style = "padding-top: 12px; padding-bottom: 0px;"
)
)
))
),
DTOutput("plants")
)
),
id = "tabselected"
)
)
)
)
server <- function(input, output, session) {
output$plants <- renderDT({iris %>% datatable(rownames = FALSE)})
}
shinyApp(ui, server)

SelectInput choices are hidden behind downloadButton in Shiny App

I am having issues with the UI of a shiny app. In my app, the choices for my selectInputs are hidden behind a downloadButton.
library(shiny)
ui <- navbarPage(
tabPanel("View Archive",
sidebarLayout(
sidebarPanel(
tags$h4("Archive Filter", style = "font-weight: 450; margin-top: 0; text-decoration: underline; text-align: center",
radioButtons(
inputId = "archive.choice",
label = "Select Tasks to Display",
choices = c("Completed" = "archive.completed", "Scheduled" = "archive.scheduled")
),
tags$h4("Create Archive Report", style = "font-weight: 450; margin-top: 0; text-decoration: underline; text-align: center"),
splitLayout(cellWidths = c("50%", "50%"),
selectInput(
inputId = "report.month",
label = "Select Month",
choices = as.list(month.name)
),
selectInput(
inputId = "report.year",
label = "Select Year",
choices = (2020:format(Sys.Date(), "%Y"))
)
),
downloadButton('downloadData', 'Download Report')
)
))
)
server <- function(input, output, session) {}
shinyApp(ui, server)
I've tried changing the z-index of the selectInputs but haven't had any success with that. Does anyone know a way to resolve this issue? It seems like it should be simple but I haven't been able to find a solution. Thanks in advance.
I changed the splitLayout approach and used a fluidRow() with two columns instead.
library(shiny)
ui <- navbarPage(
title = 'StackOverFlow App',
tabPanel(
title = "First Panel",
sidebarLayout(
sidebarPanel = sidebarPanel(
tags$h4("Archive Filter", style = "font-weight: 450; margin-top: 0; text-decoration: underline; text-align: center"),
radioButtons(
inputId = "archive.choice",
label = "Select Tasks to Display",
choices = c("Completed" = "archive.completed", "Scheduled" = "archive.scheduled")
),
tags$h4("Create Archive Report", style = "font-weight: 450; margin-top: 0; text-decoration: underline; text-align: center"),
fluidRow(
column(
width = 6,
selectInput(
inputId = "report.month", label = "Select Month",
choices = as.list(month.name)
)
),
column(
width = 6,
selectInput(
inputId = "report.year", label = "Select Year",
choices = (2020:format(Sys.Date(), "%Y")))
)
),
downloadButton('downloadData', 'Download Report', style='z-index:1;')
),
mainPanel = mainPanel()
)
)
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
To get the job down using splitLayout it would be necesary to change the css z-index property of the selectImput.

Shiny navbarpage draws over elements from below

This is the problem I am trying to solve. My navbarpage overlaps other elements from below. Is there any way to put the navbarpage in the background? Or perhaps make the daterange input show it's calendar below its input box?
The documentation mentions using fixed-top or fixed-bottom for the posotion argument will cause the navbar to overlay your body content, unless you add padding.
Adding padding does not solve the problem though.
Here is a reproducible example -
ui <- fluidPage(
fluidRow(class = 'headerrow', column(width = 12, style = "font-size: 30pt; line-height: 8vh; text-align:left; color:#FFFFFF; width = 100", tags$strong('Test')), tags$head(tags$style('.headerrow{height:8vh; background-color:#267dff}'))),
navbarPage(
'Navbar',
tabPanel(
'Menu1',
sidebarPanel(
selectInput('drink', 'Choose your poison', choices = c('Bloody Mary', 'Sex on the beach'), selected = 'Bloody Mary'),
dateRangeInput('period', 'Date range', start = '2016-05-01', end = '2017-04-01',
min = '2013-07-01', max = '2017-06-01', startview = 'year', format = 'mm/yyyy'),
width = 2
),
mainPanel(width = 10)
),
tabPanel('Menu2'),
tabPanel('Menu3'),
tabPanel('Menu4')
)
)
server <- function(input, output){
}
shinyApp(ui, server)
Thank you so much!
Try adding z-index to the div: tags$style(HTML(".datepicker {z-index:99999 !important;}"))
library(shiny)
ui <- fluidPage(
fluidRow(class = 'headerrow', column(width = 12, style = "font-size: 30pt; line-height: 8vh; text-align:left; color:#FFFFFF; width = 100", tags$strong('Test')), tags$head(tags$style('.headerrow{height:8vh; background-color:#267dff}'))),
navbarPage(
'Navbar',
tabPanel(
'Menu1',
tags$style(HTML(".datepicker {z-index:99999 !important;}")),
sidebarPanel(
selectInput('drink', 'Choose your poison', choices = c('Bloody Mary', 'Sex on the beach'), selected = 'Bloody Mary'),
dateRangeInput('period', 'Date range', start = '2016-05-01', end = '2017-04-01',
min = '2013-07-01', max = '2017-06-01', startview = 'year', format = 'mm/yyyy'),
width = 2
),
mainPanel(width = 10)
),
tabPanel('Menu2'),
tabPanel('Menu3'),
tabPanel('Menu4')
)
)
server <- function(input, output){}
shinyApp(ui, server)

R shiny Dashboard: How to add vertical scrollbar to dashboard sidebar?

I have a couple of questions regarding R shiny Dashboard.
ui.R
library(shinydashboard)
library(shiny)
dashboardPage(
dashboardHeader(title = 'Test Interface'),
dashboardSidebar(width = 600,
h3('-------Input Data-------'),
fluidRow(
column(6, div(style = "height:10px"), fileInput(inputId = 'FileInput', label = 'Upload Input:', accept = c('csv','tsv','txt'))),
column(2, div(style = "height:3px"), checkboxInput(inputId = 'header', label = 'Header', value = FALSE)),
column(2, div(style = "height:12px"), radioButtons(inputId = 'sep', label = 'Separator', choices = c(comma=',',tab="\t",space=' '), selected = ","),offset = 1)
),
fluidRow(column(6, div(style = "height:1px"), fileInput(inputId = 'FileInput1', label = 'Upload Second Input:'))),
br(),
h3('-------Select Foreground-------'),
fluidRow(
column(5, div(style = "height:17px"), radioButtons(inputId = 'cutoff', label = 'Selection', choices = c('Up'='pos','Down'='neg','Both'='both'))),
br(),
column(3, div(style = "height:1px"), textInput(inputId = 'fc', label = "Fold Change", value = '0')),
column(3, div(style = "height:1px; margin-left:10cm"), height = 6,textInput(inputId = 'pvalue', label = "Adj. Pvalue",value = '0.05'))
),
fluidRow(column(2, h1(" "), actionButton(inputId = 'select', label = "Select Data"))),
fluidRow(column(5, div(style = "height:25px;font-color:blue"), downloadButton('download', 'Download Plot')))),
dashboardBody(
tabsetPanel(type="tabs", id = "tabvalue",
tabPanel(title = "Input Table", value = 'tab1', DT::dataTableOutput('table')),
tabPanel(title = "Plot", value = 'tab7', plotOutput('plot',width = 800,height = 800)))))
server.R
library(shiny)
shinyServer(function(input, output, session){
})
I couldn't figure out how to add a vertical scroll bar to the dashboardSidebar. In my actual app, the last elements are not visible when I run the app.
Thanks!
I ran into this and came up with the following hack (and I do mean hack).
shinyDashboard(
tags$head(
tags$style(HTML(".sidebar {
height: 90vh; overflow-y: auto;
}"
) # close HTML
) # close tags$style
), # close tags#Head
# ...
The 90vh sets the sidebar height at 90% of the viewport height. You may want to adjust this to taste. Too large a percentage and some of the sidebar still drops below the horizon; too small a percentage and the sidebar ends noticeably before the main body (with the scrollbar appearing prematurely).

Resources