6

I have a bizarre and very frustrating problem. When I build plotly graphs within storyboards (from the flexdashboard package), I get a very annoying and totally unnecessary scroll bar in my legend. When someone tries to click one of the dots on or off, the scroll bar twitches and its practically impossible to click the thing. This scroll bar only appears when the tab with the plotly graph is not immediately visible during the load of the page - i.e. if the page loads with some other tab selected.

I can make the same graph outside of the storyboard, with no problems either in RStudio, or saving it as an htmlwidget and loading it in Chrome. But when I load my storyboard, either in RStudio or in Chrome, I get this annoying scrollbar. The scrollbar exists whether it's a vertical or horizontal legend.

ggplotly objects do not have this problem.

Here's an example of the unnecessary scroll bar. The ggplotly graph is fine, and the plotly one has the scrollbar.

---
title: "Untitled"
output: 
  flexdashboard::flex_dashboard:
    storyboard: true
---

```{r setup, include=FALSE}
library(flexdashboard)
```

### ggplot

```{r}

library(plotly)

carggplot <- ggplot(mtcars, aes(hp, mpg, fill = as.factor(carb))) +
    geom_point() +
    theme_bw()

ggplotly(carggplot)
```


### plotly

```{r}
carsplot <- plot_ly(
    data = mtcars,
    x = ~hp,
    y = ~mpg,
    color = ~as.factor(carb),
    type = "scatter",
    mode = "markers"
    )

carsplot
```

I have been unable to find any documentation on this issue, although I found a similar problem posted by someone using the python interface to plotly.

I'm looking for a way to either turn off the scroll bar completely (while keeping the legend), or some explanation of the scroll bar's twitchy behavior.

flexdashboard is 0.5, plotly is 4.7.1, R is 64 bit 3.4.1, Windows 7.

Adrian Martin
  • 780
  • 7
  • 21

2 Answers2

1

There are quite a lot of moving parts going on to answer your question. I won't cover each in detail but touch on them only briefly.

Background

  1. The plotly.js chart is behaving as designed when the length of the legend gets longer, it automatically inserts the scrollbar.

  2. This is not happening with the ggplotly chart because all the visual styling is coming from the ggplot object.

  3. flexdashboard is the culprit in this case because of how it is dynamically fitting the available space and informing plotly.js on how to render. It is worth noting this appears as SVG in the source html.

  4. The solution is then to manipulate the DOM in order to hide/remove/alter the problematic element.

Potential Solution

The solution I offer below is therefore a bit of a hack. A more permanent solution may be to lodge an issue with the good people at RStudio to see if any change could be made to the package, which addresses your problem.

If you add runtime: shiny to your YAML header, you can then make use of the excellent shinyjs package by Dean Attali. While I'm not an expert in this space, I've added a few lines to your MRE that remove <rect> elements from the SVG of class=scrollbar. Important to note you may need to alter the javascript I offer to be more specific and not remove elements you may wish to retain.

Update to MRE

Here is the Rmd code with comments where I've made changes.

---
title: "Untitled"
output: 
  flexdashboard::flex_dashboard:
    storyboard: true
  runtime: shiny
---

```{r setup, include=FALSE}
library(shinyjs)        # add package, note runtime option above in YAML
useShinyjs(rmd = TRUE)  # function needs to initialise js

library(flexdashboard)
library(plotly)
```

### ggplot

```{r}

library(plotly)

carggplot <- ggplot(mtcars, aes(hp, mpg, fill = as.factor(carb))) +
    geom_point() +
    theme_bw()

ggplotly(carggplot)
```


### plotly

```{r}
carsplot <- plot_ly(
    data = mtcars,
    x = ~hp,
    y = ~mpg,
    color = ~as.factor(carb),
    type = "scatter",
    mode = "markers"
    )

carsplot

runjs("$svg.selectAll('rect[class=scrollbar]').remove();") # run plain js to remove elements
```

N.B. As I post this, I have had unreliable results and will dig in further.

Kevin Arseneau
  • 6,186
  • 1
  • 21
  • 40
  • Thank you for the response. Unfortunately, when I run this code, I still get the scroll bar. Also, my organization does not have a shiny server, and this is for a dashboard that I'm pushing out to a couple dozen people, so shiny is not going to be an option for me. If the solution is to edit the DOM, as a shortterm hack, is there some edit to the rendered html file I could make in a text editor to fix the issue? – Adrian Martin Oct 25 '17 at 15:10
  • 1
    @AdrianMartin, you have four options: lodge an issue with flexdashboard and hope they fix it; use JavaScript to modify the DOM; use some other dashboard framework such as shinydashboard; or simply live with what is actually quite a minor visual aberration – Kevin Arseneau Oct 25 '17 at 22:52
  • I likely will be doing #1 & #4. Thanks for your help. – Adrian Martin Oct 26 '17 at 17:40
1

Old question but if others have the same issue, I wanted to get my solution out there...

I had the same issue and I solved it using this approach:

ggplotly(carggplot, height = 500)

I had a mini scroll bar in my legend and adjusting the height as above while calling ggplotly(), allowed me to adjust to the correct height needed to make everything work.

CWill
  • 23
  • 3
  • Interesting. I have the opposite problem though - my ggplotly is already fine and does not need to be altered. My plot_ly is the one with the scroll bar problem. – Adrian Martin Dec 08 '17 at 20:38
  • Ahh, I see. I failed to fully read the post! Lack of coffee will do that :) Are you still having the issue? – CWill Dec 09 '17 at 21:49
  • Yes :\ Other priorities at work have meant I haven't had much time to work on it, but I'll have to find a fix at some point. – Adrian Martin Dec 11 '17 at 14:49