功能
- 点击地图,地图放大,地图中心点移到鼠标点击位置
- 点击按钮重置,地图初始化原来的状态
代码实现
option.ts
echarts初始化配置option,tooltip配置弹框,geo配置中国地图底图,geo.silent为false用来开启地图底图事件监听,geo.zoom指定缩放的大小,geo.emphasis指定激活时的样式。
export const mapOption = {
tooltip: {
trigger: 'item',
position: function (point: any[]) {
// 默认返回值为相对于视图坐标系的绝对像素位置
return [point[0] + 10, point[1]]; // 在鼠标位置的基础上向右偏移10px
},
formatter: function (params: {
seriesName?:string;
data: {
code?:string;
name?:string;
value:string[];
};
}) {
return (
'经度:' +
params.data.value[0] +
'<br/>' +
'纬度:' +
params.data.value[1]
);
},
},
geo: {
show: true,
map: 'china',
roam: true,
zoom: 1.2,//缩放
silent: false,//开启事件监听,开启后监听事件能监听到
center:[103.823557, 36.058039],//地图中心位置
scaleLimit: {
min: 1,
max: 20,
},
label: {
show: false,
color: '#fff',
},
itemStyle: {
areaColor: '#0197FE',
borderColor: '#fff',
},
emphasis: {//激活样式
label: {
color: '#fff',
},
itemStyle: {
areaColor: '#0FCFFF',
},
},
},
series: [],
};
chart.ts
封装echarts地图管理类class InitChart。包含方法如下:
- init(): 初始化地图
初始化echarts,注册china.json,绑定事件 - destoryChart(): 销毁地图
解除事件,销毁echarts实例对象 - setOption(): 重新渲染地图
通过chart.setOption()方法更新地图渲染展示 - restore(): 把地图重置为原来的状态 通过chart.setOption()初始配置把地图初始化
- resize(): 屏幕大小适配
- bindEvent(): 绑定window的resize事件
- destoryEvent(): 解绑window的resize事件
- bindClick(): 绑定chart的click事件
import * as echarts from 'echarts';
import chinaMap from './china.json';
/**
*判断对象是否是一个纯粹的对象
*/
export function isPlainObject(obj: any) {
return typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Object]';
}
/**
*深度合并多个对象的方法
*/
export function deepAssign(target: any, source: any) {
if (isPlainObject(source)) {
if (!isPlainObject(target)) {
target = {};
}
for (let s in source) {
if (s === '__proto__' || target === source[s]) {
continue;
}
if (isPlainObject(source[s])) {
target[s] = deepAssign(target[s], source[s]);
} else {
target[s] = source[s];
}
}
return target;
}
}
export class InitChart {
chart: echarts.ECharts | null = null;
option: any = null;
clock: any = null;
init(chartDom: HTMLElement, option: any, isMap: boolean = false) {
this.chart = echarts.init(chartDom);
localStorage.setItem('mapZoom','1.2')//localStorage存储
isMap && echarts.registerMap('china', chinaMap as any);//注册
this.setOption(option);
this.bindEvent();
}
destoryChart() {
this.destoryEvent();
this.chart && this.chart.dispose();//释放对象
this.chart = null;
}
setOption(option: any) {
this.chart && this.chart.setOption(option);
this.option = option;
}
restore() {//重置原来的状态
let option = {
geo: {zoom: 1.2,center:[103.823557, 36.058039]}//初始缩放和中心位置
}
localStorage.setItem('mapZoom','1.2');
this.chart && this.chart.setOption(option);
}
resize() {
this.clock = setTimeout(() => {
clearTimeout(this.clock);
this.chart && this.chart.resize();
}, 300);
}
bindEvent() {
window.addEventListener('resize', this.resize.bind(this));
}
destoryEvent() {
window.removeEventListener('resize', this.resize.bind(this));
}
bindClick(callback?: (event: echarts.ECElementEvent) => void) {
this.chart?.on('click', (event) => {//click事件绑定
callback && callback(event);
});
}
}
map.vue
给option添加散点series,展示散点。
在onMounted钩子函数初始化chart,绑定点击事件。
在点击事件处理函数中,通过convertFromPixel()函数获取点击位置的经纬度,center的位置在点击的位置的经纬度,zoom在原来的基础上加1。然后通过setOption设置center和zoom的值。
重置reset调用chart的.restore()方法初始化地图展示。
<template>
<div class="item">
<div class="header">
<n-button strong secondary type="primary" size="small" @click="reset">重置</n-button>
</div>
<div class="content">
<div id="mapChart" ref="mapChart" class="w-full h-full"></div>
</div>
</div>
</template>
<script lang="ts" setup>
import { Ref, onBeforeUnmount, onMounted, ref } from 'vue';
import { InitChart } from './chart';
import { mapOption } from './option';
let option: any = mapOption;
const mapChart: Ref<HTMLElement | null> = ref(null);
let chart: any = null;
interface SeriesDataItem {
name: string;
num?: number;
value: [number, number, number?, any?];
}
interface MapSeriesItem {
name: string;
type: string;
coordinateSystem: string;
symbolSize?: number;
itemStyle: { color: string };
data: SeriesDataItem[];
}
const series: MapSeriesItem[] = [
{
name: '正常',
type: 'scatter',
coordinateSystem: 'geo',
symbolSize: 8,
itemStyle: {
color: '#00FF6C',
},
data: [
{ name: '散点1', value: [116.52, 40, 1] },
{ name: '散点2', value: [116.52, 40, 1] },
{ name: '散点3', value: [116.52, 40, 1] },
],
},
{
name: '停运',
type: 'scatter',
coordinateSystem: 'geo',
symbolSize: 8,
itemStyle: {
color: '#FF3000',
},
data: [
{ name: '散点4', value: [117.52, 36, 1] },
{ name: '散点5', value: [113.52, 22, 1] },
{ name: '散点6', value: [113.52, 24, 42] },
],
},
];
option.series = series;
function reset() {
chart.restore();
}
onMounted(() => {//挂载后
chart = new InitChart();
chart.init(mapChart.value as HTMLElement, option, true);
//点击
chart.bindClick((params: any) => {
//点击位置的经纬度
let center = chart.chart.convertFromPixel('geo', [params.event.offsetX, params.event.offsetY]);
if (center) {
let zoom = localStorage.getItem('mapZoom') || '1.2';
let zoomSize = Number(zoom) + 1;
localStorage.setItem('mapZoom',zoomSize+'')
chart.setOption({
geo: { zoom: zoomSize, center: center},
});
}
});
});
onBeforeUnmount(() => {
chart.destoryChart();
});
</script>
<style lang="scss" scoped>
.item {
background-color: rgba(255,255,255,0.9);
border-radius: 4px;
-webkit-border-radius: 4px;
margin: 10px;
padding-top:10px;
box-shadow: 0px 0px 12px rgba(0, 0, 0, .12);
.header {
display: flex;
justify-content: center;
}
.content {
height: 500px;
}
}
</style>