123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- // 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;
- },
- },
- };
|