local_alert/src/components/Max/RightTop.vue

419 lines
12 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="alert-container">
<div class="search-row">
<div class="bt-search">
<el-button type="primary" @click="handleFilter" class="alert-bt"><el-icon><Search /></el-icon></el-button>
</div>
<div class="start-col">
<el-date-picker v-model="filterParams.timeAfter" :teleported="false" type="datetime" placeholder="请选择开始时间"
prefix-icon="CaretBottom" popper-class="popperClass"></el-date-picker>
</div>
<div class="end-col">
<el-date-picker v-model="filterParams.timeBefore" :teleported="false" type="datetime" placeholder="请选择结束时间"
prefix-icon="CaretBottom" popper-class="popperClass"></el-date-picker>
</div>
</div>
<div id="3d-bar-chart" class="myPanChart"></div>
<!-- <el-row>
<el-col :span="24">
<div class="statistics-container">
<p v-for="(name, code) in typeMapping" :key="code">
{{ name }}: {{ typeCounts[code] || 0 }}
</p>
</div>
</el-col>
</el-row> -->
</div>
</template>
<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue';
import { BoxApi } from '@/utils/boxApi.ts';
import * as echarts from 'echarts';
import { Search } from '@element-plus/icons-vue';
import { useGlobalTimerStore } from '@/stores/globalTimerStore';
const globalTimerStore = useGlobalTimerStore();
const apiInstance = new BoxApi();
const typeMapping = reactive({});
const typeCounts = reactive({}); // 存储每种类型的数量
const formatDateTimeToISO = (datetime) => {
return new Date(datetime).toISOString().replace('.000', '');
};
const filterParams = reactive({
timeAfter: null,
timeBefore: null,
});
const pieChartData = computed(() => {
return Object.keys(typeCounts).map(code => ({
value: typeCounts[code] || 0,
name: typeMapping[code]
}));
});
const renderChart = () => {
const chartDom = document.getElementById('3d-bar-chart'); // 确保ID正确
const chartInstance = echarts.init(chartDom);
const colorList = [
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(135, 206, 250,0.7)" },
{ offset: 1, color: "rgba(135, 206, 250,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(95, 158, 160,0.8)" },
{ offset: 1, color: "rgba(95, 158, 160,0.3)" }
]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(255, 99, 71, 1)" },
{ offset: 1, color: "rgba(255, 99, 71, 0.3)" }
]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(218, 112, 214,0.6)" },
{ offset: 1, color: "rgba(218, 112, 214,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(138, 43, 226,0.7)" },
{ offset: 1, color: "rgba(138, 43, 226,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(75, 0, 130,0.8)" },
{ offset: 1, color: "rgba(75, 0, 130,0.3)" }
]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(173, 216, 230,0.7)" },
{ offset: 1, color: "rgba(173, 216, 230,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(100, 149, 237,0.8)" },
{ offset: 1, color: "rgba(100, 149, 237,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(25, 25, 112,0.9)" },
{ offset: 1, color: "rgba(25, 25, 112,0.3)" }
]),
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(64, 224, 208,0.7)" },
{ offset: 1, color: "rgba(64, 224, 208,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(32, 178, 170,0.8)" },
{ offset: 1, color: "rgba(32, 178, 170,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(47, 79, 79,0.9)" },
{ offset: 1, color: "rgba(47, 79, 79,0.3)" }
]),
//深海绿 //海浪青 //薄荷青 //幽夜蓝 //极地蓝 //浅冰蓝 //深紫罗兰 //静夜紫 //薰衣草紫 //薄暮紫 //冰川青 //清晨蓝
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(123, 104, 238,0.7)" },
{ offset: 1, color: "rgba(123, 104, 238,0.3)" }
]),
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(255, 165, 0, 1)" },
{ offset: 1, color: "rgba(255, 165, 0, 0.3)" }
]), // 橙色
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(255, 182, 193, 1)" },
{ offset: 1, color: "rgba(255, 182, 193, 0.3)" }
]), // 浅粉红
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(250, 128, 114, 1)" },
{ offset: 1, color: "rgba(250, 128, 114, 0.3)" }
]), // 鲑鱼橙
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(240, 128, 128, 1)" },
{ offset: 1, color: "rgba(240, 128, 128, 0.3)" }
]), // 浅珊瑚红
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(255, 140, 0, 1)" },
{ offset: 1, color: "rgba(255, 140, 0, 0.3)" }
]), // 深橙色
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(255, 215, 0, 1)" },
{ offset: 1, color: "rgba(255, 215, 0, 0.3)" }
]), // 金色
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(255, 228, 181, 1)" },
{ offset: 1, color: "rgba(255, 228, 181, 0.3)" }
]), // 小麦色
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(255, 160, 122, 1)" },
{ offset: 1, color: "rgba(255, 160, 122, 0.3)" }
]), // 浅鲑鱼色
new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "rgba(250, 250, 210, 1)" },
{ offset: 1, color: "rgba(250, 250, 210, 0.3)" }
]), // 浅金黄
new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{ offset: 0, color: "rgba(255, 223, 186, 1)" },
{ offset: 1, color: "rgba(255, 223, 186, 0.3)" }
]), // 暖杏色
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(245, 222, 179, 1)" },
{ offset: 1, color: "rgba(245, 222, 179, 0.3)" }
]), // 小麦暖黄
];
const option = {
backgroundColor: '#001529',
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(0,0,0,0.5)',
padding: [8, 16],
textStyle: {
color: '#fff',
fontSize: 16
},
formatter: function (params) {
return `${params.marker} <span style="color:${params.color}">${params.data['name']}\n${params.data['value']}</span>`;
}
},
// title: {
// text: '告警总数',
// subtext: `${pieChartData.value.reduce((sum, item) => sum + item.value, 0)}`,
// top: '45%',
// left: 'center',
// textStyle: {
// color: '#F5F8FC',
// fontSize: 20,
// fontWeight: 400
// },
// subtextStyle: {
// color: '#F5F8FC',
// fontSize: 16,
// fontWeight: 400,
// }
// },
// legend: {
// orient: 'vertical',
// icon: "circle",
// left: '0%',
// bottom: '0%',
// itemWidth: 30,
// itemGap: 15 ,
// // padding:[10],
// textStyle: {
// rich: {
// a: { color: '#F5F8FC', fontSize: 15, padding: [0, 10, 0, 0] },
// b: { color: '#F5F8FC', fontSize: 15, padding: [0, 10, 0, 10] }
// }
// },
// formatter: function (name) {
// const item = pieChartData.value.find(d => d.name === name);
// return item ? `{a| ${name}}{b|${item.value}}` : '';
// }
// },
series: [
{
type: 'pie',
radius: ['10%', '90%'],
center: ['50%', '50%'],
avoidLabelOverlap: true,
padding: [0, 10],
label: {
show: true,
position: 'inside',
formatter: '{d}%',
textStyle: {
align: 'center',
fontSize: 16,
color: '#fff'
}
},
itemStyle: {
color: params => colorList[params.dataIndex % colorList.length]
},
labelLine: { show: false },
data: pieChartData.value
}
]
};
chartInstance.setOption(option);
};
// 获取告警类型并初始化每种类型的count
const fetchTypeMapping = async (token) => {
try {
const algorithms = await apiInstance.getAlgorithms(token);
const additionalMappings = [{ code_name: 'minizawu:532', name: '杂物堆积' }];
algorithms.forEach((algorithm) => {
typeMapping[algorithm.code_name] = algorithm.name;
typeCounts[algorithm.code_name] = 0; // 初始化count为0
});
additionalMappings.forEach((item) => {
typeMapping[item.code_name] = item.name;
typeCounts[item.code_name] = 0;
});
} catch (error) {
console.error("Error fetching algorithms:", error);
}
};
// 统计每种告警类型的数量
const fetchTypeCounts = async (timeAfter = null, timeBefore = null) => {
const token = localStorage.getItem('alertToken');
// console.log(">>>>>>>>>>>>>>>>", typeMapping)
// 遍历每种类型根据code_name查询数据数量
for (const code in typeMapping) {
try {
const { count } = await apiInstance.getEventsByParams(token, 1, 1, timeBefore, timeAfter, code);
typeCounts[code] = count; // 存储每种类型的数量
} catch (error) {
console.error(`Error fetching count for type ${code}:`, error);
}
}
renderChart();
};
// 点击查询按钮时,添加时间条件并重新统计
const handleFilter = () => {
const timeAfter = filterParams.timeAfter ? formatDateTimeToISO(new Date(filterParams.timeAfter)) : null;
const timeBefore = filterParams.timeBefore ? formatDateTimeToISO(new Date(filterParams.timeBefore)) : null;
fetchTypeCounts(timeAfter, timeBefore); // 重新统计数量,添加时间条件
};
const formatDateTime = (datetime) => {
const date = new Date(datetime);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
const resizeChart = () => {
const chartDom = document.getElementById('3d-bar-chart');
if (chartDom) {
const chartInstance = echarts.getInstanceByDom(chartDom);
if (chartInstance) {
chartInstance.resize();
}
}
};
const handleResize = () => {
resizeChart();
};
onMounted(async () => {
const token = localStorage.getItem('alertToken');
await fetchTypeMapping(token);
await fetchTypeCounts(); // 初次加载时不加时间条件
window.addEventListener('resize', handleResize);
await renderChart();
globalTimerStore.registerCallback(handleFilter);
globalTimerStore.startTimer();
});
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize);
globalTimerStore.unregisterCallback(handleFilter);
globalTimerStore.stopTimer();
});
</script>
<style scoped>
/* .statistics-container {
margin-top: 20px;
} */
.alert-container {
height: auto;
display: flex;
flex-direction: column;
box-sizing: border-box;
/* padding: 2%; */
margin: 1vh;
}
/* .filter-row{
width: 100%;
height: 5vh;
} */
.search-row {
width: 95%;
padding: 0;
background-color: #001529;
display: flex;
justify-content: left;
align-items: left;
flex-direction: column;
box-sizing: border-box;
gap: 1vh;
}
.start-col,
.end-col,
.bt-search {
display: flex;
justify-content: left;
align-items: center;
height: 4vh;
}
::v-deep .filter-buttons .el-button {
background-color: #da681c;
/* 查询按钮背景颜色 */
color: white;
border-radius: 5px;
}
.myPanChart {
width: 95%;
height: 25vh;
}
::v-deep .search-row .el-input__wrapper {
background-color: transparent;
border-radius: 0px;
box-shadow: none;
}
.alert-bt {
background-color: #001529;
/* background-color: #4a4a4a; */
border: #001529;
width: 79px;
height: 30px;
margin-left: 3vh;
color: #babcbe;
}
</style>