You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用echarts4rProxy在Shiny图表中添加和移除标记?

解决echarts4rProxy动态添加/移除标记与高亮的索引问题

你在Shiny中使用echarts4rProxy动态处理图表高亮和标记时遇到两个核心问题:

  • 设置serie_index = 1时,多数场景正常,但关闭图例第一个系列(D组)后,选中其他系列(如F组)能高亮但无法显示标记;
  • 设置serie_index = linenum(对应系列序号)时,多次选择后会出现多个标记残留的异常。

问题原因分析

  1. 固定索引的适配问题:echarts中系列的实际渲染索引会随图例的显示/隐藏动态变化,关闭第一个系列后,原有的索引对应关系错位,导致标记无法绑定到正确系列;
  2. 标记移除逻辑缺陷:原JS代码仅清空全局markPoint数组,但echarts的标记是绑定到单个系列的,全局清空无法彻底清除各系列的标记残留,多次操作后就会出现重复标记。

解决方案

核心修复点

  • 用系列名称替代索引:在e_mark_p中使用series_name参数指定目标系列,彻底避免索引变化带来的错位问题;
  • 优化标记移除逻辑:修改JS代码,遍历所有系列并清除每个系列的markPoint,确保完全移除旧标记;
  • 简化代理操作逻辑:合并重复的代理调用,减少冗余操作。

修改后的完整代码

library(shiny)
library(data.table)
library(echarts4r)

dt <- as.data.table(copy(diamonds))
dt <- unique(dt[color %in% c("D", "E", "F") & cut == "Premium"], by = c("cut", "color", "clarity"))
setorder(dt, clarity)

# 移除所有标记的函数
e_remove_mark_p <- function(proxy) {
  opts <- list(id = proxy$id)
  proxy$session$sendCustomMessage("e_remove_mark_p", opts)
  return(proxy)
}

ui <- fluidPage(
  tags$head(
    tags$script(HTML("
      Shiny.addCustomMessageHandler('e_remove_mark_p', function(data) {
        var chart = get_e_charts(data.id);
        let opts = chart.getOption();
        // 遍历所有系列,清除每个系列的markPoint
        if(opts.series) {
          opts.series.forEach(function(serie) {
            if(serie.markPoint) {
              serie.markPoint.data = [];
            }
          });
        }
        chart.setOption(opts, true);
      })
    "))
  ),
  fluidRow(radioButtons("line", label = "聚焦系列", choices = c("D", "E", "F", "无"), selected = "无")),
  fluidRow(echarts4rOutput("plot"))
)

server <- function(input, output, session) {
  # 初始化图表
  output$plot <- renderEcharts4r({
    dt |>
      group_by(color) |>
      e_charts(clarity) |>
      e_line(price,
             legendHoverLink = TRUE,
             emphasis = list(disabled = FALSE, focus = "series", blurScope = "coordinateSystem", lineStyle = list(width = 2))) |>
      e_tooltip(trigger = "item")
  })
  
  # 动态处理高亮与标记
  observe({
    # 先重置所有状态:取消高亮+移除所有标记
    echarts4rProxy("plot") |>
      e_downplay_p() |>
      e_remove_mark_p()
    
    if (input$line != "无") {
      linename <- input$line
      tmp <- dt[color == linename]
      
      # 高亮目标系列 + 添加标记(用series_name指定系列)
      echarts4rProxy("plot") |>
        e_highlight_p(series_name = linename) |>
        e_mark_p(
          series_name = linename,  # 用系列名称替代serie_index
          data = list(list(
            yAxis = tmp[clarity == "IF", price],
            xAxis = tmp[clarity == "IF", clarity],
            value = tmp[clarity == "IF", price]
          )),
          itemStyle = list(color = "red")
        ) |>
        e_merge()
    }
  })
}

shinyApp(ui, server)

关键修改说明

  1. 标记移除逻辑优化:JS代码中遍历opts.series,逐个清除每个系列的markPoint.data,确保所有旧标记都被彻底移除;
  2. 系列绑定方式调整:e_mark_p中使用series_name = linename,不管系列的显示状态如何变化,都能准确绑定到目标系列;
  3. 代理操作简化:将重复的代理调用合并,避免多次创建代理实例,减少不必要的冗余操作。

内容的提问来源于stack exchange,提问作者user25339946

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:14:52