I am trying to display a graph using echarts4r in a Shiny application, where the user can adjust a dynamic threshold (Threshold).
I want only the "Threshold" series to update without redrawing the entire graph (i.e., the zoom level and other series should remain fixed).
I tried to use the poxy function from echarts4r, with no success.
Here is my code:
library(shiny)
library(echarts4r)
library(dplyr)
set.seed(123)
df <- data.frame(
Date = seq(as.Date("2023-01-01"), by = "week", length.out = 104),
Cas = sample(50:500, 52, replace = TRUE),
Cas_A = sample(20:100, 52, replace = TRUE),
Cas_B = sample(5:50, 52, replace = TRUE),
Cas_C = sample(1:20, 52, replace = TRUE),
Threshold = rep(200, 52) # Valeur initiale du seuil
)
ui <- fluidPage(
titlePanel("TEST"),
sidebarLayout(
sidebarPanel(
sliderInput("Percentile", "Threshold Value:", min = 1, max = 99, value = 50, step = 1)
),
mainPanel(
echarts4rOutput("Graph")
)
)
)
server <- function(input, output, session) {
reactive_threshold <- reactive({
perc <- input$Percentile
perc_threshold <- quantile(df$Cas, probs = perc / 100, na.rm = TRUE)
cdc_nat_threshold <- df %>%
mutate(Threshold = perc_threshold)
return(cdc_nat_threshold)
})
output$Graph <- renderEcharts4r({
reactive_threshold() |>
e_charts(Date) |>
e_line(Cas, name = "Cas", lineStyle = list(color = "#ff8000", width = 2, opacity = 0.4)) |>
e_bar(Cas_A, name = "Cas_A", stack = "group", itemStyle = list(color = "#C1D8C3")) |>
e_bar(Cas_B, name = "Cas_B", stack = "group", itemStyle = list(color = "#6A9C89")) |>
e_bar(Cas_C, name = "Cas_C", stack = "group", itemStyle = list(color = "#d63e0b")) |>
e_line(Threshold, name = "Threshold", lineStyle = list(color = "#f02b2b", width = 1, type = "dashed", opacity = 0.8)) |>
e_legend(show = TRUE) |>
e_axis_labels(y = "Weekly") |>
e_tooltip(trigger = "axis") |>
e_datazoom(x_index = 0, toolbox = FALSE, start = 20, end = 50) |>
e_group("shared_zoom") |>
e_connect_group("shared_zoom")
})
observeEvent(input$Percentile, {
echarts4rProxy("Graph") |>
e_line(
Threshold) |>
e_execute()
})
}
shinyApp(ui, server)
Perhpas this fits your need. First, to avoid that the entire chart gets redrawn when the reactive dataset changes, I wrap it in isolate()
. Second, in the observeInit
I pass the updated data to the data=
argument of echarts4rProxy()
. Additionally we have to set the x = Date
. Next, we have to remove the existing series using e.g. e_remove_series
and finally add a new line.
library(shiny)
library(echarts4r)
library(dplyr)
ui <- fluidPage(
titlePanel("TEST"),
sidebarLayout(
sidebarPanel(
sliderInput("Percentile", "Threshold Value:", min = 1, max = 99, value = 50, step = 1)
),
mainPanel(
echarts4rOutput("Graph")
)
)
)
server <- function(input, output, session) {
reactive_threshold <- reactive({
perc <- input$Percentile
perc_threshold <- quantile(df$Cas, probs = perc / 100, na.rm = TRUE)
cdc_nat_threshold <- df %>%
mutate(Threshold = perc_threshold)
return(cdc_nat_threshold)
})
output$Graph <- renderEcharts4r({
isolate(
reactive_threshold()
) |>
e_charts(Date) |>
e_line(Cas, name = "Cas", lineStyle = list(color = "#ff8000", width = 2, opacity = 0.4)) |>
e_bar(Cas_A, name = "Cas_A", stack = "group", itemStyle = list(color = "#C1D8C3")) |>
e_bar(Cas_B, name = "Cas_B", stack = "group", itemStyle = list(color = "#6A9C89")) |>
e_bar(Cas_C, name = "Cas_C", stack = "group", itemStyle = list(color = "#d63e0b")) |>
e_line(Threshold, name = "Threshold", lineStyle = list(color = "#f02b2b", width = 1, type = "dashed", opacity = 0.8)) |>
e_legend(show = TRUE) |>
e_axis_labels(y = "Weekly") |>
e_tooltip(trigger = "axis") |>
e_datazoom(x_index = 0, toolbox = FALSE, start = 20, end = 50) |>
e_group("shared_zoom") |>
e_connect_group("shared_zoom")
})
observeEvent(input$Percentile, {
echarts4rProxy("Graph", data = reactive_threshold(), x = Date) |>
e_remove_serie("Threshold") |>
e_line(Threshold, name = "Threshold", lineStyle = list(color = "#f02b2b", width = 1, type = "dashed", opacity = 0.8)) |>
e_execute()
})
}
shinyApp(ui, server)