最近项目需要开发大屏,要实现全国地图下钻,并且根据不同状态标记点位,点击弹窗显示当前点击省市区的列表信息,弹窗位置根据点击位置获取,记录一下。
其中地图数据用了阿里云数据可视化平台DataV.GeoAtlas,地址:地图数据
最终效果如下所示:
不废话,直接上代码:
<template> <div class="echart-bmap_wrapper"> <div class="btn"> <el-button type="primary" @click="goBack" size="mini">全国</el-button> </div> <div class="bmap-box" id="bmapChartBox"></div> <div class="popWin" v-if="popShow" :style="{ left: popLeft + 'px', top: popTop + 'px' }"> <div class="popWins"> <div class="titleInfos"> <p class="cityName">{{ name }}工厂</p> <span class="pop_close" @click="popShow = false">关闭</span> </div> <div class="popLine"> </div> <div class="infoBody"> <basic-table class="homeTable" :TableHeaderList="TableHeaderList" :tableData="tableData" :hasPagination="false" :tableHeight="220" :rowHeight="20"></basic-table> </div> </div> </div> </div> </template> <script> import basicTable from "@/components/basicComponents/basicTable.vue"; // 公用table组件 import * as echarts from 'echarts'; import * as basicDataApi from '@/api/basicData.js'//基础资料接口 var provinceMapData = require('./mapData/provinceMapData.json');//全国地图省份数据,自己取上面地址取 export default { components: { basicTable }, name: 'echartBmap', data() { return { pointData: [],//标点信息,需要动态获取,初始化全国地图的点位 provinceCodeData: [],//处理后全国省份数据带code mapStack: [],//存储一下地图历史记录,用于返回 nowChooseData: [],//当前选择的数据源 option: { tooltip: { trigger: 'item', }, geo: [{ map: 'js', aspectScale: 0.9, roam: true, // 是否允许缩放 zoom: 1.2, // 默认显示级别 center: [116.405285, 39.904989], // 地图中心点坐标 label: { normal: { show: true, // 是否地图显示区域的文字,各省市的名字 textStyle: { color: '#fff' } }, emphasis: { textStyle: { color: '#fff' } } }, itemStyle: { // 区域颜色 areaColor: { type: 'radial', x: 0.7, y: 0.5, r: 0.4, // 渐变效果 colorStops: [{ offset: 0, color: '#24cff4' // 0% 处的颜色 }, { offset: 0.5, color: '#2babd9' // 50% 处的颜色 }, { offset: 1, color: '#236bb2' // 100% 处的颜色 }], global: false // 缺省为 false }, emphasis: { areaColor: '#56dcf9', // 鼠标移入区域背景颜色 borderWidth: 0 }, borderColor: '#37C1FD', borderWidth: 2 }, emphasis: { itemStyle: { areaColor: '#0160AD' }, label: { show: 1, color: '#fff' } }, zlevel: 3 }], series: [{ type: 'effectScatter', coordinateSystem: 'geo', // symbol: 'diamond', showEffectOn: 'render', rippleEffect: { period: 10, scale: 6, brushType: 'fill' }, zlevel: 10, // 这里是关键,一定要放在 series中,显示层级, hoverAnimation: true, itemStyle: { normal: { // 点的颜色可以根据 params 参数里面的值去设定不通的颜色 color: function (params) { if (params.name == '7300网关') { return 'red'; } if (params.name == '700网关') { return 'yellow'; } if (params.name == '5300网关') { return 'green'; }else{ return 'pink'; } }, shadowBlur: 10, shadowColor: '#333' } }, data: [] // 点的数据,包含经纬度 }] }, // 测试标点数据 gatewayPointData: { '黑龙江省': [ { name: '7300网关', value: [126.642464, 45.756967] }, ], '哈尔滨市': [ { name: '7300网关', value: [126.957401, 45.454116] }, { name: '700网关', value: [126.394846, 45.778706] }, { name: '5300网关', value: [126.606415, 45.807463] }, { name: '300网关', value: [126.483958, 45.876779] }, { name: '2300网关', value: [126.785501, 45.739871] } ], }, popShow: false,//弹窗是否显示 popLeft: 0,//弹窗X轴距离 popTop: 0,//弹窗Y轴距离 name: '',//当前点击省份 TableHeaderList: [],//table表头数据 tableData: [],//table数据 }; }, mounted() { // 渲染地图 this.drawMap(provinceMapData, 0, [126.82862, 49.296976]); this.getProvinceCode();//处理全国省份数据 // 初始化mapStack数据,默认全国数据 this.mapStack = [] this.mapStack.push(provinceMapData) }, methods: { // 处理全国省份数据 getProvinceCode() { provinceMapData.features.forEach(item => { this.provinceCodeData.push({ name: item.properties.name, coordinateCenter: item.properties.center, cityCode: item.properties.adcode }) }); }, // 返回全国 goBack() { this.popShow = false this.mapStack = [] this.mapStack.push(provinceMapData) this.drawMap(provinceMapData, 0, [126.82862, 49.296976]); }, // 设置地图配置信息 setMapCenterZoomData(data, zoom, center) { this.option.series[0].data = data; this.option.geo[0].zoom = zoom; this.option.geo[0].center = center; if (this.mapStack.length <= 1) {//设置图层位置 this.option.geo[0].layoutSize = '100%'; this.option.geo[0].layoutCenter = ['85%', '20%']; } else { this.option.geo[0].layoutSize = ''; this.option.geo[0].layoutCenter = []; } }, // 渲染地图 drawMap(json, type = 0, city) { // 防止echarts重复 if (document.getElementById('bmapChartBox') == null) { return } echarts.dispose(document.getElementById('bmapChartBox')) // 防止echarts重复 this.echarts = echarts; this.dom = document.getElementById('bmapChartBox'); this.myChart = this.echarts.init(this.dom); this.echarts.registerMap('js', json); if (type == 1) {//地图点击进入 this.pointData = this.gatewayPointData[city];//标点数据 if(this.pointData){//如果有标点数据 this.setMapCenterZoomData(this.pointData, 1.2, this.pointData[0].value); }else{//如果没有标点数据 // 使用测试数据 - 把当前选择地图数据作为标点数据 this.nowChooseData.forEach(i=>{ i.value = i.coordinateCenter }) this.pointData = this.nowChooseData var center = this.nowChooseData[0].coordinateCenter;//取当前选择省市区第一个数据的坐标 this.setMapCenterZoomData(this.pointData, 1.2, center); } } else {//初始化进入 this.myChart.clear(); this.setMapCenterZoomData([], 1, [126.82862, 49.296976]); } this.myChart.setOption(this.option); this.myChart.off('click'); this.myChart.on('click', (param) => { // 点击弹窗方法 // 点击获取经纬度 let data = this.myChart.convertFromPixel('geo', [param.event.event.offsetX, param.event.event.offsetY]) this.popLeft = param.event.event.offsetX this.popTop = param.event.event.offsetY // 获取城市名称 list下的name值 this.name = param.name this.popShow = true // 点击弹窗方法 if (param.componentType == "geo") {//点击地图 } else {//点击标点不允许下钻 return; } // 省市区三级后跳出点击 if (this.mapStack.length >= 3) { this.$notify({ message: '没有更多啦!', type: 'warning', duration: 2000 }); return; } const city = param.name; // 获取点击对应的cityCode var cityCode = '' if (this.mapStack.length <= 1) {//初始化全国省份数据 this.provinceCodeData.forEach(i => { if (i.name == city) { cityCode = i.cityCode } }) } else {//选择后的市区数据 this.nowChooseData.forEach(i => { if (i.name == city) { cityCode = i.cityCode } }) } this.getHomeMapData(city, cityCode) }); }, // 获取基础配置数据 getHomeMapData(city, cityCode) { var cityMapData //当前选中的省市区地图数据 // 请求数据 var data if( cityCode == 710000){//台湾特殊处理,后缀没有_full data = { code: cityCode } }else{ data = { code: cityCode + '_full' } } //通过接口获取点击下钻的地图数据 basicDataApi.getHomeMapDataApi(data).then(res => { if (res) { cityMapData = res // 让历史数据一直保持在3个之内,存储显示过的地图数据 if (this.mapStack.length < 3) { this.mapStack.push(cityMapData); } this.nowChooseData = [] cityMapData.features.forEach(item => { this.nowChooseData.push({ name: item.properties.name, coordinateCenter: item.properties.center, cityCode: item.properties.adcode }) }); cityMapData && this.myChart.clear(); cityMapData && this.drawMap(cityMapData, 1, city); this.getTableData();//获取table数据 } }).catch((err) => { this.$message(err.message); }); }, //获取table数据 getTableData(){ this.TableHeaderList = [ { FieldDisplayName: "网关名称", // ColumnWidth: 120, Field: "gatewayName", IsShow: true, }, { FieldDisplayName: "状态", // ColumnWidth: 120, Field: "status", IsShow: true, QuerySource:"GatewayStatus", }, { FieldDisplayName: "设备总数", // ColumnWidth: 120, Field: "gatewayNum", IsShow: true, }, { FieldDisplayName: "测点总数", // ColumnWidth: 120, Field: "pointNum", IsShow: true, }, ] this.tableData = [ { num: 1, gatewayName: '网关1', status: '1', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '2', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '3', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '4', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '5', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '1', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '2', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '3', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '4', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '1', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '2', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '3', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '1', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '2', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '3', gatewayNum: '321', pointNum: '442', }, { num: 1, gatewayName: '网关1', status: '2', gatewayNum: '321', pointNum: '442', }, ] }, } }; </script> <style lang="scss" scoped> .echart-bmap_wrapper { position: relative; .btn { position: absolute; left: 20px; top: 20px; z-index: 1; } .bmap-box { width: 100%; height: 90vh; } .popWin { position: absolute; left: 0; top: 0; background: #00305c; background-size: 100% 100%; width: 408px; height: 300px; z-index: 100; .popLine { width: 340px; height: 1px; background: linear-gradient(90deg, #FFFFFF 0%, rgba(255, 255, 255, 0) 100%); opacity: 0.3; margin-left: 30px; } .titleInfos { text-align: center; margin-left: 30px; font-size: 22px; font-family: YouSheBiaoTiHei; font-weight: 400; color: #00FDFE; height: 50px; display: flex; justify-content: flex-start; align-items: center; flex-wrap: nowrap; flex-direction: row; align-content: flex-start; .pop_close{ color:#bbb; cursor: pointer; padding:5px; font-size:12px; position: absolute; top: 5px; right: 10px; } } } .infoBody { width: 100%; padding:3%; .homeTable{ border:1px solid #0376ae; border-radius: 10px; } } .infoBody ::v-deep .plTableBox .el-table .cell.el-tooltip{ border-bottom: 1px solid #086896; } .infoBody ::v-deep .el-table, .el-table__expanded-cell { background-color: transparent; } .infoBody ::v-deep .el-table tr { // background-color: transparent!important; background-color: #0b4d73; } .infoBody ::v-deep .el-table--enable-row-transition .el-table__body td, .el-table .cell{ background-color: transparent; } .el-table::before {//去除底部白线 left: 0; bottom: 0; width: 100%; height: 0px; } .infoBody ::v-deep .plTableBox .el-table .el-table__header th{ background-color: transparent; } .infoBody ::v-deep .plTableBox .el-table--enable-row-hover .el-table__body tr:hover>td{ background-color: rgba(0,77,167,1); } .infoBody ::v-deep .plTableBox .el-table--border td,.infoBody ::v-deep .plTableBox .el-table--border th,.infoBody ::v-deep .plTableBox .el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed{ border: none; color:#4daad3 } .infoBody ::v-deep .plTableBox .el-table--medium td{ padding: 0; } .infoBody ::v-deep .plTableBox .el-table__header-wrapper{ background-color: transparent; } .infoBody ::v-deep .plTableBox .el-table--striped .el-table__body tr.el-table__row--striped td{ background-color: #103c5c; } } </style>
复制