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 的时候位置和缩放都与手动设置的相同,不会显得违和。
