首先放效果图
实现思路大致是:
- 使用echarts绘制出地图
- 把获取到的数据和省份坐标对应上
开始之前我默认您已成功下载和导入相关插件
第一步
打开 地图选择器网站
http://datav.aliyun.com/portal/school/atlas/area_selector#&lat=30.230594564932193&lng=98.316650390625&zoom=6
鼠标点击你想要的省份 然后在右边根据需要看是否勾选(包含子区域),如果勾选了就会有市地区级的坐标,我这个项目是不需要的,所以不勾选,然后根据需要点击第三行------其他类型 点击下载保存 你会得到该省份的 .json
文件 ,然后依次下载需要的省份json文件
第二步
打开GEOJSON.IO网站
https://geojson.io/#map=2/0/20
该网站可以上传多个省份JSON,并且会在右边显示合并后的JSON文件,直接保存即可。
因为我的地图里是不需要展示
海南的四大群岛,所以需要手动删除该处的地理坐标,不然它会占很大的位置你的省份地图就会很小很小
最后,基于合并后的多省份JSON,需要在内容开头加上 var name= 即可,其中name可以自行命名,并将该文件保存为multiprovinces.js.
记得导出去啊宝子们!!
到目前为止,准备工作做完了,恭喜我们吧 哈哈哈哈哈~
第三步 绘制省份地图
有了省份js文件,接下来就生成一个.vue
文件 然后引入你的multiprovinces.js
<div>
<div id="main" class="earth_right"></div>
</div>
<script>
import * as echarts from 'echarts'
import myProvince from '@/assets/js/multiprovinces.js'
import to from '@/utils/to'
export default {
data () {
return {
myChart: null,
qualityMap:[],
centerData: {}, // 柱状图中心点的位置
}
},
created () {
var arr = myProvince.features
arr.length > 0 && arr.forEach((item, index) => {
var obj = {}
this.centerData[item.properties.name] = item.properties.center
})
},
methods: {
// 绘制地图
async getEarth () {
var _this = this
var mapChatDate = myProvince// 使用multiprovinces.js中的变量
echarts.registerMap('myProvince', mapChatDate)
this.myChart = echarts.init(document.getElementById('main'))
const option = {
legend: {
show: true,
orient: 'vertical' /* 标签文字垂直 */,
right: '10%',
top: '10%', // 居中展示
align: 'left',
icon: 'roundRect',
itemHeight: 14, // 图例图标的高度
itemWidth: 14, // 图例图标的宽度
textStyle: {
// 图例文字的样式
color: '#474747',
fontSize: 14
}
},
geo: {
map: 'myProvince',
roam: false, // 不开启缩放和平移
zoom: 1.23, // 视角缩放比例`
scaleLimit: {
min: 1,
max: 2
},
layoutSize: '100%', // 保持地图宽高比
label: {
show: true,
fontSize: '16',
color: '#000000',
},
itemStyle: {
areaColor: '#e6e6e6', // 地图区域颜色
borderColor: ' #fff', // 地图区域边界颜色
fontweight: 700, // 地图区域字体粗细
borderwidth: 1, // 地图区域边界宽度
shadowColor: 'rgba(0, 0,0,0.5)', // 阴影颜色
shadowBlur: 10 // 阴影模糊度
}
}
}
this.myChart.setOption(option)
//------------------------以上是绘制地图,以下是获取接口数据,并把柱状图渲染出来
//------------------------以上是绘制地图,以下是获取接口数据,并把柱状图渲染出来
const params = {
//需要传递给后台的参数
}
const [err, res] = await to(你的api地址(params))
if (err) return false
if (res) {
this.qualityMap = res.result.provinceList//接收后台传递的数据
}
var options2 = {
xAxis: [],
yAxis: [],
grid: [],
series: [],
legend: {
data: ['未通过', '已通过' ]
}
}
// echarts.util.each 函数遍历 _this.qualityMap中的每个数据项。
echarts.util.each(_this.qualityMap, function (dataItem, idx) {
if (!dataItem) {
console.error('Encountered undefined or null dataItem at index', idx)
return // 跳过这个循环迭代
}
// 获取地理坐标并转换为像素坐标:
//通过 centerData 获取每个数据项的地理坐标,然后使用 convertToPixel 方法将地理坐标转换为像素坐标。
var geoCoord = _this.centerData[dataItem.cockpitName]
if (!geoCoord) {
console.error('No geoCoord found for', dataItem.cockpitName)
return // 跳过这个循环迭代
}
var coord = _this.myChart.convertToPixel('geo', geoCoord)
if (!coord || coord.length < 2) {
console.error('Failed to convert geoCoord to pixel for', dataItem.name, geoCoord)
return // 跳过这个循环迭代
}
idx += ''
//设置X轴,为每个数据项创建一个新的X轴,并将其配置添加到 options.xAxis 数组中。这里定义了X轴的各种属性,包括位置、文本样式、刻度和标签等。
options2.xAxis.push({
id: idx,
gridId: idx,
// gridId:globalGridId,
type: 'category',
nameLocation: 'middle',
nameGap: 3,
nameTextStyle: {
color: '#000000'
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#fff',
show: false
},
axisLine: {
onZero: false,
lineStyle: {
color: 'rgba(0,0,0,0)'
}
},
data: ['未通过','已通过' ],
z: 100
})
//设置Y轴
options2.yAxis.push({
id: idx,
gridId: idx,
type: 'value',
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
axisLine: {
show: false,
lineStyle: {
color: '#fff'
}
},
z: 100
})
//设置网格 这里定义了网格的位置和大小。
options2.grid.push({
id: idx,
width: 55,
height: 40,
left: coord[0] - 30, // 调整左偏移量以居中两个柱状图
top: coord[1] - 15,
z: 100
})
var colors = ['#30C037', '#1E87F0']
var legendNames = ['未通过', '已通过']
var barWidth = 12 // 设置柱状图宽度
var barGap = '20%' // 设置柱状图之间的间距
var barCategoryGap = '30%' // 设置不同类别柱状图的间距
options2.series.push({
name: legendNames[0], // 未通过
id: idx + '_0',
type: 'bar',
xAxisId: idx,
yAxisId: idx,
barGap: barGap, // 设置柱状图之间的间距
barCategoryGap: barCategoryGap, // 设置不同类别柱状图的间距
data: [0, dataItem.atomicNoPassCount], // 未通过的数据
barWidth: barWidth, // 设置柱状图宽度
z: 100,
itemStyle: {
color: colors[0] // 设置颜色
},
label: {
show: true,
position: 'top',
distance: 5, // 数值离柱子上方的距离
color: colors[0], // 设置顶部数字颜色,与柱状图颜色一致
formatter: function (params) {
if (params.value > 0) {
return params.value
} else {
return ''
}
}
}
})
options2.series.push({
name: legendNames[1], // 已通过
id: idx + '_1',
type: 'bar',
xAxisId: idx,
yAxisId: idx, // 使用全局 y 轴 ID
// barGap: 0,
// barCategoryGap: 2,
data: [dataItem.atomicPassCount, 0], // 已通过的数据
barWidth: barWidth, // 设置柱状图宽度
barGap: barGap, // 设置柱状图之间的间距
barCategoryGap: barCategoryGap, // 设置不同类别柱状图的间距
z: 100,
itemStyle: {
color: colors[1] // 设置颜色
},
label: {
show: true,
position: 'top',
distance: 5, // 数值离柱子上方的距离
color: colors[1], // 设置顶部数字颜色,与柱状图颜色一致
formatter: function (params) {
if (params.value > 0) {
return params.value
} else {
return ''
}
}
}
})
})
_this.myChart.setOption(options2)
},
},
mounted () {
this.getEarth()
}
}
</script>
以上是实现的全部代码,说下我遇到的问题吧,
第一个问题就是我展示的数据内容 我获取到的数据里面有两个(储能、超高压)是没有跟省份对应上,最开始随便给了两个坐标,但是不显示,考虑到我的省份js文件不包含的原因,所以我就把这两个数据绑定在广东省东南部的小岛上的地理坐标并且coordinates不能为空
还有个问题就是由于我需要展示深圳的坐标,所以需要手动添加深圳的(前面下载的json文件不包含子区域的)
其他的问题就是,地图自适应放大缩小的时候resize 事件监听 柱状图不能跟着变化,导致错位,所以在监听resize变化的时候需要重新计算柱状图的位置和尺寸,以确保它们与地图保持同步。同时设置 roam 属性:设置 geo.roam 为 true,允许地图缩放和平移。确保在缩放时柱状图的位置和大小能够同步更新。这样,当地图缩放或窗口大小调整时,柱状图的位置和大小会自动更新,与地图保持一致。
篇幅有限,如有其他问题欢迎评论区讨论 喜欢的宝子们 麻烦点个赞赞给个鼓励哟
~~ 完结撒发发