代码提交

This commit is contained in:
name
2025-09-25 13:32:47 +08:00
parent 63022ffecd
commit 66b650750a
132 changed files with 35432 additions and 0 deletions

View File

@@ -0,0 +1,311 @@
// 辅助函数
const getMax = (temp, tempA, tempB, tempC) => {
temp = temp > tempA ? temp : tempA;
temp = temp > tempB ? temp : tempB;
if (tempC !== undefined) {
temp = temp > tempC ? temp : tempC;
}
return temp;
};
const getMaxTwo = (temp, tempA, tempB) => {
temp = temp > tempA ? temp : tempA;
temp = temp > tempB ? temp : tempB;
return temp;
};
const getMin = (temp, tempA, tempB, tempC) => {
temp = temp < tempA ? temp : tempA;
temp = temp < tempB ? temp : tempB;
if (tempC !== undefined) {
temp = temp < tempC ? temp : tempC;
}
return temp;
};
const getMinOpen = (temp, tempA, tempB) => {
temp = temp < tempA ? temp : tempA;
temp = temp < tempB ? temp : tempB;
return temp;
};
// 数据处理函数
const fliteWaveData = (wp, step, iphasicValue, isOpen) => {
const rmsData = wp.listRmsData;
const pt = Number(wp.pt) / 1000;
const ct = Number(wp.ct);
const titleList = wp.waveTitle;
let xishu = pt;
let aTitle = "",
bTitle = "",
cTitle = "",
unit = "电压";
let rmsvFirstX = 0,
rmsvFirstY = 0,
rmsvSecondX = 0,
rmsvSecondY = 0,
firstZhou = "a",
secondeZhou = "a";
let ifmax = 0,
ifmin = 0,
ismax = 0,
ismin = 0,
rfmax = 0,
rfmin = 0,
rsmax = 0,
rsmin = 0;
const shunshiFA = [];
const shunshiFB = [];
const shunshiFC = [];
const shunshiSA = [];
const shunshiSB = [];
const shunshiSC = [];
const rmsFA = [];
const rmsFB = [];
const rmsFC = [];
const rmsSA = [];
const rmsSB = [];
const rmsSC = [];
if (titleList[iphasicValue * step + 1]?.substring(0, 1) !== "U") {
xishu = ct;
unit = "电流";
}
for (let i = 1; i <= iphasicValue; i++) {
switch (i) {
case 1:
aTitle = titleList[iphasicValue * step + i]?.substring(1) || "";
break;
case 2:
bTitle = titleList[iphasicValue * step + i]?.substring(1) || "";
break;
case 3:
cTitle = titleList[iphasicValue * step + i]?.substring(1) || "";
break;
}
}
if (rmsData[0] && rmsData[0][iphasicValue * step + 1] !== undefined) {
rfmax = rmsData[0][iphasicValue * step + 1] * xishu;
rfmin = rmsData[0][iphasicValue * step + 1] * xishu;
rmsvFirstY = rmsData[0][iphasicValue * step + 1] * xishu;
rmsvFirstX = rmsData[0][0];
rsmax = rmsData[0][iphasicValue * step + 1];
rsmin = rmsData[0][iphasicValue * step + 1];
rmsvSecondY = rmsData[0][iphasicValue * step + 1];
rmsvSecondX = rmsData[0][0];
}
for (let rms = 0; rms < rmsData.length; rms++) {
if (!rmsData[rms] || rmsData[rms][iphasicValue * step + 1] === undefined) {
break;
}
switch (iphasicValue) {
case 1:
const rmsFirstA = rmsData[rms][iphasicValue * step + 1] * xishu;
rmsFA.push([rmsData[rms][0], rmsFirstA]);
rfmax = rfmax > rmsFirstA ? rfmax : rmsFirstA;
rfmin = rfmin < rmsFirstA ? rfmin : rmsFirstA;
if (rfmin < rmsvFirstY) {
rmsvFirstY = rfmin;
firstZhou = "a";
rmsvFirstX = rmsData[rms][0];
}
const rmsSecondA = rmsData[rms][iphasicValue * step + 1];
rmsSA.push([rmsData[rms][0], rmsSecondA]);
rsmax = rsmax > rmsSecondA ? rsmax : rmsSecondA;
rsmin = rsmin < rmsSecondA ? rsmin : rmsSecondA;
if (rsmin < rmsvSecondY) {
rmsvSecondY = rsmin;
secondeZhou = "a";
rmsvSecondX = rmsData[rms][0];
}
break;
case 2:
const rmsFirstA2 = rmsData[rms][iphasicValue * step + 1] * xishu;
const rmsFirstB2 = rmsData[rms][iphasicValue * step + 2] * xishu;
rmsFA.push([rmsData[rms][0], rmsFirstA2]);
rmsFB.push([rmsData[rms][0], rmsFirstB2]);
rfmax = getMaxTwo(rfmax, rmsFirstA2, rmsFirstB2);
rfmin = getMinOpen(rfmin, rmsFirstA2, rmsFirstB2);
if (rfmin < rmsvFirstY) {
rmsvFirstY = rfmin;
if (rfmin === rmsFirstA2) {
firstZhou = "a";
} else if (rfmin === rmsFirstB2) {
firstZhou = "b";
}
rmsvFirstX = rmsData[rms][0];
}
const rmsSecondA2 = rmsData[rms][iphasicValue * step + 1];
const rmsSecondB2 = rmsData[rms][iphasicValue * step + 2];
rmsSA.push([rmsData[rms][0], rmsSecondA2]);
rmsSB.push([rmsData[rms][0], rmsSecondB2]);
rsmax = getMaxTwo(rsmax, rmsSecondA2, rmsSecondB2);
rsmin = getMinOpen(rsmin, rmsSecondA2, rmsSecondB2);
if (rsmin < rmsvSecondY) {
rmsvSecondY = rsmin;
if (rsmin === rmsSecondA2) {
secondeZhou = "a";
} else if (rsmin === rmsSecondB2) {
secondeZhou = "b";
}
rmsvSecondX = rmsData[rms][0];
}
break;
case 3:
const rmsFirstA3 = rmsData[rms][iphasicValue * step + 1] * xishu;
const rmsFirstB3 = rmsData[rms][iphasicValue * step + 2] * xishu;
const rmsFirstC3 = rmsData[rms][iphasicValue * step + 3] * xishu;
rmsFA.push([rmsData[rms][0], rmsFirstA3]);
rmsFB.push([rmsData[rms][0], rmsFirstB3]);
rmsFC.push([rmsData[rms][0], rmsFirstC3]);
rfmax = getMax(rfmax, rmsFirstA3, rmsFirstB3, rmsFirstC3);
rfmin = isOpen
? getMinOpen(rfmin, rmsFirstA3, rmsFirstC3)
: getMin(rfmin, rmsFirstA3, rmsFirstB3, rmsFirstC3);
if (rfmin < rmsvFirstY) {
rmsvFirstY = rfmin;
if (rfmin === rmsFirstA3) {
firstZhou = "a";
} else if (rfmin === rmsFirstB3) {
firstZhou = "b";
} else {
firstZhou = "c";
}
rmsvFirstX = rmsData[rms][0];
}
const rmsSecondA3 = rmsData[rms][iphasicValue * step + 1];
const rmsSecondB3 = rmsData[rms][iphasicValue * step + 2];
const rmsSecondC3 = rmsData[rms][iphasicValue * step + 3];
rmsSA.push([rmsData[rms][0], rmsSecondA3]);
rmsSB.push([rmsData[rms][0], rmsSecondB3]);
rmsSC.push([rmsData[rms][0], rmsSecondC3]);
rsmax = getMax(rsmax, rmsSecondA3, rmsSecondB3, rmsSecondC3);
rsmin = isOpen
? getMinOpen(rsmin, rmsSecondA3, rmsSecondC3)
: getMin(rsmin, rmsSecondA3, rmsSecondB3, rmsSecondC3);
if (rsmin < rmsvSecondY) {
rmsvSecondY = rsmin;
if (rsmin === rmsSecondA3) {
secondeZhou = "a";
} else if (rsmin === rmsSecondB3) {
secondeZhou = "b";
} else {
secondeZhou = "c";
}
rmsvSecondX = rmsData[rms][0];
}
break;
}
}
const instantF = { max: ifmax, min: ifmin };
const instantS = { max: ismax, min: ismin };
const RMSF = { max: rfmax, min: rfmin };
const RMSS = { max: rsmax, min: rsmin };
const RMSFMinDetail = { rmsvFirstX, rmsvFirstY, firstZhou };
const RMSSMinDetail = { rmsvSecondX, rmsvSecondY, secondeZhou };
const shunshiF = { shunshiFA, shunshiFB, shunshiFC };
const shunshiS = { shunshiSA, shunshiSB, shunshiSC };
const RMSFWave = { rmsFA, rmsFB, rmsFC };
const RMSSWave = { rmsSA, rmsSB, rmsSC };
const title = { aTitle, bTitle, cTitle, unit };
return {
instantF,
instantS,
RMSF,
RMSS,
RMSFMinDetail,
RMSSMinDetail,
shunshiF,
shunshiS,
RMSFWave,
RMSSWave,
title,
unit,
};
};
// 监听消息
self.onmessage = function (e) {
const { wp, isOpen, value, boxoList } = JSON.parse(e.data);
try {
const iphasicValue = wp.iphasic || 1;
const picCounts = (wp.waveTitle.length - 1) / iphasicValue;
const waveDatas = [];
for (let i = 0; i < picCounts; i++) {
const data = fliteWaveData(wp, i, iphasicValue, isOpen,boxoList);
waveDatas.push(data);
}
// 处理标题
let titles = "";
if (boxoList.systemType == "pms") {
titles =
"变电站名称:" +
boxoList.powerStationName +
" 监测点名称:" +
boxoList.measurementPointName +
" 发生时刻:" +
boxoList.startTime +
" 残余电压:" +
(boxoList.featureAmplitude * 100).toFixed(2) +
"% 持续时间:" +
boxoList.duration +
"s";
} else if (boxoList.systemType == "ZL") {
titles =
" 监测点名称:" +
boxoList.equipmentName +
" 发生时刻:" +
boxoList.startTime +
" 残余电压:" +
boxoList.evtParamVVaDepth +
" 持续时间:" +
boxoList.evtParamTm +
"s";
} else {
titles =
"变电站名称:" +
boxoList.subName +
" 监测点名称:" +
boxoList.lineName +
" 发生时刻:" +
boxoList.startTime +
" 残余电压:" +
(boxoList.featureAmplitude * 100).toFixed(2) +
"% 持续时间:" +
boxoList.duration +
"s";
}
// 发送处理结果回主线程
self.postMessage({
titles: titles,
success: true,
waveDatas,
time: wp.time,
type: wp.waveType,
severity: wp.yzd,
iphasic: iphasicValue,
});
} catch (error) {
self.postMessage({
success: false,
error: error.message,
});
}
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
// waveData.worker.js
self.addEventListener('message', function(e) {
const { wp, value, iphasic, isOpen, boxoList } = JSON.parse(e.data);
// 处理波形数据的函数
const fliteWaveData = (wp, step) => {
// 将原有的fliteWaveData函数实现复制到这里
const shunData = wp.listWaveData;
const pt = Number(wp.pt) / 1000;
const ct = Number(wp.ct);
const titleList = wp.waveTitle;
let xishu = pt;
let aTitle = '', bTitle = '', cTitle = '', unit = '电压';
let ifmax = 0, ifmin = 0, ismax = 0, ismin = 0;
const shunshiFA = [];
const shunshiFB = [];
const shunshiFC = [];
const shunshiSA = [];
const shunshiSB = [];
const shunshiSC = [];
if (shunData.length > 0) {
if (titleList[iphasic * step + 1]?.substring(0, 1) !== 'U') {
xishu = ct;
unit = '电流';
}
for (let i = 1; i <= iphasic; i++) {
switch (i) {
case 1:
aTitle = titleList[iphasic * step + i]?.substring(1) || '';
break;
case 2:
bTitle = titleList[iphasic * step + i]?.substring(1) || '';
break;
case 3:
cTitle = titleList[iphasic * step + i]?.substring(1) || '';
break;
}
}
if (shunData[0][iphasic * step + 1] !== undefined) {
ifmax = shunData[0][iphasic * step + 1] * xishu;
ifmin = shunData[0][iphasic * step + 1] * xishu;
ismax = shunData[0][iphasic * step + 1];
ismin = shunData[0][iphasic * step + 1];
}
for (let shun = 0; shun < shunData.length; shun++) {
if (shunData[shun][iphasic * step + 1] === undefined) {
break;
}
switch (iphasic) {
case 1:
const shunFirstA = shunData[shun][iphasic * step + 1] * xishu;
shunshiFA.push([shunData[shun][0], shunFirstA]);
ifmax = Math.max(ifmax, shunFirstA);
ifmin = Math.min(ifmin, shunFirstA);
const shunSecondA = shunData[shun][iphasic * step + 1];
shunshiSA.push([shunData[shun][0], shunSecondA]);
ismax = Math.max(ismax, shunSecondA);
ismin = Math.min(ismin, shunSecondA);
break;
case 2:
const shunFirstA2 = shunData[shun][iphasic * step + 1] * xishu;
const shunFirstB2 = shunData[shun][iphasic * step + 2] * xishu;
shunshiFA.push([shunData[shun][0], shunFirstA2]);
shunshiFB.push([shunData[shun][0], shunFirstB2]);
ifmax = Math.max(ifmax, shunFirstA2, shunFirstB2);
ifmin = Math.min(ifmin, shunFirstA2, shunFirstB2);
const shunSecondA2 = shunData[shun][iphasic * step + 1];
const shunSecondB2 = shunData[shun][iphasic * step + 2];
shunshiSA.push([shunData[shun][0], shunSecondA2]);
shunshiSB.push([shunData[shun][0], shunSecondB2]);
ismax = Math.max(ismax, shunSecondA2, shunSecondB2);
ismin = Math.min(ismin, shunSecondA2, shunSecondB2);
break;
case 3:
const shunFirstA3 = shunData[shun][iphasic * step + 1] * xishu;
const shunFirstB3 = shunData[shun][iphasic * step + 2] * xishu;
const shunFirstC3 = shunData[shun][iphasic * step + 3] * xishu;
shunshiFA.push([shunData[shun][0], shunFirstA3]);
shunshiFB.push([shunData[shun][0], shunFirstB3]);
shunshiFC.push([shunData[shun][0], shunFirstC3]);
ifmax = Math.max(ifmax, shunFirstA3, shunFirstB3, shunFirstC3);
ifmin = isOpen ? Math.min(ifmin, shunFirstA3, shunFirstC3) : Math.min(ifmin, shunFirstA3, shunFirstB3, shunFirstC3);
const shunSecondA3 = shunData[shun][iphasic * step + 1];
const shunSecondB3 = shunData[shun][iphasic * step + 2];
const shunSecondC3 = shunData[shun][iphasic * step + 3];
shunshiSA.push([shunData[shun][0], shunSecondA3]);
shunshiSB.push([shunData[shun][0], shunSecondB3]);
shunshiSC.push([shunData[shun][0], shunSecondC3]);
ismax = Math.max(ismax, shunSecondA3, shunSecondB3, shunSecondC3);
ismin = isOpen ? Math.min(ismin, shunSecondA3, shunSecondC3) : Math.min(ismin, shunSecondA3, shunSecondB3, shunSecondC3);
break;
}
}
}
const instantF = { max: ifmax, min: ifmin };
const instantS = { max: ismax, min: ismin };
const shunshiF = { shunshiFA, shunshiFB, shunshiFC };
const shunshiS = { shunshiSA, shunshiSB, shunshiSC };
const title = { aTitle, bTitle, cTitle, unit };
return { instantF, instantS, shunshiF, shunshiS, title, unit };
};
// 处理标题
let titles = '';
if (boxoList.systemType == 'pms') {
titles = '变电站名称:' +
boxoList.powerStationName +
' 监测点名称:' +
boxoList.measurementPointName +
' 发生时刻:' +
boxoList.startTime +
' 残余电压:' +
(boxoList.featureAmplitude * 100).toFixed(2) +
'% 持续时间:' +
boxoList.duration +
's';
} else if (boxoList.systemType == 'ZL') {
titles = ' 监测点名称:' +
boxoList.equipmentName +
' 发生时刻:' +
boxoList.startTime +
' 残余电压:' +
boxoList.evtParamVVaDepth +
' 持续时间:' +
boxoList.evtParamTm +
's';
} else {
titles = '变电站名称:' +
boxoList.subName +
' 监测点名称:' +
boxoList.lineName +
' 发生时刻:' +
boxoList.startTime +
' 残余电压:' +
(boxoList.featureAmplitude * 100).toFixed(2) +
'% 持续时间:' +
boxoList.duration +
's';
}
const iphasicValue = wp.iphasic || 1;
const picCounts = (wp.waveTitle.length - 1) / iphasicValue;
const waveDatas = [];
for (let i = 0; i < picCounts; i++) {
const data = fliteWaveData(wp, i);
waveDatas.push(data);
}
const time = wp.time;
const type = wp.waveType;
let severity = wp.yzd;
if (severity < 0) {
severity = '/';
type = '/';
}
// 将处理结果发送回主线程
self.postMessage({
waveDatas,
time,
type,
severity,
titles,
iphasic: iphasicValue
});
});

View File

@@ -0,0 +1,863 @@
<template>
<div v-loading="loading" :element-loading-background="'rgba(122, 122, 122, 0.8)'" class="boxbx"
style="position: relative;height: 100%;">
<div id="boxsj" style="background: #343849c7">
<div id="shushi" :style="`height:${vh};overflow: hidden;`">
<div class="bx" id="wave"></div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import html2canvas from 'html2canvas'
import $ from 'jquery'
import * as echarts from 'echarts'
import url from '@/assets/img/point.png'
// 创建Worker
let waveDataWorker: Worker | null = null;
interface WaveData {
instantF: { max: number; min: number }
instantS: { max: number; min: number }
shunshiF: {
shunshiFA: number[][]
shunshiFB: number[][]
shunshiFC: number[][]
}
shunshiS: {
shunshiSA: number[][]
shunshiSB: number[][]
shunshiSC: number[][]
}
title: {
aTitle: string
bTitle: string
cTitle: string
unit: string
}
unit: string
}
interface Props {
value?: number
flag?: string | number | boolean
parentHeight?: string | number | boolean
DColor?: boolean
boxoList?: any
wp?: any
}
const props = withDefaults(defineProps<Props>(), {
value: 2,
flag: 3,
parentHeight: 0,
DColor: false,
boxoList: () => ({}),
wp: () => ({})
})
const loading = ref(true)
const tabvalue = ref(props.value)
const valA: any = ref(0)
const valB: any = ref(0)
const isOpen = ref(false)
const time = ref('')
const type = ref('')
const severity: any = ref('')
const iphasic: any = ref('')
const eventValue = ref('')
const persistTime = ref('')
const lineName = ref('')
const subName = ref('')
const waveDatas = ref<WaveData[]>([])
const ptpass = ref('')
const waveHeight = ref<number>()
const rmsHeight = ref<number>()
const color = ref('#006565')
const charts = ref({})
const arrpoints = ref([])
const titles = ref('')
const zoom = ref(1)
const myChartess = ref<echarts.ECharts | null>(null)
const myChartess1 = ref<echarts.ECharts | null>(null)
const myChartess2 = ref<echarts.ECharts | null>(null)
const myChartess3 = ref<echarts.ECharts | null>(null)
const myChartess4 = ref<echarts.ECharts | null>(null)
const myChartess5 = ref<echarts.ECharts | null>(null)
const vh = computed(() => {
if (props.flag == 1) {
return '690px'
} else if (props.parentHeight != 0) {
return '310px'
} else {
return '350px'
}
})
const vw = computed(() => '100%')
watch(() => props.value, (newVal) => {
if (newVal == 2) {
initWaves()
} else {
$('#wave1').remove()
initWaves()
}
})
onMounted(() => {
const zoomValue = document.body.style.getPropertyValue('zoom');
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
window.addEventListener('resize', handleResize)
nextTick(() => {
setTimeout(() => {
query()
}, 500)
})
})
onBeforeUnmount(() => {
console.log('组件卸载');
if (waveDataWorker) {
waveDataWorker.terminate();
waveDataWorker = null;
}
backbxlb();
window.removeEventListener('resize', handleResize);
})
const handleResize = () => {
const zoomValue = document.body.style.getPropertyValue('zoom');
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
}
const download = () => {
const boxsj = document.getElementById('boxsj')
if (boxsj) {
html2canvas(boxsj, {
scale: 2,
}).then(function (canvas) {
const creatIMg = document.createElement('a')
creatIMg.download = '瞬间波形.png'
creatIMg.href = canvas.toDataURL()
creatIMg.click()
creatIMg.remove()
})
}
}
const query = () => {
loading.value = true
initWaves()
}
const waveData = (instantF: any, instantS: any, shunshiF: any, shunshiS: any, title: any, unit: any): WaveData => {
return {
instantF,
instantS,
shunshiF,
shunshiS,
title,
unit
}
}
// 在组件中修改initWaves函数
const initWaves = () => {
if (props.wp) {
loading.value = true;
iphasic.value = props.wp.iphasic || 1
// 使用Web Worker处理数据
if (!waveDataWorker) {
waveDataWorker = new Worker(new URL('./shuWorker.js', import.meta.url));
waveDataWorker.onmessage = function (e) {
const data = e.data;
titles.value = data.titles;
iphasic.value = data.iphasic;
time.value = data.time;
type.value = data.type;
severity.value = data.severity;
initWave(data.waveDatas, data.time, data.type, data.severity, isOpen.value);
loading.value = false;
};
waveDataWorker.onerror = function (error) {
console.error('Worker error:', error);
loading.value = false;
// 备用方案:在主线程处理数据
// processDataInMainThread();
};
}
// 发送数据到Worker
waveDataWorker.postMessage(JSON.stringify({
wp: props.wp,
value: props.value,
iphasic: iphasic.value,
isOpen: isOpen.value,
boxoList: props.boxoList
}));
} else {
initWave(null, null, null, null, null);
}
}
const initWave = (waveDatas: WaveData[] | null, time: string | null, type: string | null, severity: string | null, isOpen: boolean | null) => {
$('div.bx1').remove()
let picHeight = vh.value
const show = !isOpen
let isvisible = false
let cu: number[][] = []
let titleText = ''
let unit = ''
let max: any = 0, min: any = 0
let a: string | null = null, b: string | null = null, c: string | null = null
let adata: number[][] = [], bdata: number[][] = [], cdata: number[][] = []
const colors: string[] = []
if (!waveDatas) {
titleText = '该事件暂无波形图'
} else if (waveDatas.length > 0) {
titleText = titles.value
if (Number(eventValue.value) <= 90) {
isvisible = true
}
switch (iphasic.value) {
case 1:
a = waveDatas[0].title.aTitle
if (props.value === 1) {
cu = [[0, waveDatas[0].instantF.min]]
max = waveDatas[0].instantF.max
min = waveDatas[0].instantF.min
adata = waveDatas[0].shunshiF.shunshiFA
} else {
cu = [[0, waveDatas[0].instantS.min]]
max = waveDatas[0].instantS.max
min = waveDatas[0].instantS.min
adata = waveDatas[0].shunshiS.shunshiSA
}
colors.push('#DAA520', '#fff', '#fff')
break
case 2:
a = waveDatas[0].title.aTitle
b = waveDatas[0].title.bTitle
if (props.value === 1) {
cu = [[0, waveDatas[0].instantF.min]]
max = waveDatas[0].instantF.max
min = waveDatas[0].instantF.min
adata = waveDatas[0].shunshiF.shunshiFA
bdata = waveDatas[0].shunshiF.shunshiFB
} else {
cu = [[0, waveDatas[0].instantS.min]]
max = waveDatas[0].instantS.max
min = waveDatas[0].instantS.min
adata = waveDatas[0].shunshiS.shunshiSA
bdata = waveDatas[0].shunshiS.shunshiSB
}
colors.push('#DAA520', '#2E8B57', '#fff')
break
case 3:
a = waveDatas[0].title.aTitle
b = waveDatas[0].title.bTitle
c = waveDatas[0].title.cTitle
if (props.value === 1) {
cu = [[0, waveDatas[0].instantF.min]]
max = waveDatas[0].instantF.max
min = waveDatas[0].instantF.min
adata = waveDatas[0].shunshiF.shunshiFA
bdata = waveDatas[0].shunshiF.shunshiFB
cdata = waveDatas[0].shunshiF.shunshiFC
} else {
cu = [[0, waveDatas[0].instantS.min]]
max = waveDatas[0].instantS.max
min = waveDatas[0].instantS.min
adata = waveDatas[0].shunshiS.shunshiSA
bdata = waveDatas[0].shunshiS.shunshiSB
cdata = waveDatas[0].shunshiS.shunshiSC
}
colors.push('#DAA520', '#2E8B57', '#A52a2a')
break
}
if (waveDatas[0].title.unit === '电压') {
unit = props.value === 1 ? 'kV' : 'V'
} else {
unit = 'A'
}
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
const waveId = 'wave' + step
const newDivShunshi = $(`<div style="height:${vh.value};overflow: hidden;">
<div class='bx1' id='${waveId}'></div>
</div>`)
newDivShunshi.insertAfter($('#shushi'))
$(`#${waveId}`).css('height', picHeight).css('width', vw.value)
}
} else {
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 残余电压:${(Number(eventValue.value) * 1).toFixed(0)}% 持续时间:${persistTime.value}s`
}
const wave = document.getElementById('wave')
if (!wave) return
const myChartes = echarts.init(wave)
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
setTimeout(() => {
wave.style.width = '100%'
wave.style.height = vh.value
}, 0)
const option = {
tooltip: {
top: '10px',
trigger: 'axis',
borderColor: 'grey',
style: {
color: '#fff',
fontSize: '15px',
padding: 10
},
formatter: function (params: any) {
let tips = '时刻:' + params[0].data[0] + '</br/>'
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName != '暂降触发点') {
tips += params[i].marker + params[i].seriesName + ':' + (params[i].value[1] - 0).toFixed(2) + '<br/>'
}
}
return tips
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.55)',
borderWidth: 0
},
title: {
left: 'center',
text: titleText,
textStyle: {
fontSize: '0.8rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
}
},
legend: {
right: 50,
top: 25,
verticalAlign: 'top',
enabled: true,
itemDistance: 5,
textStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
rich: { a: { verticalAlign: 'middle' } },
padding: [0, 0, 0, 0]
}
},
toolbox: {
right: 20,
top: 15,
feature: {
myCustomDownload: {
title: '',
icon: 'path://M892.342857 463.238095l-73.142857-68.266666-258.438095 258.438095V29.257143h-97.52381v624.152381L204.8 394.971429 131.657143 463.238095l380.342857 380.342857zM107.27619 897.219048h804.571429v97.523809H107.27619z',
onclick: () => download()
}
}
},
xAxis: {
type: 'value',
name: '时间\n(ms)',
boundaryGap: false,
min: props.wp?.listWaveData[0][0] || 0,
max: props.wp?.listWaveData[props.wp?.listWaveData.length - 1][0] + 1 || 1,
title: {
text: 'ms',
textStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
},
enabled: true,
align: 'high'
},
splitLine: { show: false },
nameTextStyle: { fontSize: '0.6rem' },
axisTick: { alignWithLabel: true },
axisLine: {
lineStyle: {
color: props.DColor ? '#fff' : echartsColor.thread
},
onZero: false
},
axisLabel: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
formatter: function (value: number) {
if (valA.value != (value - 0).toFixed(0)) {
valA.value = Number((value - 0).toFixed(0))
return (value - 0).toFixed(0)
}
return ''
}
}
},
yAxis: {
type: 'value',
name: unit,
title: {
align: 'high',
offset: 0,
text: unit,
rotation: 0,
y: -10
},
boundaryGap: [0, '100%'],
showLastLabel: true,
max: max.toFixed(2) * 1.1,
min: min.toFixed(2) > 0 ? min.toFixed(2) - min.toFixed(2) * 0.1 : min.toFixed(2) * 1.1,
opposite: false,
nameTextStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
},
axisLine: {
show: true,
lineStyle: {
color: props.DColor ? '#fff' : echartsColor.thread
},
onZero: false
},
axisLabel: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
formatter: function (value: number) {
return (value - 0).toFixed(2)
}
},
splitLine: {
lineStyle: {
color: [props.DColor ? '#fff' : echartsColor.thread],
type: 'dashed',
opacity: 0.5
}
}
},
grid: {
left: '1%',
right: '2.8%',
bottom: '40px',
top: '70px',
containLabel: true
},
dataZoom: [
{
type: 'inside',
height: 13,
start: 0,
bottom: '20px',
end: 100
},
{
start: 0,
height: 13,
bottom: '20px',
end: 100
}
],
series: [
{
name: a,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#DAA520' },
data: adata
},
{
name: b,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#2E8B57' },
data: bdata
},
{
name: c,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#A52a2a' },
data: cdata
},
{
name: '暂降触发点',
type: 'scatter',
symbol: 'image://' + url,
itemStyle: { width: 18, height: 18 },
data: cu
}
]
}
myChartes.setOption(option)
myChartess.value = myChartes
setTimeout(() => {
myChartes.resize()
loading.value = false
}, 400)
if (waveDatas && waveDatas.length > 1) {
const waveDatasTemp = waveDatas.slice(1).reverse()
for (let step = 0; step < waveDatasTemp.length; step++) {
drawPics(waveDatasTemp[step], picHeight, step, show, myChartes, titleText)
}
}
}
const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show: boolean, myChartes1: echarts.ECharts, title: string) => {
step = step + 1
const waveId = 'wave' + step
let a: string | null = null, b: string | null = null, c: string | null = null
let max: any = 0, min: any = 0, unit = ''
let adata: number[][] = [], bdata: number[][] = [], cdata: number[][] = []
const colors: string[] = []
switch (iphasic.value) {
case 1:
a = waveDataTemp.title.aTitle
colors.push('#DAA520', '#fff', '#fff')
break
case 2:
a = waveDataTemp.title.aTitle
b = waveDataTemp.title.bTitle
colors.push('#DAA520', '#2E8B57', '#fff')
break
case 3:
a = waveDataTemp.title.aTitle
b = waveDataTemp.title.bTitle
c = waveDataTemp.title.cTitle
colors.push('#DAA520', '#2E8B57', '#A52a2a')
break
}
if (props.value === 1) {
max = waveDataTemp.instantF.max
min = waveDataTemp.instantF.min
adata = waveDataTemp.shunshiF.shunshiFA
bdata = waveDataTemp.shunshiF.shunshiFB
cdata = waveDataTemp.shunshiF.shunshiFC
} else {
max = waveDataTemp.instantS.max
min = waveDataTemp.instantS.min
adata = waveDataTemp.shunshiS.shunshiSA
bdata = waveDataTemp.shunshiS.shunshiSB
cdata = waveDataTemp.shunshiS.shunshiSC
}
if (waveDataTemp.title.unit === '电压') {
unit = props.value === 1 ? 'kV' : 'V'
} else {
unit = 'A'
}
let titlename = ''
if (props.boxoList.systemType == 'ZL') {
const str = waveId.split('e')
const str1 = Number(str[1])
props.wp.channelNames.forEach((element: string, i: number) => {
if (i == 4 || i == 7 || i == 10) {
if (str1 == 1 && i == 4) {
const s = element.split('A')
const s1 = s[0] == 'LI' ? '电网侧-电流' : s[0] + '侧' + s[1]
titlename = s1 + ' ' + title
}
if (str1 == 2 && i == 7) {
const s = element.split('A')
const s1 = s[0] == 'SU' ? '负载侧-电压' : s[0] + '侧' + s[1]
titlename = s1 + ' ' + title
}
if (str1 == 3 && i == 10) {
const s = element.split('A')
const s1 = s[0] == 'SI' ? '负载侧-电流' : s[0] + '侧' + s[1]
titlename = s1 + ' ' + title
}
}
})
}
const waveIds = document.getElementById(waveId)
if (!waveIds) return
const myChartes = echarts.init(waveIds)
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
const option = {
tooltip: {
trigger: 'axis',
borderColor: 'grey',
formatter: function (params: any) {
let tips = '时刻:' + params[0].data[0] + '</br/>'
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName != '暂降触发点') {
tips += params[i].seriesName + ':' + (params[i].value[1] - 0).toFixed(2) + '<br/>'
}
}
return tips
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.55)',
borderWidth: 0
},
title: {
left: 'center',
text: titlename || title,
textStyle: {
fontSize: '0.8rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
}
},
legend: {
right: 50,
top: 25,
verticalAlign: 'top',
enabled: true,
itemDistance: 5,
textStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
rich: { a: { verticalAlign: 'middle' } },
padding: [0, 0, 0, 0]
}
},
xAxis: {
type: 'value',
name: '时间\n(ms)',
boundaryGap: false,
min: props.wp.listWaveData[0][0],
max: props.wp.listWaveData[props.wp.listWaveData.length - 1][0] + 1,
title: {
text: 'ms',
textStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
},
enabled: true,
align: 'high'
},
splitLine: { show: false },
axisTick: { alignWithLabel: true },
axisLine: {
lineStyle: {
color: props.DColor ? '#fff' : echartsColor.thread
},
onZero: false
},
nameTextStyle: { fontSize: '0.6rem' },
axisLabel: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
formatter: function (value: number) {
if (valB.value != (value - 0).toFixed(0)) {
valB.value = Number((value - 0).toFixed(0))
return (value - 0).toFixed(0)
}
return ''
}
}
},
yAxis: {
type: 'value',
name: unit,
title: {
align: 'high',
offset: 0,
text: unit,
rotation: 0,
y: -10
},
boundaryGap: [0, '100%'],
showLastLabel: true,
max: max.toFixed(2) * 1.1,
min: min.toFixed(2) > 0 ? min.toFixed(2) - min.toFixed(2) * 0.1 : min.toFixed(2) * 1.1,
opposite: false,
nameTextStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
},
axisLine: {
show: true,
lineStyle: {
color: props.DColor ? '#fff' : echartsColor.thread
},
onZero: false
},
axisLabel: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
formatter: function (value: number) {
return (value - 0).toFixed(2)
}
},
splitLine: {
lineStyle: {
color: [props.DColor ? '#fff' : echartsColor.thread],
type: 'dashed',
opacity: 0.5
}
}
},
grid: {
left: '1%',
right: '2.8%',
bottom: '40px',
top: '70px',
containLabel: true
},
dataZoom: [
{
type: 'inside',
height: 13,
start: 0,
bottom: '20px',
end: 100
},
{
start: 0,
height: 13,
bottom: '20px',
end: 100
}
],
series: [
{
name: a,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#DAA520' },
data: adata
},
{
name: b,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#2E8B57' },
data: bdata
},
{
name: c,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#A52a2a' },
data: cdata
}
]
}
myChartes.setOption(option)
switch (step) {
case 1: myChartess1.value = myChartes; break
case 2: myChartess2.value = myChartes; break
case 3: myChartess3.value = myChartes; break
case 4: myChartess4.value = myChartes; break
case 5: myChartess5.value = myChartes; break
}
setTimeout(() => {
myChartes.resize()
loading.value = false
}, 400)
echarts.connect([myChartes1, myChartes])
}
const backbxlb = () => {
waveDatas.value = []
const charts = [myChartess.value, myChartess1.value, myChartess2.value, myChartess3.value, myChartess4.value, myChartess5.value]
charts.forEach(chart => {
if (chart) {
chart.dispose()
}
})
myChartess.value = null
myChartess1.value = null
myChartess2.value = null
myChartess3.value = null
myChartess4.value = null
myChartess5.value = null
// echarts.disconnect(charts.filter(Boolean) as echarts.ECharts[])
charts
.filter(Boolean)
.forEach(chart => {
if (chart && typeof chart.dispose === 'function') {
chart.dispose();
}
});
}
const getMax = (temp: number, tempA: number, tempB: number, tempC: number): number => {
temp = temp > tempA ? temp : tempA
temp = temp > tempB ? temp : tempB
temp = temp > tempC ? temp : tempC
return temp
}
const getMaxTwo = (temp: number, tempA: number, tempB: number): number => {
temp = temp > tempA ? temp : tempA
temp = temp > tempB ? temp : tempB
return temp
}
const getMin = (temp: number, tempA: number, tempB: number, tempC: number): number => {
temp = temp < tempA ? temp : tempA
temp = temp < tempB ? temp : tempB
temp = temp < tempC ? temp : tempC
return temp
}
const getMinOpen = (temp: number, tempA: number, tempB: number): number => {
temp = temp < tempA ? temp : tempA
temp = temp < tempB ? temp : tempB
return temp
}
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,984 @@
<template>
<div v-loading="loading" :element-loading-background="'rgba(122, 122, 122, 0.8)'" class="boxbx"
style="position: relative;height: 100%;">
<div id="boxsj" style="background: #343849c7">
<div id="shushi" :style="`height:${vh};overflow: hidden;`">
<div class="bx" id="wave"></div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import html2canvas from 'html2canvas'
import $ from 'jquery'
import * as echarts from 'echarts'
import url from '@/assets/img/point.png'
interface WaveData {
instantF: { max: number; min: number }
instantS: { max: number; min: number }
shunshiF: {
shunshiFA: number[][]
shunshiFB: number[][]
shunshiFC: number[][]
}
shunshiS: {
shunshiSA: number[][]
shunshiSB: number[][]
shunshiSC: number[][]
}
title: {
aTitle: string
bTitle: string
cTitle: string
unit: string
}
unit: string
}
interface Props {
value?: number
flag?: string | number | boolean
parentHeight?: string | number | boolean
DColor?: boolean
boxoList?: any
wp?: any
}
const props = withDefaults(defineProps<Props>(), {
value: 2,
flag: 3,
parentHeight: 0,
DColor: false,
boxoList: () => ({}),
wp: () => ({})
})
const loading = ref(true)
const tabvalue = ref(props.value)
const valA: any = ref(0)
const valB: any = ref(0)
const isOpen = ref(false)
const time = ref('')
const type = ref('')
const severity: any = ref('')
const iphasic: any = ref('')
const eventValue = ref('')
const persistTime = ref('')
const lineName = ref('')
const subName = ref('')
const waveDatas = ref<WaveData[]>([])
const ptpass = ref('')
const waveHeight = ref<number>()
const rmsHeight = ref<number>()
const color = ref('#006565')
const charts = ref({})
const arrpoints = ref([])
const titles = ref('')
const zoom = ref(1)
const myChartess = ref<echarts.ECharts | null>(null)
const myChartess1 = ref<echarts.ECharts | null>(null)
const myChartess2 = ref<echarts.ECharts | null>(null)
const myChartess3 = ref<echarts.ECharts | null>(null)
const myChartess4 = ref<echarts.ECharts | null>(null)
const myChartess5 = ref<echarts.ECharts | null>(null)
const vh = computed(() => {
if (props.flag == 1) {
return '680px'
} else if (props.parentHeight != 0) {
return '300px'
} else {
return '340px'
}
})
const vw = computed(() => '100%')
watch(() => props.value, (newVal) => {
if (newVal == 2) {
initWaves()
} else {
$('#wave1').remove()
initWaves()
}
})
onMounted(() => {
const zoomValue = document.body.style.getPropertyValue('zoom');
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
window.addEventListener('resize', handleResize)
nextTick(() => {
setTimeout(() => {
query()
}, 500)
})
})
onBeforeUnmount(() => {
console.log('组件卸载');
backbxlb()
window.removeEventListener('resize', handleResize)
})
const handleResize = () => {
const zoomValue = document.body.style.getPropertyValue('zoom');
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
}
const download = () => {
const boxsj = document.getElementById('boxsj')
if (boxsj) {
html2canvas(boxsj, {
scale: 2,
}).then(function (canvas) {
const creatIMg = document.createElement('a')
creatIMg.download = '瞬间波形.png'
creatIMg.href = canvas.toDataURL()
creatIMg.click()
creatIMg.remove()
})
}
}
const query = () => {
loading.value = true
initWaves()
}
const waveData = (instantF: any, instantS: any, shunshiF: any, shunshiS: any, title: any, unit: any): WaveData => {
return {
instantF,
instantS,
shunshiF,
shunshiS,
title,
unit
}
}
const initWaves = () => {
if (props.wp) {
if (props.boxoList.systemType == 'pms') {
titles.value =
'变电站名称:' +
props.boxoList.powerStationName +
' 监测点名称:' +
props.boxoList.measurementPointName +
' 发生时刻:' +
props.boxoList.startTime +
' 残余电压:' +
(props.boxoList.featureAmplitude * 100).toFixed(2) +
'% 持续时间:' +
props.boxoList.duration +
's'
} else if (props.boxoList.systemType == 'ZL') {
titles.value =
' 监测点名称:' +
props.boxoList.equipmentName +
' 发生时刻:' +
props.boxoList.startTime +
' 残余电压:' +
props.boxoList.evtParamVVaDepth +
' 持续时间:' +
props.boxoList.evtParamTm +
's'
} else {
titles.value =
'变电站名称:' +
props.boxoList.subName +
' 监测点名称:' +
props.boxoList.lineName +
' 发生时刻:' +
props.boxoList.startTime +
' 残余电压:' +
(props.boxoList.featureAmplitude * 100).toFixed(2) +
'% 持续时间:' +
props.boxoList.duration +
's'
}
iphasic.value = props.wp.iphasic || 1
const picCounts = (props.wp.waveTitle.length - 1) / iphasic.value
waveDatas.value = []
for (let i = 0; i < picCounts; i++) {
const data = fliteWaveData(props.wp, i)
waveDatas.value.push(data)
}
time.value = props.wp.time
type.value = props.wp.waveType
severity.value = props.wp.yzd
if (severity.value < 0) {
severity.value = '/'
type.value = '/'
}
initWave(waveDatas.value, time.value, type.value, severity.value, isOpen.value)
} else {
initWave(null, null, null, null, null)
}
}
const fliteWaveData = (wp: any, step: number): WaveData => {
const shunData = wp.listWaveData
const pt = Number(wp.pt) / 1000
const ct = Number(wp.ct)
const titleList = wp.waveTitle
let xishu = pt
let aTitle = '', bTitle = '', cTitle = '', unit = '电压'
let ifmax = 0, ifmin = 0, ismax = 0, ismin = 0
const shunshiFA: number[][] = []
const shunshiFB: number[][] = []
const shunshiFC: number[][] = []
const shunshiSA: number[][] = []
const shunshiSB: number[][] = []
const shunshiSC: number[][] = []
if (shunData.length > 0) {
if (titleList[iphasic.value * step + 1]?.substring(0, 1) !== 'U') {
xishu = ct
unit = '电流'
}
for (let i = 1; i <= iphasic.value; i++) {
switch (i) {
case 1:
aTitle = titleList[iphasic.value * step + i]?.substring(1) || ''
break
case 2:
bTitle = titleList[iphasic.value * step + i]?.substring(1) || ''
break
case 3:
cTitle = titleList[iphasic.value * step + i]?.substring(1) || ''
break
}
}
if (shunData[0][iphasic.value * step + 1] !== undefined) {
ifmax = shunData[0][iphasic.value * step + 1] * xishu
ifmin = shunData[0][iphasic.value * step + 1] * xishu
ismax = shunData[0][iphasic.value * step + 1]
ismin = shunData[0][iphasic.value * step + 1]
}
for (let shun = 0; shun < shunData.length; shun++) {
if (shunData[shun][iphasic.value * step + 1] === undefined) {
break
}
switch (iphasic.value) {
case 1:
const shunFirstA = shunData[shun][iphasic.value * step + 1] * xishu
shunshiFA.push([shunData[shun][0], shunFirstA])
ifmax = ifmax > shunFirstA ? ifmax : shunFirstA
ifmin = ifmin < shunFirstA ? ifmin : shunFirstA
const shunSecondA = shunData[shun][iphasic.value * step + 1]
shunshiSA.push([shunData[shun][0], shunSecondA])
ismax = ismax > shunSecondA ? ismax : shunSecondA
ismin = ismin < shunSecondA ? ismin : shunSecondA
break
case 2:
const shunFirstA2 = shunData[shun][iphasic.value * step + 1] * xishu
const shunFirstB2 = shunData[shun][iphasic.value * step + 2] * xishu
shunshiFA.push([shunData[shun][0], shunFirstA2])
shunshiFB.push([shunData[shun][0], shunFirstB2])
ifmax = getMaxTwo(ifmax, shunFirstA2, shunFirstB2)
ifmin = getMinOpen(ifmin, shunFirstA2, shunFirstB2)
const shunSecondA2 = shunData[shun][iphasic.value * step + 1]
const shunSecondB2 = shunData[shun][iphasic.value * step + 2]
shunshiSA.push([shunData[shun][0], shunSecondA2])
shunshiSB.push([shunData[shun][0], shunSecondB2])
ismax = getMaxTwo(ismax, shunSecondA2, shunSecondB2)
ismin = getMinOpen(ismin, shunSecondA2, shunSecondB2)
break
case 3:
const shunFirstA3 = shunData[shun][iphasic.value * step + 1] * xishu
const shunFirstB3 = shunData[shun][iphasic.value * step + 2] * xishu
const shunFirstC3 = shunData[shun][iphasic.value * step + 3] * xishu
shunshiFA.push([shunData[shun][0], shunFirstA3])
shunshiFB.push([shunData[shun][0], shunFirstB3])
shunshiFC.push([shunData[shun][0], shunFirstC3])
ifmax = getMax(ifmax, shunFirstA3, shunFirstB3, shunFirstC3)
ifmin = isOpen.value ? getMinOpen(ifmin, shunFirstA3, shunFirstC3) : getMin(ifmin, shunFirstA3, shunFirstB3, shunFirstC3)
const shunSecondA3 = shunData[shun][iphasic.value * step + 1]
const shunSecondB3 = shunData[shun][iphasic.value * step + 2]
const shunSecondC3 = shunData[shun][iphasic.value * step + 3]
shunshiSA.push([shunData[shun][0], shunSecondA3])
shunshiSB.push([shunData[shun][0], shunSecondB3])
shunshiSC.push([shunData[shun][0], shunSecondC3])
ismax = getMax(ismax, shunSecondA3, shunSecondB3, shunSecondC3)
ismin = isOpen.value ? getMinOpen(ismin, shunSecondA3, shunSecondC3) : getMin(ismin, shunSecondA3, shunSecondB3, shunSecondC3)
break
}
}
}
const instantF = { max: ifmax, min: ifmin }
const instantS = { max: ismax, min: ismin }
const shunshiF = { shunshiFA, shunshiFB, shunshiFC }
const shunshiS = { shunshiSA, shunshiSB, shunshiSC }
const title = { aTitle, bTitle, cTitle, unit }
return waveData(instantF, instantS, shunshiF, shunshiS, title, unit)
}
const initWave = (waveDatas: WaveData[] | null, time: string | null, type: string | null, severity: string | null, isOpen: boolean | null) => {
$('div.bx1').remove()
let picHeight = vh.value
const show = !isOpen
let isvisible = false
let cu: number[][] = []
let titleText = ''
let unit = ''
let max: any = 0, min: any = 0
let a: string | null = null, b: string | null = null, c: string | null = null
let adata: number[][] = [], bdata: number[][] = [], cdata: number[][] = []
const colors: string[] = []
if (!waveDatas) {
titleText = '该事件暂无波形图'
} else if (waveDatas.length > 0) {
titleText = titles.value
if (Number(eventValue.value) <= 90) {
isvisible = true
}
switch (iphasic.value) {
case 1:
a = waveDatas[0].title.aTitle
if (props.value === 1) {
cu = [[0, waveDatas[0].instantF.min]]
max = waveDatas[0].instantF.max
min = waveDatas[0].instantF.min
adata = waveDatas[0].shunshiF.shunshiFA
} else {
cu = [[0, waveDatas[0].instantS.min]]
max = waveDatas[0].instantS.max
min = waveDatas[0].instantS.min
adata = waveDatas[0].shunshiS.shunshiSA
}
colors.push('#DAA520', '#fff', '#fff')
break
case 2:
a = waveDatas[0].title.aTitle
b = waveDatas[0].title.bTitle
if (props.value === 1) {
cu = [[0, waveDatas[0].instantF.min]]
max = waveDatas[0].instantF.max
min = waveDatas[0].instantF.min
adata = waveDatas[0].shunshiF.shunshiFA
bdata = waveDatas[0].shunshiF.shunshiFB
} else {
cu = [[0, waveDatas[0].instantS.min]]
max = waveDatas[0].instantS.max
min = waveDatas[0].instantS.min
adata = waveDatas[0].shunshiS.shunshiSA
bdata = waveDatas[0].shunshiS.shunshiSB
}
colors.push('#DAA520', '#2E8B57', '#fff')
break
case 3:
a = waveDatas[0].title.aTitle
b = waveDatas[0].title.bTitle
c = waveDatas[0].title.cTitle
if (props.value === 1) {
cu = [[0, waveDatas[0].instantF.min]]
max = waveDatas[0].instantF.max
min = waveDatas[0].instantF.min
adata = waveDatas[0].shunshiF.shunshiFA
bdata = waveDatas[0].shunshiF.shunshiFB
cdata = waveDatas[0].shunshiF.shunshiFC
} else {
cu = [[0, waveDatas[0].instantS.min]]
max = waveDatas[0].instantS.max
min = waveDatas[0].instantS.min
adata = waveDatas[0].shunshiS.shunshiSA
bdata = waveDatas[0].shunshiS.shunshiSB
cdata = waveDatas[0].shunshiS.shunshiSC
}
colors.push('#DAA520', '#2E8B57', '#A52a2a')
break
}
if (waveDatas[0].title.unit === '电压') {
unit = props.value === 1 ? 'kV' : 'V'
} else {
unit = 'A'
}
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
const waveId = 'wave' + step
const newDivShunshi = $(`<div style="height:${vh.value};overflow: hidden;">
<div class='bx1' id='${waveId}'></div>
</div>`)
newDivShunshi.insertAfter($('#shushi'))
$(`#${waveId}`).css('height', picHeight).css('width', vw.value)
}
} else {
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 残余电压:${(Number(eventValue.value) * 1).toFixed(0)}% 持续时间:${persistTime.value}s`
}
const wave = document.getElementById('wave')
if (!wave) return
const myChartes = echarts.init(wave)
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
setTimeout(() => {
wave.style.width = '100%'
wave.style.height = vh.value
}, 0)
const option = {
tooltip: {
top: '10px',
trigger: 'axis',
borderColor: 'grey',
backgroundColor: '#fff',
style: {
color: '#fff',
fontSize: '15px',
padding: 10
},
formatter: function (params: any) {
let tips = '时刻:' + params[0].data[0] + '</br/>'
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName != '暂降触发点') {
tips += params[i].marker + params[i].seriesName + ':' + (params[i].value[1] - 0).toFixed(2) + '<br/>'
}
}
return tips
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
borderWidth: 0
},
title: {
left: 'center',
text: titleText,
textStyle: {
fontSize: '0.8rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
}
},
legend: {
right: 50,
top: 25,
verticalAlign: 'top',
enabled: true,
itemDistance: 5,
textStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
rich: { a: { verticalAlign: 'middle' } },
padding: [0, 0, 0, 0]
}
},
toolbox: {
right: 20,
top: 15,
feature: {
myCustomDownload: {
title: '',
icon: 'path://M892.342857 463.238095l-73.142857-68.266666-258.438095 258.438095V29.257143h-97.52381v624.152381L204.8 394.971429 131.657143 463.238095l380.342857 380.342857zM107.27619 897.219048h804.571429v97.523809H107.27619z',
onclick: () => download()
}
}
},
xAxis: {
type: 'value',
name: '时间\n(ms)',
boundaryGap: false,
min: props.wp?.listWaveData[0][0] || 0,
max: props.wp?.listWaveData[props.wp?.listWaveData.length - 1][0] + 1 || 1,
title: {
text: 'ms',
textStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
},
enabled: true,
align: 'high'
},
splitLine: { show: false },
nameTextStyle: { fontSize: '0.6rem' },
axisTick: { alignWithLabel: true },
axisLine: {
lineStyle: {
color: props.DColor ? '#fff' : echartsColor.thread
},
onZero: false
},
axisLabel: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
formatter: function (value: number) {
if (valA.value != (value - 0).toFixed(0)) {
valA.value = Number((value - 0).toFixed(0))
return (value - 0).toFixed(0)
}
return ''
}
}
},
yAxis: {
type: 'value',
name: unit,
title: {
align: 'high',
offset: 0,
text: unit,
rotation: 0,
y: -10
},
boundaryGap: [0, '100%'],
showLastLabel: true,
max: max.toFixed(2) * 1.1,
min: min.toFixed(2) > 0 ? min.toFixed(2) - min.toFixed(2) * 0.1 : min.toFixed(2) * 1.1,
opposite: false,
nameTextStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
},
axisLine: {
show: true,
lineStyle: {
color: props.DColor ? '#fff' : echartsColor.thread
},
onZero: false
},
axisLabel: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
formatter: function (value: number) {
return (value - 0).toFixed(2)
}
},
splitLine: {
lineStyle: {
color: [props.DColor ? '#fff' : echartsColor.thread],
type: 'dashed',
opacity: 0.5
}
}
},
grid: {
left: '1%',
right: '2.8%',
bottom: '40px',
top: '70px',
containLabel: true
},
dataZoom: [
{
type: 'inside',
height: 13,
start: 0,
bottom: '20px',
end: 100
},
{
start: 0,
height: 13,
bottom: '20px',
end: 100
}
],
series: [
{
name: a,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#DAA520' },
data: adata
},
{
name: b,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#2E8B57' },
data: bdata
},
{
name: c,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#A52a2a' },
data: cdata
},
{
name: '暂降触发点',
type: 'scatter',
symbol: 'image://' + url,
itemStyle: { width: 18, height: 18 },
data: cu
}
]
}
myChartes.setOption(option)
myChartess.value = myChartes
setTimeout(() => {
myChartes.resize()
loading.value = false
}, 400)
if (waveDatas && waveDatas.length > 1) {
const waveDatasTemp = waveDatas.slice(1).reverse()
for (let step = 0; step < waveDatasTemp.length; step++) {
drawPics(waveDatasTemp[step], picHeight, step, show, myChartes, titleText)
}
}
}
const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show: boolean, myChartes1: echarts.ECharts, title: string) => {
step = step + 1
const waveId = 'wave' + step
let a: string | null = null, b: string | null = null, c: string | null = null
let max: any = 0, min: any = 0, unit = ''
let adata: number[][] = [], bdata: number[][] = [], cdata: number[][] = []
const colors: string[] = []
switch (iphasic.value) {
case 1:
a = waveDataTemp.title.aTitle
colors.push('#DAA520', '#fff', '#fff')
break
case 2:
a = waveDataTemp.title.aTitle
b = waveDataTemp.title.bTitle
colors.push('#DAA520', '#2E8B57', '#fff')
break
case 3:
a = waveDataTemp.title.aTitle
b = waveDataTemp.title.bTitle
c = waveDataTemp.title.cTitle
colors.push('#DAA520', '#2E8B57', '#A52a2a')
break
}
if (props.value === 1) {
max = waveDataTemp.instantF.max
min = waveDataTemp.instantF.min
adata = waveDataTemp.shunshiF.shunshiFA
bdata = waveDataTemp.shunshiF.shunshiFB
cdata = waveDataTemp.shunshiF.shunshiFC
} else {
max = waveDataTemp.instantS.max
min = waveDataTemp.instantS.min
adata = waveDataTemp.shunshiS.shunshiSA
bdata = waveDataTemp.shunshiS.shunshiSB
cdata = waveDataTemp.shunshiS.shunshiSC
}
if (waveDataTemp.title.unit === '电压') {
unit = props.value === 1 ? 'kV' : 'V'
} else {
unit = 'A'
}
let titlename = ''
if (props.boxoList.systemType == 'ZL') {
const str = waveId.split('e')
const str1 = Number(str[1])
props.wp.channelNames.forEach((element: string, i: number) => {
if (i == 4 || i == 7 || i == 10) {
if (str1 == 1 && i == 4) {
const s = element.split('A')
const s1 = s[0] == 'LI' ? '电网侧-电流' : s[0] + '侧' + s[1]
titlename = s1 + ' ' + title
}
if (str1 == 2 && i == 7) {
const s = element.split('A')
const s1 = s[0] == 'SU' ? '负载侧-电压' : s[0] + '侧' + s[1]
titlename = s1 + ' ' + title
}
if (str1 == 3 && i == 10) {
const s = element.split('A')
const s1 = s[0] == 'SI' ? '负载侧-电流' : s[0] + '侧' + s[1]
titlename = s1 + ' ' + title
}
}
})
}
const waveIds = document.getElementById(waveId)
if (!waveIds) return
const myChartes = echarts.init(waveIds)
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
const option = {
tooltip: {
trigger: 'axis',
borderColor: 'grey',
formatter: function (params: any) {
let tips = '时刻:' + params[0].data[0] + '</br/>'
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName != '暂降触发点') {
tips += params[i].seriesName + ':' + (params[i].value[1] - 0).toFixed(2) + '<br/>'
}
}
return tips
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.55)',
borderWidth: 0
},
title: {
left: 'center',
text: titlename || title,
textStyle: {
fontSize: '0.8rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
}
},
legend: {
right: 50,
top: 25,
verticalAlign: 'top',
enabled: true,
itemDistance: 5,
textStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
rich: { a: { verticalAlign: 'middle' } },
padding: [0, 0, 0, 0]
}
},
xAxis: {
type: 'value',
name: '时间\n(ms)',
boundaryGap: false,
min: props.wp.listWaveData[0][0],
max: props.wp.listWaveData[props.wp.listWaveData.length - 1][0] + 1,
title: {
text: 'ms',
textStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
},
enabled: true,
align: 'high'
},
splitLine: { show: false },
axisTick: { alignWithLabel: true },
axisLine: {
lineStyle: {
color: props.DColor ? '#fff' : echartsColor.thread
},
onZero: false
},
nameTextStyle: { fontSize: '0.6rem' },
axisLabel: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
formatter: function (value: number) {
if (valB.value != (value - 0).toFixed(0)) {
valB.value = Number((value - 0).toFixed(0))
return (value - 0).toFixed(0)
}
return ''
}
}
},
yAxis: {
type: 'value',
name: unit,
title: {
align: 'high',
offset: 0,
text: unit,
rotation: 0,
y: -10
},
boundaryGap: [0, '100%'],
showLastLabel: true,
max: max.toFixed(2) * 1.1,
min: min.toFixed(2) > 0 ? min.toFixed(2) - min.toFixed(2) * 0.1 : min.toFixed(2) * 1.1,
opposite: false,
nameTextStyle: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor
},
axisLine: {
show: true,
lineStyle: {
color: props.DColor ? '#fff' : echartsColor.thread
},
onZero: false
},
axisLabel: {
fontSize: '0.6rem',
color: props.DColor ? '#fff' : echartsColor.WordColor,
formatter: function (value: number) {
return (value - 0).toFixed(2)
}
},
splitLine: {
lineStyle: {
color: [props.DColor ? '#fff' : echartsColor.thread],
type: 'dashed',
opacity: 0.5
}
}
},
grid: {
left: '1%',
right: '2.8%',
bottom: '40px',
top: '70px',
containLabel: true
},
dataZoom: [
{
type: 'inside',
height: 13,
start: 0,
bottom: '20px',
end: 100
},
{
start: 0,
height: 13,
bottom: '20px',
end: 100
}
],
series: [
{
name: a,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#DAA520' },
data: adata
},
{
name: b,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#2E8B57' },
data: bdata
},
{
name: c,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#A52a2a' },
data: cdata
}
]
}
myChartes.setOption(option)
switch (step) {
case 1: myChartess1.value = myChartes; break
case 2: myChartess2.value = myChartes; break
case 3: myChartess3.value = myChartes; break
case 4: myChartess4.value = myChartes; break
case 5: myChartess5.value = myChartes; break
}
setTimeout(() => {
myChartes.resize()
loading.value = false
}, 400)
echarts.connect([myChartes1, myChartes])
}
const backbxlb = () => {
waveDatas.value = []
const charts = [myChartess.value, myChartess1.value, myChartess2.value, myChartess3.value, myChartess4.value, myChartess5.value]
charts.forEach(chart => {
if (chart) {
chart.dispose()
}
})
myChartess.value = null
myChartess1.value = null
myChartess2.value = null
myChartess3.value = null
myChartess4.value = null
myChartess5.value = null
// echarts.disconnect(charts.filter(Boolean) as echarts.ECharts[])
charts
.filter(Boolean)
.forEach(chart => {
if (chart && typeof chart.dispose === 'function') {
chart.dispose();
}
});
}
const getMax = (temp: number, tempA: number, tempB: number, tempC: number): number => {
temp = temp > tempA ? temp : tempA
temp = temp > tempB ? temp : tempB
temp = temp > tempC ? temp : tempC
return temp
}
const getMaxTwo = (temp: number, tempA: number, tempB: number): number => {
temp = temp > tempA ? temp : tempA
temp = temp > tempB ? temp : tempB
return temp
}
const getMin = (temp: number, tempA: number, tempB: number, tempC: number): number => {
temp = temp < tempA ? temp : tempA
temp = temp < tempB ? temp : tempB
temp = temp < tempC ? temp : tempC
return temp
}
const getMinOpen = (temp: number, tempA: number, tempB: number): number => {
temp = temp < tempA ? temp : tempA
temp = temp < tempB ? temp : tempB
return temp
}
</script>

View File

@@ -0,0 +1,189 @@
<template>
<div v-if="view2" v-loading="loading" element-loading-background="#343849c7">
<el-row v-if="view4">
<el-col :span="12">
<span style="font-size: 14px; line-height: 30px">值类型选择</span>
<el-select
style="width: 150px"
@change="changeView"
size="small"
v-model="value"
placeholder="请选择值类型"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-col>
</el-row>
<div
v-if="view4"
element-loading-background="rgba(122, 122, 122, 0.8)"
style="height: 750px"
>
<el-tabs
class="default-main"
v-model="bxactiveName"
@tab-click="bxhandleClick"
>
<el-tab-pane
label="瞬时波形"
name="ssbx"
class="boxbx pb10"
:style="'height:' + bxecharts + ';overflow-y: auto;'"
>
<shushiboxi
ref="shushiboxiRef"
v-if="bxactiveName == 'ssbx' && showBoxi"
:value="value"
:parentHeight="parentHeight"
:boxoList="boxoList"
:wp="wp"
></shushiboxi>
</el-tab-pane>
<el-tab-pane
label="RMS波形"
class="boxbx pb10"
name="rmsbx"
:style="'height:' + bxecharts + ';overflow-y: auto;'"
>
<rmsboxi
ref="rmsboxiRef"
v-if="bxactiveName == 'rmsbx' && showBoxi"
:value="value"
:parentHeight="parentHeight"
:boxoList="boxoList"
:wp="wp"
></rmsboxi>
</el-tab-pane>
</el-tabs>
</div>
<el-empty v-else description="暂无数据" style="height: 700px" />
</div>
</template>
<script setup lang="ts">
import shushiboxi from "./shushiboxi.vue";
import rmsboxi from "./rmsboxi.vue";
import { ref, reactive } from "vue";
import { getTransientAnalyseWave } from "@/api/statistics/index";
const emit = defineEmits(["backbxlb"]);
interface Props {
// boxoList: any
// wp: any,
senior?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
senior: false,
});
const parentHeight = ref(0);
const loading = ref(true);
const bxactiveName = ref("ssbx");
const rmsboxiRef = ref();
const value = ref(1);
const options = ref([
{
value: 1,
label: "一次值",
},
{
value: 2,
label: "二次值",
},
]);
const shushiboxiRef = ref();
const bxecharts = ref("700px");
const view2 = ref(true);
const boxoList: any = ref({});
const wp: any = ref(null);
const showBoxi = ref(true);
const view3 = ref(false);
const view4 = ref(false);
const GJList = ref([]);
const open = async (row: any) => {
console.log("🚀 ~ open ~ row:", row);
loading.value = true;
await getTransientAnalyseWave({
// id: "151984a0-4a2e-4c46-aece-493e1a2e24c1",
id: row.eventdetail_index,
systemType: 0,
type: 0,
})
.then((res) => {
row.loading = false;
if (res != undefined) {
boxoList.value = {
subName: row.bdname,
lineName: row.pointname,
startTime: row.timeid,
featureAmplitude: row.eventvalue,
duration: row.persisttime,
};
wp.value = res.data;
loading.value = false;
view4.value = true;
}
})
.catch(() => {
loading.value = false;
});
};
const bxhandleClick = (tab: any) => {
// if (shushiboxiRef.value) shushiboxiRef.value.backbxlb();
// if (rmsboxiRef.value) rmsboxiRef.value.backbxlb();
loading.value = true;
if (tab.name == "ssbx") {
bxactiveName.value = "ssbx";
} else if (tab.name == "rmsbx") {
bxactiveName.value = "rmsbx";
}
setTimeout(() => {
loading.value = false;
}, 0);
// console.log(tab, event);
};
const backbxlb = () => {
boxoList.value = null;
wp.value = null;
// if (shushiboxiRef.value) shushiboxiRef.value.backbxlb();
// if (rmsboxiRef.value) rmsboxiRef.value.backbxlb();
emit("backbxlb");
};
const setHeight = (h: any, vh: any) => {
if (h != false) {
parentHeight.value = h;
}
setTimeout(() => {
bxecharts.value = "700px";
}, 100);
};
// 高级分析
const changeView = () => {
// if (shushiboxiRef.value) shushiboxiRef.value.backbxlb();
// if (rmsboxiRef.value) rmsboxiRef.value.backbxlb();
showBoxi.value = false;
setTimeout(() => {
showBoxi.value = true;
}, 0);
};
const gaoBack = () => {
view2.value = true;
view3.value = false;
};
defineExpose({ open, setHeight });
</script>
<style lang="scss" scoped>
:deep(.el-tabs__item) {
// color: #c2c2c2;
--el-text-color-primary: #d3d4d6;
}
</style>