Table of Contents
每次写之前没碰到过的需求时都有“臣妾做不到”的烦恼。在 echarts 的示例中,可以找到很多双层 geo 的例子,但是难以找到可同步拖动的。不管怎样,先把双层 geo 搞出来。
双层 geo
geo: [ // 底图 { id: 'base', map: mapCode, animation: false, roam: true, silent: true, layoutCenter: ['51%', '51%'], layoutSize: '100%', tooltip: { show: false, }, scaleLimit: { min: 1, max: maxZoom, }, center: this.center.length ? this.center : undefined, zoom: this.zoom, label: { show: false, }, itemStyle: { areaColor: 'rgba(0, 162, 255, 0.17)', borderColor: 'rgba(0, 162, 255, 1)', borderWidth: 0, }, }, { id: 'map', map: mapCode, animation: false, zlevel: 2, roam: true, layoutCenter: ['50%', '50%'], layoutSize: '100%', tooltip: { show: false, }, scaleLimit: { min: 1, max: maxZoom, }, center: this.center.length ? this.center : undefined, zoom: this.zoom, label: { show: false, }, itemStyle: { areaColor: { image: this.dotImage, repeat: 'repeat', }, borderColor: 'rgba(0, 162, 255, 1)', borderWidth: 1.3, }, emphasis: { label: { show: false, textStyle: { color: 'rgba(255,255,255,0.7)', fontSize: 14 * windowSize.widthScale, }, }, itemStyle: { areaColor: { image: this.hoverDotImage, repeat: 'repeat', }, borderWidth: 1.6, }, }, regions: code && mapCache.get(code) ? mapCache .get(code) ?.features?.map((feature: GeoJSON.Feature) => { const igonre = feature.properties?.name === '_' return { name: feature.properties?.name ?? '', itemStyle: { areaColor: igonre ? 'rgba(0,0,0,0)' : undefined, }, label: { show: !igonre, color: 'rgba(0, 192, 255, 1)', fontSize: 14 * windowSize.widthScale, }, emphasis: { label: { show: !igonre, }, itemStyle: { areaColor: igonre ? 'rgba(0,0,0,0)' : undefined, }, }, } }) : [], }, ],
第二层 geo 包含了 regions 的配置,顺便复制上来了。
同步拖动
关于同步拖动,根据网友写的 georoam 事件的监听,适配了 react。但是,卡爆了,并且拖动缓慢、中断。原因是,我把 center 和 zoom 放到了 state 里,这样 echarts(echarts-for-react) 可以及时响应,但不停更新也导致了卡顿。因此,不能借助于 react 的响应式设计,需要自己调用 echarts 实例更新。
const onEvents = { georoam: (params: any) => { let tempOption = this.el?.getOption() if (tempOption && params.componentType === 'geo') { const geo = ( tempOption.geo as Array<echarts.EChartOption.Series> ).find((v) => v.id === params.geoId) this.center = (geo as any).center || [] this.zoom = (geo as any).zoom ;(tempOption.geo as Array<echarts.EChartOption.Series>).map( (v: any) => { v.center = this.center v.zoom = this.zoom }, ) this.el?.setOption(tempOption) } }, }
如双层 geo 的配置所示,center 和 zoom 也会取 this.center 和 this.zoom 的值,所以当组件 render 的时候位置和缩放都与手动设置的相同,不会显得违和。