我正在构建一个闪亮的应用程序来在地图上可视化酒店(使用传单包)。 我有一个下拉列表,可以加载数据的子集。除此之外,我还想在左上角建立一个过滤按钮,我可以用它来进一步按年份过滤数据。
我希望过滤器仅在我单击
apply
按钮时响应。另外,我想在单击 clear
按钮后清除过滤器。
下面是我闪亮的应用程序代码。 我的
apply
和 clear
按钮似乎不起作用。一旦我从过滤器下拉列表中选择年份,我的地图就会刷新。我希望它仅在单击 apply
按钮后刷新。过滤器也不响应“清除”。 我花了几个小时但无法弄清楚为什么。有谁知道我做错了什么。
这是一个非常简化的版本。我的实际应用程序要复杂得多。下拉按钮中有多个过滤器。
library(shiny)
library(leaflet)
library(shinyjs)
library(shinyWidgets)
library(dplyr)
df <- read.table(text = "Name Year Value longitude latitude
A 2020 12 -106.50645 35.06745
B 2020 33 -116.00994 36.21834
C 2020 44 -115.24685 36.29460
A 2019 55 -115.24685 35.06745
B 2019 22 -118.18642 33.98881
C 2019 11 -111.83064 35.06745",
header = TRUE)
ui <- fluidPage(
selectizeInput(inputId = 'hotel', label='Hotel Type:',
choices = c('A', 'B', 'C'),
multiple=TRUE,
options = list(
maxItems = 1,
placeholder = '',
onInitialize = I("function() { this.setValue(''); }"))),
actionButton("load", "load"),
div(id = 'map_filter',
dropdown(
tags$h3("Filters"),
selectizeInput(inputId = 'year', label='Choose Year:',
choices = c(2020,2019),
multiple=TRUE,
options = list(
maxItems = 2,
placeholder = '',
onInitialize = I("function() { this.setValue(''); }"))),
#uiOutput('map_zipcode_prod2ui') ,
# column(width=1, offset = 1, actionButton(inputId='map_zipcode_applyProductFilter',
# label='Apply Filter', style = 'margin-top:25px') )
actionBttn(
inputId = 'applyFilter',
label = "Apply",
style = "gradient",
color = "danger",
icon = icon("") ) ,
actionBttn(
inputId = 'clearFilter',
label = "Clear",
style = "gradient",
color = "danger",
icon = icon("") ) ,
style = "unite", icon = icon("filter"),
status = "danger", width = "300px"
) #dropdown
), #div
leafletOutput("mymap")
)
server <- function(input, output, session) {
df1 = eventReactive (input$load, {
df %>% filter(Name == input$hotel)
})
df2 = reactive({
if (length(input$year)==0) {
df2 = df1()
} else {
df2 = df1() %>% filter(Year %in% input$year)
}
})
# clear all filters
observeEvent(input$clearFilter, {
reset("map_filter")
})
observeEvent(c(input$load,input$applyFilter), ignoreInit = T, ignoreNULL = T, {
output$mymap <- renderLeaflet({
map <- leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addCircleMarkers( data = df2(),
#group = 'Data Markers 1',
lng = ~longitude,
lat = ~latitude,
radius = 10,
stroke = F,
fillOpacity = 0.9,
color = 'red')
})
})
}
shinyApp(ui, server)
这是一种方法 - 希望有帮助。
您可以将地图存储在
reactiveVal
中。然后,您可以使用加载或应用过滤器按钮更新地图。否则,地图不会改变。
会考虑使用
updateSelectizeInput
清除过滤器。
编辑:根据评论,
df1
和df2
未合并。
server <- function(input, output, session) {
map <- reactiveVal(NULL)
df1 = reactive({
req(input$hotel)
filter(df, Name == input$hotel)
})
df2 = reactive({
if (length(input$year)==0) {
df2 = df1()
} else {
df2 = df1() %>% filter(Year %in% input$year)
}
})
# clear all filters
observeEvent(input$clearFilter, {
updateSelectizeInput(session, inputId = 'year', selected = "")
})
output$mymap <- renderLeaflet({
map()
})
observeEvent(c(input$load, input$applyFilter), ignoreInit = T, ignoreNULL = T, {
map(leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addCircleMarkers( data = df2(),
#group = 'Data Markers 1',
lng = ~longitude,
lat = ~latitude,
radius = 10,
stroke = F,
fillOpacity = 0.9,
color = 'red')
)
})
}
试试这个
server <- function(input, output, session) {
df1 = eventReactive (input$load, {
df %>% filter(Name == req(input$hotel))
})
df2 = reactive({
req(input$year)
if (length(input$year)==0) {
df2 = df1()
} else {
df2 = df1() %>% filter(Year %in% input$year)
}
})
# clear all filters
observeEvent(input$clearFilter, {
output$mymap <- renderLeaflet({
return(NULL)
})
#reset("map_filter")
})
observeEvent(input$applyFilter, ignoreInit = T, ignoreNULL = T, {
req(input$load,df2())
output$mymap <- renderLeaflet({
map <- leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addCircleMarkers( data = df2(),
#group = 'Data Markers 1',
lng = ~longitude,
lat = ~latitude,
radius = 10,
stroke = F,
fillOpacity = 0.9,
color = 'red')
})
})
}
shinyApp(ui, server)