Lets assume I have a very simple application that only has 8 inputs grouped in 2 Panels (4 inputs | 4 inputs - see picture bellow) and based on these, I plot a small plot (easy peasy).
The problem that I face is that I want to have the labels only for the first panel, and on the left of the textInput box.
e.g. (Please excuse my sloppy image editing!)
Any suggestion?
My MWE for Figure 1 output:
library(shiny)
ui<-shinyUI(fluidPage(
wellPanel(
tags$style(type="text/css", '#leftPanel { max-width:300px; float:left;}'),
id = "leftPanel",
textInput("Population1000", 'Population 1000',"15"),
textInput("Area1000",'Area 1000', "20"),
textInput("GNI1000", 'GNI 1000', "2314"),
textInput("GDP1000", "GDP 1000", "1000")
),
wellPanel(
tags$style(type="text/css", '#RightPanel { max-width:300px; float:left;}'),
id = "RightPanel",
textInput("Population2000", 'Population 2000',"15"),
textInput("Area2000",'Area 2000', "20"),
textInput("GNI2000", 'GNI 2000', "2314"),
textInput("GDP2000", "GDP 2000", "1000")
)
)
)
server<-shinyServer(function(input, output) {NULL})
shinyApp(ui,server)
Hi you can try to use Bootstrap's horizontal form, look at the code below, it create 3 columns of width 4 each. You can change width in class = "col-sm-4 control-label" for labels, and in width = 4 for inputs.
library("shiny")
ui <- fluidPage(
fluidRow(
column(
width = 4,
tags$form(
class="form-horizontal",
tags$div(
class="form-group",
tags$label(class = "col-sm-4 control-label", `for` = "Population1000", br(), "Population"),
column(width = 4, textInput(inputId = "Population1000", label = "Year 1000", value = "15")),
column(width = 4, textInput(inputId = "Population2000", label = "Year 2000", value = "15"))
),
tags$div(
class="form-group",
tags$label(class = "col-sm-4 control-label", `for` = "Area1000", "Area"),
column(width = 4, textInput(inputId = "Area1000", label = NULL, value = "20")),
column(width = 4, textInput(inputId = "Area2000", label = NULL, value = "20"))
),
"..."
)
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
Result :
PS : you should not use same ids for inputs.
Related
I am trying to display some input field alongside some output field inputted from another tab. However the output field is going below and cannot align with the rest.
Code given below:-
fluidRow(
column(3, sliderInput(inputId = "avg_planned_miles", label = "Average Planner Miles", min = 5, max = 50, value = 9, step = 0.1)),
column(3, textInput(inputId = "batch_pct", label = "Batch %", value = "0.5")),
column(3, h4("Volume: "), verbatimTextOutput(outputId = "planner_volume"))
)
Try this code, it looks better to me
fluidRow(
column(3,
tagList(
tags$style(type = 'text/css','#avg_planned_miles .irs-grid-text {font-size: 12px}'), #the grid numbers size
div(id = 'avg_planned_miles', style='font-size: 16px;', #label font size
sliderInput(inputId = "avg_planned_miles", label = "Average Planner Miles\n", min = 5, max = 50, value = 9, step = 0.1)
)#div
)#tags
),
column(3,
tagList(
div(id = 'batch_pct',
style='position:absolute; top:10px; right:5px;', #add margin space
textInput(inputId = "batch_pct", width = 280,
label = "Batch%", value = "0.5")
)
)
),
column(3, p(strong("Volume")), #bold font to match the other fields
verbatimTextOutput(outputId = "planner_volume", placeholder = 1)
),
)
You can keep the sliderInput as it is in your code, I thought if the font sizes are bigger it looks better.
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)
I have two columns in a shiny app, I want to vertically align them to the bottom of their columns. I've tried adding styles to the column and the fluid row which contains them with no success. How can I adjust the css of a column to achieve this?
Many thanks!
ui <-
fluidPage(
fluidRow(
column(width = 6,
numericInput(inputId = "id_1", label = "Id number 1", value = 1, min = 0, max = 2, step =0.05),
# style = "vertical-align: bottom"
),
column(width = 6,
checkboxGroupInput("icons", "Choose icons:",
choiceNames = list(icon("calendar"), icon("bed"), icon("cog"), icon("bug")),
choiceValues = list("calendar", "bed", "cog", "bug")
)),
# style = "vertical-align: bottom"
)
)
server <- function(input, output) { }
shinyApp(ui, server)
I don't know how to do that with the bootstrap columns. Here is a way using a flexbox:
css <- "
.bottom-aligned {
display: flex;
align-items: flex-end;
}
.bottom-aligned > div {
flex-grow: 1;
}
"
ui <- fluidPage(
tags$head(
tags$style(HTML(css))
),
fluidRow(
column(
width = 12,
div(
class = "bottom-aligned",
div(
numericInput(inputId = "id_1", label = "Id number 1", value = 1, min = 0, max = 2, step = 0.05)
),
div(
checkboxGroupInput("icons", "Choose icons:",
choiceNames = list(icon("calendar"), icon("bed"), icon("cog"), icon("bug")),
choiceValues = list("calendar", "bed", "cog", "bug")
)
)
)
)
)
)
server <- function(input, output) { }
shinyApp(ui, server)
I started learning shiny recently and I am toying around with wellPanels. I am trying to create a wellPanel which will be no larger than necessary to fit its contents. I've managed to get the following:
but have not found a way to eliminate the right-hand side extra space of the wellPanel. If possible, I would also like to place the "X" button on the top right corner of the wellPanel. Is there a way to do these? Thanks in advance!
Here is the working code:
library(shiny)
ui <- fluidPage(
fluidRow(column(width = 6,
wellPanel(
fluidRow(
column(width = 3, textInput(inputId = "layer", label = "Layer name", placeholder = "Layer name")),
column(width = 3, numericInput(inputId = "att_point", label = "Attachment Point", value = 100)),
column(width = 3, numericInput(inputId = "capacity", label = "Capacity", value = 100)),
column(width = 3, actionButton(inputId = "rm_btn", label = "", icon = icon("times")))
)))))
shinyApp(ui, function(input,output){})
You need to adjust the widths something like this:
library(shiny)
ui <- fluidPage(
fluidRow(column(width = 6,
wellPanel(
fluidRow(
column(width = 4, textInput(inputId = "layer", label = "Layer name", placeholder = "Layer name")),
column(width = 4, numericInput(inputId = "att_point", label = "Attachment Point", value = 100)),
column(width = 3, numericInput(inputId = "capacity", label = "Capacity", value = 100)),
column(width = 1, actionButton(inputId = "rm_btn", label = "", icon = icon("times")))
)))))
shinyApp(ui, function(input,output){})
With this you get an output which looks like this:
Hope it helps!
I have a top banner that I want to split into two separate sections representing two different inputs. To do this, I've created a fluidRow and with two columns, one for each input. However, as it is now there is a little bit of white space between the columns, despite putting offset = 0. Is there any way to remove this white space so that the columns are immediately next to one another?
colors = c("green","blue","red")
library(shiny)
ui <- fluidPage(
tabsetPanel(
tabPanel("Info",
fluidRow(
column(width = 6, offset = 0,
div(style = "height:50px;width:100%;background-color: #999999;border-style: solid;border-color: #000000",
tags$h3("Section 1")
)
),
column(width = 6, offset = 0,
div(style = "height:50px;width:100%;background-color: #999999;border-style: solid;border-color: #000000",
tags$h3("Section 2")
)
)
),
fluidRow(
column(width = 6, offset = 0,
div(style = "height:50px;width:100%;background-color: #999999;border-style: solid;border-color: #000000",
selectInput(inputId = "color",label = "color:",
choices = colors,
selected = colors[2],
multiple = FALSE)
)
),
column(width = 6, offset = 0,
div(style = "height:50px;width:100%;background-color: #999999;border-style: solid;border-color: #000000",
selectInput(inputId = "points",label = "Number of Points:",
choices = c("30","60","90"),
selected = "10",
multiple = FALSE) )
)
),
br(),
br(),
fluidRow(
actionButton(inputId = "go",
label = "Update"
)
),
fluidRow(
plotOutput("plot", width = "100%")
)
)
)
)
server <- function(input, output,session) {
data = eventReactive(input$go, {
var1 = rnorm(isolate(as.numeric(input$points)),5)
cat1 = c(rep("red",length(var1)/3),rep("blue",length(var1)/3),rep("green",length(var1)/3))
data = cbind.data.frame(var1,cat1)
plotdata = data[which(data$cat1 ==isolate(input$color)),]
}
)
output$plot = renderPlot({
plotdata = data()
plotcol = isolate(input$color)
plot(plotdata$var1, col = plotcol)
})
}
shinyApp(ui = ui,server = server)
The white space is the padding of the column div. To remove that, use
column(width = 6, offset = 0, style='padding:0px;', ...)