Files
dyf-vue-ui/src/views/homeIndex/components/DeviceCategory.vue

171 lines
4.7 KiB
Vue
Raw Normal View History

2025-09-27 16:10:17 +08:00
<template>
2025-09-28 15:28:15 +08:00
<div class="vchartPage">
<div ref="chartRef" class="chartRef"></div>
</div>
2025-09-27 16:10:17 +08:00
</template>
2025-09-30 10:59:31 +08:00
2025-09-28 15:28:15 +08:00
<script setup lang="ts">
import { getDeviceCommunicationModeStatistics } from '@/api/homeIndex/index';
import * as echarts from 'echarts';
2025-09-30 10:59:31 +08:00
2025-09-28 15:28:15 +08:00
const chartRef = ref<HTMLDivElement | null>(null);
2025-09-30 10:59:31 +08:00
let myChart: echarts.ECharts | null = null; // 保存图表实例
let dataTimer: NodeJS.Timeout | null = null;
// 更新图表数据
const updateChartData = () => {
if (!myChart) return;
2025-09-28 15:28:15 +08:00
2025-09-30 10:59:31 +08:00
getDeviceCommunicationModeStatistics().then((res) => {
console.log(res, '接口数据');
const dataList = res.data || [];
// 1.(通信方式名称)
const xAxisData = dataList.map(item => item.communicationModeName);
// 2. 总数数据
const totalData = dataList.map(item => item.totalDevices);
// 3. 异常数数据
const abnormalData = dataList.map(item => item.abnormalDevices);
// 图表配置)
const option = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
data: ['总数', '异常'],
right: '20px',
textStyle: { color: '#DEEFFF' },
itemWidth: 12,
itemHeight: 12
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
top: '15%',
containLabel: true
},
xAxis: {
type: 'category',
data: xAxisData,
axisLine: {
lineStyle: { color: 'rgba(255,255,255,0.1)' }
2025-09-28 15:28:15 +08:00
},
2025-09-30 10:59:31 +08:00
axisLabel: {
color: '#DEEFFF'
}
},
yAxis: {
type: 'value',
axisLine: { show: false },
axisLabel: { color: '#fff' },
splitLine: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.1)',
type: 'dashed'
2025-09-28 15:28:15 +08:00
}
2025-09-30 10:59:31 +08:00
}
},
series: [
{
name: '总数',
type: 'bar',
data: totalData,
itemStyle: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{ offset: 0, color: 'rgba(0,166,255,1)' },
{ offset: 1, color: 'rgba(0,125,221, 0.3)' }
]
),
borderRadius: 4
},
barWidth: '20px'
2025-09-28 15:28:15 +08:00
},
2025-09-30 10:59:31 +08:00
{
name: '异常',
type: 'bar',
data: abnormalData,
itemStyle: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{ offset: 0, color: 'rgba(232,69,37,1)' },
{ offset: 1, color: 'rgba(240,12,12, 0.3)' }
]
),
borderRadius: 4
2025-09-28 15:28:15 +08:00
},
2025-09-30 10:59:31 +08:00
barWidth: '20px'
}
]
};
2025-09-28 15:28:15 +08:00
2025-09-30 10:59:31 +08:00
myChart.setOption(option);
}).catch(err => {
console.log('获取数据失败', err);
});
};
// 处理窗口大小变化
const handleResize = () => {
if (myChart) {
myChart.resize();
}
};
// 开始数据定时器
const startDataTimer = () => {
if (dataTimer) {
clearInterval(dataTimer);
}
// 每800秒8分钟
dataTimer = setInterval(updateChartData, 800000);
};
// 清除数据定时器
const clearDataTimer = () => {
if (dataTimer) {
clearInterval(dataTimer);
dataTimer = null;
}
};
// 初始化图表
const initChart = () => {
if (!chartRef.value) return;
myChart = echarts.init(chartRef.value);
// 初始加载数据
updateChartData();
// 启动定时器
startDataTimer();
// 窗口 resize 时自适应
window.addEventListener('resize', handleResize);
};
onMounted(() => {
initChart();
});
onUnmounted(() => {
// 清除定时器
clearDataTimer();
// 移除事件监听
window.removeEventListener('resize', handleResize);
// 销毁图表实例
if (myChart) {
myChart.dispose();
myChart = null;
2025-09-28 15:28:15 +08:00
}
});
2025-09-27 16:10:17 +08:00
</script>
2025-09-30 10:59:31 +08:00
2025-09-28 15:28:15 +08:00
<style scoped lang="scss">
.vchartPage {
margin-top: 5.8vh;
2025-09-28 15:28:15 +08:00
}
.chartRef {
width: 100%;
height: 23.5vh;
2025-09-28 15:28:15 +08:00
}
</style>