使用echarts绘制中国地图根据不同的省份划分到指定区域里面中

devtools/2024/10/24 12:22:33/

需求:我们在开发过程中会遇到使用中国地图来划分不同区域省份下面的数量统计情况,但是有时候使用Echarts里面地图功能和我们实际业务需求不匹配的,这个时候就需要我们手动自定义进行划分不同区域下面的省份数据。例如大区1下面有哪些省份,大区2对应哪些的省份进行划分显示的。

1,实现效果图如下:

在这里插入图片描述
2,关键代码如下:

【1】后端返回数据格式如下:
在这里插入图片描述

在这里插入图片描述

【2】把需要合并的省份的经纬度数据合并起来。

javascript">function mergeProvinces(chinaJson, regionMap) {//合并大区里省份的coordinatesvar oldFeatures = chinaJson.featuresvar featuress = regionMap.map((item) => {var polygonsCoordinates: any[] = []for (var z = 0; z < item.provinces.length; z++) {for (var j = 0; j < oldFeatures.length; j++) {if (oldFeatures[j].properties.name.includes(item.provinces[z].slice(0, 2))) {const coordinates = oldFeatures[j].geometry.coordinatesif (coordinates[0].length !== 1) {polygonsCoordinates = polygonsCoordinates.concat(coordinates)} else {polygonsCoordinates = polygonsCoordinates.concat(coordinates.reduce((r, e) => {return r.concat(e)}, []),)}oldFeatures[j].ok = 1break}}}return {id: 'xx',type: 'MultiPolygon',geometry: {type: 'Polygon',coordinates: polygonsCoordinates,},properties: {name: item.regionName || '',childNum: polygonsCoordinates.length,},}})const others = oldFeatures.filter((item: any) => !item.ok)featuress = featuress.concat(others)chinaJson.features = featuressreturn chinaJson}

3- 具体代码组件如下所示:

javascript"><template><div class="chinamapContentbox"><div id="chinaMap" ref="chinaMap"></div></div>
</template><script lang="ts" setup>import { onMounted, onBeforeUnmount, ref, watch } from 'vue'import china from './china.json'import { cloneDeep, debounce } from 'lodash-es'import { nextTick } from 'vue'import * as echarts from 'echarts/core'import {TooltipComponent,TooltipComponentOption,VisualMapComponent,VisualMapComponentOption,GeoComponent,GeoComponentOption,} from 'echarts/components'import { MapChart, MapSeriesOption } from 'echarts/charts'import { CanvasRenderer } from 'echarts/renderers'echarts.use([TooltipComponent, VisualMapComponent, GeoComponent, MapChart, CanvasRenderer])type EChartsOption = echarts.ComposeOption<TooltipComponentOption | VisualMapComponentOption | GeoComponentOption | MapSeriesOption>function mergeProvinces(chinaJson, regionMap) {//合并大区里省份的coordinatesvar oldFeatures = chinaJson.featuresvar featuress = regionMap.map((item) => {var polygonsCoordinates: any[] = []for (var z = 0; z < item.provinces.length; z++) {for (var j = 0; j < oldFeatures.length; j++) {if (oldFeatures[j].properties.name.includes(item.provinces[z].slice(0, 2))) {const coordinates = oldFeatures[j].geometry.coordinatesif (coordinates[0].length !== 1) {polygonsCoordinates = polygonsCoordinates.concat(coordinates)} else {polygonsCoordinates = polygonsCoordinates.concat(coordinates.reduce((r, e) => {return r.concat(e)}, []),)}oldFeatures[j].ok = 1break}}}return {id: 'xx',type: 'MultiPolygon',geometry: {type: 'Polygon',coordinates: polygonsCoordinates,},properties: {name: item.regionName || '',childNum: polygonsCoordinates.length,},}})const others = oldFeatures.filter((item: any) => !item.ok)featuress = featuress.concat(others)chinaJson.features = featuressreturn chinaJson}const chinaMap = ref()let myChart: echarts.EChartsconst resize = debounce(() => myChart && myChart.resize(), 200)const props = defineProps({type: {type: String,default: '1',},areaDataInfo: {type: Array,default: () => [],},regionMap: {type: Array,default: () => [],},})watch(() => ({areaDataInfo: props.areaDataInfo,chinaMap: chinaMap.value,regionMap: props.regionMap,}),({ areaDataInfo, chinaMap, regionMap }) => {if (chinaMap && areaDataInfo) {const getvlaueList = areaDataInfo.map((item: any) => {return item.value})let maxNum = 100if (getvlaueList && getvlaueList.length > 0) {maxNum = Math.max(...getvlaueList)}echarts.registerMap('china', mergeProvinces(cloneDeep(china), regionMap))if (!myChart) {myChart = echarts.init(chinaMap)}nextTick(() => {setOptions(maxNum, areaDataInfo)})}},{ immediate: true, deep: true },)onMounted(() => {window.addEventListener('resize', resize)})onBeforeUnmount(() => {window.removeEventListener('resize', resize)})function setOptions(maxNum, areaDataInfo) {const options: EChartsOption = {tooltip: {formatter(params) {if (!areaDataInfo.some((e) => e.name === params.name)) {return ''}const htmlStr1 = `<div style='font-size:14px; margin-bottom:10px;'> ${params.name} </div><p style='text-align:left;margin-top:-4px;'>联斯达覆盖省份:${params.data?.liansidaCoverProvinceCount || 0}<br/>联斯达覆盖城市:${params.data?.liansidaCoverCityCount || 0}<br/>斯联达覆盖中心:${params.data?.liansidaCoverCenterCount || 0}<br/>联斯达未覆盖中心:${params.data?.liansidaUnCoverCenterCount || 0}<br/>联斯达中心覆盖率:${params.data?.liansidaCoverCenterRate || 0}</p>`const htmlStr2 = `<div style='font-size:14px; margin-bottom:10px;'> ${params.name} </div><p style='text-align:left;margin-top:-4px;'>项目数:${params.data?.projectCount || 0}<br/>提前启动项目:${params.data?.preProjectCount || 0}<br/>入组数:${params.data?.enrollmentCount || 0}</p>`return props.type === '1' ? htmlStr1 : htmlStr2},backgroundColor: 'rgba(0,0,0,.6)', //提示标签背景颜色textStyle: { color: '#fff' }, //提示标签字体颜色},visualMap: {show: false,max: maxNum,color: ['#356191', '#1890ff', '#EBEBEB'],},geo: {map: 'china',roam: false,zoom: 1.2,label: {show: false,color: '#fff',textShadowColor: '#000',textShadowBlur: 10,textShadowOffsetX: 3,},itemStyle: {areaColor: '#d5e8f3',borderColor: '#fcfdfe',borderWidth: 1,},center: [104.114129, 37.550339],emphasis: {label: {color: '#fff',textShadowColor: '#000',textShadowBlur: 10,textShadowOffsetX: 0,},itemStyle: {areaColor: '#55D187',},},},series: [{name: '地图', // 浮动框的标题(上面的formatter自定义了提示框数据,所以这里可不写)type: 'map',map: 'china',geoIndex: 0,label: {show: true,},data: areaDataInfo,},],}myChart.clear()myChart.setOption(options)}
</script><style lang="less">.chinamapContentbox {width: 100%;#chinaMap {width: 100%;height: 430px;}}
</style>

http://www.ppmy.cn/devtools/57639.html

相关文章

vue require引入静态文件报错

如果是通过向后端发送请求&#xff0c;动态的获取对应的文件数据流很容易做到文件的显示和加载。现在研究&#xff0c;一些不存放在后端而直接存放在vue前端项目中的静态媒体文件如何加载。 通常情况下&#xff0c;vue项目的图片jpg&#xff0c;png等都可以直接在/ass…

算法力扣刷题 二十五【28.找出字符串中第一个匹配项的下标】

前言 字符串篇&#xff0c;继续。 记录 二十五【28.找出字符串中第一个匹配项的下标】 一、题目阅读 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不…

大数据开发如何快速进阶

目录 1. 个人经验与心得分享1.1 试错的价值与机会把握1.2 投入产出比的考量1.3 刻意练习与技能提升1.4 目标设定与职业规划1.5 自我驱动与成长1.6 第一性原理的应用 2. 大数据开发领域的挑战与机遇2.1 技术革新的挑战2.2 数据治理的难题2.3 人才短缺的问题2.4 投入产出比的考量…

【话题】AI是在帮助开发者还是取代他们

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 引言AI在代码生成中的应用AI在错误检测和自动化测试中的作用对开发者职业前景的影响技能需求的变化与适应策略结论文章推荐 引言 随着人工智能&#xff08;AI&#xff…

153. 寻找旋转排序数组中的最小值(中等)

153. 寻找旋转排序数组中的最小值 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java 1. 题目描述 题目中转&#xff1a;153. 寻找旋转排序数组中的最小值 2.详细题解 如果不考虑 O ( l o g n ) O(log n) O(logn)的时间复杂度&#xff0c;直接 O ( n ) O(n) O(n)时间复杂…

进程的控制-孤儿进程和僵尸进程

孤儿进程 &#xff1a; 一个父进程退出&#xff0c;而它的一个或多个子进程还在运行&#xff0c;那么那些子进程将成为孤儿进程。孤儿进程将被 init 进程( 进程号为 1) 所收养&#xff0c;并由 init 进程对它们完成状态收集工作 为了释放子进程的占用的系统资源&#xff1a; …

【鸿蒙学习笔记】@Link装饰器:父子双向同步

官方文档&#xff1a;Link装饰器&#xff1a;父子双向同步 目录标题 [Q&A] Link装饰器作用 [Q&A] Link装饰器特点样例&#xff1a;简单类型样例&#xff1a;数组类型样例&#xff1a;Map类型样例&#xff1a;Set类型样例&#xff1a;联合类型 [Q&A] Link装饰器作用…

【IT领域新生必看】 Java编程中的重载(Overloading):初学者轻松掌握的全方位指南

文章目录 引言什么是方法重载&#xff08;Overloading&#xff09;&#xff1f;方法重载的基本示例 方法重载的规则1. 参数列表必须不同示例&#xff1a; 2. 返回类型可以相同也可以不同示例&#xff1a; 3. 访问修饰符可以相同也可以不同示例&#xff1a; 4. 可以抛出不同的异…