ylj20011123 77aa9d2251 update
2025-06-11 19:18:32 +08:00

208 lines
5.4 KiB
Vue

<script setup lang="ts">
import SmallTitle from '../smallTitle/smallTitle.vue'
import './CustomerGroup.less'
import * as echarts from 'echarts/core';
import { ScatterChart } from 'echarts/charts';
import {
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
DatasetComponent, // 必须添加!否则 dataset 功能无效
TransformComponent // 如果使用 dataset.source 需要此组件
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import { onBeforeUnmount, onMounted, watch } from 'vue';
import { handleGetCustomerGroupRatio } from '../../service';
import moment from 'moment';
// 注册组件
echarts.use([
ScatterChart,
GridComponent,
TitleComponent,
TooltipComponent,
LegendComponent,
DatasetComponent, // 必须注册
TransformComponent, // 必须注册
CanvasRenderer
]);
let myChart: echarts.ECharts;
onMounted(async () => {
await handleShowCharts()
})
// 传入的数据
const props = defineProps<{
currentService?: any;
}>();
// 监听传入的选中服务区
watch(
() => props.currentService,
(newVal, oldVal) => {
handleShowCharts()
},
{ deep: true }
);
const handleShowCharts = async () => {
const res = await handleGetData()
console.log('handleShowChartshandleShowChartshandleShowChartshandleShowCharts', res);
const chartDom = document.getElementById('CustomerGroupBoxContent');
if (!chartDom) return;
myChart = echarts.init(chartDom);
const option = {
grid: {
left: '0',
right: '10',
bottom: '0',
top: '10',
containLabel: true
},
xAxis: {
type: 'value',
name: '年龄',
nameLocation: 'middle',
nameGap: 25,
min: 20,
axisLabel: {
formatter: '{value}岁'
},
axisTick: {
show: false // 隐藏刻度线
},
axisLine: {
show: true, // 隐藏轴线
lineStyle: {
color: '#fff'
}
},
splitLine: {
show: false // 确保网格线隐藏
}
},
yAxis: {
type: 'value',
axisLabel: {
color: '#fff',
formatter: '{value}'
},
axisTick: {
show: false // 隐藏刻度线
},
axisLine: {
show: true,// 隐藏轴线
lineStyle: {
color: '#fff'
}
},
splitLine: {
show: false // 确保网格线隐藏
},
},
series: [{
name: '用户交易',
type: 'scatter',
symbolSize: function (data: any) {
return Math.sqrt(data[2]) * 5; // 气泡大小与占比相关
},
data: res,
itemStyle: {
color: function (params: any) {
// 按性别区分颜色
const gender = params.data[3]; // 第四项是性别
return gender === '男性' ? '#0094FF' : '#FF307C'; // 男性蓝色,女性红色
},
opacity: 0.8,
// borderColor: '#fff',
// borderWidth: 1
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}],
// 添加图例说明颜色对应的性别
legend: {
data: ['男性', '女性'],
itemGap: 20,
textStyle: {
color: '#333'
}
},
// 提示框格式化
tooltip: {
trigger: 'item',
formatter: function (params: any) {
const data = params.data;
return `
年龄: ${data[0]}岁<br>
性别: ${data[3]}<br>
交易金额: ${data[1]}元<br>
占比: ${data[2]}%
`;
}
}
};
myChart.setOption(option);
window.addEventListener('resize', resizeChart);
}
const handleGetData = async () => {
const req: any = {
provinceCode: "530000",
statisticsMonth: moment().subtract(1, 'M').format('YYYYMM'),
serverpartId: props.currentService?.SERVERPART_ID || "",
}
const data = await handleGetCustomerGroupRatio(req)
console.log('jfdjsfklasjflsd', data);
let res: any = []
if (data && data.length > 0) {
data.forEach((item: any) => {
// let list: any = []
if (item.data && item.data.length > 0) {
item.data.forEach((subItem: any) => {
subItem.push(item.name)
res.push(subItem)
})
}
// res.push(list)
})
}
return res
}
const resizeChart = () => {
myChart?.resize();
};
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
myChart?.dispose();
});
</script>
<template>
<div class="CustomerGroupBox">
<SmallTitle title="客群特征分析" />
<div class="CustomerGroupBoxContent" id="CustomerGroupBoxContent">
</div>
</div>
</template>