ggvis icon indicating copy to clipboard operation
ggvis copied to clipboard

Tooltip initialized with on="click" can only be closed by click on another data point

Open paulklemm opened this issue 11 years ago • 16 comments

This issue is related to this stackoverflow question: https://stackoverflow.com/questions/25619778/hide-tooltip-initialized-with-on-click-in-ggvis-plot

The behavior of tooltips initialized with on="click" is not intuitive in my opinion. A tooltip can only be closed by clicking on another data point in the plot. I would expect the following behavior:

  • close the tooltip on click of the data point, which triggered it
  • close the tooltip on click of another data point and open the respective tooltip (the current functionality)
  • close the tooltip on click on anywhere in the plot outside of the tooltip (still makes it possible to interact with content of the tooltip, e.g. copy text)

paulklemm avatar Sep 02 '14 09:09 paulklemm

The built-in Vega events only respond to clicks on data objects; in order to make this work, we'll need to either add transparent rect for the whole plot or attach our own event handlers to the div.

wch avatar Sep 30 '14 21:09 wch

Or add a closing 'x' in top right corner of tooltip

pssguy avatar Sep 30 '14 21:09 pssguy

To blank the tooltip, I did it with a function returning NULL when moving the mouse around.

tip_values <- function(x) { if(is.null(x)) return(NULL)

your tiptext code here

rowres <- utw[utw$id == x$id, ]

paste0(c(paste0(rowres$name, " @"), "Follower: ", "Friends: "), format(c(rowres$screenName, rowres$followersCount, rowres$friendsCount)), collapse = "
")

} ... add_tooltip(tip_values, "hover")

fxcebx avatar Oct 13 '14 11:10 fxcebx

@fxcebx Sorry but this doesn't work in my example. add_tooltip(my_tooltip, "hover") automatically closes the tooltip when the mouse leaves a data entry. Also, x is the tip_values function is never null, even of you click/move the mouse anywhere in the plot. In this case, the tooltip function ist simply not called at all. Do I miss your point?

paulklemm avatar Oct 13 '14 12:10 paulklemm

@wch If you do have a look at this area, I would also be interested in the option to have more than one tooltip open at once. This would be useful for static images taken from the plot where several values need to be highlighted

pssguy avatar Dec 12 '14 03:12 pssguy

Looking forward to this feature as well. I am planning to use links in my tooltip which will require a delayed (or customizable) hover or a clickable link that can exited by clicking on a black bar of the graph. Awesome work on the package.

jhtravis avatar Apr 16 '15 15:04 jhtravis

Until this gets impemented, if you want to have this behaviour in a shiny app you can easily achieve it with minimal javascript. Example:

library(shiny)
library(ggvis)

jscode <- 
"$(function() {
  $('#ggvis').click(function(){ $('#ggvis-tooltip').hide(); });
})
"

shinyApp(
  ui = fluidPage(
    tags$script(jscode),
    uiOutput("ggvis_ui"),
    ggvisOutput("ggvis")
  ),
  server = function(input, output, session) {
    mtcars %>% 
      ggvis(~wt, ~mpg) %>%
      layer_points() %>%
      add_tooltip(function(df) df$wt, on = "click") %>%
      bind_shiny("ggvis", "ggvis_ui")
  }
)

daattali avatar Oct 06 '15 05:10 daattali

@daattali Really nice hack, works well for shiny apps. I use ggvis as shiny reactive in an interactive RMarkdown document. I guess I can convert the reactive into a shiny app. Is there, however, a way to inject the javascript into shiny reactives?

paulklemm avatar Dec 09 '15 21:12 paulklemm

Sorry I'm not quite sure what you mean by injecting JS into a reactive

daattali avatar Dec 09 '15 21:12 daattali

I think you are trying to add the javascript command to the markdown document. If that is the case just adding <script>$(function () { $("#ggvis").click(function(e){ $("#ggvis-tooltip").hide(); }); })</script> to somewhere in the document should to it. so no actual "injection" is required

oganm avatar Dec 09 '15 21:12 oganm

@oganm You are right. I've added the code to the document, but it does not work. @oganm @daattali Any idea whats wrong here? Here is a (rather stupid) minimal example:

---
title: "ggvis Hide Tooltip on Click"
runtime: shiny
output: 
  html_document
---

<script>
$(function() {
  $('#ggvis').click(function(){ $('#ggvis-tooltip').hide(); });
})
</script>

```{r loading_main_script, echo=FALSE, results='hide',message=FALSE, warning=FALSE, cache=FALSE}
library(ggvis)
# Define Shiny reactive
plot_data <- reactive({

  mtcars %>% ggvis(~wt, ~mpg) %>% 
  layer_points() %>% 
  add_tooltip(function(df) df$wt, on = "click")
})

bind_shiny(plot_data, 'plot_data')
```

```{r echo=FALSE,message=FALSE, warning=FALSE, error=FALSE, out.extra=FALSE}

ggvisOutput('plot_data')

```

The <script> tag should work according to this stackoverflow post.

paulklemm avatar Dec 09 '15 22:12 paulklemm

It's not working because you changed the name of the element. My code works by running the JS code whenever you click on the element with id ggvis, but in your code there is no such element, it's called plot_data instead. So change the JS function to $('#plot_data') instead of $('#ggvis')

daattali avatar Dec 09 '15 22:12 daattali

Thanks a ton, works like a charm! If you want to, you can add this as answer to my stackoverflow question for fame and glory :wink: .

paulklemm avatar Dec 09 '15 22:12 paulklemm

:+1: responded, thanks

daattali avatar Dec 09 '15 23:12 daattali

Strange, using this verbatim I can't seem to get it to work. The id I'm passing to 'ggvisOutput()' is 'ggvis'. But I'm getting the following:

'Warning: Error in tag: object 'jscode' not found'

Does it matter that I'm trying to use the tooltip from reactive output?

speedreader avatar Jan 21 '16 16:01 speedreader

@speedreader based on that error, it looks like you aren't defining the jscode variable, or you're defining it with an error

daattali avatar Jan 21 '16 19:01 daattali