Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ce5600fc9 |
@@ -1,311 +1,152 @@
|
||||
// 辅助函数
|
||||
const getMax = (temp, tempA, tempB, tempC) => {
|
||||
temp = temp > tempA ? temp : tempA;
|
||||
temp = temp > tempB ? temp : tempB;
|
||||
if (tempC !== undefined) {
|
||||
temp = temp > tempC ? temp : tempC;
|
||||
import {
|
||||
buildRmsMinPoint,
|
||||
buildWaveTitle,
|
||||
emptyRmsPrimarySeries,
|
||||
emptyRmsSecondarySeries,
|
||||
getMax,
|
||||
getMaxTwo,
|
||||
getMin,
|
||||
getMinOpen,
|
||||
getSampleStep,
|
||||
getXRange,
|
||||
isPrimaryValue,
|
||||
normalizeStats,
|
||||
parsePhaseTitles,
|
||||
shouldSamplePoint,
|
||||
} from "./waveWorkerUtils.js";
|
||||
|
||||
const emptyStats = () => ({ max: -Infinity, min: Infinity });
|
||||
|
||||
const pushRmsSeries = (series, time, vals, iphasic, usePrimary) => {
|
||||
if (usePrimary) {
|
||||
series.rmsFA.push([time, vals[0]]);
|
||||
if (iphasic >= 2) series.rmsFB.push([time, vals[1]]);
|
||||
if (iphasic >= 3) series.rmsFC.push([time, vals[2]]);
|
||||
} else {
|
||||
series.rmsSA.push([time, vals[0]]);
|
||||
if (iphasic >= 2) series.rmsSB.push([time, vals[1]]);
|
||||
if (iphasic >= 3) series.rmsSC.push([time, vals[2]]);
|
||||
}
|
||||
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 fliteWaveData = (wp, step, iphasicValue, isOpen, value) => {
|
||||
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 { aTitle, bTitle, cTitle, unit } = parsePhaseTitles(wp.waveTitle, iphasicValue, step);
|
||||
const xishu = unit === "电流" ? ct : pt;
|
||||
const usePrimary = isPrimaryValue(value);
|
||||
|
||||
const shunshiFA = [];
|
||||
const shunshiFB = [];
|
||||
const shunshiFC = [];
|
||||
const shunshiSA = [];
|
||||
const shunshiSB = [];
|
||||
const shunshiSC = [];
|
||||
const rmsFA = [];
|
||||
const rmsFB = [];
|
||||
const rmsFC = [];
|
||||
const rmsSA = [];
|
||||
const rmsSB = [];
|
||||
const rmsSC = [];
|
||||
let rmsvFirstX = 0, rmsvFirstY = Infinity, rmsvSecondX = 0, rmsvSecondY = Infinity;
|
||||
let firstZhou = "a", secondeZhou = "a";
|
||||
const RMSF = emptyStats();
|
||||
const RMSS = emptyStats();
|
||||
const RMSFWave = emptyRmsPrimarySeries();
|
||||
const RMSSWave = emptyRmsSecondarySeries();
|
||||
const activeSeries = usePrimary ? RMSFWave : RMSSWave;
|
||||
const activeStats = usePrimary ? RMSF : RMSS;
|
||||
|
||||
|
||||
|
||||
if (titleList[iphasicValue * step + 1]?.substring(0, 1) !== "U") {
|
||||
xishu = ct;
|
||||
unit = "电流";
|
||||
if (!rmsData?.[0] || rmsData[0][iphasicValue * step + 1] === undefined) {
|
||||
return {
|
||||
RMSF: normalizeStats(RMSF),
|
||||
RMSS: normalizeStats(RMSS),
|
||||
RMSFMinDetail: { rmsvFirstX, rmsvFirstY, firstZhou },
|
||||
RMSSMinDetail: { rmsvSecondX, rmsvSecondY, secondeZhou },
|
||||
RMSFWave,
|
||||
RMSSWave,
|
||||
title: { aTitle, bTitle, cTitle, unit },
|
||||
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;
|
||||
}
|
||||
}
|
||||
const sampleStep = getSampleStep(rmsData.length);
|
||||
const base = iphasicValue * step;
|
||||
|
||||
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;
|
||||
}
|
||||
for (let i = 0; i < rmsData.length; i++) {
|
||||
const row = rmsData[i];
|
||||
if (!row || row[base + 1] === undefined) break;
|
||||
const time = row[0];
|
||||
const scaled = [row[base + 1] * xishu, row[base + 2] * xishu, row[base + 3] * xishu];
|
||||
const raw = [row[base + 1], row[base + 2], row[base + 3]];
|
||||
const vals = usePrimary ? scaled : raw;
|
||||
|
||||
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];
|
||||
activeStats.max = Math.max(activeStats.max, vals[0]);
|
||||
activeStats.min = Math.min(activeStats.min, vals[0]);
|
||||
if (usePrimary && activeStats.min < rmsvFirstY) {
|
||||
rmsvFirstY = activeStats.min; firstZhou = "a"; rmsvFirstX = time;
|
||||
} else if (!usePrimary && activeStats.min < rmsvSecondY) {
|
||||
rmsvSecondY = activeStats.min; secondeZhou = "a"; rmsvSecondX = time;
|
||||
}
|
||||
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];
|
||||
activeStats.max = getMaxTwo(activeStats.max, vals[0], vals[1]);
|
||||
activeStats.min = getMinOpen(activeStats.min, vals[0], vals[1]);
|
||||
if (usePrimary && activeStats.min < rmsvFirstY) {
|
||||
rmsvFirstY = activeStats.min;
|
||||
firstZhou = activeStats.min === vals[0] ? "a" : "b";
|
||||
rmsvFirstX = time;
|
||||
} else if (!usePrimary && activeStats.min < rmsvSecondY) {
|
||||
rmsvSecondY = activeStats.min;
|
||||
secondeZhou = activeStats.min === vals[0] ? "a" : "b";
|
||||
rmsvSecondX = time;
|
||||
}
|
||||
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];
|
||||
activeStats.max = getMax(activeStats.max, vals[0], vals[1], vals[2]);
|
||||
activeStats.min = getMin(activeStats.min, vals[0], vals[1], vals[2]);
|
||||
if (usePrimary && activeStats.min < rmsvFirstY) {
|
||||
rmsvFirstY = activeStats.min;
|
||||
firstZhou = activeStats.min === vals[0] ? "a" : activeStats.min === vals[1] ? "b" : "c";
|
||||
rmsvFirstX = time;
|
||||
} else if (!usePrimary && activeStats.min < rmsvSecondY) {
|
||||
rmsvSecondY = activeStats.min;
|
||||
secondeZhou = activeStats.min === vals[0] ? "a" : activeStats.min === vals[1] ? "b" : "c";
|
||||
rmsvSecondX = time;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (shouldSamplePoint(i, rmsData.length, sampleStep)) {
|
||||
pushRmsSeries(activeSeries, time, vals, iphasicValue, usePrimary);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
RMSF: normalizeStats(RMSF),
|
||||
RMSS: normalizeStats(RMSS),
|
||||
RMSFMinDetail: { rmsvFirstX, rmsvFirstY, firstZhou },
|
||||
RMSSMinDetail: { rmsvSecondX, rmsvSecondY, secondeZhou },
|
||||
RMSFWave,
|
||||
RMSSWave,
|
||||
title,
|
||||
title: { aTitle, bTitle, cTitle, unit },
|
||||
unit,
|
||||
};
|
||||
};
|
||||
|
||||
// 监听消息
|
||||
self.onmessage = function (e) {
|
||||
const { wp, isOpen, value, boxoList } = JSON.parse(e.data);
|
||||
|
||||
self.addEventListener("message", (e) => {
|
||||
try {
|
||||
const { wp, isOpen, boxoList, taskId, value = 2 } = e.data;
|
||||
const valueType = Number(value) || 2;
|
||||
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);
|
||||
waveDatas.push(fliteWaveData(wp, i, iphasicValue, isOpen, valueType));
|
||||
}
|
||||
// 处理标题
|
||||
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,
|
||||
taskId,
|
||||
titles: buildWaveTitle(boxoList),
|
||||
waveDatas,
|
||||
xRange: getXRange(wp.listRmsData),
|
||||
rmsMinPoint: buildRmsMinPoint(wp, valueType),
|
||||
time: wp.time,
|
||||
type: wp.waveType,
|
||||
severity: wp.yzd,
|
||||
iphasic: iphasicValue,
|
||||
});
|
||||
} catch (error) {
|
||||
self.postMessage({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
self.postMessage({ success: false, taskId: e.data?.taskId, error: error.message });
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -12,13 +12,25 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
|
||||
import { ref, computed, onMounted, onBeforeUnmount, watch, toRaw } from 'vue'
|
||||
import html2canvas from 'html2canvas'
|
||||
import $ from 'jquery'
|
||||
import * as echarts from 'echarts'
|
||||
import url from '@/assets/img/point.png'
|
||||
import url2 from '@/assets/img/dw.png'
|
||||
const worker = ref<Worker | null>(null)
|
||||
import {
|
||||
bindRmsYAxisOnZoom,
|
||||
buildRmsWorkerPayload,
|
||||
buildRmsYAxisScale,
|
||||
calcVisibleRmsYAxis,
|
||||
cloneForWorker,
|
||||
getPhaseSeriesList,
|
||||
isPrimaryValue,
|
||||
RMS_ALIGNED_GRID,
|
||||
} from './waveWorkerUtils.js'
|
||||
|
||||
let waveDataWorker: Worker | null = null
|
||||
let workerTaskId = 0
|
||||
interface WaveData {
|
||||
instantF: { max: number; min: number }
|
||||
instantS: { max: number; min: number }
|
||||
@@ -101,6 +113,8 @@ const charts = ref({})
|
||||
const arrpoints = ref([])
|
||||
const fz = ref<number[]>([])
|
||||
const titles = ref('')
|
||||
const xRange = ref({ min: 0, max: 1 })
|
||||
const rmsMinPoint = ref<{ time: number; display: number } | null>(null)
|
||||
const zoom = ref(1)
|
||||
const myChartess = ref<echarts.ECharts | null>(null)
|
||||
const myChartess1 = ref<echarts.ECharts | null>(null)
|
||||
@@ -121,55 +135,85 @@ const vh = computed(() => {
|
||||
|
||||
const vw = computed(() => '100%')
|
||||
|
||||
watch(() => props.value, (newVal) => {
|
||||
if (newVal == 2) {
|
||||
initWaves()
|
||||
} else {
|
||||
$('#wave1').remove()
|
||||
initWaves()
|
||||
const getChartRefs = () => [
|
||||
myChartess.value,
|
||||
myChartess1.value,
|
||||
myChartess2.value,
|
||||
myChartess3.value,
|
||||
myChartess4.value,
|
||||
myChartess5.value,
|
||||
].filter((c): c is echarts.ECharts => !!c && !c.isDisposed())
|
||||
|
||||
const disposeAllCharts = () => {
|
||||
const charts = getChartRefs()
|
||||
if (charts.length > 1 && charts[0].group) {
|
||||
try { echarts.disconnect(charts[0].group) } catch { /* ignore */ }
|
||||
}
|
||||
charts.forEach(c => c.dispose())
|
||||
const rmsEl = document.getElementById('rms')
|
||||
if (rmsEl) {
|
||||
const inst = echarts.getInstanceByDom(rmsEl)
|
||||
if (inst && !inst.isDisposed()) inst.dispose()
|
||||
}
|
||||
myChartess.value = null
|
||||
myChartess1.value = null
|
||||
myChartess2.value = null
|
||||
myChartess3.value = null
|
||||
myChartess4.value = null
|
||||
myChartess5.value = null
|
||||
}
|
||||
|
||||
const clearExtraWaveDom = () => {
|
||||
$('#rmsp').nextAll().remove()
|
||||
}
|
||||
|
||||
watch(() => props.value, () => {
|
||||
workerTaskId++
|
||||
disposeAllCharts()
|
||||
clearExtraWaveDom()
|
||||
query()
|
||||
})
|
||||
|
||||
watch(() => props.wp?.listRmsData, (data) => {
|
||||
if (data?.length) query()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom');
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
|
||||
window.addEventListener('resize', handleResize)
|
||||
|
||||
// 初始化 Web Worker
|
||||
worker.value = new Worker(new URL('./rmsWorker.js', import.meta.url));
|
||||
worker.value.onmessage = (e) => {
|
||||
if (e.data.success) {
|
||||
const data = e.data
|
||||
titles.value = data.titles
|
||||
waveDatas.value = data.waveDatas
|
||||
time.value = data.time
|
||||
type.value = data.type
|
||||
severity.value = data.severity
|
||||
iphasic.value = data.iphasic
|
||||
|
||||
// 初始化波形图
|
||||
initWave(waveDatas.value, time.value, type.value, severity.value, isOpen.value)
|
||||
} else {
|
||||
console.error('Worker error:', e.data.error)
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
initWorker()
|
||||
query()
|
||||
}, 500)
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (worker.value) {
|
||||
worker.value.terminate()
|
||||
if (waveDataWorker) {
|
||||
waveDataWorker.terminate()
|
||||
waveDataWorker = null
|
||||
}
|
||||
backbxlb()
|
||||
window.removeEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
const initWorker = () => {
|
||||
if (waveDataWorker) return
|
||||
waveDataWorker = new Worker(new URL('./rmsWorker.js', import.meta.url), { type: 'module' })
|
||||
waveDataWorker.onmessage = (e) => {
|
||||
const data = e.data
|
||||
if (!data.success || data.taskId !== workerTaskId) return
|
||||
titles.value = data.titles
|
||||
iphasic.value = data.iphasic
|
||||
time.value = data.time
|
||||
type.value = data.type
|
||||
severity.value = data.severity
|
||||
xRange.value = data.xRange || { min: 0, max: 1 }
|
||||
rmsMinPoint.value = data.rmsMinPoint || null
|
||||
initWave(data.waveDatas, data.time, data.type, data.severity, isOpen.value)
|
||||
loading.value = false
|
||||
}
|
||||
waveDataWorker.onerror = () => { loading.value = false }
|
||||
}
|
||||
|
||||
const handleResize = () => {
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom');
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
|
||||
@@ -192,268 +236,36 @@ const download = () => {
|
||||
|
||||
const query = () => {
|
||||
loading.value = true
|
||||
if (props.wp) {
|
||||
// 使用 Worker 处理数据
|
||||
if (worker.value) {
|
||||
|
||||
worker.value.postMessage(JSON.stringify({
|
||||
wp: props.wp,
|
||||
isOpen: isOpen.value,
|
||||
value: props.value,
|
||||
boxoList: props.boxoList
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
initWave(null, null, null, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
const waveData = (
|
||||
instantF: any,
|
||||
instantS: any,
|
||||
RMSF: any,
|
||||
RMSS: any,
|
||||
RMSFMinDetail: any,
|
||||
RMSSMinDetail: any,
|
||||
shunshiF: any,
|
||||
shunshiS: any,
|
||||
RMSFWave: any,
|
||||
RMSSWave: any,
|
||||
title: any,
|
||||
unit: any
|
||||
): WaveData => {
|
||||
return {
|
||||
instantF,
|
||||
instantS,
|
||||
RMSF,
|
||||
RMSS,
|
||||
RMSFMinDetail,
|
||||
RMSSMinDetail,
|
||||
shunshiF,
|
||||
shunshiS,
|
||||
RMSFWave,
|
||||
RMSSWave,
|
||||
title,
|
||||
unit
|
||||
}
|
||||
initWaves()
|
||||
}
|
||||
|
||||
const initWaves = () => {
|
||||
if (props.wp) {
|
||||
|
||||
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 (Number(severity.value) < 0) {
|
||||
severity.value = '/'
|
||||
type.value = '/'
|
||||
}
|
||||
|
||||
initWave(waveDatas.value, time.value, type.value, severity.value, isOpen.value)
|
||||
} else {
|
||||
if (!props.wp?.listRmsData?.length) {
|
||||
initWave(null, null, null, null, null)
|
||||
loading.value = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
|
||||
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: number[][] = []
|
||||
const shunshiFB: number[][] = []
|
||||
const shunshiFC: number[][] = []
|
||||
const shunshiSA: number[][] = []
|
||||
const shunshiSB: number[][] = []
|
||||
const shunshiSC: number[][] = []
|
||||
const rmsFA: number[][] = []
|
||||
const rmsFB: number[][] = []
|
||||
const rmsFC: number[][] = []
|
||||
const rmsSA: number[][] = []
|
||||
const rmsSB: number[][] = []
|
||||
const rmsSC: number[][] = []
|
||||
|
||||
|
||||
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 (rmsData[0][iphasic.value * step + 1] !== undefined) {
|
||||
rfmax = rmsData[0][iphasic.value * step + 1] * xishu
|
||||
rfmin = rmsData[0][iphasic.value * step + 1] * xishu
|
||||
rmsvFirstY = rmsData[0][iphasic.value * step + 1] * xishu
|
||||
rmsvFirstX = rmsData[0][0]
|
||||
rsmax = rmsData[0][iphasic.value * step + 1]
|
||||
rsmin = rmsData[0][iphasic.value * step + 1]
|
||||
rmsvSecondY = rmsData[0][iphasic.value * step + 1]
|
||||
rmsvSecondX = rmsData[0][0]
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (let rms = 0; rms < rmsData.length; rms++) {
|
||||
if (rmsData[rms][iphasic.value * step + 1] === undefined) {
|
||||
break
|
||||
}
|
||||
|
||||
switch (iphasic.value) {
|
||||
case 1:
|
||||
const rmsFirstA = rmsData[rms][iphasic.value * 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][iphasic.value * 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][iphasic.value * step + 1] * xishu
|
||||
const rmsFirstB2 = rmsData[rms][iphasic.value * 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][iphasic.value * step + 1]
|
||||
const rmsSecondB2 = rmsData[rms][iphasic.value * 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][iphasic.value * step + 1] * xishu
|
||||
const rmsFirstB3 = rmsData[rms][iphasic.value * step + 2] * xishu
|
||||
const rmsFirstC3 = rmsData[rms][iphasic.value * 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.value ? 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][iphasic.value * step + 1]
|
||||
const rmsSecondB3 = rmsData[rms][iphasic.value * step + 2]
|
||||
const rmsSecondC3 = rmsData[rms][iphasic.value * 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.value ? 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 waveData(instantF, instantS, RMSF, RMSS, RMSFMinDetail, RMSSMinDetail, shunshiF, shunshiS, RMSFWave, RMSSWave, title, unit)
|
||||
loading.value = true
|
||||
iphasic.value = props.wp.iphasic || 1
|
||||
initWorker()
|
||||
const taskId = ++workerTaskId
|
||||
waveDataWorker!.postMessage({
|
||||
wp: cloneForWorker(buildRmsWorkerPayload(toRaw(props.wp))),
|
||||
value: Number(props.value) || 2,
|
||||
isOpen: isOpen.value,
|
||||
boxoList: cloneForWorker(toRaw(props.boxoList)),
|
||||
taskId,
|
||||
})
|
||||
}
|
||||
|
||||
const initWave = (waveDatas: WaveData[] | null, time: string | null, type: string | null, severity: string | null, isOpen: boolean | null) => {
|
||||
|
||||
$('div.bx').remove()
|
||||
disposeAllCharts()
|
||||
clearExtraWaveDom()
|
||||
|
||||
let picHeight = vh.value
|
||||
const show = !isOpen
|
||||
let isvisible = false
|
||||
let rmscu: number[][] = []
|
||||
let rmscm: number[][] = []
|
||||
let titleText = ''
|
||||
let unit = ''
|
||||
let a: string | null = null, b: string | null = null, c: string | null = null
|
||||
@@ -472,16 +284,14 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
switch (iphasic.value) {
|
||||
case 1:
|
||||
a = waveDatas[0].title.aTitle
|
||||
if (props.value === 1) {
|
||||
if (isPrimaryValue(props.value)) {
|
||||
rmscu = [[0, waveDatas[0].RMSF.min]]
|
||||
rmscm = [[0, waveDatas[0].RMSF.max]]
|
||||
radata = waveDatas[0].RMSFWave.rmsFA
|
||||
rmsvX = waveDatas[0].RMSFMinDetail.rmsvFirstX
|
||||
rmsvY = waveDatas[0].RMSFMinDetail.rmsvFirstY
|
||||
zhou = waveDatas[0].RMSFMinDetail.firstZhou
|
||||
} else {
|
||||
rmscu = [[0, waveDatas[0].RMSS.min]]
|
||||
rmscm = [[0, waveDatas[0].RMSS.max]]
|
||||
radata = waveDatas[0].RMSSWave.rmsSA
|
||||
rmsvX = waveDatas[0].RMSSMinDetail.rmsvSecondX
|
||||
rmsvY = waveDatas[0].RMSSMinDetail.rmsvSecondY
|
||||
@@ -491,9 +301,8 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
case 2:
|
||||
a = waveDatas[0].title.aTitle
|
||||
b = waveDatas[0].title.bTitle
|
||||
if (props.value === 1) {
|
||||
if (isPrimaryValue(props.value)) {
|
||||
rmscu = [[0, waveDatas[0].RMSF.min]]
|
||||
rmscm = [[0, waveDatas[0].RMSF.max]]
|
||||
radata = waveDatas[0].RMSFWave.rmsFA
|
||||
rbdata = waveDatas[0].RMSFWave.rmsFB
|
||||
rmsvX = waveDatas[0].RMSFMinDetail.rmsvFirstX
|
||||
@@ -501,7 +310,6 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
zhou = waveDatas[0].RMSFMinDetail.firstZhou
|
||||
} else {
|
||||
rmscu = [[0, waveDatas[0].RMSS.min]]
|
||||
rmscm = [[0, waveDatas[0].RMSS.max]]
|
||||
radata = waveDatas[0].RMSSWave.rmsSA
|
||||
rbdata = waveDatas[0].RMSSWave.rmsSB
|
||||
rmsvX = waveDatas[0].RMSSMinDetail.rmsvSecondX
|
||||
@@ -513,9 +321,8 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
a = waveDatas[0].title.aTitle
|
||||
b = waveDatas[0].title.bTitle
|
||||
c = waveDatas[0].title.cTitle
|
||||
if (props.value === 1) {
|
||||
if (isPrimaryValue(props.value)) {
|
||||
rmscu = [[0, waveDatas[0].RMSF.min]]
|
||||
rmscm = [[0, waveDatas[0].RMSF.max]]
|
||||
radata = waveDatas[0].RMSFWave.rmsFA
|
||||
rbdata = waveDatas[0].RMSFWave.rmsFB
|
||||
rcdata = waveDatas[0].RMSFWave.rmsFC
|
||||
@@ -524,7 +331,6 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
zhou = waveDatas[0].RMSFMinDetail.firstZhou
|
||||
} else {
|
||||
rmscu = [[0, waveDatas[0].RMSS.min]]
|
||||
rmscm = [[0, waveDatas[0].RMSS.max]]
|
||||
radata = waveDatas[0].RMSSWave.rmsSA
|
||||
rbdata = waveDatas[0].RMSSWave.rmsSB
|
||||
rcdata = waveDatas[0].RMSSWave.rmsSC
|
||||
@@ -536,19 +342,10 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
}
|
||||
|
||||
if (waveDatas[0].title.unit === '电压') {
|
||||
if (props.value === 1) {
|
||||
fz.value = [
|
||||
props.wp.listRmsMinData[0][0],
|
||||
Number(((props.wp.listRmsMinData[0][1] * Number(props.wp.pt)) / 1000).toFixed(2))
|
||||
]
|
||||
unit = 'kV'
|
||||
} else {
|
||||
fz.value = [
|
||||
props.wp.listRmsMinData[0][0],
|
||||
props.wp.listRmsMinData[0][1]
|
||||
]
|
||||
unit = 'V'
|
||||
if (rmsMinPoint.value) {
|
||||
fz.value = [rmsMinPoint.value.time, rmsMinPoint.value.display]
|
||||
}
|
||||
unit = isPrimaryValue(props.value) ? 'kV' : 'V'
|
||||
} else {
|
||||
unit = 'A'
|
||||
}
|
||||
@@ -562,16 +359,24 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
} else {
|
||||
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 残余电压:${(Number(eventValue.value) * 1).toFixed(0)}% 持续时间:${persistTime.value}s`
|
||||
}
|
||||
const rms = document.getElementById('rmsp')
|
||||
|
||||
const phaseSeries = waveDatas?.length
|
||||
? getPhaseSeriesList(iphasic.value, radata, rbdata, rcdata)
|
||||
: []
|
||||
const yBounds = calcVisibleRmsYAxis(phaseSeries)
|
||||
const yScale = buildRmsYAxisScale(yBounds)
|
||||
|
||||
const rms = document.getElementById('rms')
|
||||
if (!rms) return
|
||||
const myChartes = echarts.init(rms)
|
||||
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
|
||||
|
||||
setTimeout(() => {
|
||||
rms.style.width = '100%'
|
||||
rms.style.height = vh.value
|
||||
}, 0)
|
||||
|
||||
const existingChart = echarts.getInstanceByDom(rms)
|
||||
if (existingChart) existingChart.dispose()
|
||||
|
||||
const myChartes = echarts.init(rms)
|
||||
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
@@ -635,8 +440,8 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
name: '时间\n(ms)',
|
||||
min: props.wp?.listRmsData[0][0] || 0,
|
||||
max: props.wp?.listRmsData[props.wp?.listRmsData.length - 1][0] + 1 || 1,
|
||||
min: xRange.value.min,
|
||||
max: xRange.value.max,
|
||||
boundaryGap: false,
|
||||
title: {
|
||||
text: 'ms',
|
||||
@@ -683,8 +488,9 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
rotation: 0,
|
||||
y: -10
|
||||
},
|
||||
max: rmscm[0]?.[1] * 1.06 || 0,
|
||||
min: rmscu[0]?.[1] - (rmscu[0]?.[1] * 0.04) || 0,
|
||||
min: yScale.min,
|
||||
max: yScale.max,
|
||||
splitNumber: yScale.splitNumber,
|
||||
boundaryGap: [0, '100%'],
|
||||
showLastLabel: true,
|
||||
opposite: false,
|
||||
@@ -702,9 +508,7 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
return (value - 0).toFixed(2)
|
||||
}
|
||||
formatter: yScale.axisLabel.formatter
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
@@ -714,26 +518,22 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '45px',
|
||||
bottom: '40px',
|
||||
top: '70px',
|
||||
containLabel: true
|
||||
},
|
||||
grid: RMS_ALIGNED_GRID,
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
height: 13,
|
||||
start: 0,
|
||||
bottom: '20px',
|
||||
end: 100
|
||||
end: 100,
|
||||
filterMode: 'none'
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
height: 13,
|
||||
bottom: '20px',
|
||||
end: 100
|
||||
end: 100,
|
||||
filterMode: 'none'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
@@ -742,7 +542,6 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
sampling: 'average',
|
||||
itemStyle: { color: '#DAA520' },
|
||||
data: radata
|
||||
},
|
||||
@@ -751,7 +550,6 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
sampling: 'average',
|
||||
itemStyle: { color: '#2E8B57' },
|
||||
data: rbdata
|
||||
},
|
||||
@@ -760,7 +558,6 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
sampling: 'average',
|
||||
itemStyle: { color: '#A52a2a' },
|
||||
data: rcdata
|
||||
},
|
||||
@@ -795,6 +592,9 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
|
||||
myChartes.setOption(option)
|
||||
myChartess.value = myChartes
|
||||
if (phaseSeries.length) {
|
||||
bindRmsYAxisOnZoom(myChartes, phaseSeries)
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
myChartes.resize()
|
||||
@@ -804,12 +604,12 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
if (waveDatas && waveDatas.length > 1) {
|
||||
const waveDatasTemp = waveDatas.slice(1)
|
||||
for (let step = 0; step < waveDatasTemp.length; step++) {
|
||||
drawPics(waveDatasTemp[step], picHeight, step, show, myChartes, rmscm, rmscu, titleText)
|
||||
drawPics(waveDatasTemp[step], picHeight, step, show, myChartes, titleText)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show: boolean, myChartes1: echarts.ECharts, rmscm: number[][], rmscu: number[][], title: string) => {
|
||||
const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show: boolean, myChartes1: echarts.ECharts, title: string) => {
|
||||
step = step + 1
|
||||
const rmsId = 'rms' + step
|
||||
let a = '', b = '', c = ''
|
||||
@@ -831,7 +631,7 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
break
|
||||
}
|
||||
|
||||
if (props.value === 1) {
|
||||
if (isPrimaryValue(props.value)) {
|
||||
radata = waveDataTemp.RMSFWave.rmsFA
|
||||
rbdata = waveDataTemp.RMSFWave.rmsFB
|
||||
rcdata = waveDataTemp.RMSFWave.rmsFC
|
||||
@@ -842,11 +642,15 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
}
|
||||
|
||||
if (waveDataTemp.title.unit === '电压') {
|
||||
unit = props.value === 1 ? 'kV' : 'V'
|
||||
unit = isPrimaryValue(props.value) ? 'kV' : 'V'
|
||||
} else {
|
||||
unit = 'A'
|
||||
}
|
||||
|
||||
const phaseSeries = getPhaseSeriesList(iphasic.value, radata, rbdata, rcdata)
|
||||
const yBounds = calcVisibleRmsYAxis(phaseSeries)
|
||||
const yScale = buildRmsYAxisScale(yBounds)
|
||||
|
||||
let titlename = ''
|
||||
if (props.boxoList.systemType == 'ZL') {
|
||||
const str = rmsId.split('s')
|
||||
@@ -876,6 +680,9 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
const rmsIds = document.getElementById(rmsId)
|
||||
if (!rmsIds) return
|
||||
|
||||
const existingSub = echarts.getInstanceByDom(rmsIds)
|
||||
if (existingSub && !existingSub.isDisposed()) existingSub.dispose()
|
||||
|
||||
const myChartes = echarts.init(rmsIds)
|
||||
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
|
||||
|
||||
@@ -926,8 +733,8 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
name: '时间\n(ms)',
|
||||
min: props.wp.listRmsData[0][0],
|
||||
max: props.wp.listRmsData[props.wp.listRmsData.length - 1][0] + 1,
|
||||
min: xRange.value.min,
|
||||
max: xRange.value.max,
|
||||
boundaryGap: false,
|
||||
title: {
|
||||
text: 'ms',
|
||||
@@ -974,6 +781,9 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
rotation: 0,
|
||||
y: -10
|
||||
},
|
||||
min: yScale.min,
|
||||
max: yScale.max,
|
||||
splitNumber: yScale.splitNumber,
|
||||
boundaryGap: [0, '100%'],
|
||||
showLastLabel: true,
|
||||
opposite: false,
|
||||
@@ -991,9 +801,7 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
return (value - 0).toFixed(2)
|
||||
}
|
||||
formatter: yScale.axisLabel.formatter
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
@@ -1003,26 +811,22 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '45px',
|
||||
bottom: '40px',
|
||||
top: '70px',
|
||||
containLabel: true
|
||||
},
|
||||
grid: RMS_ALIGNED_GRID,
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
height: 13,
|
||||
start: 0,
|
||||
bottom: '20px',
|
||||
end: 100
|
||||
end: 100,
|
||||
filterMode: 'none'
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
height: 13,
|
||||
bottom: '20px',
|
||||
end: 100
|
||||
end: 100,
|
||||
filterMode: 'none'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
@@ -1031,7 +835,6 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
sampling: 'average',
|
||||
itemStyle: { color: '#DAA520' },
|
||||
data: radata
|
||||
},
|
||||
@@ -1040,7 +843,6 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
sampling: 'average',
|
||||
itemStyle: { color: '#2E8B57' },
|
||||
data: rbdata
|
||||
},
|
||||
@@ -1049,7 +851,6 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
sampling: 'average',
|
||||
itemStyle: { color: '#A52a2a' },
|
||||
data: rcdata
|
||||
}
|
||||
@@ -1057,6 +858,9 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
}
|
||||
|
||||
myChartes.setOption(option)
|
||||
if (phaseSeries.length) {
|
||||
bindRmsYAxisOnZoom(myChartes, phaseSeries)
|
||||
}
|
||||
|
||||
switch (step) {
|
||||
case 1: myChartess1.value = myChartes; break
|
||||
@@ -1075,55 +879,11 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
}
|
||||
|
||||
const backbxlb = () => {
|
||||
workerTaskId++
|
||||
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();
|
||||
}
|
||||
});
|
||||
disposeAllCharts()
|
||||
clearExtraWaveDom()
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
defineExpose({ backbxlb, query })
|
||||
</script>
|
||||
@@ -1,179 +1,124 @@
|
||||
// waveData.worker.js
|
||||
self.addEventListener('message', function(e) {
|
||||
const { wp, value, iphasic, isOpen, boxoList } = JSON.parse(e.data);
|
||||
import {
|
||||
buildWaveTitle,
|
||||
emptyInstantPrimarySeries,
|
||||
emptyInstantSecondarySeries,
|
||||
getSampleStep,
|
||||
getXRange,
|
||||
isPrimaryValue,
|
||||
normalizeStats,
|
||||
parsePhaseTitles,
|
||||
shouldSamplePoint,
|
||||
} from "./waveWorkerUtils.js";
|
||||
|
||||
// 处理波形数据的函数
|
||||
const fliteWaveData = (wp, step) => {
|
||||
// 将原有的fliteWaveData函数实现复制到这里
|
||||
const emptyStats = () => ({ max: -Infinity, min: Infinity });
|
||||
|
||||
const updateStats = (stats, vals, iphasic) => {
|
||||
const [a, b, c] = vals;
|
||||
if (iphasic === 1) {
|
||||
stats.max = Math.max(stats.max, a);
|
||||
stats.min = Math.min(stats.min, a);
|
||||
return;
|
||||
}
|
||||
if (iphasic === 2) {
|
||||
stats.max = Math.max(stats.max, a, b);
|
||||
stats.min = Math.min(stats.min, a, b);
|
||||
return;
|
||||
}
|
||||
stats.max = Math.max(stats.max, a, b, c);
|
||||
stats.min = Math.min(stats.min, a, b, c);
|
||||
};
|
||||
|
||||
const pushSeries = (series, time, vals, iphasic, usePrimary) => {
|
||||
if (usePrimary) {
|
||||
series.shunshiFA.push([time, vals[0]]);
|
||||
if (iphasic >= 2) series.shunshiFB.push([time, vals[1]]);
|
||||
if (iphasic >= 3) series.shunshiFC.push([time, vals[2]]);
|
||||
} else {
|
||||
series.shunshiSA.push([time, vals[0]]);
|
||||
if (iphasic >= 2) series.shunshiSB.push([time, vals[1]]);
|
||||
if (iphasic >= 3) series.shunshiSC.push([time, vals[2]]);
|
||||
}
|
||||
};
|
||||
|
||||
const fliteWaveData = (wp, step, iphasic, isOpen, value) => {
|
||||
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 { aTitle, bTitle, cTitle, unit } = parsePhaseTitles(wp.waveTitle, iphasic, step);
|
||||
const xishu = unit === "电流" ? ct : pt;
|
||||
const usePrimary = isPrimaryValue(value);
|
||||
|
||||
const shunshiFA = [];
|
||||
const shunshiFB = [];
|
||||
const shunshiFC = [];
|
||||
const shunshiSA = [];
|
||||
const shunshiSB = [];
|
||||
const shunshiSC = [];
|
||||
const shunshiF = emptyInstantPrimarySeries();
|
||||
const shunshiS = emptyInstantSecondarySeries();
|
||||
const instantF = emptyStats();
|
||||
const instantS = emptyStats();
|
||||
const activeSeries = usePrimary ? shunshiF : shunshiS;
|
||||
const activeStats = usePrimary ? instantF : instantS;
|
||||
|
||||
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 };
|
||||
if (!shunData?.length || shunData[0][iphasic * step + 1] === undefined) {
|
||||
return {
|
||||
instantF: normalizeStats(instantF),
|
||||
instantS: normalizeStats(instantS),
|
||||
shunshiF,
|
||||
shunshiS,
|
||||
title: { aTitle, bTitle, cTitle, unit },
|
||||
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 sampleStep = getSampleStep(shunData.length);
|
||||
const base = iphasic * step;
|
||||
|
||||
for (let i = 0; i < shunData.length; i++) {
|
||||
const row = shunData[i];
|
||||
if (row[base + 1] === undefined) break;
|
||||
const scaledVals = [row[base + 1] * xishu, row[base + 2] * xishu, row[base + 3] * xishu];
|
||||
const rawVals = [row[base + 1], row[base + 2], row[base + 3]];
|
||||
const vals = usePrimary ? scaledVals : rawVals;
|
||||
updateStats(activeStats, vals, iphasic);
|
||||
if (shouldSamplePoint(i, shunData.length, sampleStep)) {
|
||||
pushSeries(activeSeries, row[0], vals, iphasic, usePrimary);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
instantF: normalizeStats(instantF),
|
||||
instantS: normalizeStats(instantS),
|
||||
shunshiF,
|
||||
shunshiS,
|
||||
title: { aTitle, bTitle, cTitle, unit },
|
||||
unit,
|
||||
};
|
||||
};
|
||||
|
||||
self.addEventListener("message", (e) => {
|
||||
try {
|
||||
const { wp, isOpen, boxoList, taskId, value = 2 } = e.data;
|
||||
const valueType = Number(value) || 2;
|
||||
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);
|
||||
waveDatas.push(fliteWaveData(wp, i, iphasicValue, isOpen, valueType));
|
||||
}
|
||||
|
||||
const time = wp.time;
|
||||
const type = wp.waveType;
|
||||
let severity = wp.yzd;
|
||||
|
||||
let type = wp.waveType;
|
||||
if (severity < 0) {
|
||||
severity = '/';
|
||||
type = '/';
|
||||
severity = "/";
|
||||
type = "/";
|
||||
}
|
||||
|
||||
// 将处理结果发送回主线程
|
||||
self.postMessage({
|
||||
success: true,
|
||||
taskId,
|
||||
waveDatas,
|
||||
time,
|
||||
xRange: getXRange(wp.listWaveData),
|
||||
time: wp.time,
|
||||
type,
|
||||
severity,
|
||||
titles,
|
||||
iphasic: iphasicValue
|
||||
titles: buildWaveTitle(boxoList),
|
||||
iphasic: iphasicValue,
|
||||
});
|
||||
} catch (error) {
|
||||
self.postMessage({ success: false, taskId: e.data?.taskId, error: error.message });
|
||||
}
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,6 @@
|
||||
<span style="font-size: 14px; line-height: 30px">值类型选择:</span>
|
||||
<el-select
|
||||
style="width: 150px"
|
||||
@change="changeView"
|
||||
size="small"
|
||||
v-model="value"
|
||||
placeholder="请选择值类型"
|
||||
@@ -15,21 +14,16 @@
|
||||
: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-tabs class="default-main" v-model="bxactiveName">
|
||||
<el-tab-pane
|
||||
label="瞬时波形"
|
||||
name="ssbx"
|
||||
@@ -37,28 +31,28 @@
|
||||
:style="'height:' + bxecharts + ';overflow-y: auto;'"
|
||||
>
|
||||
<shushiboxi
|
||||
v-if="bxactiveName === 'ssbx'"
|
||||
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"
|
||||
class="boxbx pb10"
|
||||
:style="'height:' + bxecharts + ';overflow-y: auto;'"
|
||||
>
|
||||
<rmsboxi
|
||||
v-if="bxactiveName === 'rmsbx'"
|
||||
ref="rmsboxiRef"
|
||||
v-if="bxactiveName == 'rmsbx' && showBoxi"
|
||||
:value="value"
|
||||
:parentHeight="parentHeight"
|
||||
:boxoList="boxoList"
|
||||
:wp="wp"
|
||||
></rmsboxi>
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
@@ -68,54 +62,87 @@
|
||||
<script setup lang="ts">
|
||||
import shushiboxi from "./shushiboxi.vue";
|
||||
import rmsboxi from "./rmsboxi.vue";
|
||||
import { ref, reactive } from "vue";
|
||||
import { ref, shallowRef, markRaw, watch, onBeforeUnmount } 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 emit = defineEmits(["backbxlb"]);
|
||||
|
||||
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: "二次值",
|
||||
},
|
||||
{ value: 1, label: "一次值" },
|
||||
{ value: 2, label: "二次值" },
|
||||
]);
|
||||
const shushiboxiRef = ref();
|
||||
const rmsboxiRef = 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 boxoList: any = ref({});
|
||||
const wp: any = shallowRef(null);
|
||||
const rmsRawCache = shallowRef<{ listRmsData: any; listRmsMinData: any } | null>(null);
|
||||
|
||||
const releaseAllRawWaveData = () => {
|
||||
if (!wp.value) return;
|
||||
delete wp.value.listWaveData;
|
||||
delete wp.value.listRmsData;
|
||||
delete wp.value.listRmsMinData;
|
||||
};
|
||||
|
||||
const cleanupWaveChildren = () => {
|
||||
shushiboxiRef.value?.backbxlb?.();
|
||||
rmsboxiRef.value?.backbxlb?.();
|
||||
};
|
||||
|
||||
const destroyWaveSession = () => {
|
||||
cleanupWaveChildren();
|
||||
releaseAllRawWaveData();
|
||||
rmsRawCache.value = null;
|
||||
};
|
||||
|
||||
const attachRmsRawIfNeeded = () => {
|
||||
if (!wp.value || !rmsRawCache.value || wp.value.listRmsData) return;
|
||||
wp.value = markRaw({
|
||||
...wp.value,
|
||||
listRmsData: rmsRawCache.value.listRmsData,
|
||||
listRmsMinData: rmsRawCache.value.listRmsMinData,
|
||||
});
|
||||
};
|
||||
|
||||
const splitWavePayload = (data: any) => {
|
||||
const raw = markRaw({ ...data });
|
||||
if (raw.listRmsData || raw.listRmsMinData) {
|
||||
rmsRawCache.value = {
|
||||
listRmsData: raw.listRmsData,
|
||||
listRmsMinData: raw.listRmsMinData,
|
||||
};
|
||||
delete raw.listRmsData;
|
||||
delete raw.listRmsMinData;
|
||||
} else {
|
||||
rmsRawCache.value = null;
|
||||
}
|
||||
return raw;
|
||||
};
|
||||
|
||||
watch(bxactiveName, (name) => {
|
||||
if (name === "rmsbx") attachRmsRawIfNeeded();
|
||||
}, { flush: "sync" });
|
||||
|
||||
const open = async (row: any) => {
|
||||
console.log("🚀 ~ open ~ row:", row);
|
||||
destroyWaveSession();
|
||||
loading.value = true;
|
||||
await getTransientAnalyseWave({
|
||||
// id: "151984a0-4a2e-4c46-aece-493e1a2e24c1",
|
||||
bxactiveName.value = "ssbx";
|
||||
try {
|
||||
const res = await getTransientAnalyseWave({
|
||||
id: row.eventdetail_index,
|
||||
systemType: 0,
|
||||
type: 0,
|
||||
})
|
||||
.then((res) => {
|
||||
});
|
||||
row.loading = false;
|
||||
// console.log("🚀 ~ open ~ res.data:", res.data)
|
||||
|
||||
if (res != undefined) {
|
||||
boxoList.value = {
|
||||
subName: row.bdname,
|
||||
@@ -124,66 +151,41 @@ const open = async (row: any) => {
|
||||
featureAmplitude: row.eventvalue,
|
||||
duration: row.persisttime,
|
||||
};
|
||||
wp.value = res.data;
|
||||
loading.value = false;
|
||||
wp.value = splitWavePayload(res.data);
|
||||
view4.value = true;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
} catch {
|
||||
/* ignore */
|
||||
} finally {
|
||||
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();
|
||||
|
||||
const backbxlb = () => {
|
||||
destroyWaveSession();
|
||||
boxoList.value = {};
|
||||
wp.value = null;
|
||||
view4.value = false;
|
||||
emit("backbxlb");
|
||||
};
|
||||
const setHeight = (h: any, vh: any) => {
|
||||
if (h != false) {
|
||||
parentHeight.value = h;
|
||||
}
|
||||
|
||||
const setHeight = (h: 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 });
|
||||
onBeforeUnmount(() => {
|
||||
destroyWaveSession();
|
||||
wp.value = null;
|
||||
boxoList.value = {};
|
||||
});
|
||||
|
||||
defineExpose({ open, setHeight, backbxlb });
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tabs__item) {
|
||||
// color: #c2c2c2;
|
||||
--el-text-color-primary: #d3d4d6;
|
||||
}
|
||||
</style>
|
||||
|
||||
342
src/components/BX/waveWorkerUtils.js
Normal file
342
src/components/BX/waveWorkerUtils.js
Normal file
@@ -0,0 +1,342 @@
|
||||
export const MAX_DISPLAY_POINTS = 4000;
|
||||
|
||||
export const isPrimaryValue = (value) => Number(value) === 1;
|
||||
|
||||
export const getMax = (temp, tempA, tempB, tempC) => {
|
||||
let result = temp > tempA ? temp : tempA;
|
||||
result = result > tempB ? result : tempB;
|
||||
if (tempC !== undefined) result = result > tempC ? result : tempC;
|
||||
return result;
|
||||
};
|
||||
|
||||
export const getMaxTwo = (temp, tempA, tempB) => {
|
||||
let result = temp > tempA ? temp : tempA;
|
||||
return result > tempB ? result : tempB;
|
||||
};
|
||||
|
||||
export const getMin = (temp, tempA, tempB, tempC) => {
|
||||
let result = temp < tempA ? temp : tempA;
|
||||
result = result < tempB ? result : tempB;
|
||||
if (tempC !== undefined) result = result < tempC ? result : tempC;
|
||||
return result;
|
||||
};
|
||||
|
||||
export const getMinOpen = (temp, tempA, tempB) => {
|
||||
let result = temp < tempA ? temp : tempA;
|
||||
return result < tempB ? result : tempB;
|
||||
};
|
||||
|
||||
export const buildWaveTitle = (boxoList) => {
|
||||
if (boxoList?.systemType === "pms") {
|
||||
return `变电站名称:${boxoList.powerStationName} 监测点名称:${boxoList.measurementPointName} 发生时刻:${boxoList.startTime} 残余电压:${(boxoList.featureAmplitude * 100).toFixed(2)}% 持续时间:${boxoList.duration}s`;
|
||||
}
|
||||
if (boxoList?.systemType === "ZL") {
|
||||
return ` 监测点名称:${boxoList.equipmentName} 发生时刻:${boxoList.startTime} 残余电压:${boxoList.evtParamVVaDepth} 持续时间:${boxoList.evtParamTm}s`;
|
||||
}
|
||||
return `变电站名称:${boxoList.subName} 监测点名称:${boxoList.lineName} 发生时刻:${boxoList.startTime} 残余电压:${(boxoList.featureAmplitude * 100).toFixed(2)}% 持续时间:${boxoList.duration}s`;
|
||||
};
|
||||
|
||||
export const parsePhaseTitles = (titleList, iphasic, step) => {
|
||||
const base = iphasic * step;
|
||||
const isCurrent = titleList[base + 1]?.substring(0, 1) !== "U";
|
||||
const titles = { aTitle: "", bTitle: "", cTitle: "", unit: isCurrent ? "电流" : "电压" };
|
||||
for (let i = 1; i <= iphasic; i++) {
|
||||
const title = titleList[base + i]?.substring(1) || "";
|
||||
if (i === 1) titles.aTitle = title;
|
||||
else if (i === 2) titles.bTitle = title;
|
||||
else if (i === 3) titles.cTitle = title;
|
||||
}
|
||||
return titles;
|
||||
};
|
||||
|
||||
export const getSampleStep = (total, maxPoints = MAX_DISPLAY_POINTS) => {
|
||||
if (!total || total <= maxPoints) return 1;
|
||||
return Math.ceil(total / maxPoints);
|
||||
};
|
||||
|
||||
export const shouldSamplePoint = (index, total, step) =>
|
||||
index % step === 0 || index === total - 1;
|
||||
|
||||
export const cloneForWorker = (data) => JSON.parse(JSON.stringify(data));
|
||||
|
||||
export const buildShuWorkerPayload = (wp) => ({
|
||||
iphasic: wp.iphasic,
|
||||
pt: wp.pt,
|
||||
ct: wp.ct,
|
||||
waveTitle: wp.waveTitle,
|
||||
listWaveData: wp.listWaveData,
|
||||
time: wp.time,
|
||||
waveType: wp.waveType,
|
||||
yzd: wp.yzd,
|
||||
});
|
||||
|
||||
export const buildRmsWorkerPayload = (wp) => ({
|
||||
iphasic: wp.iphasic,
|
||||
pt: wp.pt,
|
||||
ct: wp.ct,
|
||||
waveTitle: wp.waveTitle,
|
||||
listRmsData: wp.listRmsData,
|
||||
listRmsMinData: wp.listRmsMinData,
|
||||
time: wp.time,
|
||||
waveType: wp.waveType,
|
||||
yzd: wp.yzd,
|
||||
});
|
||||
|
||||
export const getXRange = (list) => {
|
||||
if (!list?.length) return { min: 0, max: 1 };
|
||||
return { min: list[0][0], max: list[list.length - 1][0] + 1 };
|
||||
};
|
||||
|
||||
export const normalizeStats = (stats) => {
|
||||
if (!stats || !isFinite(stats.min) || !isFinite(stats.max)) {
|
||||
return { min: 0, max: 0 };
|
||||
}
|
||||
return stats;
|
||||
};
|
||||
|
||||
/** Y轴:最大值×1.2,最小值对称留白使波形居中 */
|
||||
export const calcYAxisBounds = (dataMin, dataMax) => {
|
||||
const minVal = Number(dataMin);
|
||||
const maxVal = Number(dataMax);
|
||||
if (!isFinite(minVal) || !isFinite(maxVal)) return { min: 0, max: 1 };
|
||||
if (maxVal === minVal) {
|
||||
const pad = Math.abs(maxVal) * 0.2 || 1;
|
||||
return { min: minVal - pad, max: maxVal + pad };
|
||||
}
|
||||
const yMax = maxVal * 1.2;
|
||||
const topPad = yMax - maxVal;
|
||||
return { min: minVal - topPad, max: yMax };
|
||||
};
|
||||
|
||||
export const calcGlobalInstantRange = (waveDatas, value) => {
|
||||
const usePrimary = isPrimaryValue(value);
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
for (const item of waveDatas || []) {
|
||||
const stats = normalizeStats(usePrimary ? item.instantF : item.instantS);
|
||||
min = Math.min(min, stats.min);
|
||||
max = Math.max(max, stats.max);
|
||||
}
|
||||
return calcYAxisBounds(min, max);
|
||||
};
|
||||
|
||||
export const calcGlobalRmsRange = (waveDatas, value) => {
|
||||
const usePrimary = isPrimaryValue(value);
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
for (const item of waveDatas || []) {
|
||||
const stats = normalizeStats(usePrimary ? item.RMSF : item.RMSS);
|
||||
min = Math.min(min, stats.min);
|
||||
max = Math.max(max, stats.max);
|
||||
}
|
||||
return calcYAxisBounds(min, max);
|
||||
};
|
||||
|
||||
/** 原瞬时波形 Y 轴公式(多图共用同一范围实现对齐) */
|
||||
export const calcLegacyInstantYAxis = (dataMin, dataMax) => {
|
||||
const minNum = Number(Number(dataMin).toFixed(2));
|
||||
const maxNum = Number(Number(dataMax).toFixed(2));
|
||||
return {
|
||||
max: maxNum * 1.1,
|
||||
min: minNum > 0 ? minNum - minNum * 0.1 : minNum * 1.1,
|
||||
};
|
||||
};
|
||||
|
||||
/** 从多相序列中取 [xMin, xMax] 内的 y 极值;不传 x 范围则取全量 */
|
||||
export const calcSeriesDataRange = (seriesList, xMin, xMax) => {
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
const hasXBounds = xMin != null && xMax != null && isFinite(xMin) && isFinite(xMax);
|
||||
for (const series of seriesList || []) {
|
||||
if (!series?.length) continue;
|
||||
for (const point of series) {
|
||||
const x = point[0];
|
||||
const y = point[1];
|
||||
if (hasXBounds && (x < xMin || x > xMax)) continue;
|
||||
if (!isFinite(y)) continue;
|
||||
min = Math.min(min, y);
|
||||
max = Math.max(max, y);
|
||||
}
|
||||
}
|
||||
if (!isFinite(min) || !isFinite(max)) return { min: 0, max: 1 };
|
||||
return { min, max };
|
||||
};
|
||||
|
||||
export const getPhaseSeriesList = (iphasic, adata, bdata, cdata) => {
|
||||
const list = [adata];
|
||||
if (iphasic >= 2) list.push(bdata);
|
||||
if (iphasic >= 3) list.push(cdata);
|
||||
return list.filter((s) => s?.length);
|
||||
};
|
||||
|
||||
export const getChartXExtent = (chart) => {
|
||||
const axis = chart.getModel().getComponent("xAxis", 0);
|
||||
const extent = axis.axis.scale.getExtent();
|
||||
return { min: extent[0], max: extent[1] };
|
||||
};
|
||||
|
||||
export const calcVisibleInstantYAxis = (seriesList, xMin, xMax) => {
|
||||
const { min, max } = calcSeriesDataRange(seriesList, xMin, xMax);
|
||||
return calcLegacyInstantYAxis(min, max);
|
||||
};
|
||||
|
||||
/** 按 Y 轴跨度决定小数位,避免小范围时刻度全显示为 0.0 / 0.1 */
|
||||
export const calcYAxisLabelPrecision = (min, max) => {
|
||||
const span = Math.abs(Number(max) - Number(min));
|
||||
if (!isFinite(span) || span === 0) return 2;
|
||||
if (span >= 100) return 0;
|
||||
if (span >= 10) return 1;
|
||||
if (span >= 1) return 2;
|
||||
if (span >= 0.1) return 2;
|
||||
if (span >= 0.01) return 3;
|
||||
return 4;
|
||||
};
|
||||
|
||||
/** 相邻刻度格式化后相同时隐藏,避免出现 0.0 0.0 0.1 0.1 */
|
||||
export const createYAxisLabelFormatter = (min, max) => {
|
||||
let lastLabel = null;
|
||||
const precision = calcYAxisLabelPrecision(min, max);
|
||||
return (value) => {
|
||||
const text = Number(value).toFixed(precision);
|
||||
if (text === lastLabel) return "";
|
||||
lastLabel = text;
|
||||
return text;
|
||||
};
|
||||
};
|
||||
|
||||
export const buildInstantYAxisScale = (bounds) => ({
|
||||
min: bounds.min,
|
||||
max: bounds.max,
|
||||
splitNumber: 5,
|
||||
axisLabel: {
|
||||
formatter: createYAxisLabelFormatter(bounds.min, bounds.max),
|
||||
},
|
||||
});
|
||||
|
||||
/** dataZoom 时按可见 x 范围重算 Y 轴,使 ABC 相数值与坐标对齐 */
|
||||
export const bindInstantYAxisOnZoom = (chart, seriesList) => {
|
||||
const updateYAxis = () => {
|
||||
if (!chart || chart.isDisposed()) return;
|
||||
const { min: xMin, max: xMax } = getChartXExtent(chart);
|
||||
const bounds = calcVisibleInstantYAxis(seriesList, xMin, xMax);
|
||||
chart.setOption({ yAxis: buildInstantYAxisScale(bounds) });
|
||||
};
|
||||
chart.off("dataZoom");
|
||||
chart.on("dataZoom", updateYAxis);
|
||||
return updateYAxis;
|
||||
};
|
||||
|
||||
export const calcGlobalLegacyInstantYAxis = (waveDatas, value) => {
|
||||
const usePrimary = isPrimaryValue(value);
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
for (const item of waveDatas || []) {
|
||||
const stats = normalizeStats(usePrimary ? item.instantF : item.instantS);
|
||||
min = Math.min(min, stats.min);
|
||||
max = Math.max(max, stats.max);
|
||||
}
|
||||
if (!isFinite(min) || !isFinite(max)) return { min: 0, max: 1 };
|
||||
return calcLegacyInstantYAxis(min, max);
|
||||
};
|
||||
|
||||
/** 原 RMS 波形 Y 轴公式(多图共用同一范围实现对齐) */
|
||||
export const calcLegacyRmsYAxis = (dataMin, dataMax) => {
|
||||
const min = Number(dataMin) || 0;
|
||||
const max = Number(dataMax) || 0;
|
||||
return {
|
||||
max: max * 1.06 || 0,
|
||||
min: min - min * 0.04 || 0,
|
||||
};
|
||||
};
|
||||
|
||||
export const calcVisibleRmsYAxis = (seriesList, xMin, xMax) => {
|
||||
const { min, max } = calcSeriesDataRange(seriesList, xMin, xMax);
|
||||
return calcLegacyRmsYAxis(min, max);
|
||||
};
|
||||
|
||||
export const buildRmsYAxisScale = (bounds) => ({
|
||||
min: bounds.min,
|
||||
max: bounds.max,
|
||||
splitNumber: 5,
|
||||
axisLabel: {
|
||||
formatter: createYAxisLabelFormatter(bounds.min, bounds.max),
|
||||
},
|
||||
});
|
||||
|
||||
/** dataZoom 时按可见 x 范围重算 RMS Y 轴 */
|
||||
export const bindRmsYAxisOnZoom = (chart, seriesList) => {
|
||||
const updateYAxis = () => {
|
||||
if (!chart || chart.isDisposed()) return;
|
||||
const { min: xMin, max: xMax } = getChartXExtent(chart);
|
||||
const bounds = calcVisibleRmsYAxis(seriesList, xMin, xMax);
|
||||
chart.setOption({ yAxis: buildRmsYAxisScale(bounds) });
|
||||
};
|
||||
chart.off("dataZoom");
|
||||
chart.on("dataZoom", updateYAxis);
|
||||
return updateYAxis;
|
||||
};
|
||||
|
||||
export const calcGlobalLegacyRmsYAxis = (waveDatas, value) => {
|
||||
const usePrimary = isPrimaryValue(value);
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
for (const item of waveDatas || []) {
|
||||
const stats = normalizeStats(usePrimary ? item.RMSF : item.RMSS);
|
||||
min = Math.min(min, stats.min);
|
||||
max = Math.max(max, stats.max);
|
||||
}
|
||||
if (!isFinite(min) || !isFinite(max)) return { min: 0, max: 0 };
|
||||
return calcLegacyRmsYAxis(min, max);
|
||||
};
|
||||
|
||||
export const WAVE_ALIGNED_GRID = {
|
||||
left: 56,
|
||||
right: "2.8%",
|
||||
bottom: "55px",
|
||||
top: "70px",
|
||||
containLabel: false,
|
||||
};
|
||||
|
||||
export const RMS_ALIGNED_GRID = {
|
||||
left: 56,
|
||||
right: "45px",
|
||||
bottom: "55px",
|
||||
top: "70px",
|
||||
containLabel: false,
|
||||
};
|
||||
|
||||
export const buildRmsMinPoint = (wp, value) => {
|
||||
const row = wp.listRmsMinData?.[0];
|
||||
if (!row) return null;
|
||||
const raw = row[1];
|
||||
return {
|
||||
time: row[0],
|
||||
display: isPrimaryValue(value)
|
||||
? Number(((raw * Number(wp.pt)) / 1000).toFixed(2))
|
||||
: raw,
|
||||
};
|
||||
};
|
||||
|
||||
export const emptyInstantPrimarySeries = () => ({
|
||||
shunshiFA: [],
|
||||
shunshiFB: [],
|
||||
shunshiFC: [],
|
||||
});
|
||||
|
||||
export const emptyInstantSecondarySeries = () => ({
|
||||
shunshiSA: [],
|
||||
shunshiSB: [],
|
||||
shunshiSC: [],
|
||||
});
|
||||
|
||||
export const emptyRmsPrimarySeries = () => ({
|
||||
rmsFA: [],
|
||||
rmsFB: [],
|
||||
rmsFC: [],
|
||||
});
|
||||
|
||||
export const emptyRmsSecondarySeries = () => ({
|
||||
rmsSA: [],
|
||||
rmsSB: [],
|
||||
rmsSC: [],
|
||||
});
|
||||
@@ -134,6 +134,8 @@ const renderChart = (key: any) => {
|
||||
const outerFontSize = maxChildren > 8 ? 9 : maxChildren > 5 ? 10 : 11;
|
||||
const outerLabelMaxLen = maxChildren > 8 ? 5 : maxChildren > 5 ? 6 : 8;
|
||||
const groupScales = getGroupDisplayScales(data.value.innerList || []);
|
||||
const groupCount = data.value.innerList?.length || 0;
|
||||
const innerLabelRotate = groupCount <= 1 ? "tangential" : "radial";
|
||||
myChart.setOption({
|
||||
title: {
|
||||
text: "电压暂降用户分类统计(单位:次)",
|
||||
@@ -172,7 +174,7 @@ const renderChart = (key: any) => {
|
||||
},
|
||||
parentId: item.children[0]?.parentId,
|
||||
label: {
|
||||
rotate: "radial",
|
||||
rotate: innerLabelRotate,
|
||||
color: "#ffffff",
|
||||
fontSize: 10,
|
||||
lineHeight: 12,
|
||||
@@ -236,7 +238,7 @@ const renderChart = (key: any) => {
|
||||
borderWidth: 2,
|
||||
},
|
||||
label: {
|
||||
rotate: "tangential",
|
||||
rotate: innerLabelRotate,
|
||||
},
|
||||
sort: null,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user