Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Height of the box in R Shiny

Tags:

r

shiny

I would like the box containing my map to have a 100% height so that it fits all screens. For the moment the box does not reach the bottom and does not adapt when I reduce the window

dashboardBody(
      tabItems(
        #--------- ELEMENTS TAB "carte" --------#
        tabItem(tabName ="carte",
                fluidRow(
                  box(
                    width = 3,
                    title = "Settings",
                    status = "primary",
                    solidHeader = TRUE,
                    collapsible = TRUE,
                    useShinyalert(),br(),
                    fileInput(inputId = "zip", label = "Upload your file (.zip) :", multiple = FALSE, accept = c('.zip')), 
                    checkboxGroupInput(inputId ="indice", label ="Choose a spectral index (multiple choice possible) :", choices = c("NDVI", "NDWIGAO", "NDWIMCF", "MNDWI")),br(),
                    dateRangeInput(inputId ="dates", label = "Select the date range :", start = "", end = ""), br(),
                    textInput(inputId = "mail", label = "Enter your email address :"), br(),br(),
                    useShinyjs(),
                    extendShinyjs(text = jsResetCode),
                    div(style = "display:inline-block", actionButton("reset_button", "Refresh", icon("refresh", lib ="glyphicon"))),
                    div(style = "display:inline-block", actionButton("send", "Send now !", icon("send", lib = "glyphicon"), style = "background-color : #000000 ; color : #fff ; border-color : #717878"))                 
                  ),

                  box(
                    width = 9,
                    title = "Map",
                    status = "primary",
                    solidHeader = TRUE,
                    collapsible = FALSE,
                    height = "100%",
                    leafletOutput(outputId = "map", width="100%", height = 940)
                  )
                )
        ),

enter image description here

like image 441
Grits Avatar asked Feb 03 '23 18:02

Grits


1 Answers

Unfortunately height: 100% will not work with box in shinydashboard. It is only possible via JavaScript according to this Github Issue, because the layout sizes are initiated via JavaScript.

Solution

Calculate the actual window height

This consists of two parts:

  • Calculating and setting the height initially (calculating the exact number of pixels that height: 100% would give.)
  • Modifying it any time the user resizes the browser window.

The code sets the height of the box to window height - header height - 30px (top and bottom margins).

e.g: If the window height is 960px, the dashboardHeader is 50px, then the height of the output element will be 960 - 50 - 30 = 880px.

tags$head(tags$script('
// Define function to set height of "map" and "map_container"
setHeight = function() {
  var window_height = $(window).height();
  var header_height = $(".main-header").height();

  var boxHeight = window_height - header_height - 30;

  $("#map_container").height(boxHeight);
  $("#map").height(boxHeight - 20);
};

// Set input$box_height when the connection is established
$(document).on("shiny:connected", function(event) {
  setHeight();
});

 // Refresh the box height on every window resize event    
$(window).on("resize", function(){
  setHeight();
});

Modify the UI

On the UI side, give an id or class to the box, so you can set it with the JS code. i.e: I set the id of the box to "map_container".

box(id = "map_container",
  leafletOutput("map")
)

Full code

Using the basic shinydashboard example

library(shiny)
library(shinydashboard)
library(leaflet)

ui <- dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(),
  dashboardBody(
    tags$head(tags$script('
      // Define function to set height of "map" and "map_container"
      setHeight = function() {
        var window_height = $(window).height();
        var header_height = $(".main-header").height();

        var boxHeight = window_height - header_height - 30;

        $("#map_container").height(boxHeight);
        $("#map").height(boxHeight - 20);
      };

      // Set input$box_height when the connection is established
      $(document).on("shiny:connected", function(event) {
        setHeight();
      });

      // Refresh the box height on every window resize event    
      $(window).on("resize", function(){
        setHeight();
      });
    ')),
    # Boxes need to be put in a row (or column)
    fluidRow(
      box(id = "map_container",
        leafletOutput("map")
      ),

      box(
        title = "Controls",
        sliderInput("slider", "Number of observations:", 1, 100, 50)
      )
    )
  )
)

server <- function(input, output) {
  set.seed(122)
  histdata <- rnorm(500)

  output$map <- renderLeaflet( {
    leaflet() %>%
      addProviderTiles(providers$Stamen.TonerLite,
                       options = providerTileOptions(noWrap = TRUE)
      ) %>%
      addMarkers(data = cbind(rnorm(40) * 2 + 13, rnorm(40) + 48))
  })
}

shinyApp(ui, server)
like image 63
GyD Avatar answered Feb 06 '23 06:02

GyD