Files
dyf-vue-ui/src/views/homeIndex/components/DeviceUsage.vue
2025-10-07 15:40:33 +08:00

206 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="vchartPage">
<div class="btn_mounth_box">
<div class="btn_mounth" :class="{ cur: activeTab == 'month' }" @click="switchTab('month')">近一月</div>
<div class="btn_mounth" :class="{ cur: activeTab === 'halfYear' }" @click="switchTab('halfYear')">近半年</div>
</div>
<div ref="chartRef" class="chartRef"></div>
</div>
</template>
<script setup lang="ts">
import * as echarts from 'echarts';
import { getDeviceUsageFrequency } from '@/api/homeIndex/index';
const chartRef = ref<HTMLDivElement | null>(null);
const activeTab = ref('month');
let myChart: echarts.ECharts | null = null; // 保存图表实例
let dataTimer: NodeJS.Timeout | null = null; // 数据更新定时器
// 根据天数获取数据并更新图表
const fetchDataAndUpdate = (days: number) => {
getDeviceUsageFrequency({ days }).then((res) => {
if (res.code === 200 && res.data && myChart) {
//(转换为图表所需格式)
const chartData = res.data.map(item => ({
name: item.deviceName,
value: item.frequency
}));
// 更新图表
myChart.setOption({
yAxis: {
data: chartData.map(item => item.name)
},
series: [{
data: chartData.map(item => item.value)
}]
});
}
}).catch(err => {
console.error('获取数据失败', err);
});
};
// 切换标签逻辑
const switchTab = (tab: string) => {
activeTab.value = tab;
// 根据标签切换天数(近一月=30天近半年=180天
const days = tab === 'month' ? 30 : 180;
fetchDataAndUpdate(days);
// 切换标签后重新启动定时器
startDataTimer();
};
// 开始数据定时器
const startDataTimer = () => {
if (dataTimer) {
clearInterval(dataTimer);
}
// 每300秒5分钟更新一次数据
dataTimer = setInterval(() => {
const days = activeTab.value === 'month' ? 30 : 180;
fetchDataAndUpdate(days);
}, 300000);
};
// 清除数据定时器
const clearDataTimer = () => {
if (dataTimer) {
clearInterval(dataTimer);
dataTimer = null;
}
};
// 初始化图表
const initChart = () => {
if (!chartRef.value) return;
myChart = echarts.init(chartRef.value);
const option = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' } // 柱状图建议使用阴影指示器
},
grid: {
left: '5%',
right: '10%',
bottom: '3%',
top: '20%',
containLabel: true
},
yAxis: {
type: 'category',
data: [], // 初始空数据
axisLine: {
lineStyle: {
color: '#1e3a8a',
show: false
}
},
axisLabel: {
color: '#DEEFFF'
}
},
xAxis: {
type: 'value',
axisLine: { show: false },
axisLabel: { show: false },
splitLine: { show: false }
},
series: [{
name: '使用频次',
type: 'bar',
data: [], // 初始空数据
barWidth: '9px',
stack: 'total',
label: {
show: true,
position: 'right',
valueAnimation: true,
color: '#DEEFFF'
},
itemStyle: {
color: new echarts.graphic.LinearGradient(
0, 0, 1, 0,
[
{ offset: 0, color: '#0768D4' },
{ offset: 1, color: '#0EC4DF' }
]
),
borderRadius: 4
}
}]
};
myChart.setOption(option);
// 初始化数据
fetchDataAndUpdate(30);
// 启动定时器
startDataTimer();
};
// 处理窗口大小变化
const handleResize = () => {
if (myChart) {
myChart.resize();
}
};
onMounted(() => {
initChart();
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
// 清除定时器
clearDataTimer();
// 移除事件监听
window.removeEventListener('resize', handleResize);
// 销毁图表实例
if (myChart) {
myChart.dispose();
myChart = null;
}
});
</script>
<style scoped lang="scss">
.vchartPage {
margin-top: 4.9vh;
position: relative; // 确保按钮定位正确
}
.btn_mounth_box {
display: flex;
position: absolute;
right: 1vh;
top: 0vh;
z-index: 1;
}
.btn_mounth {
width:4.5vw;
height:4.5vh;
background: url(@/assets/homeIndex/btn.png) no-repeat;
background-size: 100% 100%;
text-align: center;
line-height: 4.4vh;
color: #fff;
font-size: 0.8vw;
cursor: pointer;
margin-left: 0.5vw; // 按钮间距
}
.cur {
background: url(@/assets/homeIndex/btn_cur.png) no-repeat;
background-size: 100% 100%;
}
.chartRef {
width: 100%;
height: 24vh;
}
</style>