Resize Shiny renderImage for mobile - css

I have a Shiny App on my own Shiny Server that displays png images on a web page. This works fine. However, the images are too wide when the page is viewed on an iPhone. In my case, the correct size for the png image on a large screen is 600w x 400h and for an iPhone 330w x 220h works well. How do I auto-resize the image?
R Script
library("shiny")
library("tidyverse")
ui <- fluidPage(
imageOutput("img")
)
server <- function(input, output, session) {
output$img <- renderImage({
path_to_png <- "/var/www/..."
list(src = path_to_png,
width = "600",
height = "400",
alt = "Chart of good stuff")
}, deleteFile = FALSE)
}
shinyApp(ui, server)

You can either use relative units and/or add breakpoints in custom CSS. It looks like imageOutput puts a div around the image so you could do:
ui <- fluidPage(
imageOutput("img", width = "40vw", height = "30vh")
)
server <- function(input, output, session) {
output$img <- renderImage({
path_to_png <- "/var/www/..."
list(src = path_to_png,
width = "100%",
height = "100%",
alt = "Chart of good stuff")
}, deleteFile = FALSE)
}
OR using CSS + breakpoints, something like:
ui <- fluidPage(
tags$head(
tags$style(
"#media only screen and (max-width: 600px) {
#img {
width: 330px !important;
height: 220px !important;
}
}"
)
),
imageOutput("img")
)
...

Related

Set R shiny modal width when theme is defined by bslib

How can I set the modal width to 80% when bs_theme() is active? Is there a possibility within bs_theme()? I just can't get it right with the tags.
library(shiny)
library(bslib)
ui <- fluidPage(
shiny::bootstrapLib(),
theme = bs_theme(
version = 4,
bootswatch = "minty"),
tags$style(".modal-dialog{width: 80% !important;}"),
actionButton("open_modal", "open modal"),
)
server <- function(input, output) {
observeEvent(input$open_modal, {
showModal(
modalDialog(
title = "This modal isn't 80% wide")
)
})
}
shinyApp(ui = ui, server = server)
Use tags$style(".modal-dialog {max-width: 80vw;}") instead. It makes sure your modal is always 80% of the entire window, resize automatically when you change window size.

Easiest way to set different background images to shiny panels

I would like to know what was the easiest way to set up a different image to each of my 3 shiny main tabpanels ?
I thought that using setBackgroundImage(src = "image1.jpg", shinydashboard = TRUE), setBackgroundImage(src = "image2.jpg", shinydashboard = TRUE), etc. in each of them would do the trick but unfortunately it is not that simple.
I guess I shall use some CSS but I'm very new to this and I didn't find a solution to my problem yet.
Any guess about how I should do that ?
Minimal app:
library(shiny)
library(shinyWidgets)
ui <- shinyUI(navbarPage(id="Test", "TEST",
header = tagList(
useShinydashboard()
),
tabPanel(
"Welcome", value="welcome",
verbatimTextOutput("text1")),
tabPanel(
"Tab1", value="first_tab",
verbatimTextOutput("text2")),
tabPanel(
"Tab2", value="second_tab",
verbatimTextOutput("text3"))))
server <- shinyServer(function(input, output, session){
output$text1 <- renderText("Trying to set up a first background image in this whole panel")
output$text2 <- renderText("Trying to set up a second background image in this whole panel")
output$text3 <- renderText("Trying to set up a third background image in this whole panel")
})
shinyApp(ui, server)
You can use the CSS background-image Property to achive this:
library(shiny)
library(shinyWidgets)
# remove /* ... */ to use the arguments
backgroundImageCSS <- "/* background-color: #cccccc; */
height: 91vh;
background-position: center;
background-repeat: no-repeat;
/* background-size: cover; */
background-image: url('%s');
"
ui <- shinyUI(navbarPage(id="Test", "TEST",
header = tagList(
useShinydashboard()
),
tabPanel(
"Welcome", value="welcome",
verbatimTextOutput("text1"),
style = sprintf(backgroundImageCSS, "https://images.plot.ly/language-icons/api-home/r-logo.png")
),
tabPanel(
"Tab1", value="first_tab",
verbatimTextOutput("text2"),
style = sprintf(backgroundImageCSS, "https://images.plot.ly/language-icons/api-home/matlab-logo.png")
),
tabPanel(
"Tab2", value="second_tab",
verbatimTextOutput("text3"),
style = sprintf(backgroundImageCSS, "https://images.plot.ly/language-icons/api-home/python-logo.png")
)
))
server <- shinyServer(function(input, output, session){
output$text1 <- renderText("Trying to set up a first background image in this whole panel")
output$text2 <- renderText("Trying to set up a second background image in this whole panel")
output$text3 <- renderText("Trying to set up a third background image in this whole panel")
})
shinyApp(ui, server)
When using local images store them into a www folder (subdirectory of your app folder) or use addResourcePath to add the images as static resources to Shiny's web server,
Also see this related answer.

How to change the styling of a specific Shiny widget

I want to style a shiny input from dqshiny package in my Shiny app as below -
library(shiny)
library(dqshiny)
opts <- sapply(1:100000, function(i) paste0(sample(letters, 9), collapse=""))
shinyApp(
ui = fluidPage(
autocomplete_input("auto1", "Unnamed:", opts, max_options = 1000)
),
server = function(input, output, session) {
}
)
I want to 2 things to achieve -
Want to change the highlight color in the suggestion field from yellowish to green
Also want to change the distance between the input field and the suggestion container with let say 10px.
I have a few other Widgets in my App, so above modified styling should not impact other widgets.
Is there any way to achieve this?
Any pointer will be highly appreciated.
Easiest way is just adding the CSS directly into the header. There's a really useful article about styling Shiny apps here.
library(shiny)
library(dqshiny)
opts <- sapply(1:100000, function(i) paste0(sample(letters, 9), collapse=""))
shinyApp(
ui = fluidPage(
tags$head(
tags$style(
HTML(
'
.autocomplete-items div:hover {
background-color: green;
}
#auto1autocomplete-list {
margin-top: 10px;
}
'
)
)
),
autocomplete_input("auto1", "Unnamed:", opts, max_options = 1000)
),
server = function(input, output, session) {
}
)

Datatable column auto resizing

I have a shiny app with two datatables side by side. Are there any options to automatically resize the table or column when the width of the window is changed?
Ideally I'd like to see all columns (maybe reduced font size) with no X scroll bar in both tables, and the tables side by side. The code below makes the tables overlap as the window size reduces.
library(shiny)
library(DT)
shinyApp(
ui = fluidPage(
fluidRow(
column(5,
dataTableOutput('table.1')
),
column(2
),
column(5,
dataTableOutput('table.2')
)
)
),
server = function(input, output) {
output$table.1 <- renderDataTable(iris,options = list(autoWidth = TRUE))
output$table.2 <- renderDataTable(iris,options = list(autoWidth = TRUE))
}
)
As mentioned in the comments CSS can handle this for you using viewport based text sizes. I took the liberty of also including the syntax for specifying a maximum text size in case users have exceptionally wide screens:
library("shiny")
library("DT")
shinyApp(
fluidPage(
tags$head(
tags$style(
HTML("
.datatables {
font-size: 1.5vw;
}
#media screen and (min-width: 1024px) {
.datatables {
font-size: 12px;
}
}
")
)
),
dataTableOutput("iris")),
function(input, output) {
output$iris = renderDataTable({
datatable(iris)
})
}
)
This answer has more on viewport percentage lengths and this answer provides the example for the max size.

How can I make the width of an image in a Shiny app dynamic?

I am writing an app and I want the image in the sidebarPanel to be just a bit bigger than the image I put inside it. As the window gets smaller or larger, so does the sidebar, but the image stays static. How do I fix this problem? Is there a way to get the sidebar length or is there a better way to render images?
ui.R
library(shiny)
shinyUI(bootstrapPage(
# Application title
titlePanel("Sidebar Image App"),
sidebarPanel(
imageOutput("image", height = "auto")
)
))
server.R
library(shiny)
shinyServer(function(input, output, session) {
output$image <- renderImage({
return(list(
src = "one.png",
contentType = "image/png",
height = 185,
alt = "Face"
))
})
})
You can style the image using css tag as below:
shinyUI(bootstrapPage(
titlePanel("Sidebar Image App"),
tags$head(tags$style(
type="text/css",
"#image img {max-width: 100%; width: 100%; height: auto}"
)),
sidebarPanel(
imageOutput("image")
)
)),
where css id selector (here #image) should correspond to the outputId of the imageOutput.

Resources