0

I am trying to change a plotly graph via crosstalk in my Rmarkdown doc. This works in principle fine, however, I want to set the dropdown to the first element on startup via JavaScript. This change, however, does not update the graph. If I run the same code once the full page is rendered, or use a delay it works.

Thus, I assume that at the point the update JavaScript is run, the plotly graph is not yet rendered. The setTimeout solution works, but this feels hackis. So what is the canonical way to inform plotly/crosstalk that the input changed?

In the gif you see that upon startup the plot shows the full range, only after changing to b and then to a updated the graph accordingly. I would like that the graph is correctly filtered already upon startup.

Code

---
title: "Delay Plotly"
date: "1 2 2021"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, message = FALSE)
```
```{r libs}
library(crosstalk)
library(plotly)
```

```{r gen-data}
set.seed(1)
mdat <- data.frame(x = rep(LETTERS[1:6], 6),
                   y = sample(100, 36, TRUE),
                   fill = factor(rep(rep(1:3, each = 6), 2)),
                   grp = rep(letters[1:2], each = 18),
                   id = paste0("id", 1:36),
                   stringsAsFactors = FALSE)
sd <- SharedData$new(mdat, key = ~ id)

```

```{js}
$(function() {
   // set dropdown to first element
   // setTimeout(function() { // uncomment for workaround
      $('.selectized').each(function(idx, el) {
         const sel = this.selectize;
         const options = Object.keys(sel.options);
         sel.setValue(options[0]);
      });
   // }, 1000); // uncomment for workaround
})
```


```{r}
bscols(
   filter_select("grp",
                "Group:",
                sd,
                ~ grp, multiple = FALSE),
   plot_ly(sd) %>%
      add_trace(x = ~ x, y = ~ y, type = "bar", color = ~ fill,
                marker = list(line = list(color = "white", width = 1)) ## add border to see the 2 groups
                ) %>%
      layout(barmode = "stack"))
```

Graph is not updated

thothal
  • 16,690
  • 3
  • 36
  • 71

1 Answers1

0

A smoother workaround is to use the window.onload hook. This avoids the need to specify the timeout delay and as opposed to $.ready fires not once the DOM is loaded, but the whole page is ready. Exactly what I need, unless there is a dedicated hook in plotly for this kind of operation? plotly_afterplot semmed to be the right candidate. Yet again this is not available on $.ready

window.onload = function() {
   // set dropdown to first element
   $('.selectized').each(function(idx, el) {
      const sel = this.selectize;
      const options = Object.keys(sel.options);
      sel.setValue(options[0]);
   });

thothal
  • 16,690
  • 3
  • 36
  • 71