mapdeck icon indicating copy to clipboard operation
mapdeck copied to clipboard

Discrepancy between point ID and indexing

Open bdbmax opened this issue 3 years ago • 4 comments

Describe the bug Within shiny, when a point is clicked on a scatterplot, it retrieves the wrong id supplied through add_scatterplot. It seems it is retrieving the row number -1.

To Reproduce

library(mapdeck)
library(shiny)

# Retrieving df used in add_scatterplot examples
df <- read.csv(paste0(
  'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/',
  'examples/3d-heatmap/heatmap-data.csv'
))
df <- df[ !is.na(df$lng), ]
df <- cbind(df, ID = 1:nrow(df))
# df <- cbind(df, ID = "a"): the tooltip shows the "a" but the id retrieved is the row number -1.
# df <- cbind(df, ID = 0:(nrow(df)-1)):  has no discrepency between the ID and the point clicked on.

ui <- fluidPage(
  mapdeckOutput("map"),
  htmlOutput("selection")
)

server <- function(input, output, session) {
  # Map
  output$map <- renderMapdeck(mapdeck() |> 
                                add_scatterplot(
                                  data = df,
                                  radius = 500,
                                  tooltip = "ID",
                                  id = "ID"
                                ))
  
  # Selection
  select_id <- eventReactive(input$map_scatterplot_click, {
    jsonlite::fromJSON(input$map_scatterplot_click)$index
  })
  
  output$selection <- renderText(paste("Selected output: ", select_id()))
  
}

shinyApp(ui = ui, server = server)

Expected behaviour That the jsonlite::fromJSON(input$map_scatterplot_click)$index returns the supplied id (in add_scatterplot) of the point clicked on.

Screenshots image

Versions 0.3.4

bdbmax avatar Jan 20 '22 18:01 bdbmax

Technically this is the intended behaviour as the index is used/returned in the onClick functions from here

var eventInfo = {
  	index: info.index,
  	color: info.color,
  	object: info.object,
  	layerId: info.layer_id,
  	lat: info.coordinate[1], // deck.gl 8.4 - https://deck.gl/docs/upgrade-guide#upgrading-from-deckgl-v83-to-v84
  	lon: info.coordinate[0]
  };

  eventInfo = JSON.stringify( eventInfo );
  Shiny.onInputChange(map_id + "_" + layer + "_click", eventInfo);

I think the actual issue is the id argument in the R functions; I'm not sure they do anything and may be left over from a very early iteration of this library.


But thanks for bringing this up; the documentation certainly needs to be clearer.

dcooley avatar Jan 20 '22 21:01 dcooley

Good, interesting. I got mixed up between the different output of the onClick event depending on the layers used. add_polygon offers the possibility to retrieve the supplied ID (from the id argument in the R function) from a click through jsonlite::fromJSON(input$map_polygon_click)$object$properties$id, which is a great feature we highly rely on.

library(mapdeck)
library(shiny)

sf <- geojsonsf::geojson_sf("https://symbolixau.github.io/data/geojson/SA2_2016_VIC.json")

ui <- fluidPage(
  mapdeckOutput("map"),
  htmlOutput("selection")
)

server <- function(input, output, session) {
  # Map
  output$map <- renderMapdeck(mapdeck() |> 
                                add_polygon(
                                  data = sf,
                                  id = "SA2_MAIN16", 
                                  tooltip = "SA2_MAIN16"))
  
  # Selection
  select_id <- eventReactive(input$map_polygon_click, {
    jsonlite::fromJSON(input$map_polygon_click)$object$properties$id
  })
  
  output$selection <- renderText(paste("Selected output: ", select_id()))
  
}

shinyApp(ui = ui, server = server)

A click on any polygon return its id (its SA2_MAIN16 value in this example). Reclicking on the same polygon then returns NULL, signaling a deselection.

The same functionality would be interesting for point data!

bdbmax avatar Jan 20 '22 22:01 bdbmax

Oh that's interesting; the scatterplot object returned from deck.gl does not contain the object, (first console.log() in the screenshot), whereas the object returned for the polygon does contain the object, which is why you get the Id returned.

Screenshot 2022-01-21 at 9 12 49 am

dcooley avatar Jan 20 '22 22:01 dcooley