需求:画出全国地图,根据后台返回数据,在地图上标出对应的地点(map + 散点)
准备工作:
- 安装依赖
npm install echarts -S
- 在main.js中引入
import echarts from 'echarts'
Vue.prototype.$echarts = echarts;
- 在需要画地图的页面引入地图的 js 或者 json 文件,官方已经不提供下载很久了,我自己在网上找了一份 json datas.json 点击下载 (经纬度多少有点误差,仅供参考)
将该文件放在项目中(我放在了static目录下),引入
import geoData from "../../../../../static/json/datas.json";
以下为代码:
<template>
<div>
<div :id="chartId" style="height:100%;width:100%;"></div>
</div>
</template>
<script>
import geoData from "../../../../../static/json/datas.json";
export default {
data() {
return {
windowSize: [0, 0],
chartId: `map-${this.$root.UUID()}`, //用UUID生成图表id,防止id重复
chart: { map: null, chartData: [], },
}
},
watch: { windowSize() { this.chart.map.resize() }, }, //监听页面窗口变化
mounted() {
this.initChart();
this.$nextTick(() => { this.drawChart(); });
},
methods: {
initChart() {
let _this = this
_this.windowSize = [document.body.clientWidth, document.body.clientHeight];
window.addEventListener('resize', () => { _this.windowSize = [document.body.clientWidth, document.body.clientHeight]; });
_this.chart.map = _this.$echarts.init(document.getElementById(_this.chartId))
},
drawChart() {
let _this = this;
let mapName = 'china'
let geoCoordMap = {};
let tempData = [ //模拟数据
{city:'北京',value:'55'},
{city:'天津',value:'20'},
{city:'西藏',value:'100'},
{city:'辽宁',value:'58'},
]
_this.chart.map.showLoading(); //loading样式
let mapFeatures = _this.$echarts.getMap(mapName).geoJson.features; //获取全国地区的经纬度(只包含了一级城市、省份经纬度)
_this.chart.map.hideLoading(); //隐藏loading样式
mapFeatures.forEach(function (v) { //获取一级城市、省份经纬度
let name = v.properties.name; // 地区名称
geoCoordMap[name] = v.properties.cp; // 地区经纬度
});
let convertData = function (tempData) { //通过该方法获取自己数据中各地区的经纬度
let tempRes = [];
for (let i = 0; i < tempData.length; i++) {
let geoCoord = geoCoordMap[tempData[i].name] || [];
if (geoCoord) {
tempRes.push({
name: tempData[i].name,
value: geoCoord.concat(tempData[i].value) || [],
});
}
}
for (let i = 0; i < tempRes.length; i++) {
let tempGeoCoord = geoData.rows.filter(t => { return t.name.includes(tempRes[i].name) })
if (tempGeoCoord && tempRes[i].value.length == 1) {
tempRes[i].value.unshift(tempGeoCoord[0].lat)
tempRes[i].value.unshift(tempGeoCoord[0].lng)
}
}
return tempRes;
};
_this.chart.map.setOption({ //开始画图
geo: {
map: 'china',
label: { show: false, }, // 是否显示对应地名
roam: true,
itemStyle: {
normal: {
borderWidth: 1, // 地图边框宽度
borderColor: '#fff', // 地图边框颜色
areaColor: '#0FADFF' // 地图颜色
},
emphasis: { areaColor: '#0FADFF', borderWidth: 2 } //高亮时的样式
},
emphasis: { areaColor: '#0FADFF', borderWidth: 2, label: { show: false } }
},
tooltip: {
triggerOn: 'mousemove',
trigger: 'item',
extraCssText: 'background:transparent;border:none;',
formatter: function (params) {
let count = eval(convertData(tempData).map(a => { return a.value[2] }).join('+'))
let content = `<div class='tooltip'>${params.name} ${params.value[2]}户 ${(params.value[2]/count*100).toFixed(2)}%`;
return (content += `</div>`);
}
},
series: [{
name: '散点',
type: 'scatter',
coordinateSystem: 'geo',
color: "#5ADD8B", //点的颜色
data: convertData(tempData),
symbolSize: 10, //点的大小
symbol: "circle", //点的样式
cursor: "pointer", //鼠标放上去的效果
label: {
normal: { show: false }, //默认展示
emphasis: { show: false } //滑过展示
},
itemStyle: { color: '#5ADD8B', emphasis: { borderColor: '#fff', borderWidth: 1 } }
},
{
type: 'map',
map: 'china',
geoIndex: 0,
silent: true,
hoverable: false,
aspectScale: 0.75,
tooltip: { show: false }
},
],
});
// 取消框架自带的高亮,只高亮散点
// _this.chart.map.on('mouseover', (v) => {
// let enlarge = convertData(tempData).map(a => { return a.name })
// let point = enlarge.findIndex(t => { return t == v.name })
// if (point < 0) { _this.chart.map.dispatchAction({ type: 'downplay', dataIndex: v.dataIndex }); }
// });
// 鼠标滑动到散点外不显示tip
_this.chart.map.on('mouseover', (v) => {
let enlarge = convertData(tempData).map(a => { return a.name })
let point = enlarge.findIndex(t => { return t == v.name })
if (point < 0) { _this.chart.map.dispatchAction({ type: 'hideTip', dataIndex: v.dataIndex }); }
});
_this.$nextTick(() => { _this.chart.map.resize() })
},
},
}
</script>
<style lang="scss">
.tooltip {
color: rgba(50, 50, 50, 1);
padding: 6px 9px 11px 9px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.1);
}
</style>