vue+echarts可视化大屏,全国地图下钻,页面自适应

博客 动态
0 208
优雅殿下
优雅殿下 2022-03-16 15:56:46
悬赏:0 积分 收藏

vue+echarts可视化大屏,全国地图下钻,页面自适应

vue+echarts可视化大屏,全国地图下钻,页面自适应 vue+echarts可视化大屏,全国地图下钻,页面自适应

之前写过一篇关于数据大屏及地图下钻的文章 https://www.cnblogs.com/weijiutao/p/13977011.html ,但是存在诸多问题,如地图边界线及行政区划老旧,无法自适应问题等,正好抽时间又整理了一下修改的思路.

之前的文章已经获取了一套新的全国地图的行政区划及边界线,接下来就可以根据这套区划来进行地图的编写了.先来看一下最后的呈现效果.

代码目录如下

地图采用了最新的行政区划及边界进行加载,具体获取方式在另一篇文章 https://www.cnblogs.com/weijiutao/p/15989290.html

地图边界下目录

 这次代码与上一个版本的最大区别在于china.vue文件,如下

  1 <template>  2   <div id="map-container">  3     <el-button type="text" size="large" class="back" @click="back" v-if="deepTree.length > 1">返回</el-button>  4     <div class="echarts">  5       <div id="map"></div>  6     </div>  7   </div>  8 </template>  9  10 <script> 11  12 import {getChinaJson, getProvinceJson, getCityJson, getDistrictJson} from "@/api/map"; 13 import {mapOption} from '@/config/mapOption' 14 import resize from '@/utils/resize' 15  16  17 export default { 18   mixins: [resize], 19   name: "china", 20   components: {}, 21   props: { 22     areaCode: { 23       type: String, 24       default: '000000000000' 25     }, 26     areaLevel: { 27       type: [String, Number], 28       default: 0 29     }, 30     areaName: { 31       type: String, 32       default: 'china' 33     }, 34     // 当前地图上的地区名字 35     mapNameList: { 36       type: Array, 37       default() { 38         return [] 39       } 40     }, 41     // 当前地图上的地区Code 42     mapCodeList: { 43       type: Array, 44       default() { 45         return [] 46       } 47     }, 48     // 地区统计数据 49     areaStatistic: { 50       type: Array, 51       default() { 52         return [] 53       } 54     } 55   }, 56   data() { 57     return { 58       chart: null, // 实例化echarts 59       mapDataList: [], // 当前地图上的地区 60       option: {...mapOption.basicOption}, // map的相关配置 61       deepTree: [],// 点击地图时push,点返回时pop 62       areaStatisticMapValue: {}, // 地图数据value, 只是amounts 63       areaStatisticMapData: {}, // 地图数据data,包含所有数据 64       areaLevelMap: { 65         'country': 0, 66         'china': 0, 67         'province': 1, 68         'city': 2, 69         'district': 3, 70       }, 71       tooltipAutoplay: null, // 提示框自动播放 72       tooltipAutoplayIndex: 0, // 提示框自动播放index 73     } 74   }, 75   beforeDestroy() { 76     if (!this.chart) { 77       return 78     } 79     this.chart.dispose() 80     this.chart = null 81   }, 82   mounted() { 83     this.$nextTick(() => { 84       this.initEcharts(); 85       this.chart.on('click', this.echartsMapClick); 86       this.chart.on('mouseover', this.echartsMapMouseover); 87       this.chart.on('mouseout', this.echartsMapMouseout); 88     }); 89   }, 90   watch: { 91     areaStatistic: { 92       handler(val) { 93         var objValue = {}, objData = {} 94         for (var i = 0; i < val.length; i++) { 95           objValue[val[i]['areaCode'].substr(0, 6)] = val[i].amounts * 1 96           objData[val[i]['areaCode'].substr(0, 6)] = val[i] 97         } 98         this.areaStatisticMapValue = objValue 99         this.areaStatisticMapData = objData100         this.initEcharts()101       },102       deep: true,103     }104   },105   methods: {106     // 初次加载绘制地图107     initEcharts() {108       //地图容器109       // this.$echarts.dispose(document.getElementById('map'))110       this.chart = this.$echarts.init(document.getElementById('map'));111       if (this.areaLevel === 0) {112         this.requestGetChinaJson();113       } else if (this.areaLevel === 1) {114         this.requestGetProvinceJSON({name: this.areaName, level: 'province', adcode: this.areaCode.substr(0, 6)})115       } else if (this.areaLevel === 2) {116         this.requestGetCityJSON({name: this.areaName, level: 'city', adcode: this.areaCode.substr(0, 6)})117       } else if (this.areaLevel === 3) {118         this.requestGetDistrictJSON({name: this.areaName, level: 'district', adcode: this.areaCode.substr(0, 6)})119       } else {120         return false121       }122     },123     // 地图点击124     echartsMapClick(params) {125       this.$emit('update:areaCode', params.data.adcode + '000000')126       this.$emit('update:areaName', params.data.name)127       this.$emit('update:areaLevel', this.areaLevelMap[params.data.level])128       if (params.data.level === 'province') {129         this.requestGetProvinceJSON(params.data);130       } else if (params.data.level === 'city') {131         this.requestGetCityJSON(params.data)132       } else if (params.data.level === 'district' && this.mapDataList.length > 1) {133         this.requestGetDistrictJSON(params.data)134       } else {135         return false136       }137     },138     //绘制全国地图areaStatistic139     requestGetChinaJson() {140       getChinaJson().then(res => {141         // console.log('china--->', res)142         this.$emit('update:areaLevel', 0)143         this.setJsonData(res)144       });145     },146     // 加载省级地图147     requestGetProvinceJSON(params) {148       getProvinceJson(params.adcode).then(res => {149         // console.log('province--->', res)150         this.$emit('update:areaLevel', 1)151         this.setJsonData(res, params)152       });153     },154     // 加载市级地图155     requestGetCityJSON(params) {156       getCityJson(params.adcode).then(res => {157         // console.log('city--->', res)158         this.$emit('update:areaLevel', 2)159         this.setJsonData(res, params)160       })161     },162     // 加载县级地图163     requestGetDistrictJSON(params) {164       getDistrictJson(params.adcode).then(res => {165         // console.log('district--->', res)166         this.$emit('update:areaLevel', 3)167         this.setJsonData(res, params)168       })169     },170     // 设置数据171     setJsonData(res, params) {172       var mapDataList = [];173       var mapNameList = [];174       var mapCodeList = [];175       for (var i = 0; i < res.features.length; i++) {176         var obj = {177           ...res.features[i].properties,178           value: this._mathRandom1000(),179           valueData: this._mathRandom1000(),180         };181         mapDataList.unshift(obj)182         mapNameList.unshift(res.features[i].properties.name)183         mapCodeList.unshift(res.features[i].properties.adcode + '000000')184       }185       this.mapDataList = mapDataList;186       this.$emit('update:mapNameList', mapNameList)187       this.$emit('update:mapCodeList', mapCodeList)188       this.setMapData(res, params)189     },190     // 设置地图信息191     setMapData(res, params) {192       if (this.areaName === 'china') {193         this.deepTree.push({194           mapDataList: this.mapDataList,195           params: {name: 'china', level: 'country', adcode: '100000'}196         });197         //注册地图198         this.$echarts.registerMap('china', res);199         //绘制地图200         this.renderMap('china', this.mapDataList);201       } else {202         this.deepTree.push({mapDataList: this.mapDataList, params: params});203         this.$echarts.registerMap(params.name, res);204         this.renderMap(params.name, this.mapDataList);205       }206     },207     // 渲染地图208     renderMap(map, data) {209       var mapDataList = data.map(item => {210         return {211           name: item.name,212           value: item.value213         }214       })215       mapDataList = mapDataList.sort(function (a, b) {216         return b.value - a.value217       });218       var pointData = []219       for (var i = 0; i < data.length; i++) {220         if (data[i].value != 0) {221           pointData.push({222             ...data[i],223             value: [data[i].center[0], data[i].center[1], data[i].value],224           })225         }226       }227       // 设置左下角数量范围值228       this.option.visualMap.min = mapDataList.length > 1 ? mapDataList[mapDataList.length - 2].value : 0229       this.option.visualMap.max = mapDataList.length > 0 ? mapDataList[0].value : 0230       // 设置左上角当前位置231       this.option.title[0].text = map === 'china' ? '全国' : map232       this.option.geo = {233         show: false,234         map: map,235         zoom: 1.2, //当前视角的缩放比例236         roam: true, //是否开启平游或缩放237         center: undefined,238       }239       this.option.series = [240         {241           name: map,242           mapType: map,243           zoom: 1, //当前视角的缩放比例244           roam: false, //是否开启平游或缩放245           center: undefined,246           scaleLimit: { //滚轮缩放的极限控制247             min: .5,248             max: 10249           },250           ...mapOption.seriesOption,251           data: data252         },253         {254           name: '散点',//series名称255           type: 'effectScatter',//散点类型256           coordinateSystem: 'geo',// series坐标系类型257           rippleEffect: {258             brushType: 'fill'259           },260           normal: {261             show: true,262             // 提示内容263             formatter: params => {264               return params.name;265             },266             position: 'top', // 提示方向267             color: '#fff'268           },269           emphasis: {270             show: true //271           },272           itemStyle: {273             normal: {274               color: '#F4E925',275               shadowBlur: 10,276               shadowColor: '#000'277             }278           },279           // symbol:'pin', // 散点样式'pin'(标注)、'arrow'(箭头)280           data: pointData,281           symbolSize: function (val) {282             // return val[2] / 100;283             if (val[2] === mapDataList[0].value) {284               return 10285             }286             return 6287           },288           showEffectOn: 'render', //加载完毕显示特效289         },290       ]291       //渲染地图292       this.chart.setOption(this.option, true)293       this.setTooltipAutoplay()294     },295     // 地图鼠标移入事件296     echartsMapMouseover() {297       clearInterval(this.tooltipAutoplay)298     },299     // 地图鼠标移出事件300     echartsMapMouseout() {301       this.setTooltipAutoplay()302     },303     // 动态显示tooltip304     setTooltipAutoplay() {305       clearInterval(this.tooltipAutoplay)306       // var index = 0; //播放所在下标307       // if(this.chart.dispatchAction) {308       this.tooltipAutoplay = setInterval(() => {309         this.chart.dispatchAction({310           type: 'showTip',311           seriesIndex: 0,312           dataIndex: this.tooltipAutoplayIndex313         })314         this.tooltipAutoplayIndex++315         if (this.tooltipAutoplayIndex >= this.mapDataList.length) {316           this.tooltipAutoplayIndex = 0;317           this.setTooltipAutoplay()318         }319       }, 6666)320       // }321     },322     // 返回323     back() {324       if (this.deepTree.length > 1) {325         this.deepTree.pop();326         this.mapDataList = this.deepTree[this.deepTree.length - 1].mapDataList;327         var areaName = this.deepTree[this.deepTree.length - 1].params.name;328         var areaCode = this.deepTree[this.deepTree.length - 1].params.adcode;329         var areaLevel = this.deepTree[this.deepTree.length - 1].params.level;330         var mapNameList = this.mapDataList.map(item => {331           return item.name332         })333         var mapCodeList = this.mapDataList.map(item => {334           return item.adcode + '000000'335         })336         this.$emit('update:areaCode', (areaCode === '100000' ? '000000' : areaCode) + '000000')337         this.$emit('update:areaName', areaName)338         this.$emit('update:areaLevel', this.areaLevelMap[areaLevel])339         this.$emit('update:mapNameList', mapNameList)340         this.$emit('update:mapCodeList', mapCodeList)341         this.renderMap(areaName, this.mapDataList);342       }343     }344   }345 }346 347 </script>348 349 <style lang="scss" scoped>350 #map-container {351   height: 66.6%;352   position: relative;353 354   .echarts {355     height: 100%;356 357     #map {358       width: 100%;359       height: 100%;360     }361   }362 363   .back {364     position: absolute;365     top: 55px;366     left: 5px;367     z-index: 9;368     //color: #24CFF4;369     font-weight: bolder;370   }371 }372 373 </style>

在上一套代码中,地图的边界上没有adcode(行政区划编码),这样就会导致在选取地区的时候只能根据汉字来进行匹配,导致不必要的错误,而最新抓去的行政区划里新增了adcode(行政区划)字段,这样就能根据该地区的行政区划来精准匹配.

   

同时在上一个版本代码里,也对直辖市和特别行政区做了特殊处理,因为他们没有三级县级地图,而这次版本由于引入adcode,可以直接匹配到指定行政区划中,减少和很多不必要的判断操作,如下图

做地图下钻本人也看过很多网上所说的,但是说的都不是很清楚,也没有专门对其进行代码的整理,这套代码是本人结合自身情况编写的,很多地方可能不是你想要的,需要对其进行取舍.

做地图其实最重要的就是地图边界线,自从echarts不再更新维护地图之后,对于初识echarts地图的人来说不太好下手,希望本文可以帮助到你.

如果有需要大家可以去以下地址下载源码学习,也欢迎star。

gitee源码地址:https://gitee.com/vijtor/vue-map-echarts

 

posted @ 2022-03-16 14:42 丰寸 阅读(6) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员