echarts 地图迁徙与地图下钻
一、迁徙
1、引入中国地图数据及echarts
const china = require("./echarts-mapJson-master/china.json")
import * as echarts from 'echarts'
2、数据准备
// 点数据 需要hover或点击获取数据可以添加额外的参数,
// 如{ value: [118.8062, 31.9208], code:'440100',itemStyle: { color: '#4ab2e5' },code可以在hover或点击的时候拿到;
// 数组最后一个点是线指向的终点,也可不设
let poinstData = [
{ value: [118.8062, 31.9208], itemStyle: { color: '#4ab2e5' } }
, { value: [127.9688, 45.368], itemStyle: { color: '#4fb6d2' } }
, { value: [110.3467, 41.4899], itemStyle: { color: '#52b9c7' } }
, { value: [125.8154, 44.2584], itemStyle: { color: '#5abead' } }
, { value: [116.4551, 40.2539], itemStyle: { color: '#f34e2b' } }
, { value: [123.1238, 42.1216], keysValue: 8, itemStyle: { color: '#f56321' } }
, { value: [114.4995, 38.1006], itemStyle: { color: '#f56f1c' } }
, { value: [117.4219, 39.4189], itemStyle: { color: '#f58414' } }
, { value: [112.3352, 37.9413], itemStyle: { color: '#f58f0e' } }
, { value: [109.1162, 34.2004], itemStyle: { color: '#f5a305' } }
, { value: [103.5901, 36.3043], itemStyle: { color: '#e7ab0b' } }
, { value: [106.3586, 38.1775], itemStyle: { color: '#dfae10' } }
, { value: [101.4038, 36.8207], itemStyle: { color: '#d5b314' } }
, { value: [103.9526, 30.7617], itemStyle: { color: '#c1bb1f' } }
, { value: [108.384366, 30.439702], itemStyle: { color: '#b9be23' } }
, { value: [113.0823, 28.2568], itemStyle: { color: '#a6c62c' } }
, { value: [102.9199, 25.46639], itemStyle: { color: '#96cc34' } }
, { value: [113.335367, 23.13559]}
],
// 线数据 同样可以添加额外的参数,点击时type为lines时可拿到参数
let linesData = [
{ coords: [ [118.8062, 31.9208],[113.335367, 23.13559]], lineStyle: { color: '#4ab2e5' } }
, { coords: [ [127.9688, 45.368],[113.335367, 23.13559]], lineStyle: { color: '#4fb6d2' } }
, { coords: [ [110.3467, 41.4899],[113.335367, 23.13559]], lineStyle: { color: '#52b9c7' } }
, { coords: [ [125.8154, 44.2584],[113.335367, 23.13559]], lineStyle: { color: '#5abead' } }
, { coords: [ [116.4551, 40.2539],[113.335367, 23.13559]], lineStyle: { color: '#f34e2b' } }
, { coords: [ [123.1238, 42.1216],[113.335367, 23.13559]], lineStyle: { color: '#f56321' } }
, { coords: [ [114.4995, 38.1006],[113.335367, 23.13559]], lineStyle: { color: '#f56f1c' } }
, { coords: [ [117.4219, 39.4189],[113.335367, 23.13559]], lineStyle: { color: '#f58414' } }
, { coords: [ [112.3352, 37.9413],[113.335367, 23.13559]], lineStyle: { color: '#f58f0e' } }
, { coords: [ [109.1162, 34.2004],[113.335367, 23.13559]], lineStyle: { color: '#f5a305' } }
, { coords: [ [103.5901, 36.3043],[113.335367, 23.13559]], lineStyle: { color: '#e7ab0b' } }
, { coords: [ [106.3586, 38.1775],[113.335367, 23.13559]], lineStyle: { color: '#dfae10' } }
, { coords: [ [101.4038, 36.8207],[113.335367, 23.13559]], lineStyle: { color: '#d5b314' } }
, { coords: [ [103.9526, 30.7617],[113.335367, 23.13559]], lineStyle: { color: '#c1bb1f' } }
, { coords: [ [108.384366, 30.439702],[113.335367, 23.13559]], lineStyle: { color: '#b9be23' } }
, { coords: [ [113.0823, 28.2568],[113.335367, 23.13559]], lineStyle: { color: '#a6c62c' } }
, { coords: [ [102.9199, 25.46639],[113.335367, 23.13559]], lineStyle: { color: '#96cc34' } }
]
3、获取options
getOptions(name, id, seriesData, pointsData, linesData ){
let _this = this;
return {
backgroundColor: '#0F1C3C',
toolbox: { // 返回按钮
right: '5%',
top: '15%',
feature: {
myBack: {
show: false,
title: '返回',
icon: 'path://M473.2 276.9v-133c-4-18.4-11.7-27-20.2-30.3-17.2-6.7-37.8 8.5-37.8 8.5L95.9 395.4c-70.1 48.4-4.8 84.7-4.8 84.7L405.5 751c62.9 46 67.7-24.2 67.7-24.2V603.4c319.3-99.2 449.9 297.5 449.9 297.5 12.1 21.8 19.3 0 19.3 0 123.4-595-469.2-624-469.2-624z m0 0',
iconStyle: {
color: "#1aaef6",
borderColor: "#1aaef6"
},
onclick: async function () {
const seriesData = await _this.handleMap('china', chinaJson);
const opt = await _this.getOptions('china', '', seriesData, _this.pointsData, _this.linesData)
await _this.myChart.setOption(opt, true);
}
}
}
},
tooltip: {
trigger: 'item',
backgroundColor: '#ffff',
borderColor: '#FFFFCC',
showDelay: 0,
hideDelay: 0,
enterable: true,
transitionDuration: 0,
extraCssText: 'z-index:100',
formatter: function (params, ticket, callback) {
let name = params.name
//根据业务自己拓展要显示的内容
// 自定义数据 params.data
let res = "<div>" + name + '</div>'
return res;
},
},
geo: {
map: 'china',// 下钻时以当前地图名称命名
show: true,
roam: true,
zoom: 1.2,
label: {
show: true,
color: '#1DE9B6',
emphasis: {
show: true,
areaColor: {
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#073684' // 0% 处的颜色
},
{
offset: 1,
color: '#061E3D' // 100% 处的颜色
}
]
}
}
},
layoutSize: '100%',
itemStyle: {
areaColor: {
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#073684' // 0% 处的颜色
},
{
offset: 1,
color: '#061E3D' // 100% 处的颜色
}
]
},
borderColor: '#2863ad',
borderWidth: 1,
shadowColor: 'rgba(10,76,139,1)',
shadowOffsetY: 0,
shadowBlur: 60,
emphasis: {
areaColor: '#2AB8FF',
borderWidth: 0,
color: 'green',
label: {
show: false
}
}
},
},
series: [
{
type: 'map',
map: 'china',// 有data时不需要
roam: true,
geoIndex: 0,
aspectScale: 0.85, //长宽比
show: true,
textStyle: {
color: '#1DE9B6'
},
emphasis: {
textStyle: {
color: 'rgb(183,185,14)'
}
},
itemStyle: {
borderColor: 'rgb(147, 235, 248)',
borderWidth: 1,
areaColor: {
type: 'radial',
x: 0.5,
y: 0.5,
r: 0.8,
colorStops: [{
offset: 0,
color: '#09132c' // 0% 处的颜色
}, {
offset: 1,
color: '#274d68' // 100% 处的颜色
}],
globalCoord: true // 缺省为 false
},
emphasis: {
areaColor: 'rgb(46,229,206)',
// shadowColor: 'rgb(12,25,50)',
borderWidth: 0.1
}
},
// data:[{name:'',value:[经,纬]}]
},
{
type: 'effectScatter', // 动效散点
coordinateSystem: 'geo',
showEffectOn: 'render',
zlevel: 1,
rippleEffect: { // 涟漪特效
period: 4, // 动画的周期,秒数
scale: 5, // 动画中波纹的最大缩放比例
brushType: 'stroke',// ['fill','stroke'] 波纹海浪或线圈
},
hoverAnimation: true,
label: {
formatter: '{b}',
position: 'right',
offset: [15, 0],
color: '#1DE9B6',
show: true
},
itemStyle: {
color: '#1DE9B6',
shadowBlur: 10,
shadowColor: '#333'
},
symbolSize: function (val) { // 点大小
return 12
},
data: pointsData
}, //地图线的动画效果
{
type: 'lines',
zlevel: 2,
effect: {
show: true,
period: 4, // 箭头指向速度,值越小速度越快
trailLength: 0.4, // 特效尾迹长度[0,1]值越大,尾迹越长重
symbol: 'arrow', // 箭头图标
symbolSize: 7, // 图标大小
},
lineStyle: {
color: '#1DE9B6',
width: 1, // 线条宽度
opacity: 0.1, // 尾迹线条透明度
curveness: .3 // 尾迹线条曲直度
},
data: linesData
}
]
};
}
4、画图
// 先引入中国地图,再画图
async loadData(){
let _this = this;
this.myChart = echarts.getInstanceByDom(this.$refs.baseEcharts);
if (!this.myChart) {
this.myChart = await echarts.init(this.$refs.baseEcharts);
}
await _this.myChart.setOption(option);
}
二、下钻
1、画中国地图
2、从地图点击事件中获取到省级id或市级编码(具体看下一级显示什么)
3、根据省级id拿到对应省级地图数据,注册地图
4、拿到对应option,再setOptions,返回中国地图再画一遍中国地图(当前显示哪一个地图就画哪一个地图)
5、缩放或其他原因,切换地图后地图不在容器中心点解决,setOptions(option,true)
,true意思为重新绘画地图
/**
* 获取当前配置项
* @param{string} name 当前地图
* @param{string} id 当前地图id
* @param{array} seriesData 组[{name,value}]
* @param{array} pointsData 点
* @param{array} linesData 线
* */
async getOptions(name, id, seriesData, pointsData, linesData) {
let _this = this;
// 参考迁徙图
return{}
}
/**
* @description 画图
* @param{string} name 画图
* @param{object} json 当前地图数据
* @return{array} [{name:'',value:[]}]
* */
async handleMap(name, json) {
let obj = {}, map = [];
// 1、初始化全国地图
// 2、设置点击事件-单击下钻,双击返回
// 3、单击注册点击省份地图-setOption画图
// 4、双击返回,重新画全国地图
if (name !== 'china') { // 注册地图
echarts.registerMap(name, json);
}
let mapFeatures = echarts.getMap(name) ? echarts.getMap(name).geoJson.features : [];
mapFeatures.forEach(function (v) {
obj = { name: v.properties.name, value: v.properties.cp }
if (name === 'china') {
obj.value.push(v.properties.id)
}
map.push(obj)
});
return map
},
/**
* @description 实例化
* */
async loadData() {
let _this = this;
this.myChart = echarts.getInstanceByDom(this.$refs.baseEcharts);
if (!this.myChart) {
this.myChart = await echarts.init(this.$refs.baseEcharts);
}
// 全国地图
echarts.registerMap('china', chinaJson);
// 每个地图点,series第一个type: 'map'的data
const seriesData = await this.handleMap('china', chinaJson);
// options
const opt = await this.getOptions('china', '', seriesData, this.pointsData, this.linesData)
// 绘画
await this.myChart.setOption(opt);
// 监控窗口变化
// window.addEventListener("resize", this.resize); // myChart.resize();
this.myChart.on('click', async function (params) {
// 项目点击-下钻
if (params.data && params.data.value && params.data.value[2]) {
const json = require('./echarts-mapJson-master/geometryProvince/' + params.data.value[2] + '.json')
if (!json) {
return;
}
const seriesData = await _this.handleMap(params.data.value[2], json);
const opt = await _this.getOptions(params.data.value[2], params.data.value[2], seriesData, _this.pointsData, _this.linesData)
opt.toolbox.feature.myBack.show = true
await _this.myChart.setOption(opt, true);
}
})
// 双击返回
this.myChart.on('dblclick', async function (params) {
if (params.type === 'dblclick' && params.data && (!params.data.value || !params.data.value[2])) {
const seriesData = await _this.handleMap('china', chinaJson);
const opt = await _this.getOptions('china', '', seriesData, _this.pointsData, _this.linesData)
await _this.myChart.setOption(opt, true);
}
})
},
参考:
1、echarts Demo集 https://www.isqqw.com/
2、https://datav.aliyun.com/portal/school/atlas/area_selector#&lat=31.027163647290617&lng=106.75386074913891&zoom=4.5
3、地图资源 https://gitee.com/niceguy802/map-resources.git