I have a shiny dashboard app with a box. The box contains two elements, a slider and a switch. They should be displayed in one row.
When I zoom out, I do not want to get additional whitespace at the end of the row, but rather let the slider take up more space.
It seems like column() is not the right way to layout my app, however I did not find a way to get my elements in one row without column().
How can I get the elements in one row and let the switch take up no more space than it needs?
library(shiny)
library(shinydashboard)
library(shinyWidgets)
ui <- dashboardPage(header = dashboardHeader(),
sidebar = dashboardSidebar(),
body = dashboardBody( column(12, box(width="100%",
column(width=9, sliderInput("hi", label = "I like sliding", min = 1, max =
42, value = 20,width="100%")),
column(width=3,
switchInput("ho", label ="Switch me tonight", width="100%")))))
)
server <- function(input, output) {
}
shinyApp(ui, server)
Play around with the width in the style argument below
library(shiny)
library(shinydashboard)
library(shinyWidgets)
ui <- dashboardPage(header = dashboardHeader(),
sidebar = dashboardSidebar(),
body = dashboardBody(box(width=12,
div(style="display: inline-block; width: 92%;",sliderInput("hi", label = "I like sliding", min = 1, max = 42, value = 20)),
div(style="display: inline-block; width: 7%;",switchInput("ho", label ="Switch me tonight"))
))
)
server <- function(input, output) { }
shinyApp(ui, server)
Related
Is there a way to fix the top section of the dashboard here. Right now, the widgets (selectinput) are fixed, but when the user scroll down, it gets covered by the datatable. Can we not make sure this does not get covered and only datatable moves down?
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
titlePanel(fluidRow(
div(column(12, align="center",
selectInput("rmd1", "RMDw", choices = c(1,2)),
selectInput("rmd2", "RMD2", choices = c(1,2))
), style = "position:fixed; width:inherit;")
)),
br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),
dataTableOutput("uioutput", height = "2000px")
))
server <- function(input, output, session) {
output$uioutput <- renderDataTable({
datatable(iris)
})
}
shinyApp(ui, server)
You can use the CSS z-index property to control the stack order the HTML elements:
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
titlePanel(fluidRow(
div(column(12, align="center",
selectInput("rmd1", "RMDw", choices = c(1,2)),
selectInput("rmd2", "RMD2", choices = c(1,2))
), style = "position:fixed; width:inherit; z-index: 1; background-color: white;")
)),
br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),
dataTableOutput("uioutput", height = "2000px")
))
server <- function(input, output, session) {
output$uioutput <- renderDataTable({
datatable(iris)
})
}
shinyApp(ui, server)
Another approach is using position: sticky;.
Changing the style line to position:absolute makes it so that the selection boxes scroll up and out of the page when you scroll down, if that's what you were looking for.
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
titlePanel(fluidRow(
div(column(12, align="center",
selectInput("rmd1", "RMDw", choices = c(1,2)),
selectInput("rmd2", "RMD2", choices = c(1,2))
), style = "position:absolute; width:inherit;")
)),
br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),
dataTableOutput("uioutput", height = "2000px")
))
server <- function(input, output, session) {
output$uioutput <- renderDataTable({
datatable(iris)
})
}
shinyApp(ui, server)
If you're trying to make the table stay in place and scroll down through the table, use DTOutput() and renderDataTable() instead of dataTableOutput() and renderDataTable(). Then, get rid of datatable() inside renderDT() and just use 'iris'. Finally, you can add the Scroller extension and an options list with scrollY and scroller. Others may be able to explain the difference between DT and DataTable (this page might help as well: https://rstudio.github.io/DT/shiny.html), but I believe DTOutput and renderDT are more flexible. Note: you can add horizontal scrollbars as well with scrollX if you use a table with more fields in the future.
Updated code is below.
Hope either of these helps!
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
titlePanel(fluidRow(
div(column(12, align="center",
selectInput("rmd1", "RMDw", choices = c(1,2)),
selectInput("rmd2", "RMD2", choices = c(1,2))
), style = "position:absolute; width:inherit;")
)),
br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),
DTOutput("uioutput", height = "600px")
))
server <- function(input, output, session) {
output$uioutput <- renderDT({
iris
},
extensions = c('Scroller'),
fillContainer = T,
options = list(deferRender = T,
scrollY = 400,
scroller = T)
)
}
shinyApp(ui, server)
I have put an image as title of my shiny dashboard and I have adjusted its size in order to fit in height and width but there is a small section in the left side which remains empty. How can I make it fit exactly in the box? (The blue part of the attached image remains empty)
# app.R ##
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(DT)
library(shinyWidgets)
library(shinyjs)
dbHeader <- dashboardHeaderPlus(
enable_rightsidebar = TRUE,
rightSidebarIcon = "gears",
fixed = T,
title = tags$a(href='http://mycompanyishere.com',
tags$img(src='logo.png',height = "55px",width="232px"))
)
ui <- dashboardPagePlus(
dbHeader,
dashboardSidebar(),
dashboardBody(
useShinyjs(),
tags$hr(),
tabsetPanel(
id ="tabA",
type = "tabs",
tabPanel("Front",icon = icon("accusoft")),
tabPanel("Data", icon = icon("table")
)
)
),
rightsidebar = rightSidebar()
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
In order to do this, you need to modify dashboard CSS (i.e. padding). One way would be to insert
tags$head(tags$style(".skin-blue .main-header .logo { padding: 0px;}")),
inside dashboardBody()
Then the output looks like this (I don't have your logo but from an image below, you can see that blue part is gone).
For more on how to style apps in Shiny see here: https://shiny.rstudio.com/articles/css.html
I am using sliderTextInput from the shinyWidgets package. I am having trouble making the labels readable.
To begin with, they are too small, which I have fixed using css. However, now the labels overlap so it is hard to read them.
I would like to be able to do one or both of the following:
Angle the text at 45 or 90 degrees so labels don't overlap.
Reduce the number of labels so there is more space between them. I tried doing this in the choices = argument but that then stops those options from being selected. I think this might be to do with this relating to text rather than numbers, so that might make this impossible.
I have tried using sliderInput instead, but that presents different issues. I almost got it working using this answer, but the additional problem is that I have the input server side, fed in as a uiOutput, which is something I can't change because it's important for a different element. This approach doesn't work with the linked solution - I end up with nice enough labels but the breaks are daily rather than monthly.
Here is a pared down example:
Using sliderTextInput (labels overlapping)
library(shinydashboard)
library(shinyWidgets)
library(shiny)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
tags$head(tags$style(type = "text/css", ".irs-grid-text {font-size: 12pt !important;")),
fluidRow(
box(uiOutput("month_selection"))
)
)
)
server <- function(input, output) {
output$month_selection <- renderUI({
sliderTextInput(
inputId = "month_select",
label = "",
grid = TRUE,
force_edges = TRUE,
choices = seq(from = as.Date("2017-01-01"), to = as.Date("2019-12-31"),by = 30)
)
})
}
shinyApp(ui, server)
Using sliderInput (doesn't run)
library(shinydashboard)
library(shinyWidgets)
library(shiny)
monthStart <- function(x) {
x <- as.POSIXlt(x)
x$mday <- 1
as.Date(x)
}
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
tags$head(tags$style(type = "text/css", ".irs-grid-text {font-size: 12pt !important;")),
fluidRow(
box(uiOutput("month_selection"))
)
)
)
server <- function(input, output) {
output$month_selection <- renderUI({
sliderInput(
inputId = "month_select",
label = "",
min = as.Date("2017-01-01"),
max = as.Date("2019-12-31"),
value = as.Date("2019-12-31"),
timeFormat = "%b %Y",
animate = TRUE
)
})
sliderMonth <- reactiveValues()
observe({
sliderMonth$Month <- as.character(monthStart(input$month_select))
})
}
shinyApp(ui, server)
> Warning: Error in as.POSIXlt.default: do not know how to convert 'x' to class “POSIXlt”
Solution (credits go to Victor Perrier) taken from the shinyWidgets issue created by the asker.
Text can be roteted with nothing more than CSS. The class .irs-grid-text identifies the labels of the sliderTextInput widget. With transform the text can be rotated so that it does not overlap.
library(shinydashboard)
library(shinyWidgets)
library(shiny)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
tags$head(tags$style(
type = "text/css",
".irs-grid-text {font-size: 12pt !important; transform: rotate(-90deg) translate(-30px);"
)),
fluidRow(
box(uiOutput("month_selection"), height = "200px")
)
)
)
server <- function(input, output) {
output$month_selection <- renderUI({
sliderTextInput(
inputId = "month_select",
label = "",
grid = TRUE,
force_edges = TRUE,
choices = seq(from = as.Date("2017-01-01"), to = as.Date("2019-12-31"), by = 30)
)
})
}
shinyApp(ui, server)
I have an existing Shiny script with standard widgets from the Shiny library. Now I wish to add something to show temperature on a graphical scale? This would be a read-only value, so it wouldn't make sense to use a slider unless the slider can be locked and only changed programatically. Is that possible? If not, what are other suggestions?
To clarify:
Is it possible to have a Shiny slider as read only. The user can not slide it but it can be programmatically changed. Here is a Shiny slider:
library(shiny)
ui <- fluidPage(
sliderInput("aa", "Temp",
min = -20, max = 20,
value = 10, step = 10)
)
server <- function(input, output) { }
shinyApp(ui, server)
I'm not familiar with Shiny Dashboard but I saw taskItem. Can these be "dropped in" and used with a normal Shiny app that uses fluidPage, sidebarPanel, mainPanel? How does one remove the bullet point and the percentage? Here is an example of a taskItem.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
taskItem(value = temp <- 89, color = "red",
"Temp"
))
)
server <- function(input, output) { }
temp <- 89
shinyApp(ui, server)
AFAIK, sliderInput cannot be used as an output. However here's a potential solution using progressBar from shinyWidgets package
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
h3("Sidebar")
),
mainPanel(
br(), br(), br(),
progressBar("tempbar", value = 0, title = "Temperature", status = "danger")
)
)
)
server <- function(input, output, session) {
temp <- 89
updateProgressBar(session, id = "tempbar", value = temp)
}
shinyApp(ui, server)
shiny app with temperature bar
Replace temp in server with whatever calculated value you might have. For fixed temperature value just set it in ui, no need to use updateProgressBar. By default progressBar is scaled from 0-100. To modify see documentation for it.
You can use updateSliderInput to achieve such an behaviour. Couple this with shinyjs::disabled and you get what you want. I would however look for a less hackish solution:
library(shiny)
library(shinyjs)
ui <- fluidPage(
## add style to remove the opacity effect of disabled elements
tags$head(
tags$style(HTML("
.irs-disabled {
opacity: 1
}")
)
),
useShinyjs(),
disabled(sliderInput("aa", "Temp",
min = -20, max = 20,
value = 10, step = 10)),
actionButton("Change", "Change")
)
server <- function(input, output, session) {
observeEvent(input$Change, {
new_temp <- sample(seq(-20, 20, 10), 1)
updateSliderInput(session, "aa", value = new_temp)
})
}
shinyApp(ui, server)
I have a dataTable within a box() in my R Shiny app.
When I change the size of the page, the size of the dataTable doesn't change to stay within its box. My plot outputs within the same box have no problem adjusting size, but the data table does.
Thoughts on fixing the data table width?
Here's some code using R's mpg data set to demonstrate my UI issue. Play around with size of window to see the sizing issue I'm referring to.
library(shiny)
library(shinydashboard)
library(data.table)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(width = 325),
dashboardBody(
fluidPage(
box( width = 12,
tabsetPanel(
tabPanel("Summary",
dataTableOutput("coeffTable"))
)
)
)))
server <- function(input, output){
data<-mpg
output$coeffTable<-renderDataTable({
data.table(data[,1:2])
},options = list(lengthMenu = c(5, 10, -1), pageLength = 5))
}
shinyApp(ui = ui, server = server)
This works with the DT package. To use like this:
library(DT)
output$coeffTable <- DT::renderDataTable({...
DT::dataTableOutput("coeffTable")