// cursorReferenceMixin.js // import * as echarts from "echarts"; export default { data() { return { // 参考线相关数据 cursorHightPoints: [], // 存储所有参考线 currentCursorIndex: -1, // 当前参考线索引 peakPoints: [], // 存储所有峰值点 isHandlingCursor: false, // 防止重复处理 chartInstance: null, // ECharts实例 }; }, mounted() { // 监听键盘事件 window.addEventListener("keydown", this.handleKeyDown); }, beforeDestroy() { // 移除事件监听 window.removeEventListener("keydown", this.handleKeyDown); }, methods: { /** * 处理按钮点击生成参考线 */ handleMoveCursor() { console.log("handleMoveCursor", "222"); if (this.isHandlingCursor || !this.envelopeList) return; this.isHandlingCursor = true; // 1. 找到所有峰值点 this.findPeakPoints(); // 2. 如果没有峰值点则返回 if (this.peakPoints.length === 0) { this.isHandlingCursor = false; return; } console.log(this.peakPoints); // 3. 找到Y轴最大值点 const maxPeak = this.peakPoints.reduce((prev, current) => prev.y > current.y ? prev : current ); // 4. 创建参考线数据 const referenceLine = { xAxis: maxPeak.x, val: maxPeak.y.toFixed(9), index: maxPeak.index, }; // 5. 更新参考线 this.cursorHightPoints = [referenceLine]; this.currentCursorIndex = this.peakPoints.findIndex( (p) => p.index === maxPeak.index ); // 6. 更新图表 this.updateCursorElements2(); this.isHandlingCursor = false; }, /** * 查找所有峰值点 */ findPeakPoints() { this.peakPoints = []; const yValues = this.envelopeList.y; const xValues = this.envelopeList.x; // 1. 找到所有局部峰值点(比相邻点都高的点) const allPeaks = []; for (let i = 1; i < yValues.length - 1; i++) { if (yValues[i] > yValues[i - 1] && yValues[i] > yValues[i + 1]) { allPeaks.push({ x: xValues[i], y: yValues[i], index: i, }); } } // 2. 按y值从大到小排序 allPeaks.sort((a, b) => b.y - a.y); this.peakPoints = allPeaks; }, /** * 处理键盘事件 */ handleKeyDown(event) { if (this.cursorHightPoints.length === 0) return; switch (event.keyCode) { case 37: // 左箭头 this.moveCursorToLeft(); break; case 39: // 右箭头 this.moveCursorToRight(); break; default: return; } // 阻止默认行为 event.preventDefault(); }, /** * 向左移动参考线并保持居中 */ moveCursorToLeft() { this.findPeakPoints(); if (this.currentCursorIndex <= 0) return; const newIndex = this.currentCursorIndex - 1; const newPeak = this.peakPoints[newIndex]; this.updateCursorPosition(newPeak, newIndex); this.centerViewOnPeak(newPeak); }, /** * 向右移动参考线并保持居中 */ moveCursorToRight() { this.findPeakPoints(); if (this.currentCursorIndex >= this.peakPoints.length - 1) return; const newIndex = this.currentCursorIndex + 1; const newPeak = this.peakPoints[newIndex]; this.updateCursorPosition(newPeak, newIndex); // this.centerViewOnPeak(newPeak); }, /** * 将视图中心对准峰值点 */ centerViewOnPeak(peak) { if (!this.chartInstance || !peak) return; // 获取当前x轴配置和数据范围 const option = this.chartInstance.getOption(); const xAxis = option.xAxis[0]; // 计算当前可视范围 const axisModel = this.chartInstance.getModel().getComponent("xAxis"); const currentRange = axisModel.axis.scale.getExtent(); const viewWidth = currentRange[1] - currentRange[0]; // 计算新的居中范围(确保不超出数据边界) const newMin = Math.max(xAxis.min, peak.x - viewWidth / 2); const newMax = Math.min(xAxis.max, peak.x + viewWidth / 2); // 应用新的视图范围 this.chartInstance.dispatchAction({ type: "dataZoom", xAxisIndex: 0, start: ((newMin - xAxis.min) / (xAxis.max - xAxis.min)) * 100, end: ((newMax - xAxis.min) / (xAxis.max - xAxis.min)) * 100, animation: { duration: 300, // 添加平滑过渡效果 }, }); }, /** * 更新参考线位置 */ updateCursorPosition(peak, index) { this.cursorHightPoints = [ { xAxis: peak.x, val: peak.y.toFixed(9), index: peak.index, }, ]; console.log(this.cursorHightPoints, "updateCursorPosition"); this.currentCursorIndex = index; this.$nextTick(() => { this.updateCursorElements2(); }); }, /** * 更新参考线元素(不覆盖已有参考线) */ updateCursorElements2() { if (!this.chartInstance) return; // 1. 获取当前图表配置中的已有series const currentOption = this.chartInstance.getOption(); const existingSeries = currentOption.series || []; // 2. 过滤掉旧的峰值参考线(通过id或特定标记识别) const filteredSeries = existingSeries.filter( (series) => !series.id || !series.id.includes("PEAK_REFERENCE_LINE") ); console.log(filteredSeries); // 3. 准备新的峰值参考线配置 const cursorHighLineSeries = { id: "PEAK_REFERENCE_LINE", type: "line", markLine: { data: this.cursorHightPoints.map((point) => ({ xAxis: point.xAxis, label: { formatter: "峰值: " + point.val, }, lineStyle: { color: "#FF0000", }, })), }, }; // 4. 合并所有series配置 const allSeries = [ ...filteredSeries, // 保留已有series cursorHighLineSeries, // 添加新的峰值参考线 ]; console.log(allSeries); // 5. 更新图表配置 this.chartInstance.setOption( { series: allSeries, }, { replaceMerge: ["series"], notMerge: false, } ); }, /** * 获取参考线markLine配置 */ getCursorMarkLineConfig() { return { data: this.cursorHightPoints.map((point) => ({ xAxis: point.xAxis, label: { formatter: "峰值: " + point.val, }, lineStyle: { color: "#FF0000", }, })), symbol: ["none", "none"], silent: true, }; }, removeCursor() { if (!this.chartInstance) return; // 获取当前图表配置中的所有series const currentOption = this.chartInstance.getOption(); const existingSeries = currentOption.series || []; // 过滤掉峰值参考线(通过id或特定标记识别) const filteredSeries = existingSeries.filter( (series) => !series.id || !series.id.includes("PEAK_REFERENCE_LINE") ); // 更新图表配置,移除所有峰值参考线 this.chartInstance.setOption( { series: filteredSeries, }, { replaceMerge: ["series"], notMerge: false, } ); // 清空当前光标数据 this.cursorHightPoints = []; this.currentCursorIndex = -1; }, }, };