Files
fe.ems.vue3/src/views/index/tenantUPF.vue
2024-10-31 17:34:38 +08:00

338 lines
7.7 KiB
Vue

<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue';
import { listKPIData } from '@/api/perfManage/goldTarget';
import * as echarts from 'echarts/core';
import {
TooltipComponent,
TooltipComponentOption,
GridComponent,
GridComponentOption,
LegendComponent,
LegendComponentOption,
} from 'echarts/components';
import { LineChart, LineSeriesOption } from 'echarts/charts';
import { UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import { markRaw } from 'vue';
import useI18n from '@/hooks/useI18n';
import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import {
upfFlowData,
upfFlowParse,
} from '../dashboard/overview/hooks/useUPFTotalFlow';
import useWS from '../dashboard/overview/hooks/useWS';
const { reSendUPF } = useWS();
const { t } = useI18n();
echarts.use([
TooltipComponent,
GridComponent,
LegendComponent,
LineChart,
CanvasRenderer,
UniversalTransition,
]);
type EChartsOption = echarts.ComposeOption<
| TooltipComponentOption
| GridComponentOption
| LegendComponentOption
| LineSeriesOption
>;
/**图DOM节点实例对象 */
const upfFlow = ref<HTMLElement | undefined>(undefined);
/**图实例对象 */
const upfFlowChart = ref<any>(null);
// 使用Map去重
const uniqueItems = new Map<string, string>();
//UPF下拉框
const dropdownOptions: any = ref([]);
//UPF下拉框选中值
const selectRmUid = ref<string>('');
function fnDesign(container: HTMLElement | undefined, option: EChartsOption) {
if (!container) {
return;
}
if (!upfFlowChart.value) {
upfFlowChart.value = markRaw(echarts.init(container, 'light'));
}
option && upfFlowChart.value.setOption(option);
// 创建 ResizeObserver 实例
var observer = new ResizeObserver(entries => {
if (upfFlowChart.value) {
upfFlowChart.value.resize();
}
});
// 监听元素大小变化
observer.observe(container);
}
//渲染速率图
function handleRanderChart() {
const { lineXTime, lineYUp, lineYDown } = upfFlowData.value;
var yAxisSeries: any = [
{
name: t('views.dashboard.overview.upfFlow.up'),
type: 'line',
color: 'rgba(250, 219, 20)',
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(250, 219, 20, .5)',
},
{
offset: 1,
color: 'rgba(250, 219, 20, 0.5)',
},
]),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10,
},
symbol: 'circle',
symbolSize: 5,
formatter: '{b}',
data: lineYUp,
},
{
name: t('views.dashboard.overview.upfFlow.down'),
type: 'line',
color: 'rgba(92, 123, 217)',
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(92, 123, 217, .5)',
},
{
offset: 1,
color: 'rgba(92, 123, 217, 0.5)',
},
]),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10,
},
symbol: 'circle',
symbolSize: 5,
formatter: '{b}',
data: lineYDown,
},
];
const optionData: EChartsOption = {
tooltip: {
show: true, //是否显示提示框组件
trigger: 'axis',
//formatter:'{a0}:{c0}<br>{a1}:{c1}'
formatter: function (param: any) {
var tip = '';
if (param !== null && param.length > 0) {
tip += param[0].name + '<br />';
for (var i = 0; i < param.length; i++) {
tip +=
param[i].marker +
param[i].seriesName +
': ' +
param[i].value +
'<br />';
}
}
return tip;
},
},
legend: {
data: yAxisSeries.map((s: any) => s.name),
textStyle: {
fontSize: 12,
},
left: 'center', // 设置图例居中
},
grid: {
top: '14%',
left: '4%',
right: '4%',
bottom: '12%',
containLabel: true,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: lineXTime,
axisLabel: {
formatter: function (params: any) {
return params.split(' ')[1];
},
fontSize: 14,
},
axisLine: {
lineStyle: {},
},
},
yAxis: [
{
name: '(Mbps)',
nameTextStyle: {
fontSize: 12, // 设置文字距离x轴的距离
padding: [0, -10, 0, 0], // 设置名称在x轴方向上的偏移
},
type: 'value',
// splitNumber: 4,
min: 0,
//max: 300,
axisLabel: {
formatter: '{value}',
},
splitLine: {
lineStyle: {},
},
axisLine: {
lineStyle: {},
},
},
],
series: yAxisSeries,
};
fnDesign(upfFlow.value, optionData);
}
/**查询初始UPF数据 */
function fnGetInitData() {
// 查询10分钟前的
const nowDate: Date = new Date();
const tenMinutesAgo = new Date(nowDate.getTime() - 5 * 60 * 1000);
upfFlowData.value = {
lineXTime: [],
lineYUp: [],
lineYDown: [],
cap: 0,
};
listKPIData({
neType: 'UPF',
neId: '',
startTime: tenMinutesAgo.getTime(),
endTime: nowDate.getTime(),
// startTime: '2024-03-20 19:50:00',
// endTime: '2024-03-20 19:55:00',
interval: 5, // 5秒
sortField: 'timeGroup',
sortOrder: 'asc',
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
//先分类再分析每条数据
for (const item of res.data) {
if (item.neName && item.rmUID) {
uniqueItems.set(item.neName, item.rmUID);
}
}
// 将 Map 转换为数组
dropdownOptions.value = Array.from(uniqueItems, ([label, value]) => ({
label,
value,
}));
//填写初始值
if (dropdownOptions.value.length > 0) {
if (!selectRmUid.value) {
selectRmUid.value = dropdownOptions.value[0].value;
}
reSendUPF(selectRmUid.value);
}
for (const item of res.data) {
if (item.rmUID === selectRmUid.value) {
upfFlowParse(item);
}
}
}
})
.finally(() => {
handleRanderChart();
});
}
watch(
() => upfFlowData.value,
v => {
if (upfFlowChart.value == null) return;
upfFlowChart.value.setOption({
xAxis: {
data: v.lineXTime,
},
series: [
{
data: v.lineYUp,
},
{
data: v.lineYDown,
},
],
});
},
{
deep: true,
}
);
onMounted(() => {
fnGetInitData();
});
onUnmounted(() => {
if (upfFlowChart.value) {
upfFlowChart.value.dispose();
upfFlowChart.value = null;
}
});
</script>
<template>
<div style="background-color: #f7f8fc; padding: 20px">
<a-card
:bordered="false"
class="cardClass"
v-show="upfFlowData.lineXTime.length"
>
<template #title
><a href="#"
>{{ t('views.dashboard.overview.upfFlow.title') }}
</a></template
>
<template #extra>
<a-select
v-model:value="selectRmUid"
style="width: 120px"
@change="fnGetInitData"
:options="dropdownOptions"
/>
</template>
<div ref="upfFlow" style="padding: 24px" class="chart-container"></div>
</a-card>
</div>
</template>
<style lang="less" scoped>
.chart-container {
/* 设置图表容器大小和位置 */
width: 100%;
min-height: 400px;
}
</style>