在使用 ECharts 处理大数据场景时,我们发现触发高亮效果后,顶层 Canvas 出现图像残影未及时清理的问题。本文记录了问题的复现过程、可能的原因分析以及最终的解决方案。

问题描述

在客户环境下测试时,接口返回了大量数据。在本地重现时,我们稳定复现了以下问题:

  1. 图表渲染后不触发 hover 操作,不会出现异常。
  2. 一旦触发了 x 坐标轴的高亮效果,会在顶层 Canvas 留下残影,并且残影不会随鼠标移动或图表刷新而消失。

通过观察 DOM 结构,发现这些异常的 Canvas 节点具有属性 data-zr-dom-id="zr_100000"

Snipaste_2024-12-26_10-25-03.png

相关现象

%E6%88%AA%E5%B1%8F2024-12-26%2011.03.19.png

  • 只有触发 hover 操作时才会产生残影。
  • 残影问题在大数据量场景中稳定复现。
  • 通过分析源码和社区反馈,初步判断是 ECharts 在大数据场景下的 Canvas 分层优化策略存在问题。

原因分析

ECharts 在处理大数据时,会对 Canvas 进行分层优化。高亮效果被渲染到顶层的 Canvas,但在某些情况下,这一层没有被正确刷新,从而导致残影问题。

根本原因在于:一次性触发了太多内容(如一个 Category 中包含过多的散点、折线或箱图),导致高亮效果的刷新逻辑未能正确处理所有数据。

社区资料参考

虽然未找到直接相关的资料,但以下链接提供了一些背景信息:

解决方案

经过分析和多次尝试,最终我们决定从配置入手,禁用可能引发问题的高亮效果。

禁用高亮效果的实现

我们在 ECharts 的配置项中注释掉了 axisPointer 的相关配置:

return {
    grid: finalGrid,
    xAxis: [...xAxis, ...xAxisExtends],
    yAxis: [...yAxis, ...yAxisExtends],
    series: finalSeries,
    tooltip: {
      show: true,
      confine: true,
      // 大数据场景下一次性触发太多高亮效果会有残影问题
      // axisPointer: {
      //   axis: 'auto',
      //   type: 'cross',
      // },
    },
    legend: { show: true, top: -10000, width: 10000, data: boxPlotData.colorBys },
    xAxisConfList: finalXAxisConfList,
    dataZoom,
} as EChartsOption;

配置项说明

  • tooltip.axisPointer: axisPointer 是导致残影的主要原因。在大数据场景中禁用该功能,可以有效避免问题。
  • legend.top 和 legend.width: 用于调整图例显示,避免占用太多空间。

优化后的效果

禁用 axisPointer 后,我们重新测试了以下场景:

  1. 渲染后的静态图表。
  2. 图表中鼠标 hover 触发高亮效果。

结果显示,残影问题已完全解决,图表交互性能也有所提升。

总结

ECharts 在大数据场景下提供了强大的渲染能力,但一些高级功能(如 axisPointer)可能在极端场景中引发问题。根本原因是一次性触发了过多内容,导致刷新逻辑未能完全处理。通过合理简化配置,可以在保证功能性的同时,避免性能和交互上的潜在问题。

如果你也遇到类似问题,可以尝试调整配置,禁用高亮效果,或优化数据量和渲染方式。


A Student on the way to full stack of Web3.