需要引入二次封装的echarts和在ts文件写的option
<template>
<div class="contentPage">
<myEcharts :options="chartOptions" class="myEcharts" id="myEchartsMapId"
ref="mapEcharts" />
</div>
</template>
<script setup name="Index" lang="ts">
import { ref, onMounted, onBeforeUnmount, watch, defineExpose } from 'vue';
import myEcharts from '@/components/MyEcharts';//这是我封装的echarts组件,看个人需求添加,我放在文章最后面
import { chinaMap } from '@/plugins/optoons';
const chartOptions: any = ref({});
let dataList: any = ref([
{
name: '南海诸岛',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '北京',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '天津',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '上海',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '重庆',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '河北',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '河南',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '云南',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '辽宁',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '黑龙江',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '湖南',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '安徽',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '山东',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '新疆',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '江苏',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '浙江',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '江西',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '湖北',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '广西',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '甘肃',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '山西',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '内蒙古',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '陕西',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '吉林',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '福建',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '贵州',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '广东',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '青海',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '西藏',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '四川',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '宁夏',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '海南',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '台湾',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '香港',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
},
{
name: '澳门',
value: Math.floor(Math.random() * 100) // 返回 0 至 99 之间的数
}
]);
let observer: ResizeObserver | null = null;
let resizeTimer: any = null;
const mapEcharts: any = ref();
onMounted(() => {
initMap();
observer = new ResizeObserver(handleResize);
observer.observe(document.getElementById('myEchartsMapId'));
});
const handleResize = () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
mapEcharts.value?.autoResize();
}, 200);
};
onBeforeUnmount(() => {
if (observer) {
observer.disconnect();
}
});
const initMap = () => {
chartOptions.value = chinaMap(dataList.value);
};
</script>
<style scoped lang="scss" name="Home">
.contentPage {
width: 100%;
height: 100%;
position: relative;
display: flex;
justify-items: center;
align-items: center;
.myEcharts {
width: 100%;
}
}
</style>
单独把option写在一个ts文件里
import * as echarts from 'echarts';
import chinaMapJson from '@/plugins/chinaMap.json';
export const chinaMap = (dataList: Array<any>) => {
echarts.registerMap('china', chinaMapJson);
const option: object = {
tooltip: {
triggerOn: 'mousemove', //mousemove、click
borderColor: 'rgba(65, 119, 254, 1)', //边框颜色
alwaysShowContent: false,
backgroundColor: 'rgba(238, 241, 255, 1)', //背景颜色
textStyle: {
fontSize: 14,
color: 'rgba(51, 71, 93, 1)'
},
formatter: (params: any) => {
return params.name + ': ' + params.value + '万人';
}
},
geo: {
map: 'china',
roam: true, //是否允许缩放,拖拽
zoom: 1.2, //初始化大小
//缩放大小限制
scaleLimit: {
min: 1, //最小
max: 10 //最大
},
label: {
normal: {
show: true,
fontSize: '14',
color: 'rgba(0,0,0,0.7)'
}
},
//设置中心点
center: [104.97, 35.71],
// 省份地图添加背景
itemStyle: {
areaColor: '#bcc5ee',
borderColor: 'rgba(0, 0, 0, 0.2)',
borderWidth: 1
},
emphasis: {
areaColor: '#FF6347',
shadowOffsetX: 0,
shadowOffsetY: 0,
borderWidth: 0
}
},
// visualMap: {
// show: true,
// left: 40,
// bottom: 50,
// showLabel: true,
// textStyle: {
// color: 'rgba(0,0,0,0.7)', //图例文字的样式
// fontSize: 14 //字体大小
// },
// pieces: [
// {
// gte: 15,
// label: '15万人以上',
// color: '#009dff'
// },
// {
// gte: 10,
// lt: 15,
// label: '10-15万人',
// color: '#3c57ce'
// },
// {
// gte: 5,
// lt: 10,
// label: '5-10万人',
// color: '#6f83db'
// },
// {
// gte: 1,
// lt: 5,
// label: '1-5万人',
// color: '#9face7'
// },
// {
// lt: 1,
// label: '1万人以下',
// color: '#bcc5ee'
// }
// ]
// },
visualMap: {
type: 'continuous',
text: ['', ''],
showLabel: true,
left: '50',
min: 0,
max: 100,
inRange: {
color: ['#edfbfb', '#b7d6f3', '#40a9ed', '#3598c1', '#215096']
},
splitNumber: 0
},
series: [
{
name: '中国地图',
type: 'map',
geoIndex: 0,
data: dataList
}
]
};
return option;
};
中国地图json,也可去阿里云地理网站进行下载(重要!!!)
DataV.GeoAtlas地理小工具系列 (aliyun.com)
二次封装echarts组件
<template>
<div ref="chartRef" class="chart-container"></div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch, defineExpose } from 'vue';
import * as echarts from 'echarts';
// 定义 Props 类型
interface ChartProps {
options: EChartsOption;
// 可以添加其他 props 如:autoResize, theme 等
}
const props = withDefaults(defineProps<ChartProps>(), {
options: () => ({} as EChartsOption)
});
const chartRef = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
// 初始化 ECharts
onMounted(() => {
if (chartRef.value) {
chartInstance = echarts.init(chartRef.value);
chartInstance.setOption(props.options);
// 如果需要,添加窗口大小变化时的响应式处理
window.addEventListener('resize', () => {
chartInstance?.resize();
});
}
});
// 监听 options 的变化并更新图表
watch(
() => props.options,
(newOptions) => {
if (chartInstance) {
chartInstance.setOption(newOptions);
}
},
{ deep: true }
);
// 清理
onBeforeUnmount(() => {
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
window.removeEventListener('resize', () => chartInstance?.resize());
}
});
// 提供 API
defineExpose({
// 例如:提供一个方法来刷新图表
refreshChart(newOptions: EChartsOption) {
if (chartInstance) {
chartInstance.setOption(newOptions);
}
},
// 获取 ECharts 实例(谨慎使用,可能会破坏封装性)
getChartInstance() {
return chartInstance;
},
//自适应容器宽度高度
autoResize() {
chartInstance?.resize();
}
});
</script>
<style scoped>
.chart-container {
width: 100%;
height: 100%;
}
</style>
最后效果展示