Change height of an image in material_parallax - css

The shinymaterial package includes a function called material_parallax() which allows for a pretty parallax effect on images while scrolling. The only parameter of the function is image_source. I'd like to change the height of this parallax box in my app.
Is it possible (using custom css or otherwise) to change the height of material_parallax() so it takes up less vertical space?
Example:
library(shiny)
library(shinymaterial)
ui <- material_page(include_nav_bar = FALSE,
#I'd like this parallax to be shorter
material_parallax(
image_source = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Freudenberg_sg_Switzerland.jpg/1920px-Freudenberg_sg_Switzerland.jpg"),
material_card(
h1("This is just to add vertical space",
plotOutput("plot"))
)
)
server <- function(input,output){
output$plot <- renderPlot(height = 1000,
pairs(iris))
}
shinyApp(ui,server)

You can use this css:
ui <- material_page(
tags$head(tags$style(type="text/css",
".parallax-container{height:150px} .parallax img{height:50%}")),
include_nav_bar = FALSE,
#I'd like this parallax to be shorter
material_parallax(
image_source = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Freudenberg_sg_Switzerland.jpg/1920px-Freudenberg_sg_Switzerland.jpg"),
material_card(
h1("This is just to add vertical space",
plotOutput("plot"))
)
)

Related

How to fine-tune the positioning of objects rendered in r shiny?

I'm trying to adjust the positioning of conditionally-rendered objects in R shiny. When running the below skeleton code and clicking the "Delete" action button, I'd like to nudge the conditionally-rendered text ("Select series to delete >>") a bit to the right, and move the little selectInput() box that also conditionally appears on the far right a bit to the left, closer to "Select series to delete >>". I've fiddled with column widths, etc., and I've exhausted all the formatting options which I know of which are limited. Any suggestions for fine-tuning the positioning of these items? My guess is this would entail some CSS which I know almost nothing about.
Skeleton code:
library(dplyr)
library(shiny)
library(shinyjs)
toggleView <- function(input, output_name){
observeEvent(input$delSeries, {show(output_name)})
observeEvent(input$addSeries, {hide(output_name)})
}
ui <- fluidPage(br(),
useShinyjs(),
fluidRow(
column(1,actionButton("addSeries", "Add",width = '70px')),
column(1,actionButton("delSeries","Delete",width = '70px')),
column(3,h5((hidden((textOutput("delFlag")))))),
column(3,hidden(uiOutput("delSeries2")))
)
)
server <- function(input, output, session) {
output$delFlag <- renderText("Select series to delete >>")
output$delSeries2 <-
renderUI(
selectInput("delSeries3",
label = NULL,
choices = c(""),
selected = "",
width = '110px')
)
toggleView(input,"delSeries2")
toggleView(input,"delFlag")
}
shinyApp(ui,server)
You can add some styles to the 2 columns like so:
library(dplyr)
library(shiny)
library(shinyjs)
toggleView <- function(input, output_name){
observeEvent(input$delSeries, {hide(output_name)})
observeEvent(input$addSeries, {show(output_name)})
}
# (0)
css <- HTML("
.row .nudge-right {
padding-right:0;
}
.row .nudge-left {
padding-left:0;
}
")
ui <- fluidPage(
tags$head(tags$style(css)), # (1)
br(),
useShinyjs(),
fluidRow(
column(1,actionButton("addSeries", "Add",width = '70px')),
column(1,actionButton("delSeries","Delete",width = '70px')),
column(3,h5(hidden(textOutput("delFlag"))),
class = c("nudge-right", "text-right")), # (2)
column(3,hidden(uiOutput("delSeries2")), class = "nudge-left") # (2)
)
)
Explanation
The white space you see is partly due to the width of the column and partly due to the so called padding (an additional white space around the element). To bridge this gap you can:
Right align the text. Here you can rely on the already pre-defined (by the underlying bootstrap framework) class text-right.
Further decrease the gap by removing the right padding from the text column and the left padding from the input column. In order to so, you define new classes (I called them .nudge-right and .nudge-left respectively) where you deliberately set the padding to your liking (here I removed it completely, you may want to provide a small offset though - e.g. 5px).
Then all which is left is to
Create some css with the class definitions (#0)
Load the css (#1)
Assign the classes to the columns (#2)

Position tippy tooltip next to button in R Shiny

I would like to add a tooltip to a button using tippy 1.0.0.
The tooltip always appears in the middle of the screen and not close to the text as expected.
I tried to specifiy the position arguments, but had no success. I was able to position the tooltips correctly in tippy version 0.1.0.
How can I position the tooltip close to the text?
library(shiny)
library(tippy)
shinyApp(
ui = fluidPage(
tippy(
element = p("Test"),
content = "Tooltip"
)
),
server = function(input, output) {}
)
Result:
This is because your tags are displayed as block in CSS. Even though the element only shows a small portion of the total width, but it is still occupying the full width of the parent node by default. This is how CSS display works. tippy works on the whole occupied width, not what you see with your eyes. Use your p tag for example to inspect:
See the blue shade that takes the entire row? tippy is displayed at the center of the shade.
We can change the display to another to force the tooltip to be positioned around p, like inline-block:
library(shiny)
library(tippy)
shinyApp(
ui = fluidPage(
tippy(
element = p(
"Test",
style = "display: inline-block"
),
content = "Tooltip"
)
),
server = function(input, output) {}
)
When you inspect, the size is what we want.
However (there is always a however), this may mess up your UI display. e.g., we want a button in the second line, but here is what you will see
library(shiny)
library(tippy)
shinyApp(
ui = fluidPage(
tippy(
element = p(
"Test",
style = "display: inline-block"
),
content = "Tooltip"
),
tags$button("Test2")
),
server = function(input, output) {}
)
To fix, you can add a wrapper outside your tooltip tag with block display,
shinyApp(
ui = fluidPage(
div(style = "display: block",
tippy(
element = p(
"Test",
style = "display: inline-block"
),
content = "Tooltip"
)
),
tags$button("Test2")
),
server = function(input, output) {}
)
Or I'd prefer an easier way:
shinyApp(
ui = fluidPage(
p(tippy(element = tags$span("Test" ), content = "Tooltip")),
tags$button("Test2")
),
server = function(input, output) {}
)
Please read more about CSS display: https://www.w3schools.com/cssref/pr_class_display.asp

Resize height of DataTable inside a Box in ShinyDashboard

I'm trying to put some Datatables and Histograms inside boxes of defined height in a Shiny Dashboard, the problem is that when I fix the height (lets say, to 250), the datatable exceeds the limits.
I know we have "autowidth" to use with datatables, but havent seen nothing similar for the Height. I tried to fix the height of the datatable too, but that didn't work for me neither. Also, when I open the shiny in a smaller screen, the box would resize, but the datatable don't.
Here's an example of the problem
library(shiny)
library(shinydashboard)
library(htmltools)
ui <- dashboardPage(skin = "black", title = "Dashboard",
dashboardHeader(title = "Dashboard"),
dashboardSidebar(width = 300),
dashboardBody(
tags$head(tags$style(HTML("
div.box {
text-align: center;
border-style: solid;
border-bottom-color:red;
border-left-color:red;
border-right-color:red;
border-top-color:red;
border-bottom-width:20px;
border-top-width:20px;
border-left-width:20px;
border-right-width:20px;
}
"))),
box(title = "Resume", width = 4, column(12, withSpinner(DT::dataTableOutput("tab"))),
align="center", status = "danger",solidHeader = T,height=250)
))
server <- function(input, output) {
output$tab <- DT::renderDataTable({
datatable(head(iris),options=list("autoWidth"=TRUE, "pagelength"=15,"scrollY"=TRUE,"scrollX"=TRUE,"searching"=FALSE))
})
}
# Run the application
shinyApp(ui = ui, server = server)
Actually ScrollX works perfectly, why scrollY doesnt work aswell?
I read about using tabBox instead of Box, but that doesnt work neither.
Thank you very much in advance.
Try withSpinner(DT::dataTableOutput("tab", height = '240px'), currently your code is setting the height of the box, not the data table.
Also, try style = "overflow-x: scroll;" in the box() arguments for the scrolling

Plot does not resize 100% width after show/hide sidebar in R shiny page

I have a plot which is set to 100% width (default) in the main panel of a two-panel page in R Shiny. The sidebar is hideable through a toggle action button.
When the sidebar is visible (default), the plot fills the width of the main panel. When the sidebar is hidden, I want the plot to expand to fill 100% of the space now available, i.e. the whole browser window. But this does not happen! It keeps the same size.
library(shiny)
library(shinyBS)
UI <- fluidPage(
bsButton("showpanel", "Show/hide sidebar", type = "toggle", value = TRUE),
sidebarLayout(
conditionalPanel(condition = "input.showpanel == true",
sidebarPanel("This is my sidebar.")
),
mainPanel(plotOutput("plot", width = "100%"))
)
)
SERVER <- function(input, output) {
output$plot <- renderPlot({
plot(1:10, main = "The width of this plot adjusts\nto window resizes but not to\nshow/hide sidepanel!")
})
}
runApp(shinyApp(UI,SERVER))
Attempted so far:
Defining the plot object from within the UI file, as above.
Defining the plot object from within the server file, as a renderUI object.
Set CSS tag in the page as per tags$head(tags$style("#myplot{height:100vh !important;}")) from this question, Scaling shiny plots to window height.
Possible work-arounds:
Make the width of the plot dynamic and depending on the state of the toggle button. Then I can make the plot e.g. 140% width when the sidebar is hidden. This does not generalise well, and loses the point of using the adaptability of fluidPage.
(fluidPage changes the layout dependent on the browser window size. For example, if you make your browser window about the size of a mobile phone, it will place the sidebar above the main panel.)
#konvas answer is really good and probably the way you wan't to do this but if you want to use the sidebarLayout (and for the sake of giving another answer) you can use jQuery to toggle the bootstrap columns like:
library(shiny)
ui <- fluidPage(
tags$head(
tags$script(
HTML("
$(document).ready(function(){
// Mark columns we want to toggle
$('body').find('div [class=col-sm-4]').addClass('sidebarPanel');
$('body').find('div [class=col-sm-8]').addClass('mainPanel');
})
Shiny.addCustomMessageHandler ('resize',function (message) {
$('.sidebarPanel').toggle();
$('.mainPanel').toggleClass('col-sm-8 col-sm-12');
$(window).trigger('resize')
});
")
)
),
actionButton("showpanel", "Show/hide sidebar"),
sidebarLayout(
sidebarPanel("This is my sidebar."),
mainPanel(plotOutput("plot", width = "100%"))
)
)
server <- function(input, output, session) {
observeEvent(input$showpanel,{
session$sendCustomMessage(type = 'resize', message = 1)
})
output$plot <- renderPlot({
plot(1:10, main = "The width of this plot adjusts\nto window resizes but not to\nshow/hide sidepanel!")
})
}
runApp(shinyApp(ui,server))
The same methodology would apply if you use columns in a fluidRow or something similar.
One way to do this would be to use a reactive layout (there are many questions on this eg Switch between layouts reactively with shiny). In your case that would be something like
library(shiny)
library(shinyBS)
UI <- shinyUI(
fluidPage(
bsButton("showpanel", "Show/hide sidebar", type = "toggle", value = TRUE),
uiOutput('ui')
)
)
SERVER <- function(input, output) {
output$ui <- renderUI({
if (input$showpanel) {
sidebarLayout(
sidebarPanel("This is my sidebar."),
mainPanel(plotOutput('plot'))
)
} else {
plotOutput('plot')
}
})
output$plot <- renderPlot({
plot(1:10, main = "The width of this plot adjusts\nto window resizes and to\nshow/hide sidepanel!")
})
}
runApp(shinyApp(UI,SERVER))

Scaling shiny plots to window height

I want to scale a shiny plot to the height of the window. This related SO question only uses absolute height specifications in pixels, when a height = 100% would be preferable. I note in the documentation that absolutePanel can achieve this with its top, bottom, left, right arguments, but then you lose the side panel, and in any case the plot (while scaling to width) seems to ignore available height.
I'm guessing this relates to the html quirk that means you need to get the height with javascript innerHeight variable. But I'm unclear how to implement a solution in shiny to get ui.R to utilise this. Grateful for any pointers.
A basic app model for development:
ui.R
library(shiny)
shinyServer(
function(input, output) {
output$myplot <- renderPlot({
hist(rnorm(1000))
})
}
)
server.R
library(shiny)
pageWithSidebar(
headerPanel("window height check"),
sidebarPanel(),
mainPanel(
plotOutput("myplot")
)
)
Use CSS3. Declare your height in viewport units http://caniuse.com/#feat=viewport-units .
You should be able to declare them using the height argument in plotOutput however shiny::validateCssUnit doesnt recognise them so you can instead declare them in a style header:
library(shiny)
runApp(
list(server= function(input, output) {
output$myplot <- renderPlot({
hist(rnorm(1000))
})
}
, ui = pageWithSidebar(
headerPanel("window height check"),
sidebarPanel(
tags$head(tags$style("#myplot{height:100vh !important;}"))
),
mainPanel(
plotOutput("myplot")
)
)
)
)
This wont work in the shiny browser but should work correctly in a main browser.

Resources