rshinyecharts4r

How to individually control lines in echarts4r wihin a shiny app


I have a Shiny app that uses the echarts4r package to display animated lines.

I want to control each animated line individually using checkboxes.

For example, when I check the Line A checkbox, the animation for Line A should start and remain visible until I uncheck it. The same behavior should apply for each additional line.

However, the current behavior is that when I check a checkbox, all the lines restart their animations and then disappear together. How can I modify my app so that each line's animation is controlled independently without affecting the others?

Here is an example:

library(shiny)
library(echarts4r)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      checkboxInput("lineA", "Show Line A", value = TRUE),
      checkboxInput("lineB", "Show Line B", value = TRUE),
      checkboxInput("lineC", "Show Line C", value = TRUE)
    ),
    mainPanel(
      echarts4rOutput("chart", height = "400px")
    )
  )
)

server <- function(input, output, session) {
  set.seed(123)
  df <- data.frame(
    x  = 1:10,
    yA = cumsum(runif(10, -1, 1)),
    yB = cumsum(runif(10, -1, 1)),
    yC = cumsum(runif(10, -1, 1))
  )
  
  output$chart <- renderEcharts4r({
    chart <- df %>% e_charts(x)
    
    if (input$lineA) {
      chart <- chart %>% 
        e_line(serie = yA, name = "Line A")
    }
    if (input$lineB) {
      chart <- chart %>% 
        e_line(serie = yB, name = "Line B")
    }
    if (input$lineC) {
      chart <- chart %>% 
        e_line(serie = yC, name = "Line C")
    }
    
    chart %>% 
      e_tooltip(trigger = "axis") %>% 
      e_legend()
  })
}

shinyApp(ui, server)

Questions:

  1. Is it possible to control the animated lines, line by line?
  2. Is there another option to accomplish this task?

Solution

  • If I understand you correctly you can use echarts4rProxy and some observeEvents to achieve your desired result. Also note the use of isolate() in the initial setup of the chart. Finally, note that the use of e_legend requires that at least on of the options is checked at the start up (perhaps a bug or I simply haven't found the right option (: ):

    library(shiny)
    library(echarts4r)
    
    ui <- fluidPage(
      sidebarLayout(
        sidebarPanel(
          checkboxInput("lineA", "Show Line A", value = TRUE),
          checkboxInput("lineB", "Show Line B", value = TRUE),
          checkboxInput("lineC", "Show Line C", value = TRUE)
        ),
        mainPanel(
          echarts4rOutput("chart", height = "400px")
        )
      )
    )
    
    server <- function(input, output, session) {
      set.seed(123)
      df <- data.frame(
        x  = 1:10,
        yA = cumsum(runif(10, -1, 1)),
        yB = cumsum(runif(10, -1, 1)),
        yC = cumsum(runif(10, -1, 1))
      )
    
      output$chart <- renderEcharts4r({
        chart <- df |>
          e_charts(x) |>
          e_tooltip(trigger = "axis") |>
          e_legend()
        
        if (isolate(input$lineA)) chart <- e_line(chart, serie = yA, name = "Line A")
        if (isolate(input$lineB)) chart <- e_line(chart, serie = yB, name = "Line B")
        if (isolate(input$lineC)) chart <- e_line(chart, serie = yC, name = "Line C")
        
        chart
      })
    
      observeEvent(input$lineA, {
        name <- "Line A"
        proxy <- echarts4rProxy("chart", data = df, x = x)
        proxy <- e_remove_serie(proxy, name)
        if (input$lineA) proxy <- e_line(proxy, serie = yA, name = name)
        proxy |>
          e_execute()
      })
    
      observeEvent(input$lineB, {
        name <- "Line B"
        proxy <- echarts4rProxy("chart", data = df, x = x)
        proxy <- e_remove_serie(proxy, name)
        if (input$lineB) proxy <- e_line(proxy, serie = yB, name = name)
        proxy |>
          e_execute()
      })
    
      observeEvent(input$lineC, {
        name <- "Line C"
        proxy <- echarts4rProxy("chart", data = df, x = x)
        proxy <- e_remove_serie(proxy, name)
        if (input$lineC) proxy <- e_line(proxy, serie = yC, name = name)
        proxy |>
          e_execute()
      })
    }
    
    shinyApp(ui, server)