ggvis icon indicating copy to clipboard operation
ggvis copied to clipboard

handle_click not working in shiny modules

Open BenjaminPeter opened this issue 9 years ago • 4 comments

See example below for bug:

both plots are displayed, but click events are only registered in the first plot.

library(shiny)                                                    
library(ggvis)                                                    


m <- function(input, output, session){                            
    mtcars %>% ggvis(~mpg, ~disp) %>%                             
       layer_points() %>%                                         
       handle_click(function(location,...){print(location)}) %>%  
       bind_shiny("plot-plot")                                    
}                                                                 

ui <- fluidPage(                                                  
                ggvisOutput("plot-plot"),                         
                ggvisOutput("plot-plot2")                         
                )                                                 
server <- function(input, output, session) {                      
   callModule(m, 'plot')                                          
    mtcars %>% ggvis(~mpg, ~disp) %>%                             
       layer_points() %>%                                         
       handle_click(function(location,...){print(location)}) %>%  
       bind_shiny("plot-plot2")                                   

}                                                                 
shinyApp(ui = ui, server = server)                                

BenjaminPeter avatar May 04 '16 06:05 BenjaminPeter

This also seems to be the case for add_tooltip()

library(shiny)                                                    
library(ggvis)                                                    

all_values <- function(x) {
  if(is.null(x)) return(NULL)
  paste0(names(x), ": ", format(x), collapse = "<br />")
}

m <- function(input, output, session){                            
  mtcars %>% ggvis(~mpg, ~disp) %>%                             
    layer_points() %>%                                         
    add_tooltip(all_values, "hover") %>%
    bind_shiny("plot-plot")                                    
}                                                                 

ui <- fluidPage(                                                  
  ggvisOutput("plot-plot"),                         
  ggvisOutput("plot-plot2")                         
)                                                 
server <- function(input, output, session) {                      
  callModule(m, 'plot')                                          
  mtcars %>% ggvis(~mpg, ~disp) %>%                             
    layer_points() %>%                                         
    add_tooltip(all_values, 'hover') %>%
    bind_shiny("plot-plot2")                                   

}                                                                 
shinyApp(ui = ui, server = server)

raffscallion avatar May 06 '16 16:05 raffscallion

Came across the same problem trying to get input_slider() to work in a module.

Seems like bind_shiny() doesn't play nice with the session_proxy object coming from getDefaultReactiveDomain(). A hack is to specify session = getDefaultReactiveDomain()[["parent"]] in the call to bind_shiny() inside the module:

library(shiny)                                                    
library(ggvis)                                                    


m <- function(input, output, session){                            
  mtcars %>% ggvis(~mpg, ~disp) %>%                             
    layer_points() %>%                                         
    handle_click(function(location,...){print(location)}) %>%  
    bind_shiny("plot-plot", session = getDefaultReactiveDomain()[["parent"]])                   
}                                                                 

ui <- fluidPage(                                                  
  ggvisOutput("plot-plot"),                         
  ggvisOutput("plot-plot2")                         
)                                                 
server <- function(input, output, session) {                      
  callModule(m, 'plot')                                          
  mtcars %>% ggvis(~mpg, ~disp) %>%                             
    layer_points() %>%                                         
    handle_click(function(location,...){print(location)}) %>%  
    bind_shiny("plot-plot2")                                   

}                                                                 
shinyApp(ui = ui, server = server) 

But this feels a little like it's going against the principles of modules (it probably wouldn't work nicely if you start nesting modules). It seems to work ok with multiple instances of the same module, i.e.

library(shiny)                                                    
library(ggvis)                                                    

m_output <- function(id){
  ns <- NS(id)
  ggvisOutput(ns("plot"))
}

m <- function(input, output, session){  
  ns <- session$ns

  tmp <- mtcars %>% ggvis(~mpg, ~disp) %>%
    layer_points() %>%                                      
    handle_click(function(location,...){print(location)}) %>% 
    bind_shiny(ns("plot"), 
      session = getDefaultReactiveDomain()[["parent"]]) 
}                                                                 

ui <- fluidPage(                                           
  m_output("plot1"),
  m_output("plot2")
)  

server <- function(input, output, session) {                      
  callModule(m, "plot1") 
  callModule(m, "plot2") 

}                                                                 
shinyApp(ui = ui, server = server)   

cwickham avatar Jul 06 '16 23:07 cwickham

Is there any other workaround to this issue? For my module that uses ggvis and add_tooltip I tried using bind_shiny with session = getDefaultReactiveDomain()[["parent"]] in my app module but it's throwing a bind_shiny() must be run inside a shiny app. error

laderast avatar Nov 14 '16 17:11 laderast

I also see the "bind_shiny() must be run inside a shiny app." error. Is the only currently functioning workaround to just re-scope modules around ggvis bindings?

jazon33y avatar Dec 21 '16 15:12 jazon33y