Files
dyf-vue-ui/src/views/homeIndex/components/DeviceCategory.vue
2025-09-30 10:59:31 +08:00

171 lines
4.7 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 ref="chartRef" class="chartRef"></div>
</div>
</template>
<script setup lang="ts">
import { getDeviceCommunicationModeStatistics } from '@/api/homeIndex/index';
import * as echarts from 'echarts';
const chartRef = ref<HTMLDivElement | null>(null);
let myChart: echarts.ECharts | null = null; // 保存图表实例
let dataTimer: NodeJS.Timeout | null = null;
// 更新图表数据
const updateChartData = () => {
if (!myChart) return;
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)' }
},
axisLabel: {
color: '#DEEFFF'
}
},
yAxis: {
type: 'value',
axisLine: { show: false },
axisLabel: { color: '#fff' },
splitLine: {
lineStyle: {
color: 'rgba(255, 255, 255, 0.1)',
type: 'dashed'
}
}
},
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'
},
{
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
},
barWidth: '20px'
}
]
};
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;
}
});
</script>
<style scoped lang="scss">
.vchartPage {
margin-top: 5.8vh;
}
.chartRef {
width: 100%;
height: 23.5vh;
}
</style>