/**
描述:
使用高德api获取地图行政区geoJson,再用echarts去加载这个地图实现点击下钻功能
vue渲染地图热力图、块状图,实现方法: https://juejin.im/post/5db6a8ab5188251d5e755cdf
github上有完整的代码:https://github.com/biubiubiu01/EchartsMap
预览地址:https://gist006.gitee.io/echartsmap/#/
阿里云geoJson全国所有市县下载地址:
http://datav.aliyun.com/tools/atlas/#&lat=31.840232667909365&lng=104.2822265625&zoom=4
实现前提:你要先去高德api上去申请key值,免费的,然后引入进来
高德api上申请密钥,免费的,一天可以发出5000次请求,次数太多了你要去花钱申请企业版,直通车:[https://developer.amap.com/](https://developer.amap.com/)
**/
//存储市级的geoJson,因为高德无法获取区县级别的geoJosn数据,所以我们只能获取上一个级别的所有行政区
//然后去遍历,通过名字去比对获取geoJson
1. 根据行政区code去获取行政区边界geoJson
你要先cdn引入:
<script src='http://webapi.amap.com/maps?v=1.3&key='你申请的key'&plugin=AMap.DistrictSearch'></script>
<script src="//webapi.amap.com/ui/1.0/main.js"></script>
在build/webpack.base.conf.js里面让webpack不处理aMap的依赖库
externals: {
'AMap':'AMap',
'AMapUI': 'AMapUI'
}
通过AMapUI的DistrictExplorer 方法去获取行政区geoJson
<template>
<v-card height="1200">
<v-card-title>地区分布</v-card-title>
<v-divider></v-divider>
<v-card-text class="d-flex flex-row" style="height:550px;">
<div class="mapChoose">
<span v-for="(item, index) in parentInfo" :key="item.code">
<span class="title" @click="chooseArea(item, index)">{{
item.cityName == "全国" ? "中国" : item.cityName
}}</span>
<span class="icon" v-show="index + 1 != parentInfo.length">></span>
</span>
</div>
<div style="width:100%;height:100%;" ref="报表"></div>
</v-card-text>
<v-card-actions> </v-card-actions>
<v-divider></v-divider>
<v-card-text class="d-flex flex-row" style="height:550px;">
<div style="width:100%;height:100%;" ref="柱状图"></div>
</v-card-text>
</v-card>
</template>
<script>
import echarts from "echarts";
import { valueUtil, httpDefaultMsgUtil } from "@/util";
export default {
name: "map-map",
data: () => ({
timerId: 0,
geoJson: {
features: []
},
parentInfo: [
{
cityName: "山东",
code: 370000
}
]
}),
components: {},
computed: {},
mounted() {
const ths = this;
ths.get1();
ths.get2();
},
destroyed() {
const ths = this;
clearTimeout(ths.timerId);
},
methods: {
get1() {
const ths = this;
ths.loading = true;
ths.getGeoJson(370000);
},
get2() {
const ths = this;
ths.loading = true;
ths.地区数据加载(ths.地区数据转换());
httpDefaultMsgUtil.get(
"api/HomePageEchartsAssessment/GetMapCityBarGraph",
{},
{},
ths,
succeed => {
ths.loading = false;
let data = succeed.data;
ths.地区数据加载(ths.地区数据转换(data));
ths.timerId = setTimeout(() => {
ths.get2();
}, 1000 * 60);
}
);
},
数据转换(原始数据) {
原始数据 = valueUtil.defaultValue(原始数据, []);
const y轴城市 = 原始数据.map(rec => rec.地区);
const X轴 = 原始数据.map(rec => rec.数量);
let 转换数据 = { y轴城市, X轴 };
return 转换数据;
},
地区数据转换(原始数据) {
原始数据 = valueUtil.defaultValue(原始数据, []);
const 城市 = 原始数据.map(rec => rec.地区);
const 数量 = 原始数据.map(rec => rec.数量);
let 转换数据 = { 城市, 数量 };
return 转换数据;
},
地区数据加载(加载数据) {
const ths = this;
ths.getCity(加载数据);
},
/**
* 利用高德api获取行政区边界geoJson
* adcode 行政区code 编号
**/
//此版本不再维护,准备在写另一个新版本
getGeoJson(adcode) {
let that = this;
AMapUI.loadUI(["geo/DistrictExplorer"], DistrictExplorer => {
var districtExplorer = new DistrictExplorer();
districtExplorer.loadAreaNode(adcode, function(error, areaNode) {
if (error) {
console.error(error);
return;
}
let Json = areaNode.getSubFeatures();
if (Json.length > 0) {
that.geoJson.features = Json;
} else if (Json.length === 0) {
that.geoJson.features = that.geoJson.features.filter(
item => item.properties.adcode == adcode
);
if (that.geoJson.features.length === 0) return;
}
httpDefaultMsgUtil.get(
"api/HomePageEchartsAssessment/GetMapCity",
{ code: adcode },
{},
that,
succeed => {
that.loading = false;
let data = succeed.data;
that.getMapData(data);
}
);
});
});
},
//获取数据
getMapData(服务器数据) {
let mapData = this.geoJson.features.map(item => {
let value = 0;
return {
name: item.properties.name,
value: [item.properties.center[0], item.properties.center[1], value],
cityCode: item.properties.adcode
};
});
//获取服务器的数据 将散点的数量替换格式为[{地区:370100,数量:100},{地区:370200,数量:200}]
mapData.forEach(item => {
if (!valueUtil.isEmptyValue(服务器数据)) {
item.value[2] = 服务器数据.find(a => a.地区 == item.cityCode).数量;
}
}),
(mapData = mapData.sort(function(a, b) {
return a.value[2] - b.value[2];
}));
//去渲染echarts
this.initEcharts(mapData);
},
initEcharts(mapData) {
this.myChart = echarts.init(this.$refs.报表);
echarts.registerMap("Map", this.geoJson); //注册
this.myChart.setOption(
{
tooltip: {
trigger: "item",
formatter: p => {
let val = p.value[2];
if (window.isNaN(val)) {
val = 0;
}
let txtCon = p.name + ":" + val.toFixed();
return txtCon;
}
},
title: {
show: true,
left: "center",
top: "15",
text:
this.parentInfo[this.parentInfo.length - 1].cityName +
"区域分析图",
textStyle: {
color: "rgb(0, 0, 0)",
fontSize: 16
}
},
toolbox: {
feature: {
dataView: {
show: false
},
magicType: {
show: false
},
restore: {
show: false
},
saveAsImage: {
show: true,
name: "地图",
pixelRatio: 2
}
},
iconStyle: {
normal: {
borderColor: "#1990DA"
}
},
itemSize: 15,
top: 20,
right: 22
},
geo: {
show: true,
map: "Map", //使用
roam: false,
itemStyle: {
normal: {
show: true,
areaColor: "#3a7fd5",
borderColor: "#215495",
borderWidth: "1.3",
shadowColor: "rgb(10,76,139)",
shadowOffsetX: 5,
shadowOffsetY: 3,
shadowBlur: 65
},
//emphasis 是图形在高亮状态下的样式,比如在鼠标悬浮或者图例联动高亮时。
emphasis: {
show: true,
areaColor: "#8dd7fc"
}
},
label: {
normal: {
show: true,
color: "rgb(249, 249, 249)", //省份标签字体颜色
formatter: p => {
switch (p.name) {
case "内蒙古自治区":
p.name = "内蒙古";
break;
case "西藏自治区":
p.name = "西藏";
break;
case "新疆维吾尔自治区":
p.name = "新疆";
break;
case "宁夏回族自治区":
p.name = "宁夏";
break;
case "广西壮族自治区":
p.name = "广西";
break;
case "香港特别行政区":
p.name = "香港";
break;
case "澳门特别行政区":
p.name = "澳门";
break;
default:
break;
}
return p.name;
}
},
emphasis: {
show: true,
color: "#f75a00"
}
},
zoom: 1.15
},
series: [
{
name: "top5",
type: "effectScatter",
data: mapData,
coordinateSystem: "geo",
//这里可以设置点的大小
symbolSize: function(val) {
//return val[2] / 1.2;
return 15;
},
showEffectOn: "render", //高亮时显示特效
rippleEffect: {
brushType: "fill"
},
hoverAnimation: false,
label: {
normal: {
formatter: p => {
return p.value[2].toFixed();
},
position: "center", //地图上是否有文字
show: true,
textStyle: {
color: "#fff"
}
},
emphasis: {
show: false
}
},
itemStyle: {
normal: {
color: "rgba(255, 128, 0,0.8)" //地图点的颜色
}
},
layoutCenter: ["80%", "80%"], //属性定义地图中心在屏幕中的位置,一般结合layoutSize 定义地图的大小
layoutSize: 430
}
]
},
true
);
let that = this;
this.myChart.off("click");
this.myChart.on("click", params => {
if (!params.data) {
return;
}
if (
that.parentInfo[that.parentInfo.length - 1].code ==
params.data.cityCode
) {
return;
}
let data = params.data;
that.parentInfo.push({
cityName: data.name,
code: data.cityCode
});
that.getGeoJson(data.cityCode);
});
}, //选择切换市县
chooseArea(val, index) {
if (this.parentInfo.length === index + 1) {
return;
}
this.parentInfo.splice(index + 1);
this.getGeoJson(this.parentInfo[this.parentInfo.length - 1].code);
},
getCity(数据) {
const ths = this;
let el = ths.$refs.柱状图;
var myChart = echarts.init(el);
let option = {
color: ["#3398DB"],
tooltip: {
trigger: "axis",
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: "shadow" // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true
},
xAxis: [
{
type: "category",
data: 数据.城市,
axisTick: {
alignWithLabel: true
},
axisLabel: {
interval: 0,
formatter: function(value) {
return value.split("").join("\n");
}
}
}
],
yAxis: [
{
type: "value"
}
],
series: [
{
name: "直接访问",
type: "bar",
barWidth: "60%",
label: {
normal: {
show: true,
position: "top"
}
},
color: "#6aadf1",
data: 数据.数量
}
]
};
myChart.setOption(option);
}
}
};
</script>
<style lang="scss" scoped>
.echarts {
width: 100%;
height: 100%;
position: relative;
background-size: 100% 100%;
}
.mapChoose {
position: absolute;
left: 20px;
top: 70px;
color: #eee;
.title {
padding: 2px;
border-top: 1px solid rgba(147, 235, 248, 0.8);
border-bottom: 1px solid rgba(147, 235, 248, 0.8);
cursor: pointer;
color: rgba(8, 8, 8, 0.8);
}
.icon {
font-family: "simsun";
font-size: 5px;
margin: 0 5px;
}
}
</style>
效果