echarts-for-react 重新渲染导致地图归位的问题

其实标题应该改一改,因为这个是 echarts 的问题,不是具体的适用于某个框架的包装组件的问题。

问题的表现是,用 echarts + geojson 展示地图数据。在点击某个点,更新数据后,已经缩放/移动的地图回到了初始大小/位置。此外,数据会定时从服务端拉取,每次拉取数据也会触发重新渲染,地图归位。在之前公司,我也碰到了这样的问题(那时用的是 vue,所以说,标题不准确),但是解决问题后没有记录,现在也忘了当时是怎么解决的。所以,这次又探索了许久(原谅我太菜)。

一开始考虑是不是notMerge选项的问题,无果;然后考虑是不是 option 写在 render 里面的问题,于是尝试了在生命周期里定义初始 option ,在 render 里面比较差异,依然无果。然后想起来是不是可以在渲染之前获取 echarts 中地图的位置和缩放,然后设置这两个值,让其显示“正确”。查了下文档,echarts-for-react 确实提供了相关 Api:getEchartsInstance。看到希望了,于是,在 componentDidMount 里面获取实例:

this.echartsInstance = this.reactEchartsInstance.getEchartsInstance()

然后在 render 里面通过 this.echartsInstance.getOption() 获取配置项。但还是出了问题。第一次改变后的渲染是有效的,没有回到初始状态,但之后的渲染则都回到了第一次改变后的状态。看了下获取到的配置项,发现之后的配置项都是第一次获取到的值。没办法,只能将获取 echarts 实例的工作放到 render 里面:

let option = {...}

// 获取 echarts 实例
let instance = this.reactEchartsInstance ? this.reactEchartsInstance.getEchartsInstance() : null

// 获取之前的配置项
let prevOption = instance ? instance.getOption() : null

// 如果地图没有切换,则保持当前地图的缩放和位置,避免因为重新渲染导致地图归位
if (prevOption && prevOption.geo[0].map === (this.state.curProvince || 'china' )) {
  console.log(prevOption.geo[0])
  option.geo.zoom = prevOption.geo[0].zoom
  option.geo.center = prevOption.geo[0].center
}

看了下结果,大功告成。