优化项目

This commit is contained in:
guanj
2026-06-04 19:06:36 +08:00
parent 4f32f84132
commit 4f907a80c4
53 changed files with 987 additions and 3499 deletions

View File

@@ -236,7 +236,7 @@ const fliteWaveData = (wp, step, iphasicValue, isOpen) => {
// 监听消息
self.onmessage = function (e) {
const { wp, isOpen, value, boxoList } = JSON.parse(e.data)
const { wp, isOpen, value, boxoList, requestId } = e.data
try {
const iphasicValue = wp.iphasic || 1
@@ -303,6 +303,7 @@ self.onmessage = function (e) {
}
// 发送处理结果回主线程
self.postMessage({
requestId,
titles: titles,
success: true,
waveDatas,
@@ -313,6 +314,7 @@ self.onmessage = function (e) {
})
} catch (error) {
self.postMessage({
requestId,
success: false,
error: error.message
})

View File

@@ -14,9 +14,15 @@ import html2canvas from 'html2canvas'
import $ from 'jquery'
import * as echarts from 'echarts'
import { mainHeight } from '@/utils/layout'
import { calcRmsYAxisRange, formatAxisLabel } from '@/utils/chartAxisHelper'
import url from '@/assets/img/point.png'
import url2 from '@/assets/img/dw.png'
const worker = ref<Worker | null>(null)
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
import { getRmsWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
let waveRequestId = 0
const pendingCacheKeys = new Map<number, string>()
let rmsWorker: Worker | null = null
interface WaveData {
instantF: { max: number; min: number }
instantS: { max: number; min: number }
@@ -125,52 +131,61 @@ const vw = computed(() => '100%')
watch(
() => props.value,
newVal => {
if (newVal == 2) {
initWaves()
} else {
$('#wave1').remove()
initWaves()
}
() => {
query()
}
)
watch(
() => props.wp,
() => {
query()
}
)
const applyWorkerResult = (data: any) => {
titles.value = data.titles
waveDatas.value = data.waveDatas
time.value = data.time
type.value = data.type
severity.value = data.severity
iphasic.value = data.iphasic
if (Number(severity.value) < 0) {
severity.value = '/'
type.value = '/'
}
initWave(waveDatas.value, time.value, type.value, severity.value, isOpen.value)
loading.value = false
}
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)
rmsWorker = getRmsWorker(data => {
if (data.requestId !== waveRequestId) return
if (!data.success) {
console.error('Worker error:', data.error)
loading.value = false
return
}
}
const cacheKey = pendingCacheKeys.get(data.requestId)
if (cacheKey) {
setWaveCache(cacheKey, data)
pendingCacheKeys.delete(data.requestId)
}
applyWorkerResult(data)
})
nextTick(() => {
setTimeout(() => {
query()
}, 500)
query()
})
})
onBeforeUnmount(() => {
if (worker.value) {
worker.value.terminate()
}
backbxlb()
window.removeEventListener('resize', handleResize)
})
@@ -195,23 +210,15 @@ const download = () => {
}
}
const EXTRA_PANEL_CLASS = 'wave-extra-panel'
const resetWaveDom = () => {
backbxlb()
$('#rmsp').nextAll(`.${EXTRA_PANEL_CLASS}`).remove()
}
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)
}
initWaves()
}
const waveData = (
@@ -245,29 +252,31 @@ const waveData = (
}
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 cacheKey = buildWaveCacheKey('rms', props.wp, props.value, isOpen.value, props.boxoList)
const cached = getWaveCache<any>(cacheKey)
if (cached) {
applyWorkerResult(cached)
return
}
loading.value = true
iphasic.value = props.wp.iphasic || 1
const currentRequestId = ++waveRequestId
pendingCacheKeys.set(currentRequestId, cacheKey)
rmsWorker?.postMessage(
buildWorkerPayload('rms', props.wp, props.boxoList, {
requestId: currentRequestId,
value: props.value,
isOpen: isOpen.value
})
)
}
const fliteWaveData = (wp: any, step: number): WaveData => {
@@ -482,7 +491,7 @@ const initWave = (
severity: string | null,
isOpen: boolean | null
) => {
$('div.bx').remove()
resetWaveDom()
let picHeight = vh.value
const show = !isOpen
@@ -594,7 +603,7 @@ const initWave = (
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
const rmsId = 'rms' + step
const newDivRms = $(
`<div style="height:${vh.value};overflow: hidden;min-height: 200px;"><div class='bx' id='${rmsId}'></div></div>`
`<div class="${EXTRA_PANEL_CLASS}" style="height:${vh.value};overflow: hidden;min-height: 200px;"><div class='bx' id='${rmsId}'></div></div>`
)
newDivRms.insertAfter($('#rmsp'))
$(`#${rmsId}`).css('height', picHeight).css('width', vw.value).css('min-height', '200px')
@@ -607,6 +616,12 @@ const initWave = (
const rms = document.getElementById('rmsp')
if (!rms) return
const yRange = calcRmsYAxisRange(rmscu[0]?.[1] ?? 0, rmscm[0]?.[1] ?? 0)
const existingChart = echarts.getInstanceByDom(rms)
if (existingChart) existingChart.dispose()
const myChartes = echarts.init(rms)
const echartsColor = {
WordColor: '#000',
@@ -750,8 +765,8 @@ const initWave = (
},
// max: rmscm[0]?.[1] * 1.06 || 0,
// min: rmscu[0]?.[1] - rmscu[0]?.[1] * 0.2 || 0,
max: Math.floor((rmscm[0]?.[1] * 1.06 || 0) * 1.1 * 10) / 10,
min: Math.floor((rmscu[0]?.[1] - rmscu[0]?.[1] * 0.2 || 0) * 10) / 10,
max: yRange.max,
min: yRange.min,
boundaryGap: [0, '100%'],
showLastLabel: true,
opposite: false,
@@ -770,7 +785,7 @@ const initWave = (
fontSize: '12px',
color: props.DColor ? '#000' : echartsColor.WordColor,
formatter: function (value: number) {
return Math.floor(value * 1000) / 1000
return formatAxisLabel(value)
}
},
splitLine: {
@@ -955,6 +970,10 @@ const drawPics = (
const rmsIds = document.getElementById(rmsId)
if (!rmsIds) return
const subMin = props.value === 1 ? waveDataTemp.RMSF.min : waveDataTemp.RMSS.min
const subMax = props.value === 1 ? waveDataTemp.RMSF.max : waveDataTemp.RMSS.max
const yRange = calcRmsYAxisRange(subMin, subMax)
const myChartes = echarts.init(rmsIds)
const echartsColor = {
WordColor: '#000',
@@ -1078,6 +1097,8 @@ const drawPics = (
},
boundaryGap: [0, '100%'],
showLastLabel: true,
max: yRange.max,
min: yRange.min,
opposite: false,
// max: Math.floor((rmscm[0]?.[1] * 1.06 || 0) * 1.1 * 10) / 10,
// min: Math.floor((rmscu[0]?.[1] - rmscu[0]?.[1] * 0.2 || 0) * 10) / 10,
@@ -1096,8 +1117,7 @@ const drawPics = (
fontSize: '12px',
color: props.DColor ? '#000' : echartsColor.WordColor,
formatter: function (value: number) {
// return (value - 0).toFixed(2)
return Math.floor(value * 1000) / 1000
return formatAxisLabel(value)
}
},
splitLine: {
@@ -1213,12 +1233,7 @@ const backbxlb = () => {
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()
}
})
$('#rmsp').nextAll(`.${EXTRA_PANEL_CLASS}`).remove()
}
const getMax = (temp: number, tempA: number, tempB: number, tempC: number): number => {

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// waveData.worker.js
self.addEventListener('message', function (e) {
const { wp, value, iphasic, isOpen, boxoList } = JSON.parse(e.data)
const { wp, value, iphasic, isOpen, boxoList, requestId } = e.data
// 处理波形数据的函数
const fliteWaveData = (wp, step) => {
@@ -195,6 +195,8 @@ self.addEventListener('message', function (e) {
// 将处理结果发送回主线程
self.postMessage({
requestId,
success: true,
waveDatas,
time,
type,

View File

@@ -1,8 +1,8 @@
<template>
<div v-loading="loading" class="boxbx" style="position: relative; height: 100%">
<div id="boxsj">
<div id="shushi" :style="`height:${vh};overflow: hidden;min-height: 200px;`">
<div class="bx" id="wave" style="min-height: 200px"></div>
<div id="shushi" :style="containerStyle">
<div class="bx" id="wave" :style="waveStyle"></div>
</div>
</div>
</div>
@@ -14,9 +14,14 @@ import html2canvas from 'html2canvas'
import $ from 'jquery'
import * as echarts from 'echarts'
import { mainHeight } from '@/utils/layout'
import { calcShuYAxisRange, formatAxisLabel } from '@/utils/chartAxisHelper'
import url from '@/assets/img/point.png'
// 创建Worker
let waveDataWorker: Worker | null = null
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
import { getShuWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
let waveRequestId = 0
const pendingCacheKeys = new Map<number, string>()
let shuWorker: Worker | null = null
interface WaveData {
instantF: { max: number; min: number }
instantS: { max: number; min: number }
@@ -110,38 +115,82 @@ const vh = computed(() => {
const vw = computed(() => '100%')
const containerStyle = computed(() => ({
height: vh.value,
overflow: 'hidden',
minHeight: '200px'
}))
const waveStyle = computed(() => ({
width: '100%',
height: '100%',
minHeight: '200px'
}))
const applyChartSize = (el: HTMLElement) => {
el.style.width = '100%'
el.style.height = vh.value
}
const finishChartRender = (chart: echarts.ECharts, endLoading = false) => {
nextTick(() => {
chart.resize()
if (endLoading) {
loading.value = false
}
})
}
watch(
() => props.value,
newVal => {
if (newVal == 2) {
initWaves()
} else {
$('#wave1').remove()
initWaves()
}
() => {
query()
}
)
watch(
() => props.wp,
() => {
query()
}
)
const applyWorkerResult = (data: any) => {
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
}
onMounted(() => {
const zoomValue = document.body.style.getPropertyValue('zoom')
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1)
window.addEventListener('resize', handleResize)
shuWorker = getShuWorker(data => {
if (data.requestId !== waveRequestId) return
if (!data.success) {
console.error('Worker error:', data.error)
loading.value = false
return
}
const cacheKey = pendingCacheKeys.get(data.requestId)
if (cacheKey) {
setWaveCache(cacheKey, data)
pendingCacheKeys.delete(data.requestId)
}
applyWorkerResult(data)
})
nextTick(() => {
setTimeout(() => {
query()
}, 500)
query()
})
})
onBeforeUnmount(() => {
console.log('组件卸载')
if (waveDataWorker) {
waveDataWorker.terminate()
waveDataWorker = null
}
backbxlb()
window.removeEventListener('resize', handleResize)
})
@@ -166,6 +215,13 @@ const download = () => {
}
}
const EXTRA_PANEL_CLASS = 'wave-extra-panel'
const resetWaveDom = () => {
backbxlb()
$('#shushi').nextAll(`.${EXTRA_PANEL_CLASS}`).remove()
}
const query = () => {
loading.value = true
initWaves()
@@ -184,48 +240,32 @@ const waveData = (instantF: any, instantS: any, shunshiF: any, shunshiS: any, ti
// 在组件中修改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 {
if (!props.wp?.listWaveData?.length) {
initWave(null, null, null, null, null)
loading.value = false
return
}
const cacheKey = buildWaveCacheKey('shu', props.wp, props.value, isOpen.value, props.boxoList)
const cached = getWaveCache<any>(cacheKey)
if (cached) {
applyWorkerResult(cached)
return
}
loading.value = true
iphasic.value = props.wp.iphasic || 1
const currentRequestId = ++waveRequestId
pendingCacheKeys.set(currentRequestId, cacheKey)
shuWorker?.postMessage(
buildWorkerPayload('shu', props.wp, props.boxoList, {
requestId: currentRequestId,
value: props.value,
isOpen: isOpen.value,
iphasic: iphasic.value
})
)
}
const initWave = (
@@ -235,6 +275,7 @@ const initWave = (
severity: string | null,
isOpen: boolean | null
) => {
resetWaveDom()
$('div.bx1').remove()
let picHeight = vh.value
@@ -327,7 +368,7 @@ const initWave = (
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;min-height: 200px;">
const newDivShunshi = $(`<div class="${EXTRA_PANEL_CLASS}" style="height:${vh.value};overflow: hidden;min-height: 200px;">
<div class='bx1' id='${waveId}'></div>
</div>`)
newDivShunshi.insertAfter($('#shushi'))
@@ -342,6 +383,13 @@ const initWave = (
const wave = document.getElementById('wave')
if (!wave) return
applyChartSize(wave)
const yRange = calcShuYAxisRange(Number(min), Number(max))
const existingChart = echarts.getInstanceByDom(wave)
if (existingChart) existingChart.dispose()
const myChartes = echarts.init(wave)
const echartsColor = {
WordColor: '#000',
@@ -363,11 +411,6 @@ const initWave = (
]
}
setTimeout(() => {
wave.style.width = '100%'
wave.style.height = vh.value
}, 0)
const option = {
tooltip: {
top: '10px',
@@ -481,10 +524,8 @@ const initWave = (
},
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,
max: Math.floor(max.toFixed(2) * 1.1 * 10) / 10,
min: Math.floor(min.toFixed(2) > 0 ? min.toFixed(2) - min.toFixed(2) * 0.1 : min.toFixed(2) * 1.1 * 10) / 10 ,
max: yRange.max,
min: yRange.min,
opposite: false,
nameTextStyle: {
fontSize: '12px',
@@ -501,8 +542,7 @@ const initWave = (
fontSize: '12px',
color: props.DColor ? '#000' : echartsColor.WordColor,
formatter: function (value: number) {
// return (value - 0).toFixed(2)
return Math.floor(value * 1000) / 1000
return formatAxisLabel(value)
}
},
splitLine: {
@@ -518,7 +558,6 @@ const initWave = (
right: '45px',
bottom: '40px',
top: '60px'
// containLabel: true
},
dataZoom: [
{
@@ -578,11 +617,7 @@ const initWave = (
myChartes.setOption(option)
myChartess.value = myChartes
setTimeout(() => {
myChartes.resize()
loading.value = false
}, 400)
finishChartRender(myChartes, true)
if (waveDatas && waveDatas.length > 1) {
const waveDatasTemp = waveDatas.slice(1)
@@ -679,6 +714,13 @@ const drawPics = (
const waveIds = document.getElementById(waveId)
if (!waveIds) return
applyChartSize(waveIds)
const yRange = calcShuYAxisRange(Number(min), Number(max))
const existingChart = echarts.getInstanceByDom(waveIds)
if (existingChart) existingChart.dispose()
const myChartes = echarts.init(waveIds)
const echartsColor = {
WordColor: '#000',
@@ -791,8 +833,8 @@ const drawPics = (
},
boundaryGap: [0, '100%'],
showLastLabel: true,
max: Math.floor(max.toFixed(2) * 1.1 * 10) / 10,
min: Math.floor(min.toFixed(2) > 0 ? min.toFixed(2) - min.toFixed(2) * 0.1 : min.toFixed(2) * 1.1 * 10) / 10 ,
max: yRange.max,
min: yRange.min,
opposite: false,
nameTextStyle: {
fontSize: '12px',
@@ -809,8 +851,7 @@ const drawPics = (
fontSize: '12px',
color: props.DColor ? '#000' : echartsColor.WordColor,
formatter: function (value: number) {
// return (value - 0).toFixed(2)
return Math.floor(value * 1000) / 1000
return formatAxisLabel(value)
}
},
splitLine: {
@@ -897,10 +938,7 @@ const drawPics = (
break
}
setTimeout(() => {
myChartes.resize()
loading.value = false
}, 400)
finishChartRender(myChartes)
echarts.connect([myChartes1, myChartes])
}
@@ -929,12 +967,8 @@ const backbxlb = () => {
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()
}
})
$('#shushi').nextAll(`.${EXTRA_PANEL_CLASS}`).remove()
$('div.bx1').remove()
}
const getMax = (temp: number, tempA: number, tempB: number, tempC: number): number => {

File diff suppressed because it is too large Load Diff