r-spatial / leafgl

R package for fast web gl rendering for leaflet
Other
263 stars 31 forks source link

Pass LayerId #19

Closed zegkreist closed 4 years ago

zegkreist commented 5 years ago

Hi, there's a way to pass a layer ID to each point?

I want to build some individual graphics per point. The only information I'm getting now is the event 'click'. I can do some workaround to get the closest point to the Lat Long returned from the event 'click', but that is not ideal.

Thx for the awesome package.

tim-salabim commented 5 years ago

So you want every point to have a distinct id?

zegkreist commented 5 years ago

Yes, Is that possible?

tim-salabim commented 5 years ago

can you maybe provide a small reproducible example of what you want to achieve? I am assuming this is in a shiny context?

zegkreist commented 5 years ago

Yes, the context is a Shiny Dashboard. In this example I'm using circleMarker from leaflet (it is the current setup I'm using, limiting the number of circles that I'm plotting at once with clusters).

Basically I have two data tables. One it is just the info to plot the markers (Id, Long and Lat). The Second it is a data table that contain many other informations about that ID, in this example it is only string.

The object is to have a Dashboard page full with info and graphs based on the marker that was clicked.

Is there any way to pass this ID to leafgl and get back by click event to user somewhere?

Thanks.


library(shiny)
library(data.table)
library(magrittr)
library(leaflet)

Dt1 <- data.table::data.table(id   = 1:4,
                              Lat = c(-23.560092, -23.560225, -23.560348, -23.560309),
                              Long  = c(-46.657836, -46.657981, -46.657815, -46.657625)
                              )
Dt2 <- data.table::data.table(id = 1:4,
                              info = "Some info I want to print, compute or build something."
                              )

ui <- fluidPage(

    titlePanel("Minimal example: Click in circle markers"),
    sidebarPanel(shiny::textOutput("valor_total")
                 ),
    mainPanel(
            leaflet::leafletOutput("mymap",
                                   height = "500",
                                   width  = "100%"
                                   )
            )
    )

server <- function(input, output) {
    #Create a hold for click event
    data_of_click <- reactiveValues(clickedMarker = NULL,
                                    click         = NULL
                                    )

    #observe the click and store the info of ID
    observeEvent(input$mymap_marker_click,{
        data_of_click$clickedMarker <- input$mymap_marker_click
        })

    # Filtering second DT by layerID of marker that I get from event click
    Dt2_react <- reactive({
        if(is.null(data_of_click$clickedMarker$id)){
            NULL
        }else{
            Dt2[id == data_of_click$clickedMarker$id] 
        }

        })

    output$mymap <- renderLeaflet({

        m <- leaflet::leaflet(data    = Dt1,
                              options = leafletOptions(preferCanvas = TRUE) 
                              ) %>%
            leaflet::setView(lat  = -23.560279, 
                             lng  = -46.657778,
                             zoom = 20 ) %>% 
            leaflet::addTiles(
                options               = providerTileOptions(
                    updateWhenZooming = FALSE,      
                    updateWhenIdle    = TRUE  
                    )
                ) %>%
            leaflet::addCircleMarkers(
                lng         = ~Long,
                lat         = ~Lat,
                popup       = ~paste("Nome", Dt1$id, "<br>",
                                     "Id:", Dt1$id
                                     ),
                layerId     = ~id,  # Passingo Id info to get stored in metadata of markers
                stroke      = F,
                fillOpacity = 1
                ) 
        m
        })

    output$valor_total <- shiny::renderText({
        tmp <- Dt2_react()
        if(is.null(tmp)){
            "nothing selected"
        }else{
            tmp$info
        }

        })
}

# Run the application 
shinyApp(ui = ui, server = server)
tim-salabim commented 5 years ago

Ok, thanks! Honestly, I don't know enough about shiny and its inner workings to know what is needed to make this work. Maybe this is a good opportunity to get @jcheng5 and the leaflet/shiny team on board. We've had a quick conversation about closer collaboration to advance this type of thing further.

So, @jcheng5 in case you have already found a suitable person to take over leaflet, I'd appreciate some input here. Thanks!

Maybe also @ColinFay has any ideas?

jcheng5 commented 5 years ago

cc @alandipert

tim-salabim commented 4 years ago

This should be solved with https://github.com/r-spatial/leafgl/pull/33