简体   繁体   English

闪亮的传单贴图在切换输入时呈现两次

[英]Shiny Leaflet map renders twice on switching input

I'm trying to produce a Shiny app with Leaflet that renders a choropleth map based on different input criteria. 我正在尝试使用Leaflet生成Shiny应用程序,该应用程序可根据不同的输入条件来渲染一个Choropleth贴图。 The map displays incidents of different types ( input$type ) and backgrounds ( input$background ). 该地图显示不同类型( input$type )和背景( input$background )的事件。 When additional types or backgrounds are specified, polygons are filled with updated incident data. 指定其他类型或背景时,多边形将填充有更新的入射数据。 It is working correctly with one snag. 一键正常工作。 When I switch the date input from date range ( input$dateInput ) to presidential period ( input$president ), the choropleth for presidential period renders once, displaying polygons with no data, and then again with the polygons filled with the correct data for the pre-selected period ("President1"). 当我将日期输入从日期范围( input$dateInput )切换到总统期间( input$president )时,总统期间的choropleth渲染一次,显示没有数据的多边形,然后再次填充具有正确数据的多边形预选时段(“ President1”)。 How do I avoid the map rendering twice like this when the Presidency tab is pressed? 当按下“主席”选项卡时,如何避免两次这样的地图渲染?

Question also listed here on RStudio Community. 问题也列在这里的RStudio社区。

The raw data and shapefile used can be accessed here: https://github.com/cjbarrie/shiny_egy . 可以在这里访问使用的原始数据和shapefile: https : //github.com/cjbarrie/shiny_egy

Working example: 工作示例:

Name of raw data: wikiraw 原始数据名称: wikiraw

Name of shapefile: shapefile shapefile的名称: shapefile

Global: 全球:

library(shiny)
library(shinydashboard)
library(shinythemes)
library(leaflet)
library(rgdal)
library(rmapshaper)
library(sp)
library(dplyr)
library(lubridate)

wikiraw <-read.csv("~/wikisample_SO.csv")
shapefile <- readOGR("~/EGY_adm2.shp")
shapefile<-spTransform(shapefile, CRS("+init=epsg:4326"))
## Simplify shapefile to speed up rendering
shapefile <- ms_simplify(shapefile, keep = 0.01, keep_shapes = TRUE)
wikbounds<-bbox(shapefile)
wikiraw$incident_date <- as.Date(wikiraw$incident_date,
                                 format = "%m/%d/%Y")
wikiraw$presidency <- rep(NA, nrow(wikiraw))
wikiraw$incident_date1 <- as.numeric(wikiraw$incident_date)
wikiraw$event <- rep(1,nrow(wikiraw))
## Generate presidency categorical var.
wikiraw$presidency <- cut(wikiraw$incident_date1, 
                          breaks = c(-Inf, 15016, 15521, 15889, 16229, Inf), 
                          labels = c("President1", "President2", "President3", "President4", "President5"), 
                          right = FALSE)

Snippet of data.frame wikiraw : data.frame wikiraw片段:

  ID_2 incident_date incident_background incident_type presidency event
1  168    2013-11-26            Cultural         Group President4     1
2  133    2013-11-29            Cultural         Group President4     1
3  137    2014-01-25            Cultural         Group President4     1
4  168    2011-01-28            Cultural    Collective President1     1
5  168    2016-04-25            Cultural         Group President5     1
6  163    2015-02-08           Political    Individual President5     1

UI: 用户界面:

ui <- dashboardPage(
                    dashboardHeader(title = "Map tool"),
                    dashboardSidebar(sidebarMenu(menuItem("Map", tabName = "map"),
                                                 selectInput("input_type", "Date input type",
                                                             c("Date", "Presidency")),
                                                 uiOutput("dateSelect"),
                                                 uiOutput("typeSelect"),
                                                 uiOutput("backgroundSelect"),
                                                 uiOutput("presidentSelect"))),
                    dashboardBody(tabItems(
                      tabItem(tabName = "map",
                              leafletOutput("mymap", height=500)))))

Server: 服务器:

server <- function(input, output, session) {

  output$dateSelect <- renderUI({
    switch(input$input_type,
           "Date" = dateRangeInput("dateInput", "Dates:",
                                   min=min(wikiraw$incident_date), max = max(wikiraw$incident_date),
                                   start = min(wikiraw$incident_date), end = max(wikiraw$incident_date)),
           "Presidency" = checkboxGroupInput("president", "Presidency", 
                                             choices = levels(wikiraw$presidency),
                                             selected = "President1"))
  })

  output$typeSelect <- renderUI({
    selectInput("type", "Incident type", 
                choices = unique(wikiraw$incident_type), multiple = TRUE, 
                selected = wikiraw$incident_type[1])})

  output$backgroundSelect <- renderUI({
    checkboxGroupInput("background", "Incident background", 
                       choices = unique(wikiraw$incident_background),
                       selected = wikiraw$incident_background[1])})


  selected <- reactive({
    wikiagg <- wikiraw %>% group_by(ID_2, incident_date, incident_type, incident_background, presidency) %>%
      summarize(sum_event = sum(event))
    if(input$input_type=="Date"){wikiagg <- filter(wikiagg,
                                                   incident_date >= min(input$dateInput),
                                                   incident_date <= max(input$dateInput),
                                                   incident_type%in%input$type,
                                                   incident_background%in%input$background)}
    if(input$input_type=="Presidency"){wikiagg <- filter(wikiagg,
                                                         incident_type%in%input$type,
                                                         incident_background%in%input$background,
                                                         presidency%in%input$president)}

    wikiagg <- wikiagg %>% group_by(ID_2) %>%
      summarize(sum_event = sum(sum_event))
    wikiagg
  })

  output$mymap <- renderLeaflet({

    leaflet() %>% 
      addTiles() %>% 
      setView(mean(wikbounds[1,]),
              mean(wikbounds[2,]),
              zoom=6
      )
  })

  observe({
    if(!is.null(input$dateInput)){
      shapefile@data <- left_join(shapefile@data, selected(), by="ID_2")

      ##Define palette across range of data
      wikiaggpal <- wikiraw %>% group_by(ID_2) %>%
        summarize(sum_event = sum(event))
      pal <- colorBin("YlOrRd", wikiaggpal$sum_event, bins=5, na.color = "#bdbdbd")


      leafletProxy("mymap", data = shapefile) %>%
        addTiles() %>% 
        clearShapes() %>% 
        addPolygons(data = shapefile, fillColor = ~pal(sum_event), fillOpacity = 0.7, 
                    color = "white", weight = 2)
    }})
}
shinyApp(ui, server)

Gif of issue: 问题的Gif:

https://imgur.com/a/FnfOGKi https://imgur.com/a/FnfOGKi

Any help would be hugely appreciated! 任何帮助将不胜感激!

What if you change the reactive to a reactiveValue and assign the data in an observe ? 如果将reactive更改为reactiveValue并在observe分配数据怎么办? I don't know if it is working correctly as I dont know which shapes & colors to expect, but I am not seeing that double rendering anymore. 我不知道它是否能正常工作,因为我不知道期望使用哪种形状和颜色,但是我再也看不到这种双重渲染。

( Data & Preparation from question is used ) 使用来自问题的数据和准备

library(shiny)
library(shinydashboard)
library(shinythemes)
library(leaflet)
library(rgdal)
library(rmapshaper)
library(sp)
library(dplyr)
library(lubridate)

ui <- dashboardPage(
  dashboardHeader(title = "Map tool"),
  dashboardSidebar(sidebarMenu(menuItem("Map", tabName = "map"),
                               selectInput("input_type", "Date input type",
                                           c("Date", "Presidency")),
                               uiOutput("dateSelect"),
                               uiOutput("typeSelect"),
                               uiOutput("backgroundSelect"),
                               uiOutput("presidentSelect"))),
  dashboardBody(tabItems(
    tabItem(tabName = "map",
            leafletOutput("mymap", height=500)))))



server <- function(input, output, session) {

  output$dateSelect <- renderUI({
    switch(input$input_type,
           "Date" = dateRangeInput("dateInput", "Dates:",
                                   min=min(wikiraw$incident_date), max = max(wikiraw$incident_date),
                                   start = min(wikiraw$incident_date), end = max(wikiraw$incident_date)),
           "Presidency" = checkboxGroupInput("president", "Presidency", 
                                             choices = levels(wikiraw$presidency),
                                             selected = "President1"))
  })

  output$typeSelect <- renderUI({
    selectInput("type", "Incident type", 
                choices = unique(wikiraw$incident_type), multiple = TRUE, 
                selected = wikiraw$incident_type[1])})

  output$backgroundSelect <- renderUI({
    checkboxGroupInput("background", "Incident background", 
                       choices = unique(wikiraw$incident_background),
                       selected = wikiraw$incident_background[1])})

  sel_reactval = reactiveValues(s = NULL)

  # selected <- reactive({
  observe({
    wikiagg <- wikiraw %>% group_by(ID_2, incident_date, incident_type, incident_background, presidency) %>%
      summarize(sum_event = sum(event))

    if(input$input_type=="Date"){wikiagg <- filter(wikiagg,
                                                   incident_date >= min(input$dateInput),
                                                   incident_date <= max(input$dateInput),
                                                   incident_type%in%input$type,
                                                   incident_background%in%input$background)}
    if(input$input_type=="Presidency"){wikiagg <- filter(wikiagg,
                                                         incident_type%in%input$type,
                                                         incident_background%in%input$background,
                                                         presidency%in%input$president)}

    wikiagg <- wikiagg %>% group_by(ID_2) %>%
      summarize(sum_event = sum(sum_event))

    sel_reactval$s = wikiagg
    # wikiagg
  })

  output$mymap <- renderLeaflet({

    leaflet() %>% 
      addTiles() %>% 
      setView(mean(wikbounds[1,]),
              mean(wikbounds[2,]),
              zoom=6
      )
  })

  observe({

    req(!is.null(input$dateInput))
    req(nrow(as.data.frame(sel_reactval$s))!=0)

    # if(!is.null(input$dateInput)){
      # shapefile@data <- left_join(shapefile@data, selected(), by="ID_2")
      shapefile@data <- left_join(shapefile@data, sel_reactval$s, by="ID_2")

      ##Define palette across range of data
      wikiaggpal <- wikiraw %>% group_by(ID_2) %>%
        summarize(sum_event = sum(event))
      pal <- colorBin("YlOrRd", wikiaggpal$sum_event, bins=5, na.color = "#bdbdbd")


      leafletProxy("mymap") %>%
        addTiles() %>%
        clearShapes() %>%
        addPolygons(data = shapefile, fillColor = ~pal(sum_event), fillOpacity = 1, 
                    color = "white", weight = 2)
    # }
    })
}
shinyApp(ui, server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM