Search code examples
rshinyechartsecharts4r

echarts4r with tabsetPanel - re-animate when switching back to tab


I want the charts to show the animation every time you click on a tab, not just the first. Here's what I got:

library(echarts4r)
library(magrittr)

ui <- fluidPage(
  tabsetPanel(id = "tabsetpanel", 
              tabPanel("Panel A", value = "A", echarts4rOutput("chartA")
              ),
              tabPanel("Panel B", value = "B", echarts4rOutput("chartB")
              )
  )
)

server <- function(input, output, session) {

  output$chartA <- renderEcharts4r({
    data <- data.frame(x = 1:2, y = 1:10)
    
    input$tabsetpanel
    
    e_charts(data, x = x) %>%
    e_bar(serie = y)
  })
  
  output$chartB <- renderEcharts4r({
    data <- data.frame(x = 1:5, y = 11:20)
    
    input$tabsetpanel
    
    e_charts(data, x = x) %>%
      e_bar(serie = y)
  })
    
}


shinyApp(ui, server)

Including input$tabsetpanel is very close to what I want, it invalidates the expression. However, for a split second the graph seems to shrink, and only then does it start up again. This looks kinda janky, is there a better approach?


Solution

  • We could add an observer that reacts to changes in the active tab and re-renders the appropriate chart. This ensures that the animation is played every time the user switches to a different tab:

    library(echarts4r)
    library(magrittr)
    library(shiny)
    
    ui <- fluidPage(
      tabsetPanel(id = "tabsetpanel", 
                  tabPanel("Panel A", value = "A", echarts4rOutput("chartA")
                  ),
                  tabPanel("Panel B", value = "B", echarts4rOutput("chartB")
                  )
      )
    )
    
    server <- function(input, output, session) {
      
      current_tab <- reactiveVal("A")
      
      observeEvent(input$tabsetpanel, {
        current_tab(input$tabsetpanel)
      })
      
      output$chartA <- renderEcharts4r({
        data <- data.frame(x = 1:2, y = 1:10)
        
        e_charts(data, x = x) %>%
          e_bar(serie = y)
      })
      
      output$chartB <- renderEcharts4r({
        data <- data.frame(x = 1:5, y = 11:20)
        
        e_charts(data, x = x) %>%
          e_bar(serie = y)
      })
      
      observe({
        if (current_tab() == "A") {
          output$chartA <- renderEcharts4r({
            data <- data.frame(x = 1:2, y = 1:10)
            
            e_charts(data, x = x) %>%
              e_bar(serie = y)
          })
        } else {
          output$chartB <- renderEcharts4r({
            data <- data.frame(x = 1:5, y = 11:20)
            
            e_charts(data, x = x) %>%
              e_bar(serie = y)
          })
        }
      })
    }
    
    shinyApp(ui, server)
    
    

    enter image description here