189 lines
7.6 KiB
HTML
189 lines
7.6 KiB
HTML
<!doctype html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<link rel="icon" href="data:;base64,iVBORw0KGgo=" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>频谱图+瀑布图的html页面</title>
|
|
</head>
|
|
<body>
|
|
<div id="waterfall" style="width: 100%; height: 100%"></div>
|
|
<script src="./lib/konva.2.4.2.min.js"></script>
|
|
<script src="./lib/jquery.3.6.0.min.js"></script>
|
|
<script src="./lib/lodash@4.17.21.min.js"></script>
|
|
<script src="colormapwidget.js"></script>
|
|
<script src="waterfallwidget.js"></script>
|
|
<script>
|
|
// 定义默认配置对象
|
|
const payload = {
|
|
minFreq: 0,
|
|
maxFreq: 200000000,
|
|
rtmode: 0,
|
|
doppler: false,
|
|
adjShow: true,
|
|
adjMaxbw: 100000,
|
|
enableWfBuff: false,
|
|
unitId: 0,
|
|
coorFreqType: 0,
|
|
showFreqLable: true,
|
|
wfFreqPointLable: true,
|
|
wfFreqPointLableList: [],
|
|
showWhitelist: false,
|
|
waveSplite: 0.5,
|
|
};
|
|
|
|
const wfOption = {
|
|
wfRulerEnable: true,
|
|
wfTheme: 'default',
|
|
wfRulerGravity: true,
|
|
wfRulerLocation: -100,
|
|
wfMindB: -120,
|
|
wfMaxdB: 0,
|
|
showPeakMarker: true,
|
|
wfShowAvg: true,
|
|
wfShowMin: false,
|
|
wfShowMax: false,
|
|
wfInfoPos: 0,
|
|
wfCurLine: true,
|
|
specColor: '#00ff00',
|
|
specAvgColor: '#ffff00',
|
|
specMaxColor: '#ff0000',
|
|
specMinColor: '#0000ff',
|
|
afterGlowColor: '#00ffff',
|
|
wfAdjStepType: 0,
|
|
wfAdjStep: 1000,
|
|
};
|
|
|
|
const id = 'waterfall';
|
|
|
|
// 定义 label_manager
|
|
const pl = {
|
|
label_manager: {
|
|
labels: [
|
|
// 这里可以添加一些示例标签,或者保持为空
|
|
// { name: 'FM', id: 'id1', bg_color: '#2bffc6', fore_color: '#000', location: 80000000, bw: 100000 },
|
|
// { name: 'AM', id: 'id2', bg_color: '#2bffc6', fore_color: '#000', location: 90000000, bw: 10000 },
|
|
// { name: 'AM', id: 'id2', bg_color: '#ff0000', fore_color: '#ff0000', location: 90000000, bw: 10000 },
|
|
],
|
|
onclick: function (label) {
|
|
console.log('Label clicked:', label);
|
|
},
|
|
load: function (start, end) {
|
|
// 简单的 load 实现,可以根据需要扩展
|
|
console.log(`Loading labels for range: ${start} - ${end}`);
|
|
// return this.labels.filter(label => label.location >= start && label.location <= end);
|
|
return []; // 返回空数组以避免依赖 this.labels
|
|
},
|
|
},
|
|
};
|
|
|
|
// 全局变量,用于存储 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');
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
<style>
|
|
html,
|
|
body {
|
|
width: 100%;
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
overflow: hidden; /* 防止滚动条出现 */
|
|
}
|
|
|
|
/* 确保容器占满整个 iframe */
|
|
body > div {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|
|
</html>
|