fix: 看板告警图统计逻辑优化
This commit is contained in:
@@ -1,21 +1,26 @@
|
|||||||
<template>
|
|
||||||
<div ref="alarmTypeBar" class="chart-container"></div>
|
|
||||||
</template>
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { markRaw, onMounted, reactive, ref } from 'vue';
|
|
||||||
import { origGet, top3Sel } from '@/api/faultManage/actAlarm';
|
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import {
|
import {
|
||||||
DatasetComponent,
|
|
||||||
GridComponent,
|
|
||||||
TransformComponent,
|
|
||||||
TitleComponent,
|
TitleComponent,
|
||||||
|
TitleComponentOption,
|
||||||
TooltipComponent,
|
TooltipComponent,
|
||||||
|
TooltipComponentOption,
|
||||||
|
GridComponent,
|
||||||
|
GridComponentOption,
|
||||||
LegendComponent,
|
LegendComponent,
|
||||||
|
LegendComponentOption,
|
||||||
} from 'echarts/components';
|
} from 'echarts/components';
|
||||||
import { BarChart, PieChart } from 'echarts/charts';
|
import {
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
PieChart,
|
||||||
|
PieSeriesOption,
|
||||||
|
BarChart,
|
||||||
|
BarSeriesOption,
|
||||||
|
} from 'echarts/charts';
|
||||||
import { LabelLayout } from 'echarts/features';
|
import { LabelLayout } from 'echarts/features';
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
|
|
||||||
|
import { markRaw, onMounted, ref } from 'vue';
|
||||||
|
import { origGet, top3Sel } from '@/api/faultManage/actAlarm';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
|
||||||
@@ -24,231 +29,226 @@ const { t } = useI18n();
|
|||||||
echarts.use([
|
echarts.use([
|
||||||
TitleComponent,
|
TitleComponent,
|
||||||
TooltipComponent,
|
TooltipComponent,
|
||||||
|
GridComponent,
|
||||||
LegendComponent,
|
LegendComponent,
|
||||||
PieChart,
|
PieChart,
|
||||||
|
BarChart,
|
||||||
CanvasRenderer,
|
CanvasRenderer,
|
||||||
LabelLayout,
|
LabelLayout,
|
||||||
DatasetComponent,
|
|
||||||
GridComponent,
|
|
||||||
TransformComponent,
|
|
||||||
BarChart,
|
|
||||||
CanvasRenderer,
|
|
||||||
GridComponent,
|
|
||||||
BarChart,
|
|
||||||
CanvasRenderer,
|
|
||||||
GridComponent,
|
|
||||||
BarChart,
|
|
||||||
CanvasRenderer,
|
|
||||||
CanvasRenderer,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
type EChartsOption = echarts.ComposeOption<
|
||||||
|
| TitleComponentOption
|
||||||
|
| TooltipComponentOption
|
||||||
|
| GridComponentOption
|
||||||
|
| LegendComponentOption
|
||||||
|
| PieSeriesOption
|
||||||
|
| BarSeriesOption
|
||||||
|
>;
|
||||||
|
|
||||||
/**图DOM节点实例对象 */
|
/**图DOM节点实例对象 */
|
||||||
const alarmTypeBar = ref<HTMLElement | undefined>(undefined);
|
const alarmTypeBar = ref<HTMLElement | undefined>(undefined);
|
||||||
|
|
||||||
/**图实例对象 */
|
/**图实例对象 */
|
||||||
const alarmTypeBarChart = ref<any>(null);
|
const alarmTypeBarChart = ref<any>(null);
|
||||||
|
|
||||||
// 将现有数据补全为期望的格式
|
/**告警类型数据 */
|
||||||
function completeData(existingData: any, expectedData: any) {
|
const alarmTypeType = ref<any>([
|
||||||
const result = expectedData.map((item: any) => {
|
{
|
||||||
const found = existingData.find(
|
value: 0,
|
||||||
(existingItem: any) => existingItem.name === item.name
|
name: t('views.index.Critical'),
|
||||||
);
|
},
|
||||||
if (found) return found;
|
{
|
||||||
else {
|
value: 0,
|
||||||
return item;
|
name: t('views.index.Major'),
|
||||||
}
|
},
|
||||||
});
|
{
|
||||||
|
value: 0,
|
||||||
|
name: t('views.index.Minor'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: t('views.index.Warning'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: t('views.index.Event'),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
return result;
|
/**告警类型Top数据 */
|
||||||
}
|
const alarmTypeTypeTop = ref<any>([
|
||||||
|
{ name: 'AMF', value: 0 },
|
||||||
var wantArr = [
|
{ name: 'UDM', value: 0 },
|
||||||
{
|
{ name: 'SMF', value: 0 },
|
||||||
value: 0,
|
]);
|
||||||
name: 'Critical',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
name: 'Major',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
name: 'Minor',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
name: 'Warning',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
name: 'Event',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
//
|
//
|
||||||
function initPicture() {
|
function initPicture() {
|
||||||
Promise.allSettled([origGet(), top3Sel()]).then(resArr => {
|
Promise.allSettled([origGet(), top3Sel()])
|
||||||
let barArr: any = [
|
.then(resArr => {
|
||||||
{ name: 'AMF', value: 0 },
|
if (resArr[0].status === 'fulfilled') {
|
||||||
{ name: 'UDM', value: 0 },
|
const res0 = resArr[0].value;
|
||||||
{ name: 'SMF', value: 0 },
|
if (res0.code === RESULT_CODE_SUCCESS && Array.isArray(res0.data)) {
|
||||||
];
|
for (const item of res0.data) {
|
||||||
let pieArr: any = [];
|
let index = 0;
|
||||||
let testArr: any = [];
|
switch (item.name) {
|
||||||
if (resArr[0].status === 'fulfilled') {
|
case 'Critical':
|
||||||
const res0 = resArr[0].value;
|
index = 0;
|
||||||
if (res0.code === RESULT_CODE_SUCCESS) {
|
break;
|
||||||
testArr = completeData(res0.data, wantArr);
|
case 'Major':
|
||||||
testArr.map((item: any) => {
|
index = 1;
|
||||||
item.name = t('views.index.' + item.name) + ': ' + item.value;
|
break;
|
||||||
pieArr.push(item);
|
case 'Minor':
|
||||||
});
|
index = 2;
|
||||||
|
break;
|
||||||
|
case 'Warning':
|
||||||
|
index = 3;
|
||||||
|
break;
|
||||||
|
case 'Event':
|
||||||
|
index = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
alarmTypeType.value[index].value = Number(item.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (resArr[1].status === 'fulfilled') {
|
||||||
if (resArr[1].status === 'fulfilled') {
|
const res1 = resArr[1].value;
|
||||||
const res1 = resArr[1].value;
|
if (res1.code === RESULT_CODE_SUCCESS && Array.isArray(res1.data)) {
|
||||||
if (res1.code === RESULT_CODE_SUCCESS) {
|
alarmTypeTypeTop.value = alarmTypeTypeTop.value
|
||||||
res1.data.map((item: any) => {
|
.concat(res1.data)
|
||||||
barArr.push(item);
|
.sort((a: any, b: any) => {
|
||||||
});
|
return b.value - a.value;
|
||||||
|
})
|
||||||
|
.slice(0, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
.then(() => {
|
||||||
let firstThreeItems = barArr
|
const optionData: EChartsOption = {
|
||||||
.sort((a: any, b: any) => {
|
title: [
|
||||||
return b.value - a.value;
|
{
|
||||||
})
|
show: false,
|
||||||
.slice(0, 3);
|
},
|
||||||
// pieArr.sort((a: any, b: any) => {
|
{
|
||||||
// return b.value - a.value;
|
text: t('views.dashboard.overview.alarmTypeBar.topTitle'),
|
||||||
// });
|
textStyle: {
|
||||||
const optionData: any = {
|
color: '#fff',
|
||||||
title: [
|
fontSize: '14',
|
||||||
{
|
fontWeight: 400,
|
||||||
text: '',
|
},
|
||||||
show: false,
|
top: '50%',
|
||||||
|
left: '0%',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: '{b} : {c}',
|
||||||
},
|
},
|
||||||
{
|
legend: {
|
||||||
text: t('views.dashboard.overview.alarmTypeBar.topTitle'),
|
orient: 'vertical',
|
||||||
|
right: '2%',
|
||||||
|
top: '10%',
|
||||||
|
data: alarmTypeType.value.map((item: any) => item.name), //label数组
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: '#fff',
|
color: '#A7D6F4', // 设置图例文字颜色
|
||||||
fontSize: '14',
|
|
||||||
fontFamily: 'PingFang',
|
|
||||||
fontWeight: '400',
|
|
||||||
},
|
},
|
||||||
top: '50%',
|
|
||||||
left: '0%',
|
|
||||||
},
|
},
|
||||||
],
|
grid: [
|
||||||
tooltip: {
|
{
|
||||||
trigger: 'item',
|
top: '60%',
|
||||||
formatter: '{b}',
|
left: '15%',
|
||||||
},
|
right: '25%',
|
||||||
grid: [
|
bottom: '10%',
|
||||||
{
|
},
|
||||||
top: '60%',
|
],
|
||||||
left: '15%',
|
series: [
|
||||||
right: '25%',
|
//饼图:
|
||||||
bottom: '10%',
|
{
|
||||||
},
|
type: 'pie',
|
||||||
],
|
radius: '35%',
|
||||||
legend: {
|
color: ['#f5222d', '#ffc069', '#fadb14', '#722ed1', '#1677ff'],
|
||||||
orient: 'vertical',
|
label: {
|
||||||
right: '2%',
|
show: true,
|
||||||
top: '10%',
|
position: 'inner',
|
||||||
data: pieArr.map((item: any) => item.name), //label数组
|
formatter: ' {c}',
|
||||||
textStyle: {
|
},
|
||||||
color: '#A7D6F4', // 设置图例文字颜色
|
labelLine: {
|
||||||
},
|
show: false,
|
||||||
},
|
},
|
||||||
// 饼图设置
|
center: ['35%', '25%'],
|
||||||
// color: ['#FFAE57', '#FF7853', '#EA5151', '#CC3F57', '#9A2555'],
|
data: alarmTypeType.value,
|
||||||
color: ['#f5222d', '#ffc069', '#fadb14', '#722ed1', '#1677ff'], //红橙黄紫蓝 为告警级别配色 以严重性依次往下!
|
zlevel: 2, // 设置zlevel为1,使得柱状图在下层显示
|
||||||
|
itemStyle: {
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
//柱状
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: 12, // 柱子宽度
|
||||||
|
barCategoryGap: '30%', // 控制同一系列的柱间距离
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'right', // 位置
|
||||||
|
color: '#A7D6F4', //淡蓝色
|
||||||
|
fontSize: 14,
|
||||||
|
distance: 14, // label与柱子距离
|
||||||
|
formatter: '{c}',
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: [0, 20, 20, 0], // 圆角(左上、右上、右下、左下)
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
|
{ offset: 0, color: '#f0f5ff' },
|
||||||
|
{ offset: 0.5, color: '#adc6ff' },
|
||||||
|
{ offset: 1, color: '#2f54eb' },
|
||||||
|
]), // 渐变
|
||||||
|
},
|
||||||
|
data: alarmTypeTypeTop.value,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 柱状图设置
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
type: 'value',
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
//y轴
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
type: 'category',
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
inverse: true,
|
||||||
|
data: alarmTypeTypeTop.value.map((item: any) => item.name),
|
||||||
|
axisLabel: {
|
||||||
|
color: '#A7D6F4',
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
series: [
|
fnDesign(alarmTypeBar.value, optionData);
|
||||||
//饼图:
|
});
|
||||||
{
|
|
||||||
type: 'pie',
|
|
||||||
radius: '35%',
|
|
||||||
label: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
center: ['35%', '25%'],
|
|
||||||
data: pieArr,
|
|
||||||
lineStyle: 'none', // 设置线条样式为无,即可去掉线条
|
|
||||||
zlevel: 2, // 设置zlevel为1,使得柱状图在下层显示
|
|
||||||
itemStyle: {
|
|
||||||
shadowBlur: 10,
|
|
||||||
shadowOffsetX: 0,
|
|
||||||
shadowColor: 'rgba(0, 0, 0, 0.5)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
//柱状
|
|
||||||
{
|
|
||||||
type: 'bar',
|
|
||||||
barWidth: 12, // 柱子宽度
|
|
||||||
barCategoryGap: '30%', // 控制同一系列的柱间距离
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: 'right', // 位置
|
|
||||||
color: '#A7D6F4', //淡蓝色
|
|
||||||
fontSize: 14,
|
|
||||||
distance: 14, // label与柱子距离
|
|
||||||
formatter: '{c}',
|
|
||||||
}, // 柱子上方的数值
|
|
||||||
itemStyle: {
|
|
||||||
borderRadius: [0, 20, 20, 0], // 圆角(左上、右上、右下、左下)
|
|
||||||
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|
||||||
{ offset: 0, color: '#f0f5ff' },
|
|
||||||
{ offset: 0.5, color: '#adc6ff' },
|
|
||||||
{ offset: 1, color: '#2f54eb' },
|
|
||||||
]), // 渐变
|
|
||||||
},
|
|
||||||
data: firstThreeItems.map((item: any) => item.value),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// 柱状图设置
|
|
||||||
xAxis: [
|
|
||||||
{
|
|
||||||
splitLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
type: 'value',
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
splitLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisLine: {
|
|
||||||
//y轴
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
type: 'category',
|
|
||||||
axisTick: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
inverse: true,
|
|
||||||
data: firstThreeItems.map((item: any) => item.name),
|
|
||||||
axisLabel: {
|
|
||||||
color: '#A7D6F4',
|
|
||||||
fontSize: 14,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
fnDesign(alarmTypeBar.value, optionData);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fnDesign(container: HTMLElement | undefined, option: any) {
|
function fnDesign(container: HTMLElement | undefined, option: any) {
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
const { clientHeight, clientWidth } = container;
|
|
||||||
|
|
||||||
alarmTypeBarChart.value = markRaw(echarts.init(container, 'light'));
|
alarmTypeBarChart.value = markRaw(echarts.init(container, 'light'));
|
||||||
option && alarmTypeBarChart.value.setOption(option);
|
option && alarmTypeBarChart.value.setOption(option);
|
||||||
@@ -268,6 +268,10 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="alarmTypeBar" class="chart-container"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.chart-container {
|
.chart-container {
|
||||||
/* 设置图表容器大小和位置 */
|
/* 设置图表容器大小和位置 */
|
||||||
|
|||||||
Reference in New Issue
Block a user