yihui / xaringan

Presentation Ninja 幻灯忍者 · 写轮眼
https://slides.yihui.org/xaringan/
Other
1.49k stars 280 forks source link

hover position is slightly off when using plotly #98

Open Yue-Jiang opened 6 years ago

Yue-Jiang commented 6 years ago

Sorry I understand that the support for HTML widgets is experimental and low priority. This may or may not relate to #77 , but thought I'd bring this to your attention anyways... Please feel free to close if this is not of immediate interest.

Basically I wanted to be able to use plotly's hover behavior to display information when doing presentation, but came to realize that the position is a little off. In this below example, especially the (2, 4) dot, the hover text gets displayed when I moused over to somewhere to the left of the actual dot, but not when the mouse is on the dot.

I was using xaringan 0.4 and plotly 4.7.1.

蟹蟹!

---
title: "xaringan + plotly"
subtitle: "Hover is slightly off?"
author: "Yue Jiang"
date: "2018/1/7"
output:
  xaringan::moon_reader:
    lib_dir: libs
    nature:
      highlightStyle: github
      highlightLines: true
      countIncrementalSlides: false
---

```{r setup, include=FALSE}
options(htmltools.dir.version = FALSE)

Hover your mouse on these 3 dots and see when the hover text gets displayed

esp the (2, 4) dot

library(plotly)
df <- data.frame(x=c(1,2,1), y=c(3,4,5))
plot_ly(data=df, x=~x, y=~y)

Library versions

packageVersion("xaringan")
packageVersion("plotly")
yihui commented 6 years ago

You can check if resizing your browser window fixes the issue. If not, I don't have time to investigate this issue, but I do have a conjecture: I think the problem may be solved if we can find a way to hold on HTML widgets (don't initialize them) until the slide is visible. If you are familiar with JavaScript, this will be a good challenge for you to solve.

I'm not the author of the plotly package, and I don't know if plotly widgets are rendered or not when a slide is not visible, but in my DT package, I'll hold on when the DT widget does not have non-zero width/height:

https://github.com/rstudio/DT/blob/f27ce3232e7eff1bc71ec3842449f424ea7177f5/inst/htmlwidgets/datatables.js#L112-L115

and render the widget when the resize event is triggered:

https://github.com/rstudio/DT/blob/f27ce3232e7eff1bc71ec3842449f424ea7177f5/inst/htmlwidgets/datatables.js#L989-L990

In xaringan, I'll manually trigger the resize event when the afterShowSlide event is triggered:

https://github.com/yihui/xaringan/blob/master/inst/rmarkdown/templates/xaringan/resources/js/show-widgets.js

This works (actually I have never verified it by myself) because the HTML widgets framework triggers the resize handler of the widget when the resize event on the window is triggered:

https://github.com/ramnathv/htmlwidgets/blob/18687ee29485ca4852044bde61499e7418bae44b/inst/www/htmlwidgets.js#L567-L582

I guess the same idea can be used to fix #62 (do not render math expressions until the slide is visible).

Yue-Jiang commented 6 years ago

Thanks Yihui! Resizing the browser definitely affects the issue, sometimes make it better sometimes worse. And it also seems to be browser dependent, i.e. chrome, safari and firefox has this issue to different degrees. Thanks for pointing out a direction - I'm actually not familiar with javascript, but will be happy to take a stab at this, slowly...

yihui commented 6 years ago

It is a complicated issue, and I guess it will be a long way for you to go :)

Yue-Jiang commented 6 years ago

Yeah this has really been bothering me these days... I still haven't been able to track down the exact issue, but have found a workaround: wrapping htmlwidgets inside iframe with widgetframe seems to fix my issue... and also #77. While I continue to look into this, I'm pasting the workaround here.

---
title: "xaringan + plotly"
subtitle: "Hover is slightly off?"
author: "Yue Jiang"
date: "2018/1/25"
output:
  xaringan::moon_reader:
    lib_dir: libs
    nature:
      highlightStyle: github
      highlightLines: true
      countIncrementalSlides: false
---

```{r setup, include=FALSE}
options(htmltools.dir.version = FALSE)
```

# Hover your mouse on these 3 dots and see when the hover text gets displayed

esp the (2, 4) dot
```{r, message=FALSE, fig.width=6, fig.height=4}
library(plotly)
df <- data.frame(x=c(1,2,1), y=c(3,4,5))
plot_ly(data=df, x=~x, y=~y)
```

---
# This is a work around for my issue #98

```{r, message=FALSE}
library(widgetframe)
l <- plot_ly(data=df, x=~x, y=~y)
frameWidget(l, width='60%', height='40%')
```

---
# This also fixes #77

```{r, echo=FALSE}
library(leaflet)
df <- data.frame(
  name = c("Adyghe", "Udi"),
  lat = c(44, 40.9),
  long = c(39.33,47.7236),
  stringsAsFactors = FALSE)

l <- leaflet(df) %>% 
  addTiles() %>%
  addCircleMarkers(~long, ~lat, 
                   popup = ~name,
                   stroke = FALSE,
                   fillOpacity = 1)

frameWidget(l)
```
tbrambor commented 6 years ago

@Yue-Jiang thank you for posting the work around. Fixes the off positioning of the leaflet popups.

It also fixes another issue I had. When adding long character vectors to the leaflet popup, the Xaringan new slide command (---) would be ignored after the leaflet map. Essentially, I was unable to add any new slides after the slide with the leaflet map with the popup inserted but your iframe idea saved the day.

yihui commented 5 years ago

As I said in https://github.com/yihui/xaringan/issues/77#issuecomment-468836308, this issue may have been fixed in the current dev version of xaringan. Please test it! Thank you!

Yue-Jiang commented 5 years ago

Thanks for the note! Hmmm I don't think it works for me yet... I tested with the same example I posted on top of this thread and still find the hovering position being slightly off. I'm using xaringan 0.8.16 and plotly 4.8.0.

yihui commented 5 years ago

Okay. I realized this issue was kind of random. Sometimes it works and sometimes it doesn't. Even when it works, it stops working after I resize the window a little bit. Below is a screencast:

untitled

I have ran out of ideas. I'm not sure if @cpsievert has an idea on top of his head.

MeganBeckett commented 5 years ago

At the moment, I am also using frameWidget() to include any plotly plots in {xaringan} slides. This seems to be the best solution for now.

emitanaka commented 5 years ago

I found this post by Di useful for this!

JustinKurland commented 2 years ago

I realize that this issue is closed, but it appears that @Yue-Jiang 's hack is the only viable solution. I suspect @yihui that both the complexity of the plotly plot that is rendered and the size of the tooltip here is the issue. Not sure it is worth investing the time since @Yue-Jiang's workaround works well, may be worth making this more visible in the markdown on Xaringan to make it easier for others who run into this bug.