Vue使用echarts渲染地图并根据地区编码展示区域地图
2023-07-09 本文已影响0人
空格x
1 功能介绍
- 默认展示主地图,点击某个省市区根据地区编码展示对应的省市区地图,当匹配不到对应的省市区编码则展示主地图。
-
根据地理位置坐标加标记。
最终效果图 -
点击省市区展示省市区地图
省市区效果 如果觉得地名位置歪/想让省市区位置在区域中心位置,则需下载地图JSON地图文件进行手动修改(一般名字的位置为省会坐标点),具体修改会在 --- 2.3创建echarts地图 --- 区域写到,因为现在写好像并不清楚到底在写什么。
2 功能实现
2.1 下载所需NPM
包
npm i axios
npm i echarts
2.2 引入所需配置文件与初始化
2.2.1编码JSON数据项(由于数据量过大,有需要麻烦移步下面文章获取)
2.2.2 初始化
<template>
<div>
<div id="echatsMap" style="width: 100%; height: 800px"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import axios from "axios";
import { cityCode } from "@/components/cityCode.js";
export default {
name: "echatsMap",
components: {},
data() {
return {
cityCode: cityCode,
myChart: "",
distributionOptions: "",
};
},
mounted() {},
methods: {},
};
</script>
2.3 创建echarts地图
- 此处会用到外部链接来获取地图JSON数据(100000是主视图的地区编码):http://datav.aliyun.com/portal/school/atlas/area_selector#&lat=32.287132632616384&lng=101.1181640625&zoom=4
- 传递不同的编码,会返回不同省市区的JSON数据。
2.3.1 上面有提到省市区名字可能不在中心位置,可以按以下操作:
- 点击红框里的下载,就会得到一份本地的JSON文件,
2.3.2的代码块为动态获取方式
,将本地的JSON地图文件进行修改即可,示例:
// 此处只举例子
// 直接在下载的文件里搜甘肃省 --- 这样是默认的
"properties": {
"adcode": 620000,
"name": "甘肃省",
"center": [
103.823557,
36.058039
],
"childrenNum": 14,
"level": "province",
"parent": {
"adcode": 100000
},
"subFeatureIndex": 27,
"acroutes": [
100000
]
},
// 在里面加上 用来改变文字展示坐标点
"cp": [
103.823557,
36.058039
],
// 修改后--
"properties": {
"adcode": 620000,
"name": "甘肃省",
"center": [
103.823557,
36.058039
],
"cp": [
103.823557,
36.058039
],
"childrenNum": 14,
"level": "province",
"parent": {
"adcode": 100000
},
"subFeatureIndex": 27,
"acroutes": [
100000
]
},
修改后就不能用动态获取了,需要存放到本地,让其使用本地的文件示例如下(具体改哪来,):
// 初始化地图数据
init() {
// 主地图的JSON文件下载
let path = require('../../../../../public/mapJson/china.json');
echarts.registerMap("china", path );
this.changeOptions("china");
this.myChart = echarts.init(document.querySelector("#echatsMap"));
this.myChart.setOption(this.distributionOptions)
window.onresize = function () {
if (this.myChart) this.myChart.resize();
};
},
2.3.2 代码实现
<template>
<div>
<div id="echatsMap" style="width: 100%; height: 800px"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import axios from "axios";
import { cityCode } from "@/components/cityCode.js";
export default {
name: "echatsMap",
components: {},
data() {
return {
cityCode: cityCode,
myChart: "",
distributionOptions: "",
};
},
mounted() {
this.$nextTick(() => {
this.init();
});
},
methods: {
// 初始化地图数据
init() {
// 主地图的JSON文件下载
let path = `https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json`;
axios.get(path).then((res) => {
echarts.registerMap("china", res.data);
this.changeOptions("china");
this.myChart = echarts.init(document.querySelector("#echatsMap"));
this.myChart.setOption(this.distributionOptions)
});
window.onresize = function () {
if (this.myChart) this.myChart.resize();
};
},
// echarts 配置项
changeOptions(name) {
// 经纬度数据
const seriesList = [
{
data: [{ value: [106.9, 27.7] }, { value: [105.29, 27.32] }],
},
];
// 图标
const series = seriesList.map((v) => {
return {
type: "scatter", //配置显示方式为用户自定义
coordinateSystem: "geo",
data: v.data,
// 自定义图标的样式 支持svg与bse64
symbol: function (params, key) {
return "image://" + require("@/assets/logo.png");
},
symbolSize: 16,
};
});
// options
this.distributionOptions = {
tooltip: {
// 提示框组件
show: true, // 显示提示框组件
trigger: "item", // 触发类型
triggerOn: "mousemove", // 触发条件
formatter: "名称:{b}<br/>坐标:{c}",
},
series, // 数据
geo: {
map: name || "china", // 引入地图 省份或者 国家
layoutCenter: ["50%", "50%"], //设置后left/right/top/bottom等属性无效
layoutSize: "45%",
roam: true, //开启鼠标缩放
zoom: 2,
label: {
normal: {
//静态的时候展示样式
show: true, //是否显示地图省份得名称
textStyle: {
color: "#fff",
fontSize: 10,
fontFamily: "Arial",
},
},
emphasis: {
// 高亮状态下的样式
//动态展示的样式
color: "#fff",
},
},
itemStyle: {
// 地图区域的多边形 图形样式。
normal: {
borderColor: "#fff", // 边框颜色
areaColor: "#1c2f59", // 区域颜色
textStyle: {
// 文字颜色
color: "#fff",
},
// shadowBlur: 10, // 图形阴影的模糊大小
// shadowOffsetX: 10, // 阴影水平方向上的偏移距离。
},
emphasis: {
areaColor: "#1c2f59",
color: "#fff",
},
},
regions: [
//对不同的区块进行着色
// {
// name: "河南省", //区块名称
// itemStyle: {
// normal: {
// areaColor: "#281fe1",
// },
// },
// },
// {
// name: "浙江省", //区块名称
// itemStyle: {
// normal: {
// areaColor: "#193094",
// },
// },
// },
],
},
};
},
},
};
</script>
2.4 点击地图省市区展示省市区地图
- 大概就是点击省市区时根据名称与编码文件去匹配,把匹配到的编码通过外部接口去获取想要的省市区JSON地图数据。再次渲染echarts即可。
注意:如果没匹配到需跳主地图/获取不到此区域的JSON地图数据。
<template>
<div>
<div id="echatsMap" style="width: 100%; height: 800px"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import axios from "axios";
import { cityCode } from "@/components/cityCode.js";
export default {
name: "echatsMap",
components: {},
data() {
return {
cityCode: cityCode,
myChart: "",
distributionOptions: "",
};
},
mounted() {
this.$nextTick(() => {
this.init();
});
},
methods: {
// 初始化地图数据
init() {
// 主地图的JSON文件下载
let path = `https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json`;
axios.get(path).then((res) => {
echarts.registerMap("china", res.data);
this.changeOptions("china");
this.myChart = echarts.init(document.querySelector("#echatsMap"));
this.myChart.setOption(this.distributionOptions);
// 点击省份子区域的时候可以切换到省份地图
this.myChart.on("click", (chinaParam) => {
// 如果没有下层则展示主地图
if (!this.cityCode) {
this.cityCode = cityCode;
// 100000 主地图
this.getProvinceMapOpt(100000, "")
return;
}
// 根据点击位置地图名字去跟编码数据匹配
let code = this.cityCode.find(
(x) => chinaParam.name.indexOf(x ? x.name : "") !== -1
);
// 找到正确的编码 去获取对应的地图数据
// 将该省市区的下级放入 -- 如果接口支持根据编码查询省市区所有下级子级就不需要这么写
if (code) {
this.cityCode = code.city;
this.getProvinceMapOpt(Number(code.adcode), chinaParam.name);
} else {
// 没有对应的编码跳主地图
this.cityCode = cityCode;
// 100000 主地图
this.getProvinceMapOpt(100000, "");
}
});
});
window.onresize = function () {
if (this.myChart) this.myChart.resize();
};
},
// 下载/显示各省地图
getProvinceMapOpt(provinceAlphabet, name) {
// 根据地区编码获取所在地区的JSON地图
let path = `https://geo.datav.aliyun.com/areas_v3/bound/${provinceAlphabet}_full.json`;
if (provinceAlphabet === 100000) {
path = "/mapJson/china.json";
}
axios.get(path).then((res) => {
// 获取完最新的JSON地图数据后,重新渲染
echarts.registerMap(name, res.data);
this.changeOptions(name);
this.myChart.setOption(this.distributionOptions, true);
});
},
// echarts 配置项
changeOptions(name) {
// 经纬度数据 --- 不存在的经纬度不会展示出来
const seriesList = [
{
data: [{ value: [106.9, 27.7] }, { value: [105.29, 27.32] }],
},
];
// 图标
const series = seriesList.map((v) => {
return {
type: "scatter", //配置显示方式为用户自定义
coordinateSystem: "geo",
data: v.data,
// 自定义图标的样式 支持svg与bse64
symbol: function (params, key) {
return "image://" + require("@/assets/logo.png");
},
symbolSize: 16,
};
});
// options
this.distributionOptions = {
tooltip: {
// 提示框组件
show: true, // 显示提示框组件
trigger: "item", // 触发类型
triggerOn: "mousemove", // 触发条件
formatter: "名称:{b}<br/>坐标:{c}",
},
series, // 数据
geo: {
map: name || "china", // 引入地图 省份或者 国家
layoutCenter: ["50%", "50%"], //设置后left/right/top/bottom等属性无效
layoutSize: "45%",
roam: true, //开启鼠标缩放
zoom: 2,
label: {
normal: {
//静态的时候展示样式
show: true, //是否显示地图省份得名称
textStyle: {
color: "#fff",
fontSize: 10,
fontFamily: "Arial",
},
},
emphasis: {
// 高亮状态下的样式
//动态展示的样式
color: "#fff",
},
},
itemStyle: {
// 地图区域的多边形 图形样式。
normal: {
borderColor: "#fff", // 边框颜色
areaColor: "#1c2f59", // 区域颜色
textStyle: {
// 文字颜色
color: "#fff",
},
// shadowBlur: 10, // 图形阴影的模糊大小
// shadowOffsetX: 10, // 阴影水平方向上的偏移距离。
},
emphasis: {
areaColor: "#1c2f59",
color: "#fff",
},
},
regions: [
//对不同的区块进行着色
// {
// name: "河南省", //区块名称
// itemStyle: {
// normal: {
// areaColor: "#281fe1",
// },
// },
// },
// {
// name: "浙江省", //区块名称
// itemStyle: {
// normal: {
// areaColor: "#193094",
// },
// },
// },
],
},
};
},
},
};
</script>
3 完整代码
<template>
<div>
<div id="echatsMap" style="width: 100%; height: 800px"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import axios from "axios";
import { cityCode } from "@/components/cityCode.js";
export default {
name: "echatsMap",
components: {},
data() {
return {
cityCode: cityCode,
myChart: "",
distributionOptions: "",
};
},
mounted() {
this.$nextTick(() => {
this.init();
});
},
methods: {
// 初始化地图数据
init() {
// 主地图的JSON文件下载
let path = `https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json`;
axios.get(path).then((res) => {
echarts.registerMap("china", res.data);
this.changeOptions("china");
this.myChart = echarts.init(document.querySelector("#echatsMap"));
this.myChart.setOption(this.distributionOptions);
// 点击省份子区域的时候可以切换到省份地图
this.myChart.on("click", (chinaParam) => {
// 如果没有下层则展示主地图
if (!this.cityCode) {
this.cityCode = cityCode;
// 100000 主地图
this.getProvinceMapOpt(100000, "")
return;
}
// 根据点击位置地图名字去跟编码数据匹配
let code = this.cityCode.find(
(x) => chinaParam.name.indexOf(x ? x.name : "") !== -1
);
// 找到正确的编码 去获取对应的地图数据
// 将该省市区的下级放入 -- 如果接口支持根据编码查询省市区所有下级子级就不需要这么写
if (code) {
this.cityCode = code.city;
this.getProvinceMapOpt(Number(code.adcode), chinaParam.name);
} else {
// 没有对应的编码跳主地图
this.cityCode = cityCode;
// 100000 主地图
this.getProvinceMapOpt(100000, "");
}
});
});
window.onresize = function () {
if (this.myChart) this.myChart.resize();
};
},
// 下载/显示各省地图
getProvinceMapOpt(provinceAlphabet, name) {
// 根据地区编码获取所在地区的JSON地图
let path = `https://geo.datav.aliyun.com/areas_v3/bound/${provinceAlphabet}_full.json`;
if (provinceAlphabet === 100000) {
path = "/mapJson/china.json";
}
axios.get(path).then((res) => {
// 获取完最新的JSON地图数据后,重新渲染
echarts.registerMap(name, res.data);
this.changeOptions(name);
this.myChart.setOption(this.distributionOptions, true);
});
},
// echarts 配置项
changeOptions(name) {
// 经纬度数据 --- 不存在的经纬度不会展示出来
const seriesList = [
{
data: [{ value: [106.9, 27.7] }, { value: [105.29, 27.32] }],
},
];
// 图标
const series = seriesList.map((v) => {
return {
type: "scatter", //配置显示方式为用户自定义
coordinateSystem: "geo",
data: v.data,
// 自定义图标的样式 支持svg与bse64
symbol: function (params, key) {
return "image://" + require("@/assets/logo.png");
},
symbolSize: 16,
};
});
// options
this.distributionOptions = {
tooltip: {
// 提示框组件
show: true, // 显示提示框组件
trigger: "item", // 触发类型
triggerOn: "mousemove", // 触发条件
formatter: "名称:{b}<br/>坐标:{c}",
},
series, // 数据
geo: {
map: name || "china", // 引入地图 省份或者 国家
layoutCenter: ["50%", "50%"], //设置后left/right/top/bottom等属性无效
layoutSize: "45%",
roam: true, //开启鼠标缩放
zoom: 2,
label: {
normal: {
//静态的时候展示样式
show: true, //是否显示地图省份得名称
textStyle: {
color: "#fff",
fontSize: 10,
fontFamily: "Arial",
},
},
emphasis: {
// 高亮状态下的样式
//动态展示的样式
color: "#fff",
},
},
itemStyle: {
// 地图区域的多边形 图形样式。
normal: {
borderColor: "#fff", // 边框颜色
areaColor: "#1c2f59", // 区域颜色
textStyle: {
// 文字颜色
color: "#fff",
},
// shadowBlur: 10, // 图形阴影的模糊大小
// shadowOffsetX: 10, // 阴影水平方向上的偏移距离。
},
emphasis: {
areaColor: "#1c2f59",
color: "#fff",
},
},
regions: [
//对不同的区块进行着色
// {
// name: "河南省", //区块名称
// itemStyle: {
// normal: {
// areaColor: "#281fe1",
// },
// },
// },
// {
// name: "浙江省", //区块名称
// itemStyle: {
// normal: {
// areaColor: "#193094",
// },
// },
// },
],
},
};
},
},
};
</script>