GregF
GregF

Reputation: 1392

ggvis and shiny - hover property fails on added data with key

I'm trying to learn how to use ggvis and shiny together, by adapting the code from the movie explorer exmaple.

I have come across a problem where when a user's interaction adds new data to the graph, the hover effects don't work for the new data if there is a key. I'd like to be able to keep the key, because I'll also want to have a tooltip.

A quick example is below. To reproduce bug:
1) Run shiny app.
2) Use the select box to add the "b" points.
3) Now the "a" points will increase in size upon hover, as expected, but the "b" points will not.

To get proper behavior, I could just comment out the line in server.r, but I don't want to do that (because of the tooltip I want to add). Is there something I can do with reactive to get the hover behavior on all points?

Thank you!

server.r

library(ggvis)

# Set up data on app start
all_data <- data.frame(x=1:4, y=1:4, z=c("a", "b", "b", "a"), ID=1:4)

shinyServer(function(input, output, session) {

  # Filter the data
  this_data <- reactive({
    all_data[all_data$z %in% input$z, ]
  })

  # A reactive expression with the ggvis plot
  vis <- reactive({
    this_data %>%
      ggvis(~x, ~y) %>%
      layer_points(fill = ~z, 
        key := ~ID, # Comment out this line for proper behavior
        size := 50, size.hover := 500, 
        fillOpacity := 0.9, fillOpacity.hover := 0.5)
  })

  vis %>% bind_shiny("plot1")
})

ui.r

library(ggvis)

shinyUI(fluidPage(
  titlePanel("Example"),
  fluidRow(
    column(3,
      wellPanel(
        selectInput("z", "Select Z", c("a", "b"), 
          selected = "a", multiple=TRUE)
      )
    ),
    column(9,
      ggvisOutput("plot1")
    )
  )
))

Upvotes: 1

Views: 491

Answers (1)

jalapic
jalapic

Reputation: 14192

This had me pretty confused. I could replicate it in a bunch of strange ways - e.g. adding groups / adding points. The order in which you added groups and removed them also did strange things.

In one of my own shiny/ggvis plots that I made after the movie example, I had a similar issue with key/ID and I found that adding the ID after all data filtering worked better. I tried that here by adding the ID variable after the filtering but it still didn't work. However, adding it in a new reactive did.

here is my ggvis/shiny where I had to do something similar - https://jalapic.shinyapps.io/cricket and the raw code - https://github.com/jalapic/shinyapps/blob/master/cricket/server.R

I think this works - at least for me. Effectively, note I remove the ID from the data setup. I then add it in a new reactive after our filtering is done in the first reactive.

# Set up data on app start
all_data <- data.frame(x=c(1,3:5), y=1:4, z=c("a", "b", "b", "a"))

shinyServer(function(input, output, session) {

  # Filter the data
  this_data <- reactive({

   all_data[all_data$z %in% input$z, ] 


  })

  this_data1 <- reactive({

  as.data.frame(this_data() ) %>% mutate(ID = row_number(x))
  })


  # A reactive expression with the ggvis plot
  vis <- reactive({
    this_data1 %>%
      ggvis(~x, ~y) %>%
      layer_points(fill = ~z, 
                   key := ~ID, # Comment out this line for proper behavior
                   size := 50, size.hover := 500, 
                   fillOpacity := 0.9, fillOpacity.hover := 0.5)
  })

  vis %>% bind_shiny("plot1")
}) 
  • I should add that I have added the ID variable using the %>% mutate(row_number()) command from dplyr but I'm sure you could do it in another way if this doesn't suit you.

Upvotes: 1

Related Questions