vue + echart 实现中国地图 和 省市地图(可切换省份)

一.中国地图

1.先导入echarts,然后再main.js里引入echarts

// 引入echarts
import echarts from 'echarts'
Vue.prototype.$echarts = echarts

// 还要特别引入china.json,这样中国地图才会出现,不然只会出现右下角的南海诸岛

import china from 'echarts/map/json/china.json'
echarts.registerMap('china', china)

2.页面代码
<div id="chinaChart" :style="{width: '100%', height: '500px'}"></div>

async drawChina() {
//加载中国地图
const that = this;

// 基于准备好的dom,初始化echarts实例
var myChartContainer = document.getElementById('chinaChart');
var resizeMyChartContainer = function () {
myChartContainer.style.width = (document.body.offsetWidth / 2) + 'px'//页面一半的大小
}
resizeMyChartContainer();
var myChartChina = this.$echarts.init(myChartContainer);

var chinaData = that.diTuData;//后台返回的地图数据,要去掉"省"字
var chinaBigValue = that.bigValue;//返回数据中最大值

// 绘制图表
var chinaMap = {
title: {//标题
text: '省级统计',
left: 'center'
},
visualMap: {
min: 0,
max: chinaBigValue,
left: '10%',
top: 'bottom',
text: ['高', '低'],
calculable: true,
color: ['#0b50b9', '#c3e2f4']
},
tooltip: { //鼠标移动到某个省份时显示内容
show: true,
formatter: function (item) {
let resData = item.data;
if (resData) {
return "省份:" + resData.name + "<br/>" + "数量:" + resData.value + "<br/>" + "百分比:" + resData.scale
} else {
return "省份:" + item.name + "<br/>" + "数量: 0" + "<br/>" + "百分比: 0.00%"
}
}
},
selectedMode: 'single',
calculable: true,
series: [
{
name: '',
type: 'map',
mapType: 'china',//main.js引入的中国地图
itemStyle: {
normal: {
borderColor: 'rgba(0, 0, 0, 0.2)'
},
emphasis: {
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
showLegendSymbol: true,
label: {
normal: {
show: true
},
emphasis: {
show: true
}
},
data: chinaData
}
]
}

myChartChina.setOption(chinaMap);
window.onresize = function () {
resizeMyChartContainer();
myChartChina.resize();
}
}

async changeCityData() {
//转变获取市区数据(因为我这边是获取微信小程序数据,所以要转变下数据格式)
const that = this;
let provinceData = that.allCity;//所有市区数据
var provinceItem = that.provinceItem;//下拉选中省份
var countNum = 0; //当前省份总值
var bigCityValue = 0; //市区最大值
var newProData = []; //转变后数据
for (let i = 0; i < allProvince.length; i++) {
let itemName = allProvince[i].name;
let reg = RegExp(itemName);
//判断下拉选中的省份
if (reg.test(provinceItem)) {
var cityList = [];
//区别有的省份没有市只有区
if (allProvince[i].city.length <= 1) {
cityList = allProvince[i].city[0].area;
} else {
cityList = allProvince[i].city;
}
for (let j = 0; j < provinceData.length; j++) {
let proName = provinceData[j].name;
let proValue = provinceData[j].value;
let regProName = RegExp(proName);
if (regProName.test("未知")) {
var newProItem = {};
newProItem.name = "未知";
newProItem.value = proValue;
newProData.push(newProItem);
} else {
for (let k = 0; k < cityList.length; k++) {
let cityName = "";
//区别有的省份没有市只有区
if (allProvince[i].city.length <= 1) {
cityName = cityList[k];
} else {
cityName = cityList[k].name;
}
//判断当前省份的市区
if (regProName.test(cityName)) {
var newProItem = {};
newProItem.name = cityName;
newProItem.value = proValue;
newProData.push(newProItem);
countNum += proValue;
if (bigCityValue < proValue) {
bigCityValue = proValue;
}
}
}
}
}
}
}

//添加遗漏的省份的市区
if (newProData.length <= 0) {
for (let i = 0; i < allProvince.length; i++) {
let itemName = allProvince[i].name;
let reg = RegExp(itemName);
//判断下拉选中的省份
if (reg.test(provinceItem)) {
var cityList = [];
//区别有的省份没有市只有区
if (allProvince[i].city.length <= 1) {
cityList = allProvince[i].city[0].area;
} else {
cityList = allProvince[i].city;
}
for (let j = 0; j < cityList.length; j++) {
let cityName = "";
//区别有的省份没有市只有区
if (allProvince[i].city.length <= 1) {
cityName = cityList[j];
} else {
cityName = cityList[j].name;
}
var newProItem = {};
newProItem.name = cityName;
newProItem.value = 0;
newProData.push(newProItem);
}
}
}
}

//计算百分比
for (let i = 0; i < newProData.length; i++) {
let newProName = newProData[i].name;
let regNewPro = RegExp(newProName);
if ((countNum > 0 || newProData[i].value > 0) && !regNewPro.test("未知")) {
let itemNum = newProData[i].value * 100 / countNum;
newProData[i].scale = itemNum.toFixed(2) + "%";
} else {
newProData[i].scale = "0.00%";
}
}

//从大到小排序
newProData.sort((a, b) => {
return b.value - a.value;
})

that.bigCityValue = bigCityValue;
that.provinceCity = newProData;
}
async getProvinceItem(val) {
//省份选择
let that = this;
that.provinceItem = val;
that.getMethodType = "ProvinceType";
that.changeCityData();
that.drawProvince();
}


3.样式

 

 

二。省市地图(可切换省份)

1.最好把所有省份的js下载并放到本地(也可以连线上的,下面有下载所有地图的json数据链接,我这边没有钓鱼岛和台湾的js),并且还要下载一份所有省市区的json数据和省份的js数据对应。

2.页面

<el-card v-loading="isProvinceLoading">
<div class="chart-top">
<el-select v-model="provinceVal" @change="getProvinceVal" placeholder="请选择">
<el-option
v-for="item in provinceScatter"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="provinceValue" @change="getProvinceValue" placeholder="请选择">
<el-option
v-for="item in provinceOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="provinceItem" @change="getProvinceItem" placeholder="请选择">
<el-option
v-for="item in provinceDatas"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<span>{{provinceBeginDate}}</span><span>至</span><span>{{provinceEndDate}}</span>
</div>

<div style="display: flex">
<div id="provinceChart" :style="{width: '100%', height: '500px'}"></div>

<el-table
:data="provinceCity"
style="width: 100%" height="500">
<el-table-column
prop="name"
label="市区"
min-width="100">
</el-table-column>
<el-table-column
prop="value"
label="用户数">
</el-table-column>
<el-table-column
prop="scale"
label="占比">
</el-table-column>
</el-table>
</div>
</el-card>

import allProvince from "../../assets/province-json/all-province";
import "../../assets/province-js/anhui";
import "../../assets/province-js/aomen";
import "../../assets/province-js/beijing";
import "../../assets/province-js/chongqing";
import "../../assets/province-js/fujian";
import "../../assets/province-js/gansu";
import "../../assets/province-js/guangdong";
import "../../assets/province-js/guangxi";
import "../../assets/province-js/guizhou";
import "../../assets/province-js/hainan";
import "../../assets/province-js/hebei";
import "../../assets/province-js/heilongjiang";
import "../../assets/province-js/henan";
import "../../assets/province-js/hubei";
import "../../assets/province-js/hunan";
import "../../assets/province-js/jiangxi";
import "../../assets/province-js/jilin";
import "../../assets/province-js/liaoning";
import "../../assets/province-js/jiangsu";
import "../../assets/province-js/neimenggu";
import "../../assets/province-js/ningxia";
import "../../assets/province-js/qinghai";
import "../../assets/province-js/shandong";
import "../../assets/province-js/shanghai";
import "../../assets/province-js/shanxi";
import "../../assets/province-js/shanxi1";
import "../../assets/province-js/sichuan";
import "../../assets/province-js/tianjin";
import "../../assets/province-js/xianggang";
import "../../assets/province-js/xinjiang";
import "../../assets/province-js/xizang";
import "../../assets/province-js/yunnan";
import "../../assets/province-js/zhejiang";

async drawProvince() {
//加载省市区地图
const that = this;

// 基于准备好的dom,初始化echarts实例
var mychartContainer = document.getElementById('provinceChart');
var resizeMyChartContainer = function () {
mychartContainer.style.width = (document.body.offsetWidth / 2) + 'px'//页面一半的大小
}
resizeMyChartContainer();
var mychart = this.$echarts.init(mychartContainer);

var provinceData = that.provinceCity;//返回的市区数据
var bigCityValue = that.bigCityValue;//最大值
var provinceItem = that.provinceItem;//下拉选中省份

// 绘制图表
var optionMap = {
title: {
text: provinceItem + '省统计',
left: 'center'
},
tooltip: {
show: true,
formatter: function (item) {
let resData = item.data;
if (resData) {
return "市区:" + resData.name + "<br/>" + "数量:" + resData.value + "<br/>" + "百分比:" + resData.scale
} else {
return "市区:" + item.name + "<br/>" + "数量: 0" + "<br/>" + "百分比: 0.00%"
}
}
},
visualMap: {
min: 0,
max: bigCityValue,
left: '10%',
top: 'bottom',
text: ['高', '低'],
calculable: true,
color: ['#0b50b9', '#c3e2f4']
},
selectedMode: 'single',
series: [
{
// 类型
type: 'map',
// 系列名称,用于tooltip的显示,legend 的图例筛选 在 setOption 更新数据和配置项时用于指定对应的系列
map: provinceItem,
// 地图类型
mapType: 'province',//对应省份,中文(如:广东)
//设置图形大小
zoom: 0.8,
itemStyle: {
normal: {
borderColor: 'rgba(0, 0, 0, 0.2)'
},
emphasis: {
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
showLegendSymbol: true,
label: {
normal: {
show: true
},
emphasis: {
show: true
}
},
data: provinceData
}
]
}

mychart.setOption(optionMap);
window.onresize = function () {
resizeMyChartContainer();
mychart.resize();
}
}

3.样式

 

 

地图数据链接:https://pan.baidu.com/s/1BdYWC8Ldbdc8bpD814xCIQ

密码:97op

 

参考文档

http://datav.aliyun.com/tools/atlas/#&lat=31.840232667909365&lng=104.2822265625&zoom=4

https://blog.csdn.net/qq_38021296/article/details/84380709

https://www.jianshu.com/p/028525cbd080

https://www.cnblogs.com/colorful-paopao1/p/10566289.html

posted @ 2020-07-01 10:39  伏沙金  阅读(8089)  评论(6编辑  收藏  举报