本博客对作者后除的上述方法进行再度解释,便于自己的理解与后续的使用。初次见到后除的文章链接为https://www.jb51.net/article/130980.htm,其github链接为https://github.com/mazeyqian/vue-china-map。若涉及侵权等问题请及时联系我,谢谢!
效果图
环境与插件安装
我使用的编译器为IDEA,可直接在Terminal处进行插件安装。
npm install vuex --save
npm install axios --save
npm install echarts --save
项目结构
此处需要特别说明的是public文件夹下的data文件夹,在Vue-cli3及以上的版本中,只需要将静态资源放在public文件夹下即可被成功访问到。在后续还将有说明。原github博客下的放置方式将找不到json文件。
具体代码
由于这是我第一次使用vue和echarts很多具体原理有待后续补充,现在只能做到实现,见谅。
main.js
首先是main.js。在这个js文件中导入我们需要的各种包/依赖。其中,ElementUI是项目其他组件所需要的,在这个单独案例中可以不添加。echarts可以在这里进行全局导入,但我们根据原作者意图进行了局部导入。
关于什么是vue和store,简单来说就是在各个组件之间传值的工具。
import Vue from 'vue'
import Vuex from 'vuex'
import store from "./store/index";
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import Analysis from "@/components/Analysis";
Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.use(Vuex)
new Vue({
el:'#app',
store,
render: h => h(Analysis),
})
index.js
可以在上面的main.js文件的new Vue函数中看到,我们的store引用的是store文件夹下的index.js文件。这里主要是引入了ChinaMap这一主要的管理和分发数据的js文件。
import Vue from 'vue'
import Vuex from 'vuex'
import ChinaMap from "@/store/modules/ChinaMap";
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
ChinaMap
}
})
export default store
Analysis.vue
首先给这个样例一个地方显示,即增加一个Dom容器。
<template>
<div id="region" style="width: 60%;height: 600px"></div>
</template>
接下来在<script>
处写绘制地图的方法。
此处的mounted函数是一个钩子函数,一般在初始化页面完成后,再对dom节点进行相关操作。生命周期函数可见官方链接。在这里简单理解为,它会在其他组件完成之后进行绘制即可。
首先是引入echarts的各种需要的组件。前面的require函数就是引入函数。
echarts.init()
创建一个echarts实例,括号内的参数为实例容器,一般为指定宽高的div容器
chinaMap.setOption()
设置图表实例的配置项以及数据,万能接口,所有参数和数据的修改都可以通过 setOption 完成,ECharts 会合并新的参数和数据,然后刷新图表。
chinaMap.showLoading
显示加载动画效果。即数据在加载时的效果。一般来说运行速度很快不会看到,但若数据加载失败会显示这个画面。
上述函数均为echarts的指定函数,可在官方文档查看说明。最后的store暂不解释。
mounted(){
let echarts = require('echarts/lib/echarts')
require('echarts/lib/chart/scatter')
require('echarts/lib/chart/effectScatter')
require('echarts/lib/chart/map')
require('echarts/lib/component/legend')
require('echarts/lib/component/tooltip')
require('echarts/lib/component/geo')
require('echarts/map/js/china')
let chinaMap = echarts.init(document.getElementById('region'))
chinaMap.setOption({
backgroundColor: '#272D3A',
// 标题
title: {
text: '中国地图闪闪发光',
left: 'center',
textStyle: {
color: '#fff'
}
},
// 地图上圆点的提示
tooltip: {
trigger: 'item',
formatter: function (params) {
return params.name + ' : ' + params.value[2]
}
},
// 图例按钮 点击可选择哪些不显示
legend: {
orient: 'vertical',
left: 'left',
top: 'bottom',
data: ['地区热度', 'top5'],
textStyle: {
color: '#fff'
}
},
// 地理坐标系组件
geo: {
map: 'china',
label: {
// true会显示城市名
emphasis: {
show: false
}
},
itemStyle: {
// 地图背景色
normal: {
areaColor: '#465471',
borderColor: '#282F3C'
},
// 悬浮时
emphasis: {
areaColor: '#8796B4'
}
}
},
// 系列列表
series: [
{
name: '地区热度',
// 表的类型 这里是散点
type: 'scatter',
// 使用地理坐标系,通过 geoIndex 指定相应的地理坐标系组件
coordinateSystem: 'geo',
data: [],
// 标记的大小
symbolSize: 12,
// 鼠标悬浮的时候在圆点上显示数值
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
itemStyle: {
normal: {
color: '#ddb926'
},
// 鼠标悬浮的时候圆点样式变化
emphasis: {
borderColor: '#fff',
borderWidth: 1
}
}
},
{
name: 'top5',
// 表的类型 这里是散点
type: 'effectScatter',
// 使用地理坐标系,通过 geoIndex 指定相应的地理坐标系组件
coordinateSystem: 'geo',
data: [],
// 标记的大小
symbolSize: 12,
showEffectOn: 'render',
rippleEffect: {
brushType: 'stroke'
},
hoverAnimation: true,
label: {
normal: {
show: false
}
},
itemStyle: {
normal: {
color: '#f4e925',
shadowBlur: 10,
shadowColor: '#333'
}
},
zlevel: 1
}
]
})
let showLoadingDefault = {
text: '加载中...',
color: '#23531',
textColor: '#fff',
// 地图背景色
maskColor: '#272D3A',
zlevel: 0
}
chinaMap.showLoading(showLoadingDefault)
this.$store.commit('openLoading')
this.$store.dispatch('fetchHeatChinaRealData', chinaMap)
setInterval(() => {
this.$store.dispatch('fetchHeatChinaRealData', chinaMap)
}, 1000)
}
ChinaMap.js
此处geoCoordMap有其他数据未放上来,请下载原github文件。
state
state里放置的是一些初始化的数据。可以通过$store.state.xxx获取。
getters
从state里获得数据或返回一个函数,在函数中返回数据,这样即可添加形参。此处未用到getters。
mutations
提交(commit)mutation是修改state值的唯一方法,里面的代码都是同步的。在mutations中添加对应的mutation函数,在组件对应的事件中提交对应的mutation即可修改state值。如本例修改isLoading值。
actions
与mutations类似,但其操作未异步操作,需要用dispatch函数进行分发。在本例中,fetchHeatChinaRealData({commit,state},chartsObj)中的state只是获取了state中的数据,无修改功能。
最后在export中进行导出使用。
此时可以用上文Analysis.vue文件中最后几个函数进行对应理解了。
此处的axios请求了本地的json文件,应当注意刚刚提到的路径问题,对应起来看。
import axios from 'axios'
const state = {
geoCoordMap: {'香港特别行政区': [114.08, 22.2], '澳门特别行政区': [113.33, 22.13], '台北': [121.5, 25.03], '基隆': [121.73, 25.13], '台中': [120.67, 24.15], '台南': [120.2, 23.0], '宜兰县': [121.75, 24.77]},
showCityNumber: 5,
showCount: 0,
isLoading: true
}
const getters = {}
const actions = {
fetchHeatChinaRealData ({state, commit}, chartsObj) {
axios.get('/data/heatChinaRealData.json')
.then(
(res) => {
let data = res.data
let paleData = ((state, data) => {
let arr = []
let len = data.length
while (len--) {
let geoCoord = state.geoCoordMap[data[len].name]
if (geoCoord) {
arr.push({
name: data[len].name,
value: geoCoord.concat(data[len].value)
})
}
}
return arr
})(state, data)
let lightData = paleData.sort((a, b) => {
return b.value - a.value
}).slice(0 + state.showCount, state.showCityNumber + state.showCount)
if (state.isLoading) {
chartsObj.hideLoading()
commit('closeLoading')
}
chartsObj.setOption({
series: [
{
name: '地区热度',
data: paleData
},
{
name: 'top5',
data: lightData
}
]
})
commit('addCount')
}
)
}
}
const mutations = {
closeLoading (state) {
state.isLoading = false
},
openLoading (state) {
state.isLoading = true
},
addCount (state) {
state.showCount ++
// test
if (state.showCount >= 70) {
state.showCount = 1
}
}
}
export default {
state,
getters,
actions,
mutations
}
更加具体的各函数功能后续再更新,现在已经能顺利使用了。