[英]Adding reactive popup graphs/plots to a Leaflet map with Shiny R
我已經構建了一個 Shiny 儀表板。 用戶可以從下拉菜單中 select 一個城市,然后下載該城市的一系列數據並使用 Leaflet 進行可視化。 一個主要的用戶要求是單擊 map 上的一個區域會生成一個包含該區域所有分數的彈出圖(見下圖)
這是我的一般方法:
這不應該那么難,但我已經被困了好幾天了。 我還嘗試生成一個圖表列表(市政當局的每個區域一個),因為我相信這就是 leafpop 的工作原理。 然而,再次走向成功。 有沒有人可以解決我的掙扎?
可重現的例子:
library(sf)
library(dplyr)
library(shiny)
library(shinydashboard)
library(leaflet)
library(leafpop)
library(ggplot2)
library(reshape2)
# Let's use this municipality in the example
inputMunicipality = "Landgraaf"
# Download municipality geometry
df <-st_read(URLencode(sprintf("https://geo.leefbaarometer.nl/leefbaarometer/wfs?version=1.0.0&cql_filter=gemeente=%s%s%s&request=GetFeature&typeName=leefbaarometer:wijken_2018&srsName=epsg:4326&outputFormat=json",
"'", inputMunicipality, "'")))[c("WK_NAAM", "WK_CODE")]
# Add some fake scores
df$environmentScore <- sample(10, size = nrow(df), replace = TRUE)
df$facilitiesScore <- sample(10, size = nrow(df), replace = TRUE)
df$housingScore <- sample(10, size = nrow(df), replace = TRUE)
df$safetyScore <- sample(10, size = nrow(df), replace = TRUE)
# Define dashboard UI
ui <- dashboardPage(
dashboardHeader(title = "Testing reactive popup on click event!"),
dashboardSidebar(),
dashboardBody(
fluidRow(leafletOutput("myMap")
)
)
)
# Define server logic
server <- function(input, output) {
# When a person clicks the map, the name of the clicked area is saved in this reactive value
clickValue <- reactiveValues(areaName=NULL)
# I then want to use the reactive "clickValue$areaName" in this function to generate a reactive ggplot
# The reactive ggplot should then be shown as a popup with the addPopupGraphs function
reactivePopup <- reactive ({
makePopupPlot(clickValue$areaName, df)
})
output$myMap <- renderLeaflet({
leaflet() %>%
addProviderTiles(providers$nlmaps.grijs) %>%
addPolygons(data = df, weight = 1, fillOpacity = 0.3,
group = "test", layerId = ~WK_CODE, popup = df$WK_NAAM) %>%
addPopupGraphs(list(nonReactiveExamplePopup), group = "test", width = 500, height = 200)
})
# Save the name of a clicked area in a reactive variable
observeEvent(input$map_shape_click, {
event <- input$map_shape_click
clickAreaName <- df$WK_NAAM[df$WK_CODE == event$id]
clickValue$areaName <- clickAreaName
})
}
# Run the application
shinyApp(ui = ui, server = server)
# Function for generation a popup based on the area clicked by the user
makePopupPlot <- function (clickedArea, df) {
# prepare the df for ggplot
noGeom <- st_drop_geometry(df)
plotData <- noGeom[c("WK_NAAM", "environmentScore", "facilitiesScore","housingScore", "safetyScore")]
plotDataSubset <- subset(plotData, plotData['WK_NAAM'] == clickedArea)
plotDataMelt = melt(plotDataSubset, id.vars = "WK_NAAM")
popupPlot <- ggplot(data = plotDataMelt, aes(x = variable, y = value, fill=value)) +
geom_bar(position="stack", stat="identity", width = 0.9) +
scale_fill_steps2(
low = "#ff0000",
mid = "#fff2cc",
high = "#70ad47",
midpoint = 5) +
coord_flip() +
ggtitle(paste0("Score overview in ", clickedArea)) +
theme(legend.position = "none")
return (popupPlot)
}
# Add this graph to addPopupGraphs(list() to see how I want it to work
nonReactiveExamplePopup <- makePopupPlot("Wijk 00 Schaesberg", df)
如果我理解正確:
library(sf)
library(dplyr)
library(shiny)
library(shinydashboard)
library(leaflet)
library(leafpop)
library(ggplot2)
library(reshape2)
set.seed(1)
# Let's use this municipality in the example
inputMunicipality = "Landgraaf"
# Download municipality geometry
df <-st_read(URLencode(sprintf("https://geo.leefbaarometer.nl/leefbaarometer/wfs?version=1.0.0&cql_filter=gemeente=%s%s%s&request=GetFeature&typeName=leefbaarometer:wijken_2018&srsName=epsg:4326&outputFormat=json",
"'", inputMunicipality, "'")))[c("WK_NAAM", "WK_CODE")]
# Add some fake scores
df$environmentScore <- sample(10, size = nrow(df), replace = TRUE)
df$facilitiesScore <- sample(10, size = nrow(df), replace = TRUE)
df$housingScore <- sample(10, size = nrow(df), replace = TRUE)
df$safetyScore <- sample(10, size = nrow(df), replace = TRUE)
# Define dashboard UI
ui <- dashboardPage(
dashboardHeader(title = "Testing reactive popup on click event!"),
dashboardSidebar(),
dashboardBody(
fluidRow(leafletOutput("myMap")
)
)
)
# Define server logic
server <- function(input, output) {
# Function for generation a popup based on the area clicked by the user
makePopupPlot <- function (clickedArea, df) {
# prepare the df for ggplot
noGeom <- st_drop_geometry(df)
plotData <- noGeom[c("WK_NAAM", "environmentScore", "facilitiesScore","housingScore", "safetyScore")]
plotDataSubset <- subset(plotData, plotData['WK_NAAM'] == clickedArea)
plotDataMelt = melt(plotDataSubset, id.vars = "WK_NAAM")
popupPlot <- ggplot(data = plotDataMelt, aes(x = variable, y = value, fill=value)) +
geom_bar(position="stack", stat="identity", width = 0.9) +
scale_fill_steps2(
low = "#ff0000",
mid = "#fff2cc",
high = "#70ad47",
midpoint = 5) +
coord_flip() +
ggtitle(paste0("Score overview in ", clickedArea)) +
theme(legend.position = "none") +
theme(plot.margin = unit(c(0,0.5,0,0), "cm"), plot.title = element_text(size = 10))
return (popupPlot)
}
# chart list
p <- as.list(NULL)
p <- lapply(1:nrow(df), function(i) {
p[[i]] <- makePopupPlot(df$WK_NAAM[i], df)
})
output$myMap <- renderLeaflet({
leaflet() %>%
addProviderTiles(providers$nlmaps.grijs) %>%
addPolygons(data = df, popup = popupGraph(p, type = "svg"))
})
}
# Run the application
shinyApp(ui = ui, server = server)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.