Files
admin-govern/src/views/govern/device/control/tabs/components/harmonicSpectrum.vue
2024-10-18 16:24:44 +08:00

645 lines
21 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">
<div class="harmonic_select">
<el-form :model="searchForm" id="history_select">
<el-form-item label="稳态指标">
<el-select
multiple
collapse-tags
collapse-tags-tooltip
v-model="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" v-loading="loading">
<div
class="harmonic_body_charts"
:style="{ height: height }"
v-for="(item, index) in searchForm.index"
:key="index"
>
<!-- <p class="charts_title">
{{
indexOptions.find((item: any) => {
return item.id == searchForm.index[index]
})?.name
}}
</p> -->
<MyEchart :ref="setChildRef(index)" :options="item.echartsData" :isInterVal="true"></MyEchart>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue'
import MyEchart from '@/components/echarts/MyEchart.vue'
import { getDeviceHarmonicSpectrumData, getRealTimeTableList } from '@/api/cs-device-boot/EquipmentDelivery.ts'
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: [] },
{ name: 'vRmsB', phase: 'B相', data: [] },
{ name: 'vRmsC', phase: 'C相', data: [] }
],
unit: 'kV',
data: []
},
{
id: 1,
name: '电流总有效值(A)',
children: [
{ name: 'iRmsA', phase: 'A相', data: [] },
{ name: 'iRmsB', phase: 'B相', data: [] },
{ name: 'iRmsC', phase: 'C相', data: [] }
],
unit: 'A',
data: []
},
{
id: 2,
name: '有功功率(kW)',
children: [
{ name: 'pA', phase: 'A相', data: [] },
{ name: 'pB', phase: 'B相', data: [] },
{ name: 'pC', phase: 'C相', data: [] },
{ name: 'pTot', phase: '总', data: [] }
],
unit: 'kW',
data: []
},
{
id: 3,
name: '无功功率(kW)',
children: [
{ name: 'qA', phase: 'A相', data: [] },
{ name: 'qB', phase: 'B相', data: [] },
{ name: 'qC', phase: 'C相', data: [] },
{ name: 'qTot', phase: '总', data: [] }
],
unit: 'kW',
data: []
},
{
id: 4,
name: '基波电压总有效值(kV)',
children: [
{ name: 'v1A', phase: 'A相', data: [] },
{ name: 'v1B', phase: 'B相', data: [] },
{ name: 'v1C', phase: 'C相', data: [] }
],
unit: 'kV',
data: []
},
{
id: 5,
name: '基波电流总有效值(A)',
children: [
{ name: 'i1A', phase: 'A相', data: [] },
{ name: 'i1B', phase: 'B相', data: [] },
{ name: 'i1C', phase: 'C相', data: [] }
],
unit: 'A',
data: []
},
{
id: 6,
name: '频率(Hz)',
children: [
{ name: 'freq', phase: '频率', data: [] },
{ name: 'freqDev', phase: '频率偏差', data: [] }
],
unit: 'Hz',
data: []
},
{
id: 7,
name: '电压不平衡度(%)',
children: [{ name: 'vUnbalance', phase: '电压不平衡度', data: [] }],
unit: '%',
data: []
},
{
id: 8,
name: '电流不平衡度(%)',
children: [{ name: 'iUnbalance', phase: '电流不平衡度', data: [] }],
unit: '%',
data: []
}
]
// searchForm.value.index[0] = indexOptions.value[0]
const heightTop = mainHeight(275)
let height: any = mainHeight(275).height
const params: any = ref({})
const resetData = () => {
indexOptions.value = [
{
id: 0,
name: '电压总有效值(kV)',
children: [
{ name: 'vRmsA', phase: 'A相', data: [] },
{ name: 'vRmsB', phase: 'B相', data: [] },
{ name: 'vRmsC', phase: 'C相', data: [] }
],
unit: 'kV',
data: []
},
{
id: 1,
name: '电流总有效值(A)',
children: [
{ name: 'iRmsA', phase: 'A相', data: [] },
{ name: 'iRmsB', phase: 'B相', data: [] },
{ name: 'iRmsC', phase: 'C相', data: [] }
],
unit: 'A',
data: []
},
{
id: 2,
name: '有功功率(kW)',
children: [
{ name: 'pA', phase: 'A相', data: [] },
{ name: 'pB', phase: 'B相', data: [] },
{ name: 'pC', phase: 'C相', data: [] },
{ name: 'pTot', phase: '总', data: [] }
],
unit: 'kW',
data: []
},
{
id: 3,
name: '无功功率(kW)',
children: [
{ name: 'qA', phase: 'A相', data: [] },
{ name: 'qB', phase: 'B相', data: [] },
{ name: 'qC', phase: 'C相', data: [] },
{ name: 'qTot', phase: '总', data: [] }
],
unit: 'kW',
data: []
},
{
id: 4,
name: '基波电压总有效值(kV)',
children: [
{ name: 'v1A', phase: 'A相', data: [] },
{ name: 'v1B', phase: 'B相', data: [] },
{ name: 'v1C', phase: 'C相', data: [] }
],
unit: 'kV',
data: []
},
{
id: 5,
name: '基波电流总有效值(A)',
children: [
{ name: 'i1A', phase: 'A相', data: [] },
{ name: 'i1B', phase: 'B相', data: [] },
{ name: 'i1C', phase: 'C相', data: [] }
],
unit: 'A',
data: []
},
{
id: 6,
name: '频率(Hz)',
children: [
{ name: 'freq', phase: '频率', data: [] },
{ name: 'freqDev', phase: '频率偏差', data: [] }
],
unit: 'Hz',
data: []
},
{
id: 7,
name: '电压不平衡度(%)',
children: [{ name: 'vUnbalance', phase: '电压不平衡度', data: [] }],
unit: '%',
data: []
},
{
id: 8,
name: '电流不平衡度(%)',
children: [{ name: 'iUnbalance', phase: '电流不平衡度', data: [] }],
unit: '%',
data: []
}
]
searchForm.value.index = []
searchForm.value.index[0] = indexOptions.value[0]
}
resetData()
const mqttMessage: any = ref()
const setHarmonicSpectrumData = (val: any) => {
mqttMessage.value = val
init()
}
const chartsList: any = ref([])
const loading = ref(false)
// 为每个子组件实例设置ref
const setChildRef = (index: any) => {
return `child-${index}`
}
const childRefs: any = {}
const harmonicData: any = ref([])
const init = () => {
loading.value = true
mqttMessage.value
searchForm.value.index.map((item: any, index: any) => {
item?.children.map((vv: any, vvs: any) => {
if (mqttMessage.value[vv.name]) {
console.log(
mqttMessage.value[vv.name],
'这是一个哥哥哥哥哥哥哥哥还是哈哈',
mqttMessage.value.dataTime,
vvs,
index,
vv.name
)
item.linesList = []
item?.data.push({
time: mqttMessage.value.dataTime,
value: mqttMessage.value[vv.name],
key: vv.name
})
vv.data.push(mqttMessage.value[vv.name])
}
})
})
loading.value = false
//循环渲染图表
let timeList: any = []
searchForm.value.index.map((item: any, index: any) => {
timeList = Array.from(
new Set(
item.data.map((vv: any) => {
return vv.time
})
)
)
//循环渲染图表
const refName = setChildRef(index)
childRefs[refName] = ref(null) // 初始化ref
item.echartsData = {
options: {
title: [
{
left: '10%',
top: 0,
text: item.name
}
],
// grid: {
// top: '16%',
// bottom: '15%', //也可设置left和right设置距离来控制图表的大小
// left: '3%',
// right: '4%'
// },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
show: false
}
}
},
legend: {
data: [],
top: '2%',
right: '2%'
},
xAxis: {
name: '时间',
data: timeList,
axisLine: {
show: true, //隐藏X轴轴线
lineStyle: {
color: '#000'
}
},
axisTick: {
show: true //隐藏X轴刻度
},
axisPointer: {
type: 'shadow'
},
axisLabel: {
show: true,
textStyle: {
color: '#000' //X轴文字颜色
}
},
boundaryGap: false
},
yAxis: {
type: 'value',
name: item.unit,
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000'
}
},
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) => {
item.echartsData.options.legend.data.push(zz.phase)
item.echartsData.options.series.push({
name: zz.phase,
type: 'line',
increment: true,
barMaxWidth: 24, //使用的 y 轴的 index在单个图表实例中存在多个 y轴的时候有用
itemStyle: {
// normal: {
barBorderRadius: [3, 3, 0, 0]
// color: '#00CC99'
// }e
},
data: zz.data,
smooth: true, // 这里设置平滑曲线
symbol: 'none' // 设置为 'none' 去掉折点小圆
})
})
console.log(searchForm.value.index, '最新的结果')
return
//横轴数据
item.echartsData.options.xAxis.data =
item.thdDataVOS.length != 0 &&
item.thdDataVOS[0].list &&
item.thdDataVOS[0].list.map((ss: any) => {
return ss.frequency + '次'
})
let aar: any = []
//y轴数据
item.thdDataVOS.map((vv: any) => {
item.echartsData.options.series.push({
name: vv.phase + '相',
type: 'line',
barMaxWidth: 24, //使用的 y 轴的 index在单个图表实例中存在多个 y轴的时候有用
itemStyle: {
// normal: {
barBorderRadius: [3, 3, 0, 0]
// color: '#00CC99'
// }e
},
data: vv.list.map((vvs: any) => {
aar.push(vvs.statisticalData)
return vvs.statisticalData
}),
smooth: true, // 这里设置平滑曲线
symbol: 'none' // 设置为 'none' 去掉折点小圆
})
//legend数据
item.echartsData.options.legend.data.push(vv.phase + '相')
})
let [min, max] = yMethod(aar)
item.echartsData.options.yAxis.max = max
item.echartsData.options.yAxis.min = min
})
return
params.value.list = []
searchForm.value.index.map((item: any) => {
params.value.list.push({ statisticalId: item })
})
// 查询谐波频谱
getDeviceHarmonicSpectrumData(params.value).then(res => {
res.data.length > 3 ? (height = mainHeight(275, 3).height) : (height = mainHeight(275, res.data.length).height)
chartsList.value = res.data
//数据根据相别组装成新数组
chartsList.value.map((item: any) => {
item.countList = []
item.thdDataVOS = item.thdDataVOS.reduce((acc: any, current: any) => {
const existing = acc.find((redu: any) => redu.phase == current.phase)
if (existing) {
existing.list.push(current)
} else {
acc.push({
phase: current.phase,
list: [current]
})
}
return acc
}, [])
return
})
//循环渲染图表
chartsList.value &&
chartsList.value.map((item: any, index: any) => {
const refName = setChildRef(index)
childRefs[refName] = ref(null) // 初始化ref
item.echartsData = {
options: {
title: [
{
left: '10%',
top: 0
// text: item.showName
}
],
// grid: {
// top: '16%',
// bottom: '15%', //也可设置left和right设置距离来控制图表的大小
// left: '3%',
// right: '4%'
// },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
show: false
}
}
},
legend: {
data: [],
top: '2%',
right: '2%'
},
xAxis: {
name: '时间',
data: [],
axisLine: {
show: true, //隐藏X轴轴线
lineStyle: {
color: '#000'
}
},
axisTick: {
show: true //隐藏X轴刻度
},
axisPointer: {
type: 'shadow'
},
axisLabel: {
show: true,
textStyle: {
color: '#000' //X轴文字颜色
}
},
boundaryGap: false
},
yAxis: {
type: 'value',
name:
item.thdDataVOS.length != 0 &&
item.thdDataVOS[0].list &&
item.thdDataVOS[0].list[0].unit,
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000'
}
},
splitNumber: 5,
minInterval: 1
},
series: []
}
}
//横轴数据
item.echartsData.options.xAxis.data =
item.thdDataVOS.length != 0 &&
item.thdDataVOS[0].list &&
item.thdDataVOS[0].list.map((ss: any) => {
return ss.frequency + '次'
})
let aar: any = []
//y轴数据
item.thdDataVOS.map((vv: any) => {
item.echartsData.options.series.push({
name: vv.phase + '相',
type: 'line',
barMaxWidth: 24, //使用的 y 轴的 index在单个图表实例中存在多个 y轴的时候有用
itemStyle: {
// normal: {
barBorderRadius: [3, 3, 0, 0]
// color: '#00CC99'
// }e
},
data: vv.list.map((vvs: any) => {
aar.push(vvs.statisticalData)
return vvs.statisticalData
}),
smooth: true, // 这里设置平滑曲线
symbol: 'none' // 设置为 'none' 去掉折点小圆
})
//legend数据
item.echartsData.options.legend.data.push(vv.phase + '相')
})
let [min, max] = yMethod(aar)
item.echartsData.options.yAxis.max = max
item.echartsData.options.yAxis.min = min
})
loading.value = false
})
}
watch(
() => searchForm.value.index,
(val: any, oldval: any) => {
if (val && val.length != 0) {
// init()
}
},
{
deep: true,
immediate: true
}
)
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;
// padding-bottom: 200px;
.harmonic_body_charts {
// margin: 15px 0;
border: 1px solid #eee;
position: relative;
.charts_title {
position: absolute;
top: 10px;
left: 10%;
font-size: 18px;
font-weight: 800;
}
}
}
}
</style>