timevis icon indicating copy to clipboard operation
timevis copied to clipboard

timevis not rendering properly in quarto dashboard

Open antoine4ucsd opened this issue 8 months ago • 7 comments

Hello I have an issue with htmlwidgets - I was hoping you could help given your expertise with js and htmlwidget. when I render R dashboard like below, the first tab 'timeline' is showing the expected timeline but the second tab is not: the height is incorrect and the data are not displayed properly.if I refresh manually my browser, it 'works' but I have to do it each time I move to a new layout panel or a new tabset within a tab

I also tried to save my widget and include it as iframe but same issue when the timevis is not on the first tab...

# Save widget to an HTML file
timevis(dataOB, height = "700px", width = "1800px") %>%
  saveWidget("timevis_widget.html", selfcontained = TRUE)


<iframe src="timevis_widget.html" width="100%" height="600px" style="border:none;">
</iframe>

see below before refresh the second tab

Image

and after refresh the second tab

Image

my quarto code:

---
title: "test timeline"
format: 
  dashboard:
    embed-resources: true
    scrolling: false
    nav-buttons:
      - icon: globe
---



# Timeline (showing as expected)

## Row {height="100%"}

```{r}
#| title: ⏰ timeline


library(timevis)

countryToCode <- list(
  "Argentina" = "ar",
  "Belgium" = "be",
  "Brazil" = "br",
  "Colombia" = "co",
  "Costa Rica" = "cr",
  "France" = "fr",
  "Germany" = "de",
  "Netherlands" = "nl"
)

# Template for world cup HTML of each item
templateWC <- function(stage, team1, team2, score1, score2) {
  sprintf(
    '<table><tbody>
      <tr><td colspan="3"><em>%s</em></td></tr>
      <tr>
        <td>%s</td>
        <th>&nbsp;%s - %s&nbsp;</th>
        <td>%s</td>
      </tr>
      <tr>
        <td><img src="https://flagpedia.net/data/flags/mini/%s.png" width="31" height="20" alt="%s"></td>
        <th></th>
        <td><img src="https://flagpedia.net/data/flags/mini/%s.png" width="31" height="20" alt="%s"></td>
      </tr>
    </tbody></table>',
    stage, team1, score1, score2, team2, countryToCode[[team1]], team1, countryToCode[[team2]], team2
  )
}

# Data for world cup 2014
dataWC <- data.frame(
  start = c(
    "2014-07-04 13:00",
    "2014-07-04 17:00",
    "2014-07-05 13:00",
    "2014-07-05 17:00",
    "2014-07-08 17:00",
    "2014-07-09 17:00",
    "2014-07-13 16:00"
  ),
  content = c(
    templateWC("quarter-finals", "France", "Germany", 0, 1),
    templateWC("quarter-finals", "Brazil", "Colombia", 2, 1),
    templateWC("quarter-finals", "Argentina", "Belgium", 1, 0),
    templateWC("quarter-finals", "Netherlands", "Costa Rica", "0 (4)", "0 (3)"),
    templateWC("semi-finals", "Brazil", "Germany", 1, 7),
    templateWC("semi-finals", "Netherlands", "Argentina", "0 (2)", "0 (4)"),
    templateWC("final", "Germany", "Argentina", 1, 0)
  ),
  goalsHome = c(0, 2, 1, 4, 1, 2, 1),
  goalsAway = c(1, 1, 0, 3, 7, 4, 0)
)


timevis(dataWC)


```



# Timeline 2 (not showing as expected)

## Row {height="100%"}

```{r}
#| title: ⏰ timeline


timevis(dataWC)

```

thank you!

antoine4ucsd avatar Apr 13 '25 15:04 antoine4ucsd

I have explained in https://github.com/quarto-dev/quarto-cli/issues/12526#issuecomment-2801777603 what Quarto does to trigger a resize for widgets.

It seems timevis does not define something for resize https://github.com/daattali/timevis/blob/ff2bab7e91c6f248919e779e56fb93ba60c19be4/inst/htmlwidgets/timevis.js#L199-L201

So it does nothing.

There could be something else going on, but at least what Quarto tries to do for HTMLwidgets is not efficient with this one.

cderv avatar Apr 14 '25 14:04 cderv

not sure if it can help debugging but I am having similar issue when trying to combine timevis and plotly. in the example below, the timevis will only resize properly after refreshing manually my browser

---
title: "test pltly and timeline"
format: dashboard
---

# pltly

## Row {height="100%"}

```{r}
#| title: example
library(plotly)
library(dplyr)
library(lubridate)

set.seed(123)
df_plot <- data.frame(
  x = rnorm(100),
  y = rnorm(100)
)

plot_ly(df_plot, x = ~x, y = ~y, type = "scatter", mode = "markers")
```

# Timeline

## Row {height="100%"}

```{r}
#| title: example

library(timevis)

countryToCode <- list(
  "Argentina" = "ar",
  "Belgium" = "be",
  "Brazil" = "br",
  "Colombia" = "co",
  "Costa Rica" = "cr",
  "France" = "fr",
  "Germany" = "de",
  "Netherlands" = "nl"
)

# Template for world cup HTML of each item
templateWC <- function(stage, team1, team2, score1, score2) {
  sprintf(
    '<table><tbody>
      <tr><td colspan="3"><em>%s</em></td></tr>
      <tr>
        <td>%s</td>
        <th>&nbsp;%s - %s&nbsp;</th>
        <td>%s</td>
      </tr>
      <tr>
        <td><img src="https://flagpedia.net/data/flags/mini/%s.png" width="31" height="20" alt="%s"></td>
        <th></th>
        <td><img src="https://flagpedia.net/data/flags/mini/%s.png" width="31" height="20" alt="%s"></td>
      </tr>
    </tbody></table>',
    stage, team1, score1, score2, team2, countryToCode[[team1]], team1, countryToCode[[team2]], team2
  )
}

# Data for world cup 2014
dataWC <- data.frame(
  start = c(
    "2014-07-04 13:00",
    "2014-07-04 17:00",
    "2014-07-05 13:00",
    "2014-07-05 17:00",
    "2014-07-08 17:00",
    "2014-07-09 17:00",
    "2014-07-13 16:00"
  ),
  content = c(
    templateWC("quarter-finals", "France", "Germany", 0, 1),
    templateWC("quarter-finals", "Brazil", "Colombia", 2, 1),
    templateWC("quarter-finals", "Argentina", "Belgium", 1, 0),
    templateWC("quarter-finals", "Netherlands", "Costa Rica", "0 (4)", "0 (3)"),
    templateWC("semi-finals", "Brazil", "Germany", 1, 7),
    templateWC("semi-finals", "Netherlands", "Argentina", "0 (2)", "0 (4)"),
    templateWC("final", "Germany", "Argentina", 1, 0)
  ),
  goalsHome = c(0, 2, 1, 4, 1, 2, 1),
  goalsAway = c(1, 1, 0, 3, 7, 4, 0)
)


timevis(dataWC)


```

antoine4ucsd avatar Apr 17 '25 14:04 antoine4ucsd

It is not a combination of library here. The problem is that if timevis is used in the hidden tab, it won't be properly sized by default. Switching tab triggers a resize event, but timevis does not do anything about it AFAIK.

cderv avatar Apr 17 '25 15:04 cderv

not sure if there is any 'easy' fix to trigger a refresh/resize? otherwise I guess this is a timevis issue. thank you!

antoine4ucsd avatar Apr 17 '25 15:04 antoine4ucsd

hello just following up. would it be possible to use the 'redraw' option and trigger it when moving to the corresponding tab?

antoine4ucsd avatar Apr 23 '25 00:04 antoine4ucsd

be possible to use the 'redraw' option and trigger it when moving to the corresponding tab

Can you share the JS that would trigger the redraw ? You can add a event listener for tab switching event and call the function. And try if this works

cderv avatar Apr 28 '25 13:04 cderv

I don't have a good redraw JS yet. running more tests. thank you!

antoine4ucsd avatar Apr 28 '25 14:04 antoine4ucsd