Files
admin-govern/src/views/govern/device/control/tabs/components/harmonicSpectrum.vue
2025-11-17 15:44:20 +08:00

433 lines
14 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="harmonic" :style="heightTop" v-loading="loading">
<div class="harmonic_select" v-if="!loading">
<el-form :model="searchForm" id="history_select">
<el-form-item label="稳态指标">
<el-select multiple collapse-tags collapse-tags-tooltip v-model.trim="searchForm.index"
placeholder="请选择统计指标" :multiple-limit="3" value-key="id">
<el-option v-for="(item, index) in indexOptions" :label="item.name" :key="index"
:value="item"></el-option>
</el-select>
</el-form-item>
<!-- <el-button type="primary" :loading="loading" @click="init">查询</el-button> -->
</el-form>
</div>
<div class="harmonic_body">
<div class="harmonic_body_charts" :style="{ height: height }" v-for="(item, index) in searchForm.index"
:key="index">
<MyEchart :ref="setChildRef(index)" :options="item.echartsData" :isInterVal="true"></MyEchart>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import MyEchart from '@/components/echarts/MyEchart.vue'
import { mainHeight } from '@/utils/layout'
import { yMethod } from '@/utils/echartMethod'
const searchForm: any = ref({})
searchForm.value = {
index: []
}
//统计指标
const indexOptions: any = ref([])
indexOptions.value = [
{
id: 0,
name: '电压总有效值(kV)',
children: [
{ name: 'vRmsA', phase: 'A相', data: [], yMethodList: [] },
{ name: 'vRmsB', phase: 'B相', data: [], yMethodList: [] },
{ name: 'vRmsC', phase: 'C相', data: [], yMethodList: [] }
],
unit: 'kV',
data: [],
yMethodList: []
},
{
id: 1,
name: '电流总有效值(A)',
children: [
{ name: 'iRmsA', phase: 'A相', data: [], yMethodList: [] },
{ name: 'iRmsB', phase: 'B相', data: [], yMethodList: [] },
{ name: 'iRmsC', phase: 'C相', data: [], yMethodList: [] }
],
unit: 'A',
data: [],
yMethodList: []
},
{
id: 2,
name: '有功功率(kW)',
children: [
{ name: 'pA', phase: 'A相', data: [], yMethodList: [] },
{ name: 'pB', phase: 'B相', data: [], yMethodList: [] },
{ name: 'pC', phase: 'C相', data: [], yMethodList: [] },
{ name: 'pTot', phase: '总', data: [], yMethodList: [] }
],
unit: 'kW',
data: [],
yMethodList: []
},
{
id: 3,
name: '无功功率(kW)',
children: [
{ name: 'qA', phase: 'A相', data: [], yMethodList: [] },
{ name: 'qB', phase: 'B相', data: [], yMethodList: [] },
{ name: 'qC', phase: 'C相', data: [], yMethodList: [] },
{ name: 'qTot', phase: '总', data: [], yMethodList: [] }
],
unit: 'kW',
data: [],
yMethodList: []
},
{
id: 4,
name: '基波电压总有效值(kV)',
children: [
{ name: 'v1A', phase: 'A相', data: [], yMethodList: [] },
{ name: 'v1B', phase: 'B相', data: [], yMethodList: [] },
{ name: 'v1C', phase: 'C相', data: [], yMethodList: [] }
],
unit: 'kV',
data: [],
yMethodList: []
},
{
id: 5,
name: '基波电流总有效值(A)',
children: [
{ name: 'i1A', phase: 'A相', data: [], yMethodList: [] },
{ name: 'i1B', phase: 'B相', data: [], yMethodList: [] },
{ name: 'i1C', phase: 'C相', data: [], yMethodList: [] }
],
unit: 'A',
data: [],
yMethodList: []
},
{
id: 6,
name: '频率(Hz)',
children: [
{ name: 'freq', phase: '频率', data: [], yMethodList: [] },
{ name: 'freqDev', phase: '频率偏差', data: [], yMethodList: [] }
],
unit: 'Hz',
data: [],
yMethodList: []
},
{
id: 7,
name: '电压不平衡度(%)',
children: [{ name: 'vUnbalance', phase: '电压不平衡度', data: [], yMethodList: [] }],
unit: '%',
data: [],
yMethodList: []
},
{
id: 8,
name: '电流不平衡度(%)',
children: [{ name: 'iUnbalance', phase: '电流不平衡度', data: [], yMethodList: [] }],
unit: '%',
data: [],
yMethodList: []
}
]
searchForm.value.index[0] = indexOptions.value[0]
const heightTop = mainHeight(275)
let height: any = mainHeight(275).height
const loading = ref(false)
const allDataList: any = ref([])
const xAixsTimeList: any = ref([])
const resetData = (dataLevel: string) => {
loading.value = true
indexOptions.value = [
{
id: 0,
name: '电压总有效值',
children: [
{ name: 'vRmsA', phase: 'A相', data: [], yMethodList: [] },
{ name: 'vRmsB', phase: 'B相', data: [], yMethodList: [] },
{ name: 'vRmsC', phase: 'C相', data: [], yMethodList: [] }
],
unit: dataLevel === 'Primary' ? 'kV' : 'V',
data: [],
yMethodList: []
},
{
id: 1,
name: '电流总有效值',
children: [
{ name: 'iRmsA', phase: 'A相', data: [], yMethodList: [] },
{ name: 'iRmsB', phase: 'B相', data: [], yMethodList: [] },
{ name: 'iRmsC', phase: 'C相', data: [], yMethodList: [] }
],
unit: 'A',
data: [],
yMethodList: []
},
{
id: 2,
name: '有功功率',
children: [
{ name: 'pA', phase: 'A相', data: [], yMethodList: [] },
{ name: 'pB', phase: 'B相', data: [], yMethodList: [] },
{ name: 'pC', phase: 'C相', data: [], yMethodList: [] },
{ name: 'pTot', phase: '总', data: [], yMethodList: [] }
],
unit: dataLevel === 'Primary' ? 'kW' : 'W',
data: [],
yMethodList: []
},
{
id: 3,
name: '无功功率',
children: [
{ name: 'qA', phase: 'A相', data: [], yMethodList: [] },
{ name: 'qB', phase: 'B相', data: [], yMethodList: [] },
{ name: 'qC', phase: 'C相', data: [], yMethodList: [] },
{ name: 'qTot', phase: '总', data: [], yMethodList: [] }
],
unit: dataLevel === 'Primary' ? 'kVar' : 'Var',
data: [],
yMethodList: []
},
{
id: 4,
name: '基波电压总有效值',
children: [
{ name: 'v1A', phase: 'A相', data: [], yMethodList: [] },
{ name: 'v1B', phase: 'B相', data: [], yMethodList: [] },
{ name: 'v1C', phase: 'C相', data: [], yMethodList: [] }
],
unit: dataLevel === 'Primary' ? 'kV' : 'V',
data: [],
yMethodList: []
},
{
id: 5,
name: '基波电流总有效值',
children: [
{ name: 'i1A', phase: 'A相', data: [], yMethodList: [] },
{ name: 'i1B', phase: 'B相', data: [], yMethodList: [] },
{ name: 'i1C', phase: 'C相', data: [], yMethodList: [] }
],
unit: 'A',
data: [],
yMethodList: []
},
{
id: 6,
name: '频率',
children: [
{ name: 'freq', phase: '频率', data: [], yMethodList: [] },
{ name: 'freqDev', phase: '频率偏差', data: [], yMethodList: [] }
],
unit: 'Hz',
data: [],
yMethodList: []
},
{
id: 7,
name: '电压不平衡度',
children: [{ name: 'vUnbalance', phase: '电压不平衡度', data: [], yMethodList: [] }],
unit: '%',
data: [],
yMethodList: []
},
{
id: 8,
name: '电流不平衡度',
children: [{ name: 'iUnbalance', phase: '电流不平衡度', data: [], yMethodList: [] }],
unit: '%',
data: [],
yMethodList: []
}
]
searchForm.value.index = []
searchForm.value.index[0] = indexOptions.value[0]
allDataList.value = []
xAixsTimeList.value = []
}
resetData('Primary')
const mqttMessage: any = ref()
const setHarmonicSpectrumData = (val: any) => {
mqttMessage.value = val
init()
}
// 为每个子组件实例设置ref
const setChildRef = (index: any) => {
return `child-${index}`
}
const childRefs: any = {}
const init = () => {
loading.value = true
//循环渲染图表
xAixsTimeList.value.push(mqttMessage.value.dataTime.split(" ")[1])
// 限制x轴数据点数量避免过多数据点导致性能问题和显示重复
if (xAixsTimeList.value.length > 50) {
xAixsTimeList.value.shift()
}
searchForm.value.index.map((item: any, index: any) => {
item?.children.map((vv: any, vvs: any) => {
if (mqttMessage.value[vv.name] != undefined) {
// 清空当前时间点的数据(如果存在),防止重复
const currentTime = mqttMessage.value.dataTime.split(" ")[1];
vv.yMethodList = vv.yMethodList.filter((point: any) => point[0] !== currentTime);
item.data.push({
// time: mqttMessage.value.dataTime,
value: mqttMessage.value[vv.name],
key: vv.name
})
allDataList.value.push(mqttMessage.value[vv.name])
vv.data.push(mqttMessage.value[vv.name])
// 更新yMethodList数据确保与xAixsTimeList保持同步
vv.yMethodList.push([currentTime, mqttMessage.value[vv.name] + '', vv.phase])
// 限制数据点数量,避免过多数据点导致性能问题和显示重复
if (vv.yMethodList.length > 50) {
vv.yMethodList.shift()
}
}
})
})
searchForm.value.index.map((item: any, index: any) => {
//循环渲染图表
const refName = setChildRef(index)
childRefs[refName] = ref(null) // 初始化ref
item.echartsData = {
title: {
text: item.name
},
// grid: {
// top: '16%',
// bottom: '15%', //也可设置left和right设置距离来控制图表的大小
// left: '3%',
// right: '4%'
// },
tooltip: {
axisPointer: {
type: 'cross',
label: {
color: '#fff',
fontSize: 16
}
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.55)',
borderWidth: 0
},
xAxis: {
name: '时间',
type: 'category',
// axisLabel: {
// formatter: {
// day: '{MM}-{dd}',
// month: '{MM}',
// year: '{yyyy}'
// }
// },
boundaryGap: false,
data: xAixsTimeList.value
},
yAxis: {
// type: 'value',
name: item.unit,
splitNumber: 5,
minInterval: 1
},
series: []
}
//根据指标判断渲染几条线
searchForm.value.index.length == 3
? (height = mainHeight(275, 3).height)
: (height = mainHeight(275, searchForm.value.index.length).height)
item.children.map((zz: any, zzIndex: any) => {
item.echartsData.series.push({
name: zz.phase,
type: 'line',
increment: true,
itemStyle: {
barBorderRadius: [3, 3, 0, 0],
color: ['#DAA520', '#2E8B57', '#A52a2a', '#000'][zzIndex]
},
data: zz.yMethodList,
smooth: true, // 这里设置平滑曲线
symbol: 'none' // 设置为 'none' 去掉折点小圆
})
})
let arrList = item.children?.map((item: any) => item.yMethodList.map((val: any) => val[1])).flat()
let [min, max] = yMethod(arrList.length == 0 ? [0] : arrList)
item.echartsData.yAxis.max = max
item.echartsData.yAxis.min = min
})
loading.value = false
}
onMounted(() => { })
defineExpose({ resetData, setHarmonicSpectrumData })
</script>
<style lang="scss" scoped>
.harmonic {
width: 100%;
// height: 100%;
display: 'flex';
flex-direction: column;
position: relative;
.harmonic_select {
width: 50%;
height: 30px;
display: flex;
position: absolute;
top: -32px;
left: 0;
justify-content: flex-start;
.el-button {
margin-left: 10px;
}
}
.harmonic_body {
flex: 1;
overflow-y: auto;
.harmonic_body_charts {
border: 1px solid #eee;
position: relative;
padding-top: 10px;
box-sizing: border-box;
.charts_title {
position: absolute;
top: 10px;
left: 10%;
font-size: 18px;
font-weight: 800;
}
}
}
}
</style>