效果图
Components
<template>
<div id="bmap" ref="canvas" class="canvas" :style="{width: '100%;', height: canHeight+'px'}"></div>
</template>
<script setup lang="ts">
import { defineProps, computed, onMounted } from 'vue'
import { createPinia } from 'pinia'
import guangdong from '@/components/maps/map/json/province/guangdong.json'
import * as echarts from 'echarts/core';
import {
TooltipComponent,
type TooltipComponentOption,
GeoComponent,
type GeoComponentOption,
LegendComponent,
type LegendComponentOption,
VisualMapComponent,
type VisualMapComponentOption,
GridComponent,
type GridComponentOption,
MarkPointComponent,
type MarkPointComponentOption,
TitleComponent,
type TitleComponentOption,
} from 'echarts/components';
import { LabelLayout } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import { MapChart, type MapSeriesOption
} from 'echarts/charts';
import { useChartsStore } from '@/stores/charts';
import { BarChart, type BarSeriesOption, PictorialBarChart, PictorialBarSeriesOption } from 'echarts/charts';
const pinia = createPinia();
const chartStore = useChartsStore(pinia)
echarts.use([
TooltipComponent,
GeoComponent,
LegendComponent,
CanvasRenderer,
LabelLayout,
VisualMapComponent,
MapChart,
GridComponent,
MarkPointComponent,
LegendComponent,
TitleComponent,
BarChart,
PictorialBarChart
]);
type EChartsOption = echarts.ComposeOption<
| TooltipComponentOption
| GeoComponentOption
| LegendComponentOption
| VisualMapComponentOption
| MapSeriesOption
| GridComponentOption
| MarkPointComponentOption
| LegendComponentOption
| TitleComponentOption
| BarSeriesOption
| PictorialBarSeriesOption
>;
const props = defineProps({
canvasHeight: {
type:Number,
default: 300
},
data: {
type: Object,
default: () => { }
}
})
let canHeight = computed(() => { return props.canvasHeight })
onMounted(() => {
echarts.registerMap('guangdong', guangdong);
var chartDom = document.getElementById('bmap')!;
var myChart = echarts.init(chartDom);
var option: EChartsOption;
var barOption: EChartsOption;
option = {
title: {show: true, name: "广东地图"},
color: chartStore.colors,
grid: { show: true, left: "0", right: "0", bottom: "0", top: "0", borderColor: "transparent" },
legend: { show: true},
geo: {
show: true,
map: 'guangdong',
roam: false,
zoom: 1.2,
nameMap: {'guangdong' : '广东'},
label: { show: true, color: '#a4a896'},
itemStyle: {
areaColor: '#0000ff60',
borderColor: '#fefefe',
borderWidth: 2,
borderType: 'dashed'
},
emphasis: {
disabled: false,
label: { show: true, color: '#ffffff', fontSize: 20,},
itemStyle: {
areaColor: '#0e3c8b',
borderColor: '#2e74ea',
borderWidth: 4,
borderType: 'soild'
},
},
select: {
disabled: false,
label: { show: true, color: '#fefefe', fontSize: 20},
itemStyle: {
areaColor: '#0000ff',
borderColor: '#2e74ea',
borderWidth: 4,
borderType: 'soild'
},
},
left: '10%',
top: '10%',
},
tooltip: {
show: true,
position: 'right',
formatter: (param) => {
return param.value ? [param.name+":", param.value].join('\n') : null
},
backgroundColor: '#a2c1f6',
borderColor: '#0e3c8b',
borderWidth: 2,
textStyle: {
color: 'blue',
fontSize: 18,
fontWeight: 600
}
},
series: [
{
type: 'map',
map: 'guangdong',
geoIndex: 0,
selectedMode: 'multiple',
data: props.data.map((m) => {
m['selected'] = true
return m
})
}
]
};
option && myChart.setOption(option);
let mdata = [...props.data]
barOption = {
xAxis: [],
yAxis: [],
grid: [],
series: []
}
mdata.forEach((item, i) => {
const coord = myChart.convertToPixel('geo', item.pos);
barOption.xAxis.push({
id: item.id + i,
gridId: item.id + i,
show: false,
type: 'category',
data: [item.name],
z: 1
})
barOption.yAxis.push({
id: item.id + i,
gridId: item.id + i,
show: false,
type: 'value',
z: 1
})
barOption.grid.push({
id: item.id + i,
width: 40 * 1,
height: 70 * 1,
left: coord[0] -20,
top: coord[1] -80,
z: 1
})
barOption.series.push({
id: item.id + i,
xAxisId: item.id + i,
yAxisId: item.id + i,
data: [item.value],
type: 'pictorialBar',
symbol: "path://M538.624 65.536c-156.16 0-293.376 126.464-293.376 281.6 0 144.384 290.304 490.496 290.304 490.496s300.544-340.992 300.544-490.496c0-155.648-140.8-281.6-297.472-281.6z m5.12 421.888c-73.216 0-132.608-58.368-132.608-130.048S471.04 227.328 543.744 227.328c73.216 0 132.608 58.368 132.608 130.048s-59.392 130.048-132.608 130.048z",
symbolSize: 30,
symbolRotate: 0
})
});
barOption && myChart.setOption(barOption);
})
</script>
<style scope></style>
Html
<section class="map">
<GuangDongMap v-if="show" :canvasHeight="340" :data="mapData" />
<section class="data-legend">
<n-flex v-for="(item, i) in mapData" :key="i" class="flex-start">
<n-icon :size="16" :color="chartStore.colors[i+1]"><LocationSharp /></n-icon> {{ item.name }}
</n-flex>
</section>
</section>
CSS
.map {
background-color: #02082c;
border-radius: 10px;
border: 1px solid #0000ff;
padding: 10px 0;
position: relative;
}
.data-legend {
position: absolute;
bottom: 20px;
right: 20px;
color: #ffffff;
}