思路:
1、創建一個地圖組件mapView,使用openlayers進行地圖展示
2、創建一個圖表組件chart,用於呈現圖表
3、創建一個overlay組件,在模板中使用chart組件;利用openlayers的ol.Overlay類來把overlay組件添加到地圖上。
示例代碼
1、數據
以這次新冠病毒數據爲例,這裏是今年2月份全國新增新冠肺炎患者的數據(數據源來自百度),分爲全國的新增數量和湖北省內的新增數量。
ncovData.js
const ncovData = {
add: {
startDate: '2.1',
endDate: '2.29',
quanguoTotal: [2590, 2829, 3235, 3887, 3694, 3151, 3399, 2653, 3073, 2484, 2022, 15153, 5093, 2644, 2009, 2051, 1891, 1751, 825, 892, 399, 649, 416, 517, 411, 440, 329, 430, 579],
hubeiTotal: [1921, 2103, 2345, 3156, 2987, 2447, 2841, 2147, 2618, 2097, 1638, 14840, 4823, 2420, 1843, 1933, 1807, 1693, 775, 631, 366, 630, 398, 499, 401, 409, 318, 423, 570]
}
}
export default ncovData
2、圖表組件
在圖表組件中,以折線圖的形式來展示數據。
chart.vue
<template>
<div>
<div ref="chart" class="overlay-chart"></div>
</div>
</template>
<script>
import echarts from 'echarts'
export default {
data () {
return {
}
},
props: ['source'],
mounted () {
this.chart = echarts.init(this.$refs['chart'])
if (this.source) {
this.drawChart(this.source)
}
},
methods: {
drawChart (data) {
let dateLine = Array.apply(null, { length: 29 }).map((item, index) => {
return '2.' + (index + 1).toString()
})
let option = {
title: {
text: '全國/湖北疫情趨勢'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['全國新增', '湖北新增']
},
xAxis: {
type: 'category',
boundaryGap: false,
data: dateLine
},
yAxis: {
type: 'value'
},
series: [
{
name: '全國新增',
type: 'line',
data: data.addTotal
},
{
name: '湖北新增',
type: 'line',
data: data.hubeiAddTotal
}
]
}
this.chart.setOption(option)
}
}
}
</script>
<style lang="less" scoped>
.overlay-chart{
width: 100%;
height: 100%;
}
</style>
3、overlay組件
overlayChart .vue
<template>
<div v-if="visible" class="overlay-container">
<div class="overlay-header">
<span>{{name}}</span>
</div>
<div>
<chart class="chart-container" v-if="overlay" :source="chartData"></chart>
</div>
</div>
</template>
<script>
import Overlay from 'ol/Overlay'
import chart from './chart'
export default {
data () {
return {
visible: false,
name: '疫情趨勢',
overlay: undefined
}
},
components: {chart},
methods: {
show () {
let overlay = new Overlay({
element: this.$mount().$el,
stopEvent: false, // 設爲false,允許事件傳播
autoPanAnimation: {
duration: 250
},
// offset: [20,0],
position: this.position,
positioning: 'center-left',
className: 'point-overlay'
})
this.map.addOverlay(overlay)
this.overlay = overlay
this.visible = true
},
close () {
this.visible = false
}
}
}
</script>
<style lang="less">
.overlay-container{
width: 480px;
min-height: 320px;
background-color: #f5f5f5;
.overlay-header{
height: 20px;
position: relative;
background-color: #171819;
color: #cec3ce;
text-align: center;
.name{
font-size: 16px;
font-weight: bold;
line-height: 1.2;
width: 95%;
}
}
.chart-container{
height: 360px;
width: 100%;
}
}
</style>
這個組件中,我們引入了上面的chart組件,並向其中傳遞數據。另外,在show方法中,創建了一個ol.Overlay實例,把它添加到map地圖對象上。
4、地圖組件
mapView.vue
<template>
<div id="map">
</div>
</template>
<script>
import Vue from 'vue'
import { Map, View } from 'ol'
import TileLayer from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
import overlayChart from './overlayChart'
import ncovData from './ncovData'
const OverlayChart = Vue.extend(overlayChart)
export default {
data () {
return {
map: undefined,
overlayChartObj: undefined,
data: {
}
}
},
mounted () {
this.init()
},
methods: {
/**
* 地圖初始化
*/
init () {
let baseLayer = new TileLayer({
source: new XYZ({
url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
})
})
this.map = new Map({
target: 'map',
layers: [baseLayer],
view: new View({
projection: 'EPSG:4326',
zoom: 5,
center: [114, 32]
})
})
console.log(ncovData)
this.map.on('click', (evt) => {
let data = ncovData.add
this.showOverlayChart(evt.coordinate, data)
})
},
/**
* 顯示圖表
*/
showOverlayChart (position, data) {
if (this.overlayChartObj) {
this.overlayChartObj.close()
this.overlayChartObj = null
}
this.overlayChartObj = this.createOverlay({
position,
data
})
this.overlayChartObj.show()
},
/**
* 創建一個overlay組件實例
*/
createOverlay (params) {
let obj = new OverlayChart({
data: {
map: this.map,
position: params.position,
chartData: params.data
}
})
return obj
}
}
}
</script>
在這個mapview組件中,以vue.extend方式引入了overlayChart組件,然後再在必要的時候,new出一個overlayChart的實例,通過overlayChart的show方法來呈現想要的圖表。
這裏,當我在地圖上任意位置點擊時,即彈出圖表。
參數傳遞
從mapView -> overlayChart, 通過在new對象時傳入data參數,數據包裝在data內,不要再overlayChart中使用props
從overlayChart -> chart,props方式傳遞。