步骤:
- 通过 DataV.GeoAtlas地理小工具系列 网站获取到数据
- registerMap注册地图
- 初始化图表
- 配置echarts地理坐标系组件, 配置要渲染的数据
示意图 | 示意图 |
---|---|
|
|
|
|
核心代码如下,更多代码详细见仓库: https://gitee.com/whongli/map
import * as echarts from 'echarts'
import {httpGet} from '@/js/api/baseApi'
var chinaMap
export default {
methods: {
async init ({url, option}) {
let res = await httpGet(url) // 获取地图数据
let chinaJson = res
echarts.registerMap('china', chinaJson)
chinaMap = echarts.init(document.getElementById('china-map'))
chinaMap.setOption(option)
chinaMap.on('click', async (params) => {
console.log(params)
this.$router.push(`/province?name=${params.name}`)
})
},
async provinceInit ({url, option}) {
let res = await httpGet(url)
let chinaJson = res
echarts.registerMap('china', chinaJson)
chinaMap = echarts.init(document.getElementById('china-map'))
chinaMap.setOption(option)
chinaMap.on('click', async (params) => {
console.log(params)
// TODO: 省市点击回调
})
},
/**
* 地图配置
* @param {*} series {data,title,zoom, tooltip, center}
* @returns 返回配置信息
*/
constructorOption (series) {
return {
backgroundColor: '#fff',
// 地图上圆点的提示
tooltip: {
trigger: 'item',
formatter: function (params) {
console.log(params)
return params.name + ' : ' + params.value[2]
}
},
// 图例按钮 点击可选择哪些不显示
legend: {
orient: 'vertical',
left: 'left',
top: 'bottom',
data: [],
textStyle: {
color: '#fff'
}
},
// 地理坐标系组件
geo: {
map: 'china',
zoom: series.zoom || 1.25, // 设置初始化的缩放比例
roam: false, // true 允许缩放拖动
center: series.center || [104.123557, 32.058039],
label: {
// true hover时地图内部会显示城市名
emphasis: {
show: false
}
},
tooltip: series.tooltip || {
show: true,
trigger: 'item',
formatter: function (params) {
console.log(params)
let html = `
地区: ${params.name}
人口:46万(人) ${params.name}
旅游人数:6万(人) ${params.name}
`
return html
}
},
itemStyle: {
// 地图背景色
normal: {
areaColor: '#fff',
borderColor: '#747569'
},
// 悬浮时
emphasis: {
areaColor: '#c82a29',
borderColor: '#c82a29'
}
},
regions: [{ // 省份颜色与界线颜色的修改,如果想修改多个省份就在后面多添加几个对象即可.
// name: '广东', // 对应的是import './china' 数据中的名称如: name: '广东'
// itemStyle: {
// normal: {
// borderColor: '#c82a29', // 省份界线颜色
// borderWidth: 1 // 省份界线的宽度
// }
// }
}]
},
// 系列列表
series: [
{
name: series.name,
type: 'effectScatter',
coordinateSystem: 'geo',
data: series.data, // 从方法中传进来
symbolSize: 8, // 点的大小
symbol: 'circle',
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
// 涟漪特效相关配置
rippleEffect: {
color: '#c82a29',
period: 4,
scale: 2,
brushType: 'fill', // stroke | fill
number: 2
},
showEffectOn: 'render',
itemStyle: {
normal: {
color: {
type: 'radial',
colorStops: [
{
offset: 1,
color: '#c82a29'
}
],
global: false // 缺省为 false
}
}
}
}
]
}
}
}
}
- 直接下载的地图数据文件比较大,可做压缩处理,控制台执行
node minify-map-data.js
,压缩代码参考 echart源码-encode.js
// minify-map-data.js
var fs = require('fs');
var glob = require('glob');
glob('static/map-data/*.json', {}, function (err, files) {
files.forEach(function (file) {
// 这里有做修改
var output = file.replace('map-data', 'minify-map');
var rawStr = fs.readFileSync(file, 'utf8');
var json = JSON.parse(rawStr);
// Meta tag
json.UTF8Encoding = true;
var features = json.features;
if (!features) {
return;
}
features.forEach(function (feature) {
var encodeOffsets = feature.geometry.encodeOffsets = [];
var coordinates = feature.geometry.coordinates;
if (feature.geometry.type === 'Polygon') {
coordinates.forEach(function (coordinate, idx) {
coordinates[idx] = encodePolygon(
coordinate, encodeOffsets[idx] = []
);
});
} else if (feature.geometry.type === 'MultiPolygon') {
coordinates.forEach(function (polygon, idx1) {
encodeOffsets[idx1] = [];
polygon.forEach(function (coordinate, idx2) {
coordinates[idx1][idx2] = encodePolygon(
coordinate, encodeOffsets[idx1][idx2] = []
);
});
});
}
});
// 这里有做修改
fs.writeFileSync(
output, JSON.stringify(json), 'utf8'
);
});
});
function encodePolygon(coordinate, encodeOffsets) {
var result = '';
var prevX = quantize(coordinate[0][0]);
var prevY = quantize(coordinate[0][1]);
// Store the origin offset
encodeOffsets[0] = prevX;
encodeOffsets[1] = prevY;
for (var i = 0; i < coordinate.length; i++) {
var point = coordinate[i];
result += encode(point[0], prevX);
result += encode(point[1], prevY);
prevX = quantize(point[0]);
prevY = quantize(point[1]);
}
return result;
}
// 这个方法我没用
function addAMDWrapper(jsonStr) {
return ['define(function() {',
' return ' + jsonStr + ';',
'});'].join('\n');
}
function encode(val, prev) {
// Quantization
val = quantize(val);
// var tmp = val;
// Delta
val = val - prev;
if (((val << 1) ^ (val >> 15)) + 64 === 8232) {
//WTF, 8232 will get syntax error in js code
val--;
}
// ZigZag
val = (val << 1) ^ (val >> 15);
// add offset and get unicode
return String.fromCharCode(val + 64);
// var tmp = {'tmp' : str};
// try{
// eval("(" + JSON.stringify(tmp) + ")");
// }catch(e) {
// console.log(val + 64);
// }
}
function quantize(val) {
return Math.ceil(val * 1024);
}