本期内容
使用 Vue + Echarts + vxeTable 搭建前端展示界面,接口请求示例是腾讯肺炎疫情实时动态页面中的开放接口
知识基础
如何在 Vue 中引入 Echarts,点这里
如何在 Vue 中引入 vxeTable,点这里
部分效果
一、申请百度地图 ak 以使用 Echarts 地图
1、申请 ak
② 登录后点击 控制台
③ 按要求操作后,点击申请 密钥
④选择 浏览器端
⑤保存好 ak
2、创建 map.js 文件调用 BMap
① 建立 map.js 文件
② 在 map.js 中将申请的 ak 填入下方函数中
export function MP () {
const ak = '...' // 这里填的是你自己的 ak
return new Promise(function (resolve, reject) {
window.init = function () {
resolve(BMap)
}
var script = document.createElement('script')
script.type = 'text/javascript'
script.src = `http://api.map.baidu.com/api?v=2.0&ak=${ak}&callback=init`
script.onerror = reject
document.head.appendChild(script)
})
}
③ 在需要调用地图的 vue 页面的 js 中引入,并声明 bmap
import { MP } from '../map.js'
require('echarts/extension/bmap/bmap')
二、引入 Echarts 中对应的地图插件(完整代码)
下列代码中每块函数的功能都有注释,值得注意的几点:
① api 是因为跨域问题,具体解决方法可以参考这篇文章
// 此处的 api 是通过配置跨域,将原本的 url 替换成 api 来表示
const url = `/api/g2/getOnsInfo?name=disease_h5&callback=&_=${timeStamp}`
② geoCoordMap:各省会经纬度
③ 页面中调用了 定时器 以实现固定时间刷新页面
④ option 中的内容均为 Echarts 文档中的图表写法,若用其他图表可以参考官方文档代码写法
完整代码如下
<!-- Description:肺炎疫情地图 -->
<template>
<div>
<div>现在时间:{{timeNow}}</div>
<div>刷新次数:{{timeCount}}</div>
<vxe-table :data="countryData" align="center" stripe>
<vxe-table-column type="seq" title="序号" width="80"></vxe-table-column>
<vxe-table-column field="name" title="国家"></vxe-table-column>
<vxe-table-column field="total.confirm" title="确诊人数"></vxe-table-column>
<vxe-table-column field="total.suspect" title="疑似病例"></vxe-table-column>
<vxe-table-column field="total.heal" title="治愈人数"></vxe-table-column>
<vxe-table-column field="total.dead" title="死亡人数"></vxe-table-column>
</vxe-table>
<div style="height:100px"></div>
<vxe-table :data="provinceData" align="center" stripe>
<vxe-table-column type="seq" title="序号" width="80"></vxe-table-column>
<vxe-table-column field="name" title="省份"></vxe-table-column>
<vxe-table-column field="total.confirm" title="确诊人数"></vxe-table-column>
<vxe-table-column field="total.suspect" title="疑似病例"></vxe-table-column>
<vxe-table-column field="total.heal" title="治愈人数"></vxe-table-column>
<vxe-table-column field="total.dead" title="死亡人数"></vxe-table-column>
</vxe-table>
<div style="height:100px"></div>
<div style="height:900px" id="main"></div>
</div>
</template>
<script>
import { MP } from '../map.js'
require('echarts/extension/bmap/bmap')
export default {
data () {
return {
provinceData: null,
countryData: null,
timeNow: new Date(),
timeCount: 0,
echartsDatas: [],
temp: {},
// convertData: null,
geoCoordMap: {
'山东': [117.000923, 36.675807],
'河北': [115.48333, 38.03333],
'吉林': [125.35000, 43.88333],
'黑龙江': [127.63333, 47.75000],
'辽宁': [123.38333, 41.80000],
'内蒙古': [111.670801, 41.818311],
'新疆': [87.68333, 43.76667],
'甘肃': [103.73333, 36.03333],
'宁夏': [106.26667, 37.46667],
'山西': [112.53333, 37.86667],
'陕西': [108.95000, 34.26667],
'河南': [113.65000, 34.76667],
'安徽': [117.283042, 31.86119],
'江苏': [119.78333, 32.05000],
'浙江': [120.20000, 30.26667],
'福建': [118.30000, 26.08333],
'广东': [113.23333, 23.16667],
'江西': [115.90000, 28.68333],
'海南': [110.35000, 20.01667],
'广西': [108.320004, 22.82402],
'贵州': [106.71667, 26.56667],
'湖南': [113.00000, 28.21667],
'湖北': [114.298572, 30.584355],
'四川': [104.06667, 30.66667],
'云南': [102.73333, 25.05000],
'西藏': [91.00000, 30.60000],
'青海': [96.75000, 36.56667],
'天津': [117.20000, 39.13333],
'上海': [121.55333, 31.20000],
'重庆': [106.45000, 29.56667],
'北京': [116.41667, 39.91667],
'台湾': [121.30, 25.03],
'香港': [114.10000, 22.20000],
'澳门': [113.50000, 22.20000]
}
}
},
created () {
this.getInfo()
},
mounted () {
// 调用实时刷新的方法
this.time()
this.$nextTick(() => {
MP().then(BMap => {
this.drawChart()
})
})
},
destroyed () {
// 销毁时关闭时间器
clearInterval(this.timer)
},
methods: {
// 获取武汉疫情信息
getInfo () {
const timeStamp = new Date().getTime()
// 此处的 api 是通过配置跨域,将原本的 url 替换成 api 来表示
const url = `/api/g2/getOnsInfo?name=disease_h5&callback=&_=${timeStamp}`
this.$http.get(url).then(res => {
// 用 JSON.parse 转换成 json 格式的数据
const subData = JSON.parse(res.data.data)
// areaTree 取 0 为中国,其他国家需递增
// ------省份数据------
const china = subData.areaTree[0]
this.provinceData = china.children
// ------国家数据------
this.countryData = subData.areaTree
for (var i = 0; i < this.provinceData.length; i++) {
this.temp.name = this.provinceData[i].name
this.temp.value = this.provinceData[i].total.confirm
this.echartsDatas.push(this.temp)
this.temp = {}
}
this.drawChart()
}).catch(err => {
console.log(err)
})
},
// 定时刷新,发起请求, 1800000 为毫秒,即为半小时刷新一次
time () {
if (this.timer) {
clearInterval(this.timer)
} else {
this.timer = setInterval(() => {
this.timeNow = new Date()
this.timeCount += 1
this.getInfo()
}, 300000)
}
},
/**
* 画echarts
*/
drawChart () {
var convertData = (echartsDatas) => {
var res = []
// console.log('res1', res)
// console.log('echartsDatas', echartsDatas)
for (var i = 0; i < echartsDatas.length; i++) {
var geoCoord = this.geoCoordMap[echartsDatas[i].name]
// console.log('geoCoord:', geoCoord)
if (geoCoord) {
res.push({
name: echartsDatas[i].name,
value: geoCoord.concat(echartsDatas[i].value)
})
}
}
return res
}
var echarts = require('echarts')
var myChart = echarts.init(document.getElementById('main'))
// 指定图表的配置项和数据
var option = {
backgroundColor: 'transparent',
title: {
text: '新型肺炎疫情实时动态',
subtext: 'Data from news',
left: 'center',
textStyle: {
color: '#fff'
}
},
tooltip: {
trigger: 'item',
formatter: (obj) => {
var str = ''
str = '确诊人数</br>' + obj.data.name + ': ' + obj.data.value[2]
return str
}
},
bmap: {
// 首次呈现的地理位置
center: [104.114129, 37.550339],
// zoom:放大倍数
zoom: 5,
// roam:是否可以拖动地图
roam: false,
mapStyle: {
styleJson: [
{
'featureType': 'water',
'elementType': 'all',
'stylers': {
'color': '#044161'
}
},
{
'featureType': 'land',
'elementType': 'all',
'stylers': {
'color': '#004981'
}
},
// 我国边界线颜色
{
'featureType': 'boundary',
'elementType': 'geometry',
'stylers': {
'color': 'fff'
}
},
{
'featureType': 'railway',
'elementType': 'all',
'stylers': {
'visibility': 'off'
}
},
{
'featureType': 'highway',
'elementType': 'geometry',
'stylers': {
'color': '#004981'
}
},
{
'featureType': 'highway',
'elementType': 'geometry.fill',
'stylers': {
'color': '#005b96',
'lightness': 1
}
},
{
'featureType': 'highway',
'elementType': 'labels',
'stylers': {
'visibility': 'off'
}
},
{
'featureType': 'arterial',
'elementType': 'geometry',
'stylers': {
'color': '#004981'
}
},
{
'featureType': 'arterial',
'elementType': 'geometry.fill',
'stylers': {
'color': '#00508b'
}
},
{
'featureType': 'poi',
'elementType': 'all',
'stylers': {
'visibility': 'off'
}
},
{
'featureType': 'green',
'elementType': 'all',
'stylers': {
'color': '#056197',
'visibility': 'off'
}
},
{
'featureType': 'subway',
'elementType': 'all',
'stylers': {
'visibility': 'off'
}
},
{
'featureType': 'manmade',
'elementType': 'all',
'stylers': {
'visibility': 'off'
}
},
{
'featureType': 'local',
'elementType': 'all',
'stylers': {
'visibility': 'off'
}
},
{
'featureType': 'arterial',
'elementType': 'labels',
'stylers': {
'visibility': 'off'
}
},
// 所有国边界线
{
'featureType': 'boundary',
'elementType': 'geometry.fill',
'stylers': {
'color': '#029fd4'
}
},
{
'featureType': 'building',
'elementType': 'all',
'stylers': {
'color': '#1a5787'
}
},
{
'featureType': 'label',
'elementType': 'all',
'stylers': {
'visibility': 'off'
}
}
]
}
},
series: [
{
name: '确诊人数',
// type:圆点的样式
type: 'effectScatter',
coordinateSystem: 'bmap',
// 0-6 即为排名前六,sort 为排序
data: convertData(this.echartsDatas.sort(function (a, b) {
return b.value - a.value
}).slice(0, 35)),
symbolSize: 20,
// 小圆点是否有“范围圈”
showEffectOn: 'emphasis',
rippleEffect: {
brushType: 'stroke'
},
// 控制圆点在 hover 的时候是否变大
hoverAnimation: true,
label: {
formatter: '{b}',
position: 'right',
show: true
},
// 大圆点颜色
// shadowcolor 圆点阴影颜色
itemStyle: {
color: '#f4e925',
shadowBlur: 10,
shadowColor: '#fff'
},
zlevel: 1
}
]
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option)
}
}
}
</script>
<style scoped>
</style>
三、过程中遇到的问题
1、如何往结构体数组中加入二级数组
如:要将多个 temp{name:' ',value:' '} 添加到 echartsDatas[ ] 中
解决方法如下:记得用完 temp 后将其清空!否则数组会无限叠加。
2、原生地图代码中,对应各地的 value 出不来,只显示经纬度的 “经度”
原因:官方提供的图表代码中,只能获取到经纬度数组中的 arr[0] 的数据,即经度
思路:在数据中,value 和经纬度的数据合并在一起了,因此尝试在formatter中加入function来获取数据展示
解决方法:在 tooltip 中写入 formatter 的函数即可
来源:CSDN
作者:Joker-ls
链接:https://blog.csdn.net/weixin_42678675/article/details/104661674