208 lines
5.4 KiB
Vue
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>
|