需求:地图区分大区展示,将某几个省份绘制成一个大区图形式
注意:如果需要直辖市绘制为一个区域,不绘制区,同样的思路
// config.js
export const regionsMap = {
华北大区: {
names: ['北京', '天津', '河北', '山西', '内蒙古'],
cp: [115.24, 41.54] // 名称的经纬度,可以自己调整到合适的位置
},
东北大区: {
names: ['黑龙江', '吉林', '辽宁'],
cp: [126.32, 44.50]
},
华东大区: {
names: ['山东', '江苏', '安徽', '江西', '浙江', '福建', '上海', '台湾'],
cp: [118.28, 31.13]
},
华中大区: {
names: ['河南', '湖北', '湖南'],
cp: [112.20, 30.32]
},
华南大区: {
names: ['广东', '广西', '海南', '香港', '澳门'],
cp: [113.15, 23.08]
},
西南大区: {
names: ['重庆', '四川', '云南', '西藏', '贵州'],
cp: [98.04, 30.39]
},
西北大区: {
names: ['陕西', '甘肃', '青海', '宁夏', '新疆'],
cp: [98.49, 36.03]
}
}
// utils.js
/**
* 生成大区的 Coordinates & EncodeOffsets
* @param {*} regionNames 省份名称的二维数组 [['北京', ...], ['吉林', ...]]
* @param {*} features 原json数据的features => chinaJson.features
*/
export function mergeCoordEncodeWithRegionNames (regionNames, features) {
const regionsCoordinates = []
const regionsEncodeOffsets = []
for (let i = 0; i < regionNames.length; i++) {
// 大区内省份中属性集合
const polygonsCoordinates = []
const polygonsEncodeOffsets = []
// 大区对应内部的省份名称集合
const provinceNames = regionNames[i]
for (let j = 0; j < provinceNames.length; j++) {
for (let z = 0; z < features.length; z++) {
const { properties: { name }, geometry: { coordinates, encodeOffsets } } = features[z]
// 名称相同,数据写入
if (name === provinceNames[j]) {
// coordinates
if (coordinates[0].constructor === String) {
polygonsCoordinates.push(...coordinates)
} else if (coordinates[0].constructor === Array) {
for (let k = 0; k < coordinates.length; k++) {
polygonsCoordinates.push(...coordinates[k])
}
}
// encodeOffsets
if (encodeOffsets[0].constructor === String) {
// 合并encodeOffsets
polygonsEncodeOffsets.push(encodeOffsets)
} else if (encodeOffsets[0].constructor === Array) {
for (var k = 0; k < encodeOffsets.length; k++) {
if (encodeOffsets[k][0].constructor === Array) {
polygonsEncodeOffsets.push(...encodeOffsets[k])
} else {
polygonsEncodeOffsets.push(encodeOffsets[k])
}
}
}
break
}
}
}
regionsCoordinates.push(polygonsCoordinates)
regionsEncodeOffsets.push(polygonsEncodeOffsets)
}
return {
regionsCoordinates,
regionsEncodeOffsets
}
}
/**
* 生成新的大区 features
* @param {*} regionsMap 大区数据
* @param {*} regionsCoordEncode mergeCoordEncodeWithRegionNames 新生成的 Coordinates & EncodeOffsets
*/
export function createRegionFeatures (regionsMap, regionsCoordEncode) {
const keys = Object.keys(regionsMap)
const values = Object.values(regionsMap)
const {
regionsCoordinates,
regionsEncodeOffsets
} = regionsCoordEncode
const newFeatures = []
for (let i = 0; i < keys.length; i++) {
const feature = {
id: '',
type: 'FeatureCollection',
geometry: {
type: 'Polygon',
coordinates: regionsCoordinates[i],
encodeOffsets: regionsEncodeOffsets[i]
},
properties: {
name: keys[i] || '',
childNum: regionsCoordinates[i].length,
cp: values[i].cp
}
}
newFeatures.push(feature)
}
return newFeatures
}
// region-map.vue
import chinaJson from './china.json'
import regionsMap from './config.js'
import { mergeCoordEncodeWithRegionNames, createRegionFeatures } from './utils.js'
export default {
data () {
chinaJson,
regionsMap,
chart: null,
newJson: null
},
methods: {
// 生成新的json数据
createNewJson () {
const chinaJson = Object.assign({}, this.chinaJson)
const regionNames = Object.values(this.regionsMap).reduce((pre, nex) => {
pre.push(nex.names)
return pre
}, [])
const { features } = chinaJson
const regionsCoordEncode = mergeCoordEncodeWithRegionNames(regionNames, features)
const newFeatures = createRegionFeatures(this.regionsMap, regionsCoordEncode)
chinaJson.features = newFeatures
return chinaJson
},
// 绘制地图
drawChinaMap () {
this.chart = this.$echarts.init(document.getElementById('chinaCon'))
this.chart.off('click')
this.newJson = this.newJson || this.createNewJson()
// 注册
this.$echarts.registerMap('china', this.newJson)
const option = { //... }
this.chart.setOption(option)
// 绑定点击事件
// 注:新版本的echarts用hightlight会出现不能取消选中的情况
this.chart.on('click', (info) => {
const { data: { name } } = info
// 取消高亮
this.chart.dispatchAction({
type: 'unselect'
})
// 高亮
this.chart.dispatchAction({
type: 'select',
seriesIndex: 0,
name: name
})
this.$emit('click', info)
})
}
}
}