diff --git a/public/html-page/Spectrogram.html b/public/html-page/Spectrogram.html index 1f44e01..5624187 100644 --- a/public/html-page/Spectrogram.html +++ b/public/html-page/Spectrogram.html @@ -54,14 +54,6 @@ wfAdjStep: 1000, }; - // 模拟频谱数据 - const generateFakeData = (len) => { - const data = []; - for (let i = 0; i < len; i++) { - data.push(-80 - Math.random() * 20); - } - return data; - }; const id = 'waterfall'; // 定义 label_manager @@ -85,62 +77,112 @@ }, }; - // 初始化频谱图组件 - this.waterWidget = new waterfallwidget(id, { - wfOption: wfOption, - min_freq: payload.minFreq, //全局最小频率 - max_freq: payload.maxFreq, //全局最大频率 - min_band: 500, //最小选择带宽 - max_band: 100000, //最大选择带宽 - min_db: wfOption.wfMindB, //全局最小增益 - max_db: wfOption.wfMaxdB, //全局最大增益 - showPeakMarker: wfOption.showPeakMarker, //是否显示极值标注 - showSpectrogramAvg: wfOption.wfShowAvg, //是否显示平均保持 - showSpectrogramMin: wfOption.wfShowMin, //是否显示最小保持 - showSpectrogramMax: wfOption.wfShowMax, //是否显示最大保持 - spec_per: payload.waveSplite, //波形图占比 - menuEnableHandle: this.getAnalysisRun, - menuDisableText: '---', - menuDoppler: payload.doppler, - allowRunMode: payload.rtmode, //实时选择模式 - //allowCycleControl: payload.allowCycleControl, - info_Position: wfOption.wfInfoPos, - showCurLine: wfOption.wfCurLine, - adj_maxbw: payload.adjMaxbw, - adj_show: payload.adjShow, - fucFFTBuff: payload.enableWfBuff ? this.fucFFTBuff.bind(this) : null, - unitBuffId: payload.unitId, - wave_color: wfOption.specColor, - wave_color_avg: wfOption.specAvgColor, - wave_color_max: wfOption.specMaxColor, - wave_color_min: wfOption.specMinColor, - waveAfterglow_color: wfOption.afterGlowColor, - adj_step: wfOption.wfAdjStepType == 1 ? 0 : wfOption.wfAdjStep, - label_manager: pl.label_manager, - coorFreqType: payload.coorFreqType, - showFreqLable: payload.showFreqLable, //是否显示高亮频点 - wfFreqPointLable: payload.wfFreqPointLable, //是否显示频点标注 - wfFreqPointLableList: payload.wfFreqPointLableList, //频点标注数据 - showWhitelist: payload.showWhitelist, //黑名单频谱阴影显示 + // 全局变量,用于存储 waterfallwidget 实例 + window.waterWidgetInstance = null; + + // 监听来自父窗口的消息 + window.addEventListener('message', (event) => { + // 强烈建议在此处添加来源验证 (event.origin) 以提高安全性 + // 例如: if (event.origin !== 'YOUR_VUE_APP_ORIGIN') return; + + if (!event.data) return; // 如果没有数据,则忽略 + + // 处理初始化消息 + if (event.data.type === 'INIT_WIDGET') { + console.log('[🌐] HTML (频谱图): 收到初始化指令'); + if (!window.waterWidgetInstance) { + // 合并 Vue 传递的配置(如果存在) + const mergedPayload = { ...payload, ...(event.data.config?.payload || {}) }; + const mergedWfOption = { ...wfOption, ...(event.data.config?.wfOption || {}) }; + + // 创建 waterfallwidget 实例 + window.waterWidgetInstance = new waterfallwidget(id, { + wfOption: mergedWfOption, + min_freq: mergedPayload.minFreq, + max_freq: mergedPayload.maxFreq, + min_band: 500, + max_band: 100000, + min_db: mergedWfOption.wfMindB, + max_db: mergedWfOption.wfMaxdB, + showPeakMarker: mergedWfOption.showPeakMarker, + showSpectrogramAvg: mergedWfOption.wfShowAvg, + showSpectrogramMin: mergedWfOption.wfShowMin, + showSpectrogramMax: mergedWfOption.wfShowMax, + spec_per: mergedPayload.waveSplite, + menuEnableHandle: null, // 在 iframe 中通常不需要此句柄 + menuDisableText: '---', + menuDoppler: mergedPayload.doppler, + allowRunMode: mergedPayload.rtmode, + info_Position: mergedWfOption.wfInfoPos, + showCurLine: mergedWfOption.wfCurLine, + adj_maxbw: mergedPayload.adjMaxbw, + adj_show: mergedPayload.adjShow, + fucFFTBuff: mergedPayload.enableWfBuff ? this.fucFFTBuff.bind(this) : null, // 如果需要,保留 FFT 缓冲功能 + unitBuffId: mergedPayload.unitId, + wave_color: mergedWfOption.specColor, + wave_color_avg: mergedWfOption.specAvgColor, + wave_color_max: mergedWfOption.specMaxColor, + wave_color_min: mergedWfOption.specMinColor, + waveAfterglow_color: mergedWfOption.afterGlowColor, + adj_step: mergedWfOption.wfAdjStepType == 1 ? 0 : mergedWfOption.wfAdjStep, + label_manager: pl.label_manager, // 保留 label_manager + coorFreqType: mergedPayload.coorFreqType, + showFreqLable: mergedPayload.showFreqLable, + wfFreqPointLable: mergedPayload.wfFreqPointLable, + wfFreqPointLableList: mergedPayload.wfFreqPointLableList, + showWhitelist: mergedPayload.showWhitelist, + }); + console.log('[🌐] HTML (频谱图): waterfallwidget 已实例化'); + + // 监听用户框选范围变更事件 (移到初始化之后) + window.waterWidgetInstance.on('zoom-change', (e) => { + console.log('频率范围变更:', e.start, e.end); + // 可选:将此事件通知回 Vue 组件 + // if (window.parent !== window) { + // window.parent.postMessage({ type: 'ZOOM_CHANGE', payload: { start: e.start, end: e.end } }, '*'); + // } + }); + } else { + console.log('[🌐] HTML (频谱图): waterfallwidget 已存在,无需重复实例化'); + } + // 可选:通知父窗口已准备好接收数据 + // if (window.parent !== window) { + // window.parent.postMessage({ type: 'WIDGET_READY' }, '*'); // 使用更具体的 targetOrigin + // } + } + // 处理数据馈送消息 + else if (event.data.type === 'FEED_DATA') { + if (window.waterWidgetInstance) { + console.log('[🌐] HTML (频谱图): 收到来自父窗口的数据:', event.data.payload); + if (Array.isArray(event.data.payload)) { + // waterfallwidget.addData 接受可选的第二个参数 time + // 如果 Vue 组件传递了时间戳,可以在这里使用 + const time = event.data.time || new Date().toLocaleTimeString(); // 如果没有提供时间,使用当前时间 + window.waterWidgetInstance.addData(event.data.payload, time); + } else { + console.error('[🌐] HTML (频谱图): 收到的数据格式无效:', event.data.payload); + } + } else { + console.warn('[🌐] HTML (频谱图): Widget 尚未初始化,无法处理 FEED_DATA'); + } + } }); - // 监听用户框选范围变更事件 - this.waterWidget.on('zoom-change', (e) => { - console.log('频率范围变更:', e.start, e.end); - }); - - // 生成模拟数据并更新频谱图 - const updateData = () => { - const data = generateFakeData(100 /* 0 */); - console.debug(`data :>> `, data); - const time = new Date().toLocaleTimeString(); - this.waterWidget.addData(data, time); - }; - - // 首次更新 - updateData(); - - // 定期更新数据 - setInterval(updateData, 1000); + diff --git a/src/components/iframe-page/IframeConstellationDiagram.vue b/src/components/iframe-page-comps/IframeConstellationDiagram.vue similarity index 100% rename from src/components/iframe-page/IframeConstellationDiagram.vue rename to src/components/iframe-page-comps/IframeConstellationDiagram.vue diff --git a/src/components/iframe-page-comps/IframeSpectrogram.vue b/src/components/iframe-page-comps/IframeSpectrogram.vue new file mode 100644 index 0000000..90789ea --- /dev/null +++ b/src/components/iframe-page-comps/IframeSpectrogram.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/src/pages/Page/iframe-page/Spectrogram.page.vue b/src/pages/Page/iframe-page/Spectrogram.page.vue new file mode 100644 index 0000000..79a6224 --- /dev/null +++ b/src/pages/Page/iframe-page/Spectrogram.page.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/typed-router.d.ts b/typed-router.d.ts index c89c109..fa5a207 100644 --- a/typed-router.d.ts +++ b/typed-router.d.ts @@ -29,6 +29,7 @@ declare module 'vue-router/auto-routes' { 'PageFonts': RouteRecordInfo<'PageFonts', '/Page/fonts', Record, Record>, 'PageIcons': RouteRecordInfo<'PageIcons', '/Page/Icons', Record, Record>, 'PageIframePageIframeConstellationDiagram': RouteRecordInfo<'PageIframePageIframeConstellationDiagram', '/Page/iframe-page/IframeConstellationDiagram', Record, Record>, + 'PageIframePageSpectrogram': RouteRecordInfo<'PageIframePageSpectrogram', '/Page/iframe-page/Spectrogram', Record, Record>, 'PageJSPage': RouteRecordInfo<'PageJSPage', '/Page/JSPage', Record, Record>, 'PageMDPage': RouteRecordInfo<'PageMDPage', '/Page/MDPage', Record, Record>, 'PageP5Js': RouteRecordInfo<'PageP5Js', '/Page/p5_js', Record, Record>,