仅作为记录,欢迎参考,不喜勿喷
<template>
<v-chart :option="option" autoresize></v-chart>
</template>
<script>
import { mapState } from 'vuex';
import { use, registerMap } from 'echarts/core';
import { MapChart, EffectScatterChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import {
TitleComponent,
TooltipComponent,
GeoComponent,
VisualMapComponent,
} from 'echarts/components';
import VChart from 'vue-echarts';
import ErrorTip from '@/assets/image/overview/icon_error.png';
import SuccessTip from '@/assets/image/overview/icon_success.png';
import chinaMap from '@/assets/map/china';
use([
TitleComponent,
TooltipComponent,
GeoComponent,
VisualMapComponent,
MapChart,
CanvasRenderer,
EffectScatterChart
]);
const defaultOptions = () => ({
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(5, 52, 84, 0.50)',
borderColor: 'rgba(128,227,255,0.32)',
formatter(params) {
const { seriesType, name, data } = params;
let alive_count = 0;
let rule_hit_car_count = 0;
let rule_hit_count = 0;
try {
if (seriesType === 'effectScatter') {
alive_count = data.value[2].value.alive_count;
rule_hit_car_count = data.value[2].value.rule_hit_car_count;
rule_hit_count = data.value[2].value.rule_hit_count;
} else {
alive_count = data?.other.alive_count || 0;
rule_hit_car_count = data?.other.rule_hit_car_count || 0;
rule_hit_count = data?.other.rule_hit_count || 0;
}
} catch (error) {
// console.log(error);
}
return `
<div class="custom-tooltip-wrapper">
<p class="title">${name}</p>
<p>
<span class="text">激活车辆:</span>
<span class="value">${alive_count}</span>
</p>
<p>
<span class="text">风险车辆:</span>
<span class="value">${rule_hit_car_count}</span>
</p>
<p>
<span class="text">风险总数:</span>
<span class="value">${rule_hit_count}</span>
</p>
</div>
`;
}
},
visualMap: {
type: 'piecewise',
bottom: 20,
textStyle: {
color: '#fff',
fontSize: 10,
fontWeight: 400
},
pieces: [
{ min: 501, label: '500以上', color: '#E34438' },
{ min: 301, max: 500, color: '#F28F4C' },
{ min: 101, max: 300, color: '#2E70EE' },
{ min: 0, max: 100, label: '100以下', color: '#02A6D1' },
],
itemWidth: 22,
itemHeight: 9
},
// 实际地图
geo: [
{
map: 'china',
z: 1,
aspectScale: 0.9,
zoom: 1,
roam: false,
label: {
show: true,
color: '#9AEDFF',
position: 'inside',
distance: 0,
fontSize: 10,
},
// 所有地图的区域颜色
itemStyle: {
normal: {
areaColor: '#2d6b92',
borderWidth: 1,
borderColor: '#092138',
},
},
emphasis: {
label: {
show: false
},
itemStyle: {
areaColor: '#01CCFF',
}
},
select: {
label: {
show: false
},
itemStyle: {
areaColor: '#01CCFF'
}
},
},
// 底部背景地图
{
map: 'china',
z: 0,
top: 67,
aspectScale: 0.9,
zoom: 1,
roam: false,
label: {
normal: {
show: false,
},
emphasis: {
show: false,
},
},
itemStyle: {
normal: {
areaColor: '#091F35',
borderColor: '#073256',
borderWidth: 2,
},
},
emphasis: {
label: {
show: false
},
itemStyle: {
areaColor: '#091F35',
}
},
tooltip: {
show: false
},
regions: [
{
name: '南海诸岛',
itemStyle: {
opacity: 0
},
label: {
show: false // 隐藏文字
}
}
]
},
],
series: [
{
name: '风险分布',
type: 'map',
map: 'china',
geoIndex: 0,
data: []
},
{
name: '风险数',
type: 'effectScatter',
coordinateSystem: 'geo',
data: [],
// 自定义标注
symbol: function (params) {
if (!params || !params[2]) {
return 'none';
} else
if (params[2].status === '未处理') {
return `image://${ErrorTip}`;
} else {
return `image://${SuccessTip}`;
}
},
symbolSize: [24.5, 36],
rippleEffect: {
number: 0
},
showEffectOn: 'emphasis',
animation: false
},
]
});
export default {
name: 'v-china-chart',
components: {
VChart
},
data() {
return {
option: defaultOptions(),
};
},
computed: {
...mapState('overview', ['chartData'])
},
watch: {
chartData(newValue) {
this.initData();
this.option.series[0].data = this.formatChartData(newValue);
},
option(newOption) {
this.option = newOption;
}
},
methods: {
initData() {
let seriesData = chinaMap.features.map(province => {
if (province.properties.name) {
const item = this.chartData.find(item => {
const itemProvince = item.province.replace(/省|市|自治区/g, '');
return itemProvince === province.properties.name;
});
return item ? {
name: province.properties.name,
// echarts地图实现自定义标注的关键
value: province.properties.cp.concat({
value: { ...item }
})
} : {
name: province.properties.name,
value: 0
};
}
});
this.option.series[0].data = this.formatChartData(this.chartData);
this.option.series[1].data = seriesData;
},
formatChartData(data) {
return data.map(item => {
const province = item.province.replace(/省|市|自治区/g, '');
return {
name: province,
value: item.rule_hit_count,
other: { ...item }
};
});
},
},
created() {
// 注册地图
registerMap('china', chinaMap);
this.initData();
}
};
</script>
<style lang="scss" scoped>
</style>