I'm a shiny newbie and was thrilled when I used SO to figure out how to filter one selectInput based on another. However, as I added more inputs they became misaligned and I was hoping there was a simple fix. I do not know HTML at all. And while I searched for similar questions, the different shiny layouts and other code overhead made it difficult to understand the way to fix.
I'm assuming I just need to include the UI part for a reproducible example rather than confuse future searches with all of the "overhead" of longer code, so I am including the UI here. Please let me know if I need to include more.
The shiny input is more and more off with additional inputs as you can see:
Here is the reproducible example:
# Define UI
ui <- fluidPage(headerPanel(strong("Carbohydrate Calculator")),
fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_1',
label = 'Food Category',
choices = c("None", categories)
),
selectInput(
inputId = 'cat_2',
label = 'Food Category',
choices = c("None", categories)
),
selectInput(
inputId = 'cat_3',
label = 'Food Category',
choices = c("None", categories)
),
selectInput(
inputId = 'cat_4',
label = 'Food Category',
choices = c("None", categories)
),
selectInput(
inputId = 'cat_5',
label = 'Food Category',
choices = c("None", categories)
),
selectInput(
inputId = 'cat_6',
label = 'Food Category',
choices = c("None", categories)
),
selectInput(
inputId = 'cat_7',
label = 'Food Category',
choices = c("None", categories)
),
selectInput(
inputId = 'cat_8',
label = 'Food Category',
choices = c("None", categories)
)
),
column(
width = 3,
selectInput(
inputId = 'food_1',
label = 'Food Item',
choices = foods[1]
),
selectInput(
inputId = 'food_2',
label = 'Food Item',
choices = foods[1]
),
selectInput(
inputId = 'food_3',
label = 'Food Item',
choices = foods[1]
),
selectInput(
inputId = 'food_4',
label = 'Food Item',
choices = foods[1]
),
selectInput(
inputId = 'food_5',
label = 'Food Item',
choices = foods[1]
),
selectInput(
inputId = 'food_6',
label = 'Food Item',
choices = foods[1]
),
selectInput(
inputId = 'food_7',
label = 'Food Item',
choices = foods[1]
),
selectInput(
inputId = 'food_8',
label = 'Food Item',
choices = foods[1]
)
),
column(
width = 3,
numericInput(
inputId = "actual_serving_1",
label = "How much?",
value = "",
min = 0,
max = 100
),
numericInput(
inputId = "actual_serving_2",
label = "How much?",
value = "",
min = 0,
max = 100
),
numericInput(
inputId = "actual_serving_3",
label = "How much?",
value = "",
min = 0,
max = 100
),
numericInput(
inputId = "actual_serving_4",
label = "How much?",
value = "",
min = 0,
max = 100
),
numericInput(
inputId = "actual_serving_5",
label = "How much?",
value = "",
min = 0,
max = 100
),
numericInput(
inputId = "actual_serving_6",
label = "How much?",
value = "",
min = 0,
max = 100
),
numericInput(
inputId = "actual_serving_7",
label = "How much?",
value = "",
min = 0,
max = 100
),
numericInput(
inputId = "actual_serving_8",
label = "How much?",
value = "",
min = 0,
max = 100
)
),
column(8,
tableOutput("my_table"),
span(textOutput("my_message"), style="color:red")
) # Column close
) # fluidRow close
) # fluidPage close
To better align the elements in a row, it may be better to fill the elements in a row. Try this
# Define UI
ui <- fluidPage(headerPanel(strong("Carbohydrate Calculator")),
fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_11',
label = 'Food Category',
choices = c("None", categories)
)),
column(
width = 3,
selectInput(
inputId = 'food_11',
label = 'Food Item',
choices = foods[1]
)),
column(
width = 3,
numericInput(
inputId = "actual_serving_11",
label = "How much?",
value = "",
min = 0,
max = 100
))
),
fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_12',
label = 'Food Category',
choices = c("None", categories)
)),
column(
width = 3,
selectInput(
inputId = 'food_12',
label = 'Food Item',
choices = foods[1]
)),
column(
width = 3,
numericInput(
inputId = "actual_serving_12",
label = "How much?",
value = "",
min = 0,
max = 100
))
),
fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_13',
label = 'Food Category',
choices = c("None", categories)
)),
column(
width = 3,
selectInput(
inputId = 'food_13',
label = 'Food Item',
choices = foods[1]
)),
column(
width = 3,
numericInput(
inputId = "actual_serving_13",
label = "How much?",
value = "",
min = 0,
max = 100
))
),
fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_14',
label = 'Food Category',
choices = c("None", categories)
)),
column(
width = 3,
selectInput(
inputId = 'food_14',
label = 'Food Item',
choices = foods[1]
)),
column(
width = 3,
numericInput(
inputId = "actual_serving_14",
label = "How much?",
value = "",
min = 0,
max = 100
))
),
fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_15',
label = 'Food Category',
choices = c("None", categories)
)),
column(
width = 3,
selectInput(
inputId = 'food_15',
label = 'Food Item',
choices = foods[1]
)),
column(
width = 3,
numericInput(
inputId = "actual_serving_15",
label = "How much?",
value = "",
min = 0,
max = 100
))
),
fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_16',
label = 'Food Category',
choices = c("None", categories)
)),
column(
width = 3,
selectInput(
inputId = 'food_16',
label = 'Food Item',
choices = foods[1]
)),
column(
width = 3,
numericInput(
inputId = "actual_serving_16",
label = "How much?",
value = "",
min = 0,
max = 100
))
)
# column(8,
# tableOutput("my_table"),
# span(textOutput("my_message"), style="color:red")
# ) # Column close
) # fluidPage close
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
Related
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)
I ran into a bit of trouble in my app. I have a fluidrow, which contains 2 colums, and these columns again contain fluid rows.
I have a textinput in the left column and a selectInput (with selectize = TRUE) on the right side.
While the contents of that row are on exactly one level, the contents of the next row are sadly pushed further down. This only happens with a selectInput in that location, so I assume that it has a larger margin below than for example a textInput.
I hope somebody had a similar problem an a solution before!
edit:
fluidRow(
column(
width = 4,
offset = 2,
h3("Unsere Kontaktdaten"),
fluidRow(
column(
width = 12,
disabled(
textInput(
inputId = "Kontakt",
label = "Firma",
value = "Digitale Giganten",
width = "100%"
)
),
)
),
fluidRow(
column(
width = 9,
disabled(
textInput(
inputId = "unsere_straße",
label = "Straße",
value = "Mohnstraße",
width = "100%"
)
),
),
column(
width = 3,
disabled(
textInput(
inputId = "unsere_hausnummer",
label = "Hausnummer",
value = 123,
width = "100%"
)
),
)
),
),
column(
width = 4,
offset = 1,
h3("Ansprechpartner"),
fluidRow(
column(
width = 3,
disabled(
selectInput(
inputId = "unsere_anrede",
label = "Anrede",
choices = c("Herr", "Frau", "Divers"),
width = "100%" )
)
),
column(
width = 9,
disabled(
textInput(
inputId = "unser_ansprechpartner",
label = "Ansprechpartner",
width = "100%",
value = "name"
)
)
)
),
disabled(
textInput(
inputId = "unsere_nummer",
label = "Telefon",
width = "100%",
value = 123456789
)
),
)
),
You can fix this via css. I wrapped the selectinput in a div() to style it:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
fluidRow(
column(
width = 4,
offset = 2,
h3("Unsere Kontaktdaten"),
fluidRow(
column(
width = 12,
disabled(
textInput(
inputId = "Kontakt",
label = "Firma",
value = "Digitale Giganten",
width = "100%"
)
),
)
),
fluidRow(
column(
width = 9,
disabled(
textInput(
inputId = "unsere_straße",
label = "Straße",
value = "Mohnstraße",
width = "100%"
)
),
),
column(
width = 3,
disabled(
textInput(
inputId = "unsere_hausnummer",
label = "Hausnummer",
value = 123,
width = "100%"
)
),
)
),
),
column(
width = 4,
offset = 1,
h3("Ansprechpartner"),
fluidRow(
column(
width = 3,
disabled(
div(selectInput(
inputId = "unsere_anrede",
label = "Anrede",
choices = c("Herr", "Frau", "Divers"),
width = "100%"),
style = "margin-bottom: -5px;")
)
),
column(
width = 9,
disabled(
textInput(
inputId = "unser_ansprechpartner",
label = "Ansprechpartner",
width = "100%",
value = "name"
)
)
)
),
disabled(
textInput(
inputId = "unsere_nummer",
label = "Telefon",
width = "100%",
value = 123456789
)
),
)
)
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
If you have multiple selectInputs you need to style and don't want to wrap each in a div, you can add:
tags$style("
.selectize-input {
margin-bottom: -5px !important;
}
")
somewhere in your UI.
I have created a shiny app that allows you to enter info on product, quantity and rate and gives an output. I would like the user to download it into a pdf file that is formatted differently.
Here is my code
ui code
body <- dashboardBody(
tabItem(
tabName = 'Create_PI',
inputPanel(
selectizeInput(inputId = 'Customer_Name',label='Customer Name',
choices= sales$Customer, options = list(create=T)),
textInput(inputId = 'Contact',label='Contact Person'),
dateInput(inputId = 'Date', label = 'Date', format = 'dd MM yy')),
inputPanel(
selectizeInput(inputId = 'Product_Name1', label='Product Name',
choices= sales$Product, options = list(create=T)),
numericInput(inputId = 'Quantity1',value=0,label = 'Quantity (kg)',
min = 1, width = '100px'),
numericInput(inputId = 'Rate1',value=0,label = 'Rate (INR/kg)',
min = 1, width = '100px'),
textOutput(outputId = 'total1')
),
inputPanel(
selectizeInput(inputId = 'Product_Name2', label='Product Name',
choices= sales$Product, options = list(create=T)),
numericInput(inputId = 'Quantity2',value=0,label = 'Quantity (kg)',
min = 1, width = '100px'),
numericInput(inputId = 'Rate2',value=0,label = 'Rate (INR/kg)',
min = 1, width = '100px'),
textOutput(outputId = 'total2')
),
inputPanel(
numericInput(inputId = 'CGST', value = 9, label = 'CGST'),
numericInput(inputId = 'SGST', value = 9, label = 'SGST'),
textOutput(outputId = 'Final_Total'),
downloadButton(outputId = 'Create',label='Create PI')
)
)
server code
### The PI part
server <- function(input, output) {
output$total1 <- renderText(
paste('INR',formatC(input$Quantity1*input$Rate1, format="d", big.mark=','))
)
output$total2 <- renderText(
paste('INR',formatC(input$Quantity2*input$Rate2, format="d", big.mark=','))
)
output$Final_Total <- renderText({
total1 <- input$Quantity1*input$Rate1
total1[is.na(total1)] <-0
total2<-input$Quantity2*input$Rate2
total2[is.na(total2)]<-0
gst <- (input$CGST+input$SGST)/100
finaltotal <- total1+total2+(gst*(total1+total2))
paste('Final Rate INR',formatC(finaltotal, format="d", big.mark=','))
})
}
I'm facing an issue while deploying my app on Rshiny cloud
I am getting the following error when I run the code below code for UI:
Error in data$Type : object of type 'closure' is not subsettable
I've looked at many issues online but am unable to figure out what is wrong in my code
ui <- semantic.dashboard::dashboard_body(
semantic.dashboard::dashboard_header(color = "blue",title = "Dashboard Demo",inverted = TRUE),
semantic.dashboard::dashboard_sidebar(
# size = "thin", color = "teal",
semantic.dashboard::sidebar_menu(
semantic.dashboard::menu_item(tabName = "Visualization", "Visualization", icon = icon("chart line")),
semantic.dashboard::menu_item(tabName = "RawData", "RawData", icon = icon("table"))
)
),
semantic.dashboard::dashboard_body(
shiny::fluidRow(
column(width = 3, offset =0, div(style = "height:35px"),
selectInput("type",
"Type:",
c("All",
unique(as.character(data$Type))))
),
column(width = 3, offset =0, div(style = "height:35px"),
selectInput("Bname",
"Business Name:",
c("All",
unique(as.character(data$Business_Name))))
),
column(width = 3, offset =0, div(style = "height:35px"),
selectInput("BUnit",
"Business Unit:",
c("All",
unique(as.character(data$Business_Unit))))
),
column(width = 3, offset =0, div(style = "height:35px"),
selectInput("region",
"Region:",
c("All",
unique(as.character(data$Region))))
)
),
semantic.dashboard::tab_items(
selected = 1,
semantic.dashboard::tabItem(
tabName = "Visualization",
# Create a new row for the table.
plotOutput('waterfall')
),
semantic.dashboard::tabItem(
tabName = "RawData",
# Create a new row f
DT::dataTableOutput("table")
),
shiny::downloadButton("downloadData", "Download Raw Data")
)
)
)
I am working with shiny to do un R web application, the application is composed with a sidebarpanel on the left of the mainpanel (with 2 tabspanel) and another sidebarpanel below.
I want to keep the bottom sidebarpanel for the first mainpanel but removing it for the second.
The code looks like :
sidebarPanel(
wellPanel(
fileInput('file1', 'Choisissez les data service ?',
accept = c('text/csv', 'text/comma-separated-values',
'text/tab-separated-values', 'text/plain',
'.csv', '.tsv', 'RData'
)
)
),
wellPanel(
selectInput(inputId = "fonction.de",
label = "En fonction de ?",
choices = fonctions.de,
selected = "perimetre_commercial_estime"
),
selectInput(inputId = "perimetre",
label = "Perimetres commercial",
choices = perimetres,
selected = "2-HDM MARCHAND",
multiple = TRUE
),
checkboxInput(inputId = "case1", label = "Tous perimetres", value = FALSE),
selectInput(inputId = "ae",
label = "AE",
choices = aes,
selected = "AE Paris",
multiple = TRUE
),
checkboxInput(inputId = "case2", label = "Tous AE", value = FALSE),
selectInput(inputId = "segment",
label = "Segment commercial",
choices = segments,
selected = "Premium",
multiple = TRUE
),
checkboxInput(inputId = "case3", label = "Tous segments", value = FALSE)
)
),
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Graphiques",
plotlyOutput("my.chart")),
tabPanel("Tables",
dataTableOutput("my.table"),
htmlOutput("my.text1"))
)
),
sidebarPanel(
selectInput(inputId = "abscisse",
label = "Abscisse",
choices = abscisses,
selected = "",
multiple = FALSE
),
selectInput(inputId = "ordonnee",
label = "Ordonnee",
choices = ordonnees,
selected = "",
multiple = FALSE
)
),
sidebarPanel(
img(src="Dymetryyy.jpg", height = 150, width = 350)
)
)
)
For people who are facing the same problem, you have to use conditionalPanel to solve it.
mainPanel(
tabsetPanel(id = "bab",
type = "tabs",
tabPanel(value = "graphiques",
"Graphiques",
plotlyOutput("my.chart")),
tabPanel(value = "tables",
"Tables",
dataTableOutput("my.table"),
htmlOutput("my.text1"))
)
),
conditionalPanel(condition = "input.bab == 'graphiques'",
sidebarPanel(
selectInput(inputId = "abscisse",
label = "Abscisse",
choices = abscisses,
selected = "",
multiple = FALSE
),
selectInput(inputId = "ordonnee",
label = "Ordonnee",
choices = ordonnees,
selected = "",
multiple = FALSE
)
),
sidebarPanel(
img(src="dymetryyy", height = 150, width = 350)
)
)