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.
Related
I am interested in removing or hiding the side arrows that appear when you use numericInput() with shiny. I will attach an image of the arrows that I am referring to so everyone can understand which part I would like to remove/hide. After reading the documentation, it does not appear that there is an option to remove these arrows. So I am wondering if there is a way to use CSS to remove these arrows. I did see one other post that asked a similar question. However, I am only interested in using numericInput().
I will attach some sample code. The code essentially does nothing but it will give you a reproducible example.
library(shiny)
server <- function(input, output){
}
ui <- fluidPage(
titlePanel("Test1"),
sidebarLayout(
sidebarPanel(
numericInput("n",
label = h4("Test2"),
min=1,
value = 20),
numericInput("x",
label = h4("Test3"),
min=0,
value = 10),
h4(textOutput("pvalue"))
),
mainPanel(
plotOutput("nullplot")
)
)
)
shinyApp(ui = ui, server = server)
runApp()
WARNING: I have read online that the side arrows do not show up on all web browsers and some versions of RStudio. See here
It does not appear that there is a way to remove the arrows from a numericInput(), however, there is a way to hide them. Just to be clear there is a difference between removing and hiding. Removing the arrows, in theory, should completely remove the code for the arrows. Hiding the arrows will simply mask the code for the side arrows, however, the code will still be present but will not be seen by the user unless they inspect the page.
Below is CSS that can be used to hide the side arrows from numericInput().
tags$head(
tags$style(HTML("
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::{
-moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
"))
)
If you wanted to apply this code to the example given in the question, then you could do something like this
library(shiny)
server <- function(input, output){
}
ui <- fluidPage(
titlePanel("Test1"),
sidebarLayout(
sidebarPanel(
tags$head(
tags$style(HTML("
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::{
-moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
"))
),
numericInput("n",
label = h4("Test2"),
min=1,
value = 20),
numericInput("x",
label = h4("Test3"),
min=0,
value = 10),
h4(textOutput("pvalue"))
),
mainPanel(
plotOutput("nullplot")
)
)
)
shinyApp(ui = ui, server = server)
runApp()
Overall this is just a workaround because there is no option to remove the side arrows.
The Shinyglide package is just what I need, using a carousel for grouped radio buttons giving the user many choices for data parsing.
However, the "Next" (and "Back") button occupies a large white space. I'd like to shift the button in line with the glide row (see image at bottom). Does anyone know how to do this? Is there a CSS trick? Reading through the Glide manual, the only choices are "top" and "bottom".
If moving the Next/Back button isn't possible, a secondary option is to insert (a somewhat superfluous) line of text but in line with the Next/Back buttons, to at least cover up the annoyingly large white space.
The actual panel this is for has much more information presented than in this example, so I'm trying to make the page as clean as possible.
Please see image at bottom that better explains what I'm trying to do.
Reproducible example:
library(dplyr)
library(DT)
library(shiny)
library(shinyglide)
ui <-
fluidPage(
fluidRow(div(style = "margin-top:15px"),
strong("Input choices shown in row below, click ´Next´ to see more choices:"),
column(12, glide(
height = "25",
controls_position = "top",
screen(
div(style = "margin-top:10px"),
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(
div(style = "margin-top:10px"),
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")
)
server <- function(input, output, session) {
output$plants <- renderDT({iris %>% datatable(rownames = FALSE)})
}
shinyApp(ui, server)
You could use a custom control element with custom_controls, and then have it hover over the displayed screen on the top right with a container set to absolute positioning. Setting a limited width for the container will ensure that the back button won't fly too far out.
Something along these lines:
glide(custom_controls = div(class = "glide-controls", glideControls()), ...)
# Somewhere in the UI
tags$style(
".glide-controls { position: absolute; top: 18px; right: 15px; width: 160px; }"
)
Just make sure to also set controls_position = "bottom" so that the controls hover over the screen content, rather than under it.
A minimal example app:
library(shiny)
library(shinyglide)
ui <- fixedPage(
h3("Simple shinyglide app"),
tags$style(
".glide-controls { position: absolute; top: 18px; right: 15px; width: 160px; }"
),
glide(
custom_controls = div(class = "glide-controls", glideControls()),
screen(wellPanel(p("First screen."))),
screen(wellPanel(p("Second screen.")))
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
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")
)
...
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) {
}
)
I am facing some trouble including particles.js output (API provided by shinyparticles in shinydashboard. I am working with R.
Following is an example that works for shiny
library(shiny)
library(shinyparticles)
ui <- fluidPage(
particles(),
headerPanel("This is a sample app")
)
server <- function(input, output, session){}
shinyApp(ui, server)
And here is one for shinydashboard that does not seem to work
library(shinydashboard)
library(shinyparticles)
shinyApp(
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(tags$body(div(particles()))),
title = "Dashboard example",
skin = "black"
),
server = function(input, output) { }
)
The resulting HTMLs seem identical when I view the page source, but the viz for particles does not appear.
The particles don't appear because they are below the dashboardBody (by default: z-index: -10).
If you set the z-index of the particles to 1 they will be visible, however any element you add to the body will be under the particles.
So set elements z-index to a higher number. (in this example I only use boxes)
Code:
dashboardBody(
tags$head(tags$style("
.particles-full {
z-index: 1;
}
.box {
z-index: 2;
}
")),
particles(),
box(
h2("Header"),
p("Paragraph")
),
box(
plotOutput("plot")
)
)
Output: