单独图表组件的开发 --- 商家分布模块(地图+散点图 )
Posted So istes immer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单独图表组件的开发 --- 商家分布模块(地图+散点图 )相关的知识,希望对你有一定的参考价值。
目录
效果预览
通用代码结构和流程
显示地图
获取中国地区的矢量数据(数据在之前导入的static文件夹中)
注册地图数据
配置geo
显示散点图
获取数据:/api/map
处理数据:散点数据、图例数据
图表的设置:配置series(type为effectScatter、coordinateSystem为geo)
UI调整
主题的使用:init方法的第二个参数
标题的显示:title
地图位置和颜色:geo、geo.itemStyle
图例的位置和方向:legend
涟漪效果:rippleEffect:scale、rippleEffect.brushType
分辨率适配
screenAdapter(标题文字大小、图例大小)
地图点击事件
点击事件的监听:this.chartInstance.on('click', ()=>{})
获取所点击省份的矢量地图数据:需要有省份拼音的对照数据、得到点击省份地图数据的路径
显示省份:注册地图数据、配置geo
回到中国地图:配置geo、map:'china'
将地图数据缓存
单击地图省份,能得到该省份的地图,双击屏幕,能够回到中国地图
当点击同一个省份多次,为了防止多次请求,每次请求之后,就将该省份的数据存到这个mapData对象中,下次请求的时候,先判断一下mapData中有没有自己想要的数据。
components/Map.vue
<!-- 商家分布图表 -->
<template>
<div class="com-container" @dblclick="revertMap">
<div class="com-chart" ref="map_ref"></div>
</div>
</template>
<script>
import axios from 'axios'
import { getProvinceMapInfo } from '../utils/map_utils'
export default {
data () {
return {
chartInstance: null,
allData: null,
mapData: {} // 所获取的地图矢量数据
}
},
mounted () {
this.initChart()
this.getData()
window.addEventListener('resize', this.screenAdapter)
this.screenAdapter()
},
destroyed () {
window.removeEventListener('resize', this.screenAdapter)
},
methods: {
async initChart () {
this.chartInstance = this.$echarts.init(this.$refs.map_ref, 'chalk')
// 获取中国地图的矢量数据
const ret = await axios.get('http://localhost:8081/static/map/china.json')
this.$echarts.registerMap('china', ret.data)
const initOption = {
title: {
text: '▎商家分布',
left: 20,
top: 20
},
geo: {
type: 'map',
map: 'china',
top: '5%',
bottom: '5%',
itemStyle: {
areaColor: '#2E72BF',
borderColor: '#333'
}
},
legend: {
left: '5%',
bottom: '5%',
orient: 'vertical'
}
}
this.chartInstance.setOption(initOption)
this.chartInstance.on('click', async arg => {
// arg.name得到所点击的省份,这个省份是中文
const provinceInfo = getProvinceMapInfo(arg.name)
// 获取这个省份的地图矢量数据
// 判断当前所点击的这个省份的地图矢量数据在mapData中是否存在,防止重复请求
if (!this.mapData[provinceInfo.key]) {
const ret = await axios.get('http://localhost:8081' + provinceInfo.path)
this.mapData[provinceInfo.key] = ret.data
this.$echarts.registerMap(provinceInfo.key, ret.data)
}
const changeOption = {
geo: {
map: provinceInfo.key
}
}
this.chartInstance.setOption(changeOption)
})
},
async getData () {
// 获取服务器的数据,对this.allData进行赋值之后,调用updateChart方法更新图表
const { data: ret } = await this.$http.get('map')
this.allData = ret
this.updateChart()
},
updateChart () {
// 处理图表需要的数据
// 如果想在地图中显示散点的数据,我们需要给散点图增加一个配置:coordinateSystem:geo
const legendArr = this.allData.map(item => {
return item.name
})
const seriesArr = this.allData.map(item => {
return {
type: 'effectScatter',
rippleEffect: {
scale: 5,
brushType: 'stroke'
},
name: item.name,
data: item.children,
coordinateSystem: 'geo'
}
})
const dataOption = {
legend: {
data: legendArr
},
series: seriesArr
}
this.chartInstance.setOption(dataOption)
},
screenAdapter () {
const titleFontSize = this.$refs.map_ref.offsetWidth / 100 * 3.6
const adapterOption = {
title: {
textStyle: {
fontSize: titleFontSize
}
},
legend: {
itemWidth: titleFontSize / 2,
itemHeight: titleFontSize / 2,
itemGap: titleFontSize / 2,
textStyle: {
fontSize: titleFontSize / 2
}
}
}
this.chartInstance.setOption(adapterOption)
this.chartInstance.resize()
},
// 回到中国地图
revertMap () {
const revertOption = {
geo: {
map: 'china'
}
}
this.chartInstance.setOption(revertOption)
}
}
}
</script>
<style>
</style>
views/MapPage.vue
<!--
针对/mappage这条路径而显示出来
在这个组件中,通过子组件注册的方式,要显示出Map.vue这个组件
-->
<template>
<div class="com-page">
<single-map></single-map>
</div>
</template>
<script>
import Map from '../components/Map'
export default {
components: {
'single-map': Map
}
}
</script>
<style>
</style>
router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import SellerPage from '../views/SellerPage'
import TrendPage from '../views/TrendPage'
import MapPage from '../views/MapPage'
Vue.use(VueRouter)
const routes = [
{
path: '/sellerpage',
component: SellerPage
},
{
path: '/trendpage',
component: TrendPage
},
{
path: '/mappage',
component: MapPage
}
]
const router = new VueRouter({
routes
})
export default router
util/map_utils.js
封装了一个方法:将省份的中文名转换成拼音
const name2pinyin = {
安徽: 'anhui',
陕西: 'shanxi1',
澳门: 'aomen',
北京: 'beijing',
重庆: 'chongqing',
福建: 'fujian',
甘肃: 'gansu',
广东: 'guangdong',
广西: 'guangxi',
贵州: 'guizhou',
海南: 'hainan',
河北: 'hebei',
黑龙江: 'heilongjiang',
河南: 'henan',
湖北: 'hubei',
湖南: 'hunan',
江苏: 'jiangsu',
江西: 'jiangxi',
吉林: 'jilin',
辽宁: 'liaoning',
内蒙古: 'neimenggu',
宁夏: 'ningxia',
青海: 'qinghai',
山东: 'shandong',
上海: 'shanghai',
山西: 'shanxi',
四川: 'sichuan',
台湾: 'taiwan',
天津: 'tianjin',
香港: 'xianggang',
新疆: 'xinjiang',
西藏: 'xizang',
云南: 'yunnan',
浙江: 'zhejiang'
}
export function getProvinceMapInfo (arg) {
const path = `/static/map/province/${name2pinyin[arg]}.json`
return {
key: name2pinyin[arg],
path: path
}
}
以上是关于单独图表组件的开发 --- 商家分布模块(地图+散点图 )的主要内容,如果未能解决你的问题,请参考以下文章