在 Shiny 中渲染传单或绘图时删除不需要的白色 space

Remove unwanted white space when rendering leaflet or plot in Shiny

我希望我的 Shiny 应用程序的用户能够通过单击“事件”面板中的单选按钮在两种类型的绘图之间进行选择。我编写的代码有效,但是从“地图”到“绘图”时,页面留下了巨大的白色 space。有没有办法去掉白色的 space 并将情节放在最上面?

# Load R packages
library(shiny)
library(shinythemes)
library(tidyverse)
library(leaflet)

set.seed(123)

year <- 2001:2020
event <- sample(1:100, size = 20, replace = TRUE)

dat <- as.data.frame(cbind(year, event))


# Define UI
ui <- fluidPage(
  shinyjs::useShinyjs(),
  theme = shinytheme("journal"),
                navbarPage(
                  "Title",
                  tabPanel("About",
                  ),
                  tabPanel("Events", 
                           fluidPage(
                             titlePanel("Title"),
                             sliderInput("range", label = "Move slider to select time period", min(2001), max(2020),
                                         value = range(2001:2002), step = 1,  sep = "", width = "65%"),
                             sidebarLayout(
                               sidebarPanel(
                                 radioButtons("plotType", "Plot type", choices = c("Map" = "m", "Chart" = "l"))),
                               mainPanel(
                                 leafletOutput("map"),
                                 plotOutput("plot"))
                             )
                    )
            )
      )
)


# Define server function  
server <- function(input, output, session) {
  
  observeEvent(input$plotType, {
    if(input$plotType == "l"){
      shinyjs::disable("range")
    }else{
      shinyjs::enable("range")
    }
  })
  
  
  output$plot <- renderPlot({
    if (input$plotType == "l") {
  
        ggplot(dat, aes(year, event)) +
        geom_line() +
        labs(x = "Year", y = "Events") +
        theme_bw()
    }
  })  
  
  output$map <- renderLeaflet({
    if ( input$plotType == "m") {
      
      leaflet(dat) %>% addTiles() %>%
        fitBounds(~min(11), ~min(54), ~max(67), ~max(24))
    }
  })

  
} # server


# Create Shiny object
shinyApp(ui = ui, server = server)

有一个很大的 space 因为地图 html 对象仍然存在,但是是空的。为避免这种情况,我创建并观察了根据输入值隐藏或显示地图输出的 observeEvent。我对情节做了同样的事情,因为你需要在它下面添加其他元素。

请注意,还有其他解决方案(例如 conditionalPanel),我只提供我认为最简单的解决方案。

# Load R packages
library(shiny)
library(shinythemes)
library(tidyverse)
library(leaflet)

set.seed(123)

year <- 2001:2020
event <- sample(1:100, size = 20, replace = TRUE)

dat <- as.data.frame(cbind(year, event))


# Define UI
ui <- fluidPage(
  shinyjs::useShinyjs(),
  theme = shinytheme("journal"),
  navbarPage(
    "Title",
    tabPanel("About",
    ),
    tabPanel("Events", 
             fluidPage(
               titlePanel("Title"),
               sliderInput("range", label = "Move slider to select time period", min(2001), max(2020),
                           value = range(2001:2002), step = 1,  sep = "", width = "65%"),
               sidebarLayout(
                 sidebarPanel(
                   radioButtons("plotType", "Plot type", choices = c("Map" = "m", "Chart" = "l"))),
                 mainPanel(
                   leafletOutput("map"),
                   plotOutput("plot"))
               )
             )
    )
  )
)


# Define server function  
server <- function(input, output, session) {
        
  # hide or show map and plot
  observeEvent(input$plotType, {
    if(input$plotType == "l"){
      shinyjs::disable("range")
      shinyjs::hide("map") 
      shinyjs::show("plot")
    } 
    if(input$plotType == "m"){
      shinyjs::enable("range")
      shinyjs::show("map")
      shinyjs::hide("plot")
    } 
  })
  
  output$plot <- renderPlot({
    req(input$plotType == "l") # good practice to use req instead of if
    ggplot(dat, aes(year, event)) +
      geom_line() +
      labs(x = "Year", y = "Events") +
      theme_bw()
  })  
  
  output$map <- renderLeaflet({
    req(input$plotType == "m")
    leaflet(dat) %>% addTiles() %>%
      fitBounds(~min(11), ~min(54), ~max(67), ~max(24))
  })
  
  
} # server


# Create Shiny object
shinyApp(ui = ui, server = server)