I'm trying to create a tabBox that spans the entire mainPanel. I'm able to get the width to span the entire screen but I'm unable to get the height to do the same. I do not wish to use absolute values in pixels (or some other unit) since I expect the app to be used across different screens.
I played with the example and an example of the modified tabBox is as below
fluidRow(
tabBox(
title = "First tabBox",
# The id lets us use input$tabset1 on the server to find the current tab
id = "tabset1", height = "450px",
tabPanel("Tab1", "First tab content"),
tabPanel("Tab2", "Tab content 2"),
width = 12
),
height = '20%',
width = 12
)
You can use the vh css unit that is defined as 1% of viewport height and then basically follow the example in this answer where you set the relative height in the css:
fluidRow(
tabBox(
tags$head(
tags$style(HTML(" #tabBox { height:90vh !important; } "))
),
id="tabBox",
title = "tabBox",
width = 12
)
You can of course also put this in an external css file, especially if you are going to do more than one of these css tricks. With 100% goes slightly over the bottom edge because of the header. Around 90% seems to work fine.
Related
Is there a way to show scrollbars for the content in tabBoxes if I want to fix the height? Additionally, the scrollbar should only work for the content not the tab header itself. The closest I came to a solution was to fix the height of the .tab-content but this obviously highly depends on the height of the tabBox and the height of the tab header within. Resizing the window might cause the tab header to increase in size which causes this workaround to fail. Also, this would fix the height of all .tab-content elements, so if I wanted to create new tabBoxes with different heights, this also would not work.
This is a minimal example of my attempt to solve the problem. If you resize the window such that the second tab does not fit in the first row, the scrollbar and content do not work properly anymore.
if (interactive()) {
library(shiny)
body <- dashboardBody(
tags$head(tags$style(HTML(".nav-tabs-custom { overflow-y: hidden; } .nav-tabs-custom>.tab-content { overflow-y: auto; height: 100px; }"))),
fluidRow(
tabBox(
height = "150px",
tabPanel(
title = "Tab Header 1 - Scrollbar failing when resizing",
p("Test 1"),
p("Test 2"),
p("Test 3"),
p("Test 4"),
p("Test 5")
),
tabPanel(
title = "Tab Header 2 - looooooooooooooooong",
p("Test 1"),
p("Test 2")
)
)
)
)
shinyApp(
ui = dashboardPage(dashboardHeader(disable = TRUE), dashboardSidebar(disable = TRUE), body),
server = function(input, output) {
}
)
}
Any help would be greatly appreciated.
The key is to add the css style overflow-y:scroll; to the div you need a scroll bar on. In this case, I have added it to a div within the first tabPanel by using:
div(style = 'overflow-y:scroll;', ...)
This requires that you wrap the objects that you want to scroll inside of a div().
I've edited your original example to show how to add scrolling to a large data table. also set the height to 500px manually in the same div so that you could see the scroll bar in action.
if (interactive()) {
library(shiny)
body <- dashboardBody(
fluidRow(
tabBox(
tabPanel(
title = "Tab Header 1 - Scrollbar failing when resizing",
div(style = 'overflow-y:scroll;height:500px;',
tableOutput('largedata')
)
),
tabPanel(
title = "Tab Header 2 - looooooooooooooooong",
p("Test 1"),
p("Test 2")
)
)
)
)
shinyApp(
ui = dashboardPage(dashboardHeader(disable = TRUE), dashboardSidebar(disable = TRUE), body),
server = function(input, output) {
output$largedata <- renderTable(mtcars)
}
)
}
I was wondering if it's possible to set a leaflet output's height to "100%" relative to it's parent container in Shiny/R. I've seen some solutions which set the height relative to an entire body output but for my purpose, my map appears in a small tab panel, as seen here.
I've tried creating a surrounding div with modified CSS and simply changing the output's height variable to 100% with no prevail. I was wondering if anyone has a solution which is responsive to changes of the parent container.
From my understanding, the issue is that the column container created by Shiny doesn't have defined dimension. Below is the related code segements and to look at the issue first hand you can go to my shiny app.
UI
fluidRow(
br(),
tabsetPanel(
tabPanel("Drink Information",
column(2,
withSpinner(htmlOutput("beerImage"))
),
column(5,align = "center",
strong(h4("Name")),
textOutput('beerName'),
strong(h4("Primary Category")),
textOutput('beerPrimaryCategory'),
strong(h4("Secondary Category")),
textOutput('beerSecondaryCategory')
),column(5, align = "center",
strong(h4("Varietal")),
textOutput('beervarietal'),
strong(h4("Tertiary Category")),
textOutput('beerTertiaryCategory'),
strong(h4("Style")),
textOutput('beerStyle')
)
),
tabPanel("Drink Location",
column(9,
br(),
#This is the output I would like to use 100% of the row
withSpinner(leafletOutput("lcboLocations"))
),
column(3,h6("temp"))
)
)
)
I'm using a side-by-side layout to display multiple plots on the same row. However it looks bad on mobile. How can I keep the side by side layout on desktop, but 1 plot per row on mobile?
fluidRow(
splitLayout(cellWidths = c('49%', '49%'),
plotlyOutput('pWaterLvl'),
plotlyOutput('pHumidity')
)
),
fluidRow(
splitLayout(cellWidths = c('49%', '49%'),
plotlyOutput('pWaterTemp'),
plotlyOutput('pAirTemp')
)
)
I think you can let bootstrap grid system handle it.
fluidRow(
column(6, plotlyOutput('pWaterLvl')),
column(6, plotlyOutput('pHumidity'))
)
If you need to control the grid sizes on multiple devices, you can use a combination of the width and class settings (width controls 'col-sm' by default).
This example puts the plots on top of each other on small screens, next to each other on medium screens, and makes the second plot slightly wider on large screens.
fluidRow(
column(12, class = "col-md-6 col-lg-5", plotlyOutput('pWaterLvl')),
column(12, class = "col-md-6 col-lg-7", plotlyOutput('pHumidity'))
)
The structure of the page below contains
dashboardBody(
wellPanel(
fluidRow(
box(width = 6,
DT::dataTableOutput("topLineTable"),
uiOutput("promoOverlapUI")
),
box(width = 6,
selectInput("selectGraph2", label=NULL, choices=NULL),
uiOutput("baselineGraphUI2")
)
),
#other stuff...
)
I'd like to make it so the shorter element expands to fill the fluidRow. I tried height=100% without success. The element that won't expand is box(), (col-sm-6 is generated by box())
I'd like to avoid absolute pixel sizing.
You could use display:flex; on the row and col-sm-6 classes,.
You could add:
tags$style(HTML("div.row,div.col-sm-6 {display:flex;}"))
to your dashboardbody for example.
I have a very basic Shiny app.
ui.R:
library(shiny)
shinyUI(fluidPage(
titlePanel("Average Run Length Simulation"),
fluidRow(
tabsetPanel(
tabPanel("Shewhart v. Shewhart",
fluidRow(
column(4,"Rule"),
column(2,"Group 1"),
column(2,"Group 2")
),
fluidRow(
column(4,"1 point more than k sigma away from mean"),
column(2,
checkboxInput("svsg1r1",label=" ",value=F),
numericInput("svsg1k1",label=" ",value=3,min=1,step=1)
),
column(2,
checkboxInput("svsg2r1",label=" ",value=F),
numericInput("svsg2k1",label=" ",value=3,min=1,step=1)
)
)
)
)
)
))
The server.r file is the basic one created by Rstudio in a new project.
What I really want is a tabular layout of widget elements, but, I don't think I'll get that without a lot of work and this isn't worth it. So, instead, I want to reduce the width of the numericInput() boxes akin the the size attribute of an <input> element in an HTML form.
How would I do this in shiny? Is there a standard way to apply css/html specifics to particular elements?
This works, though it's global css and I'd rather have element specific. I added this inside the fluidPage() element in ui.r and it resized both boxes.
tags$head(
tags$style(HTML("
input[type=\"number\"] {
width: 100px;
}
"))
)
For a numericInput box specific resizing, you can use the CSS id selector. In the example above, the following should work to just resize the first box.
tags$head(
tags$style(HTML("
#svsg1k1 {
width: 100px;
}
")))