rui.jiang 5 dagar sedan
förälder
incheckning
dbc05a76ee

+ 0 - 2
jg/src/typings/components.d.ts

@@ -31,8 +31,6 @@ declare module 'vue' {
     ElCard: typeof import('element-plus/es')['ElCard']
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCol: typeof import('element-plus/es')['ElCol']
-    ElCollapse: typeof import('element-plus/es')['ElCollapse']
-    ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
     ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
     ElContainer: typeof import('element-plus/es')['ElContainer']

+ 792 - 0
jg/src/views/laserRangeFinder/components/PlotOfFit copy.vue

@@ -0,0 +1,792 @@
+<template>
+  <div class="chartsContent">
+    <el-card class="boxchart" shadow="never" v-if="type === 'LeafRootOutline'">
+      <div slot="header" class="clearfix">
+        <h4 style="color: black; font-size: 16px; font-weight: 700">
+          叶片轮廓拟合图
+        </h4>
+        <div style="font-size: 12px; color: #666">
+          <!-- 江西大唐国际新能源有限公司\金华山风电场\01#风机 2024/3/1 11:00:00 -->
+        </div>
+      </div>
+      <div class="line-chart" :ref="`chart${keys}`"></div>
+    </el-card>
+    <el-card
+      class="boxchart"
+      shadow="never"
+      v-else-if="type === 'LeafTipProfile'"
+    >
+      <div slot="header" class="clearfix">
+        <h4 style="color: black; font-size: 16px; font-weight: 700">
+          叶根轮廓拟合图
+        </h4>
+        <!-- <div style="font-size: 12px; color: #666">
+          江西大唐国际新能源有限公司\金华山风电场\01#风机 2024/3/1 11:00:00
+        </div> -->
+      </div>
+      <div class="line-chart" :ref="`chart${keys}`" style="width: 100%"></div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import * as echarts from "echarts"; // 导入 echarts 库
+import screenfull from "screenfull";
+
+export default {
+  props: {
+    keys: {
+      type: String,
+      default: "",
+    },
+    type: {
+      default: "",
+    },
+    LeafRootOutlineData: {
+      // 叶根轮廓拟合图数据
+      type: Object,
+      default: {},
+    },
+  },
+  data() {
+    return {
+      currentIndex: 0, // 默认索引
+      tableData: [], // 数据
+      originalChartStyle: {}, // 用于存储原始样式
+      // 控制标注的显示/隐藏
+      markPointVisible: false,
+      markLineVisible: false,
+    };
+  },
+  watch: {
+    LeafRootOutlineData: {
+      handler(newVal, oldVal) {
+        console.log("newVal, oldVal LeafRootOutlineData", newVal, oldVal);
+        this.updateChart(); // 更新图表
+      },
+      deep: true, // 深度监听
+      immediate: true, // 立即触发
+    },
+    // 监听标注的显示状态变化
+    markPointVisible(newVal, oldVal) {
+      if (newVal !== oldVal) {
+        this.updateChart();
+      }
+    },
+    markLineVisible(newVal, oldVal) {
+      if (newVal !== oldVal) {
+        this.updateChart(); // 更新图表
+      }
+    },
+  },
+  mounted() {
+    this.initializeChart();
+    // 监听键盘事件
+    window.addEventListener("keydown", this.handleKeyDown);
+  },
+  destroyed() {
+    // 移除键盘事件监听
+    window.removeEventListener("keydown", this.handleKeyDown);
+    if (this.chartInstance) {
+      this.chartInstance.dispose(); // 销毁图表实例
+      this.chartInstance = null;
+    }
+  },
+  methods: {
+    handleResize() {
+      if (this.chartInstance) {
+        this.chartInstance.resize();
+      }
+    },
+    // 初始化图表
+    initializeChart() {
+      this.$nextTick(() => {
+        const chartDom = this.$refs[`chart${this.keys}`];
+        this.chartInstance = echarts.init(chartDom);
+
+        if (this.LeafRootOutlineData?.first_blade?.ydata?.length > 0) {
+          this.updateChart();
+          // 保存初始样式
+          this.originalChartStyle = {
+            width: chartDom.style.width,
+            height: chartDom.style.height,
+            backgroundColor: chartDom.style.backgroundColor,
+          };
+        }
+      });
+    },
+updateChart() {
+  console.log("=== LeafRootOutlineData 详细结构 ===");
+  console.log("数据类型:", this.type);
+  console.log(
+    "完整数据:",
+    JSON.parse(JSON.stringify(this.LeafRootOutlineData))
+  );
+
+  if (!this.chartInstance) {
+    console.warn("图表实例未初始化,无法更新图表");
+    this.initializeChart();
+    return;
+  }
+
+  // === 关键修改:只在叶片轮廓拟合图中进行X轴和Y轴偏移 ===
+  let centerXOffset = 0;
+  let centerYOffset = 0;
+
+  if (this.type === "LeafRootOutline") {
+    // 获取叶片1中心点作为坐标零点
+    if (
+      this.LeafRootOutlineData?.blade_center?.xdata?.length > 0 &&
+      this.LeafRootOutlineData?.blade_center?.xdata[0] !== undefined &&
+      this.LeafRootOutlineData?.blade_center?.ydata?.length > 0 &&
+      this.LeafRootOutlineData?.blade_center?.ydata[0] !== undefined
+    ) {
+      centerXOffset = this.LeafRootOutlineData.blade_center.xdata[0];
+      centerYOffset = this.LeafRootOutlineData.blade_center.ydata[0];
+      console.log("叶片轮廓拟合图 - 使用叶片1中心点作为坐标零点:", {
+        X偏移量: centerXOffset.toFixed(4),
+        Y偏移量: centerYOffset.toFixed(4)
+      });
+    } else {
+      console.log("叶片轮廓拟合图 - 没有中心点数据,坐标轴不进行偏移");
+    }
+  }
+
+  // 1) 原始数据 → 四舍五入到4位(保持数值类型)
+  const xRawOriginal = (this.LeafRootOutlineData?.first_blade?.xdata || []).map(
+    (v) => Number(Number(v).toFixed(4))
+  );
+
+  // 处理基础3条叶片数据(叶根和叶片都有的)
+  const y1Raw = this.LeafRootOutlineData.first_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+  const y2Raw = this.LeafRootOutlineData.second_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+  const y3Raw = this.LeafRootOutlineData.third_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+
+  // 2) 根据类型决定是否处理旋转叶片数据
+  let y4Raw, y5Raw, y6Raw;
+  let hasRotateData = false;
+  let allRawY = [y1Raw, y2Raw, y3Raw];
+
+  // 只有在叶片轮廓拟合图中才处理旋转叶片数据
+  if (this.type === "LeafRootOutline") {
+    // 检查旋转叶片数据是否存在,存在则处理
+    if (this.LeafRootOutlineData?.first_rotate_blade?.ydata?.length > 0) {
+      y4Raw = this.LeafRootOutlineData.first_rotate_blade.ydata.map((v) =>
+        Number(Number(v).toFixed(4))
+      );
+      allRawY.push(y4Raw);
+      hasRotateData = true;
+    }
+
+    if (this.LeafRootOutlineData?.second_rotate_blade?.ydata?.length > 0) {
+      y5Raw = this.LeafRootOutlineData.second_rotate_blade.ydata.map((v) =>
+        Number(Number(v).toFixed(4))
+      );
+      allRawY.push(y5Raw);
+      hasRotateData = true;
+    }
+
+    if (this.LeafRootOutlineData?.third_rotate_blade?.ydata?.length > 0) {
+      y6Raw = this.LeafRootOutlineData.third_rotate_blade.ydata.map((v) =>
+        Number(Number(v).toFixed(4))
+      );
+      allRawY.push(y6Raw);
+      hasRotateData = true;
+    }
+  }
+
+  // 3) 计算 minValue(叶根轮廓拟合图使用)
+  const allMinValues = allRawY.map((arr) => Math.min(...arr));
+  const minYAmongAll = Math.min(...allMinValues);
+  const minValue = Number((minYAmongAll - 0.1).toFixed(4));
+
+  // 4) Y数据根据类型决定是否偏移
+  let y1, y2, y3;
+  if (this.type === "LeafRootOutline") {
+    // 叶片轮廓拟合图:Y轴也进行偏移
+    y1 = y1Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+    y2 = y2Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+    y3 = y3Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+  } else {
+    // 叶根轮廓拟合图:保持原来的归一化逻辑
+    y1 = y1Raw.map(v => Number((v - minValue).toFixed(4)));
+    y2 = y2Raw.map(v => Number((v - minValue).toFixed(4)));
+    y3 = y3Raw.map(v => Number((v - minValue).toFixed(4)));
+  }
+
+  // 5) 根据类型决定是否归一化旋转叶片数据
+  let y4, y5, y6;
+  if (hasRotateData && this.type === "LeafRootOutline") {
+    if (y4Raw) y4 = y4Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+    if (y5Raw) y5 = y5Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+    if (y6Raw) y6 = y6Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+  }
+
+  // 6) 基于"偏移后的数据"计算等比例范围
+  const allY = [...y1, ...y2, ...y3];
+  if (hasRotateData && this.type === "LeafRootOutline") {
+    if (y4) allY.push(...y4);
+    if (y5) allY.push(...y5);
+    if (y6) allY.push(...y6);
+  }
+
+  // === 关键修改:对X数据进行偏移 ===
+  const xRaw = this.type === "LeafRootOutline"
+    ? xRawOriginal.map(v => Number((v - centerXOffset).toFixed(4))) // 叶片轮廓拟合图偏移
+    : xRawOriginal; // 叶根轮廓拟合图保持原样
+
+  const minX = Math.min(...xRaw);
+  const maxX = Math.max(...xRaw);
+  const xRange = Number((maxX - minX).toFixed(4));
+
+  const minY = Math.min(...allY);
+  const maxY = Math.max(...allY);
+  
+  // 这里的 targetYRange 仅用于确保显示比例,不作为强制范围
+  const { clientWidth: w, clientHeight: h } = this.chartInstance.getDom();
+  const aspectRatio = w / h;
+  const targetYRange = Number((xRange / aspectRatio).toFixed(4));
+
+  // 检查是否有拟合圆数据
+  const hasCircleData =
+    this.type === "LeafTipProfile" &&
+    (this.LeafRootOutlineData?.first_circle ||
+      this.LeafRootOutlineData?.second_circle ||
+      this.LeafRootOutlineData?.third_circle);
+
+  // === 关键修改:计算拟合圆的真实范围(使用归一化后的数据)===
+  let circleXMinGlobal = Infinity,
+    circleXMaxGlobal = -Infinity;
+  let circleNormalizedYMinGlobal = Infinity,
+    circleNormalizedYMaxGlobal = -Infinity;
+
+  // === 新增:处理拟合圆数据(只针对叶根轮廓拟合图)===
+  const circleSeries = [];
+  if (this.type === "LeafTipProfile") {
+    // 定义拟合圆名称和颜色
+    const circleConfigs = [
+      { key: "first_circle", name: "叶根1拟合圆", color: "#F44336" },
+      { key: "second_circle", name: "叶根2拟合圆", color: "#4CAF50" },
+      { key: "third_circle", name: "叶根3拟合圆", color: "#FFA726" },
+    ];
+
+    // 循环处理三个拟合圆数据
+    circleConfigs.forEach((config, index) => {
+      const circleData = this.LeafRootOutlineData[config.key];
+
+      if (circleData?.xdata?.length > 0 && circleData?.ydata?.length > 0) {
+        // === 修复:拟合圆数据也需要减去minValue进行归一化 ===
+        const circlePoints = circleData.xdata.map((x, i) => [
+          Number(x.toFixed(4)),  // X轴保持不变
+          Number((circleData.ydata[i] - minValue).toFixed(4)),  // Y轴减去minValue归一化
+        ]);
+
+        // === 计算归一化后的拟合圆Y值范围 ===
+        const normalizedYValues = circleData.ydata.map(y => y - minValue);
+        const thisCircleXMin = Math.min(...circleData.xdata);
+        const thisCircleXMax = Math.max(...circleData.xdata);
+        const thisNormalizedYMin = Math.min(...normalizedYValues);
+        const thisNormalizedYMax = Math.max(...normalizedYValues);
+
+        // 更新全局范围
+        circleXMinGlobal = Math.min(circleXMinGlobal, thisCircleXMin);
+        circleXMaxGlobal = Math.max(circleXMaxGlobal, thisCircleXMax);
+        circleNormalizedYMinGlobal = Math.min(circleNormalizedYMinGlobal, thisNormalizedYMin);
+        circleNormalizedYMaxGlobal = Math.max(circleNormalizedYMaxGlobal, thisNormalizedYMax);
+
+        circleSeries.push({
+          name: config.name,
+          type: "line",
+          showSymbol: false,
+          lineStyle: {
+            width: 2,
+            type: "dashed", // 虚线区分
+            color: config.color,
+          },
+          itemStyle: { color: config.color },
+          data: circlePoints,
+          smooth: true, // 拟合圆需要平滑
+        });
+      }
+    });
+  }
+
+  // === 关键修改:调整坐标轴显示范围 - 计算实际数据边界 ===
+  // 计算所有需要显示的数据的X范围(包括拟合圆)
+  const allDisplayXMin = Math.min(
+    minX,
+    circleXMinGlobal !== Infinity ? circleXMinGlobal : minX
+  );
+  const allDisplayXMax = Math.max(
+    maxX,
+    circleXMaxGlobal !== -Infinity ? circleXMaxGlobal : maxX
+  );
+  const allDisplayXRange = allDisplayXMax - allDisplayXMin;
+
+  // 计算所有需要显示的数据的Y范围(包括拟合圆)
+  const allDisplayYMin = Math.min(
+    minY,
+    circleNormalizedYMinGlobal !== Infinity ? circleNormalizedYMinGlobal : minY
+  );
+  const allDisplayYMax = Math.max(
+    maxY,
+    circleNormalizedYMaxGlobal !== -Infinity ? circleNormalizedYMaxGlobal : maxY
+  );
+  const allDisplayYRange = allDisplayYMax - allDisplayYMin;
+
+  // 为显示增加10%的边距
+  const xMargin = allDisplayXRange * 0.1;
+  const yMargin = allDisplayYRange * 0.1;
+
+  // 1. 初始计算轴系边界 (包含边距)
+  let xAxisMin = allDisplayXMin - xMargin;
+  let xAxisMax = allDisplayXMax + xMargin;
+  let yAxisMin = allDisplayYMin - yMargin;
+  let yAxisMax = allDisplayYMax + yMargin;
+
+  // ============= 修改点 1:X轴范围处理逻辑(新增) =============
+  // 如果实际数据的最小值 >= 0,则强制 X 轴从 0 开始
+  if (allDisplayXMin >= 0) {
+    xAxisMin = 0;
+  }
+  // 如果 allDisplayXMin < 0,保持上面的 xAxisMin 计算结果(即实际最小值减去边距)
+
+  // 调整X轴最大值为整洁数值(只在叶片轮廓拟合图中)
+  if (this.type === "LeafRootOutline") {
+    const adjustedXAxisMax = Math.ceil(xAxisMax * 10) / 10;
+    xAxisMax = adjustedXAxisMax + 0.02; // 增加0.02的边距
+  }
+
+  // ============= 修改点 2:Y轴范围处理逻辑(保留上一步的修改) =============
+  // 如果实际数据的最小值 >= 0,则强制 Y 轴从 0 开始
+  if (allDisplayYMin >= 0) {
+    yAxisMin = 0;
+  }
+  
+  console.log("坐标轴显示范围:", {
+    最终X范围: `${xAxisMin.toFixed(4)}-${xAxisMax.toFixed(4)}`,
+    最终Y范围: `${yAxisMin.toFixed(4)}-${yAxisMax.toFixed(4)}`,
+    实际数据X最小值: allDisplayXMin.toFixed(4),
+    实际数据Y最小值: allDisplayYMin.toFixed(4),
+  });
+
+  // 生成所有Y轴标签
+  const yLabels = Array.from(new Set(allY.map((v) => v.toFixed(1))));
+  const xLabels = xRaw.map((v) => v.toFixed(1));
+
+  // 准备中心点数据
+  const centerSeries = [];
+  const baseColors = ["#F44336", "#4CAF50", "#FFA726"]; // 基础叶片颜色
+  const testColors = ["#FF0000", "#00FF00", "#0000FF"]; // 测试颜色
+
+  // 如果blade_center存在且有数据,使用实际数据
+  if (
+    this.LeafRootOutlineData?.blade_center?.xdata?.length > 0 &&
+    this.LeafRootOutlineData?.blade_center?.ydata?.length > 0
+  ) {
+    const centerData = this.LeafRootOutlineData.blade_center;
+    // 为叶片1-3添加中心点
+    for (
+      let i = 0;
+      i < Math.min(3, centerData.xdata.length, centerData.ydata.length);
+      i++
+    ) {
+      const centerX = this.type === "LeafRootOutline"
+        ? Number((centerData.xdata[i] - centerXOffset).toFixed(4))
+        : Number(centerData.xdata[i].toFixed(4));
+
+      let centerY;
+      if (this.type === "LeafRootOutline") {
+        centerY = Number((centerData.ydata[i] - centerYOffset).toFixed(4));
+      } else {
+        centerY = Number((centerData.ydata[i] - minValue).toFixed(4));
+      }
+
+      centerSeries.push({
+        name: this.keys === "blade_tip" ? `叶根${i + 1}中心点` : `叶片${i + 1}中心点`,
+        type: "scatter",
+        symbolSize: 10,
+        itemStyle: { color: baseColors[i] },
+        data: [[centerX, centerY]],
+      });
+    }
+
+    // 只有在叶片轮廓拟合图且有旋转数据时,才为旋转叶片添加中心点
+    if (this.type === "LeafRootOutline" && hasRotateData) {
+      for (
+        let i = 3;
+        i < Math.min(6, centerData.xdata.length, centerData.ydata.length);
+        i++
+      ) {
+        const centerX = Number((centerData.xdata[i] - centerXOffset).toFixed(4));
+        const centerY = Number((centerData.ydata[i] - centerYOffset).toFixed(4));
+
+        centerSeries.push({
+          name: `旋转叶片${i - 2}中心点`,
+          type: "scatter",
+          symbolSize: 10,
+          itemStyle: { color: baseColors[i - 3] },
+          data: [[centerX, centerY]],
+        });
+      }
+    }
+  } else {
+    // 测试数据逻辑...
+    const testBladeCenter = {
+      xdata: [1.1409272443980873, 1.1486257802831674, 1.1449090600730372],
+      ydata: [88.97949196195555, 88.9672705736207, 88.98638594209639],
+    };
+    const pointCount = 3;
+    for (let i = 0; i < pointCount; i++) {
+      const centerX = this.type === "LeafRootOutline"
+        ? Number((testBladeCenter.xdata[i] - centerXOffset).toFixed(4))
+        : Number(testBladeCenter.xdata[i].toFixed(4));
+      let centerY;
+      if (this.type === "LeafRootOutline") {
+        centerY = Number((testBladeCenter.ydata[i] - centerYOffset).toFixed(4));
+      } else {
+        centerY = Number((testBladeCenter.ydata[i] - minValue).toFixed(4));
+      }
+      centerSeries.push({
+        name: this.keys === "blade_tip" ? `叶根${i + 1}中心点(测试)` : `叶片${i + 1}中心点(测试)`,
+        type: "scatter",
+        symbolSize: 12,
+        itemStyle: { color: testColors[i] },
+        data: [[centerX, centerY]],
+      });
+    }
+  }
+
+  // 准备所有叶片系列
+  const series = [
+    {
+      name: this.keys === "blade_tip" ? "叶根1轮廓" : "叶片1轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#F44336" },
+      data: xRaw.map((x, i) => [x, y1[i]]),
+      smooth: true,
+    },
+    {
+      name: this.keys === "blade_tip" ? "叶根2轮廓" : "叶片2轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#4CAF50" },
+      data: xRaw.map((x, i) => [x, y2[i]]),
+      smooth: true,
+    },
+    {
+      name: this.keys === "blade_tip" ? "叶根3轮廓" : "叶片3轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#FFA726" },
+      data: xRaw.map((x, i) => [x, y3[i]]),
+      smooth: true,
+    },
+  ];
+
+  const legendData = [
+    this.keys === "blade_tip" ? "叶根1轮廓" : "叶片1轮廓",
+    this.keys === "blade_tip" ? "叶根2轮廓" : "叶片2轮廓",
+    this.keys === "blade_tip" ? "叶根3轮廓" : "叶片3轮廓",
+  ];
+
+  if (this.type === "LeafRootOutline" && hasRotateData) {
+    const rotateSeries = [];
+    if (y4) {
+      rotateSeries.push({
+        name: "旋转叶片1轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" },
+        itemStyle: { color: "#F44336" },
+        data: xRaw.map((x, i) => [x, y4[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片1轮廓");
+    }
+    if (y5) {
+      rotateSeries.push({
+        name: "旋转叶片2轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" },
+        itemStyle: { color: "#4CAF50" },
+        data: xRaw.map((x, i) => [x, y5[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片2轮廓");
+    }
+    if (y6) {
+      rotateSeries.push({
+        name: "旋转叶片3轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" },
+        itemStyle: { color: "#FFA726" },
+        data: xRaw.map((x, i) => [x, y6[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片3轮廓");
+    }
+    series.push(...rotateSeries);
+  }
+
+  if (this.type === "LeafTipProfile" && circleSeries.length > 0) {
+    series.push(...circleSeries);
+    circleSeries.forEach((circle) => {
+      legendData.push(circle.name);
+    });
+  }
+  series.push(...centerSeries);
+
+  let colors = ["#F44336", "#4CAF50", "#FFA726"];
+  if ((this.type === "LeafRootOutline" && hasRotateData) || (this.type === "LeafTipProfile" && circleSeries.length > 0)) {
+    colors = [...colors, "#F44336", "#4CAF50", "#FFA726"];
+  }
+
+  // === Y轴配置 ===
+  const yAxisConfig = {
+    type: "value",
+    name: "距离(m)",
+    nameLocation: "middle",
+    nameTextStyle: { fontWeight: "bold", padding: [0, 0, 40, 0] },
+    min: yAxisMin,
+    max: yAxisMax,
+    interval: 0.2,
+    axisLabel: {
+      formatter: function (value) {
+        return value.toFixed(1);
+      },
+    },
+  };
+
+  const option = {
+    grid: { left: 80, right: 40, top: 40, bottom: 60 },
+    color: colors,
+    toolbox: {
+      feature: {
+        dataZoom: { yAxisIndex: "none" },
+        restore: {},
+        saveAsImage: {},
+        myCustomTool1: {
+          show: true,
+          title: "标注",
+          icon: `image://${new URL("@/assets/analyse/mark.png", import.meta.url)}`,
+          onclick: () => this.WhetherToDisplay(),
+        },
+        myCustomTool2: {
+          show: true,
+          title: "全屏",
+          icon: `image://${new URL("@/assets/analyse/fullScreen.png", import.meta.url)}`,
+          onclick: () => this.fullScreen(),
+        },
+        myCustomTool3: {
+          show: true,
+          title: "退出全屏",
+          icon: `image://${new URL("@/assets/analyse/exitFullScreen.png", import.meta.url)}`,
+          onclick: () => this.exitFullScreen(),
+        },
+      },
+    },
+    xAxis: {
+      type: "value",
+      name: "距离(m)",
+      nameLocation: "middle",
+      nameTextStyle: { fontWeight: "bold", padding: [20, 0, 0, 0] },
+      min: xAxisMin, // 使用经过调整后的 xAxisMin
+      max: xAxisMax,
+      splitNumber: 15,
+      data: [...new Set(xLabels)],
+      splitLine: { show: true, lineStyle: { color: "rgb(220,220,220)" } },
+      axisLabel: {
+        formatter: function (value) {
+          return value.toFixed(1);
+        }
+      },
+      interval: 0.2,
+    },
+    yAxis: yAxisConfig,
+    tooltip: {
+      trigger: "axis",
+      valueFormatter: (v) => (typeof v === "number" ? v.toFixed(4) : v),
+      position: (pt) => [pt[0], "10%"],
+      confine: false,
+      appendToBody: true,
+    },
+    legend: {
+      data: legendData,
+      left: 0,
+      top: 0,
+    },
+    series: series,
+  };
+
+  this.chartInstance.setOption(option, true);
+
+  // ======== 动态高度计算 ========
+  this.$nextTick(() => {
+    const maxYLabelLen = [...new Set(yLabels)].length;
+    const chartDom = this.$refs[`chart${this.keys}`];
+    const chartWidth = chartDom.clientWidth;
+    const grid = option.grid && option.grid[0] ? option.grid[0] : { left: 0, right: 0 };
+    const xAxisWidth = chartWidth - (parseInt(grid.left) || 0) - (parseInt(grid.right) || 0);
+    const xAxisWidthPerLabel = xAxisWidth / 15;
+
+    let baseHeight = 400;
+
+    if (maxYLabelLen > [...new Set(xLabels)].length) {
+      baseHeight = maxYLabelLen * xAxisWidthPerLabel;
+    } else if (maxYLabelLen < [...new Set(xLabels)].length) {
+      const xAxisWidthPerLabelAll = xAxisWidth / [...new Set(xLabels)].length;
+      baseHeight = maxYLabelLen * xAxisWidthPerLabelAll;
+    }
+
+    // 拟合圆模式保持1:1比例
+    if (hasCircleData) {
+      const xDisplayRange = xAxisMax - xAxisMin;
+      const yDisplayRange = yAxisMax - yAxisMin;
+      const rangeRatio = xDisplayRange / yDisplayRange;
+      const heightFor1to1 = chartWidth / rangeRatio;
+      baseHeight = Math.max(baseHeight, heightFor1to1);
+    }
+
+    chartDom.style.height = baseHeight + "px";
+    this.chartInstance.resize();
+  });
+
+  if (this._onResizeEqualScale) {
+    window.removeEventListener("resize", this._onResizeEqualScale);
+  }
+  this._onResizeEqualScale = () => this.updateChart();
+  window.addEventListener("resize", this._onResizeEqualScale);
+},
+    // 标注是否显示
+    WhetherToDisplay() {
+      // 切换显示状态
+      this.markPointVisible = !this.markPointVisible;
+      this.markLineVisible = !this.markLineVisible;
+    },
+    previousRow() {
+      let newIndex =
+        this.currentIndex > 0
+          ? this.currentIndex - 1
+          : this.tableData.length - 1;
+      this.$emit("update:currentIndex", newIndex);
+    },
+    nextRow() {
+      console.log("下一条");
+      let newIndex =
+        this.currentIndex < this.tableData.length - 1
+          ? this.currentIndex + 1
+          : 0;
+      this.$emit("update:currentIndex", newIndex);
+    },
+    toggleFullScreen() {
+      const chartDom = this.$refs[`chart${this.keys}`];
+      if (screenfull.isEnabled) {
+        screenfull.toggle(chartDom);
+      }
+    },
+    fullScreen() {
+      const chartDom = this.$refs[`chart${this.keys}`];
+      if (screenfull.isEnabled) {
+        // 设置全屏样式
+        chartDom.style.position = "absolute";
+        chartDom.style.top = 0;
+        chartDom.style.left = 0;
+        chartDom.style.width = "100vw";
+        chartDom.style.height = "100vh";
+        chartDom.style.backgroundColor = "#ffffff";
+
+        // 进入全屏
+        screenfull.request(chartDom);
+        this.chartInstance.resize();
+
+        // 监听全屏变化
+        screenfull.on("change", this.handleFullScreenChange);
+      }
+    },
+    exitFullScreen() {
+      const chartDom = this.$refs[`chart${this.keys}`];
+      if (screenfull.isEnabled) {
+        screenfull.exit();
+        // 监听全屏变化
+        screenfull.on("change", this.handleFullScreenChange);
+      }
+    },
+    // 处理全屏变化的回调
+    handleFullScreenChange() {
+      const chartDom = this.$refs[`chart${this.keys}`];
+      if (!screenfull.isFullscreen) {
+        // 退出全屏时恢复样式
+        chartDom.style.position = this.originalChartStyle.position || "";
+        chartDom.style.top = this.originalChartStyle.top || "";
+        chartDom.style.left = this.originalChartStyle.left || "";
+        chartDom.style.width = this.originalChartStyle.width || "100%";
+        chartDom.style.height = this.originalChartStyle.height || "400px";
+        chartDom.style.backgroundColor =
+          this.originalChartStyle.backgroundColor || "#fff";
+
+        // 调整图表尺寸
+        this.chartInstance.resize();
+
+        // 可选:移除事件监听(如果不再需要)
+        screenfull.off("change", this.handleFullScreenChange);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep .el-card__body {
+  width: 100%;
+  // height: 250px;
+  position: relative;
+}
+.chartsContent {
+  .boxchart {
+    overflow: hidden !important;
+    :deep(.el-card__body) {
+      width: 100%;
+      overflow: hidden !important;
+    }
+  }
+}
+
+.line-chart {
+  width: 100%;
+  // height: 400px;
+  background-color: #fff;
+  position: relative;
+}
+.line-chart > div {
+  width: 100%;
+  height: 100%;
+}
+.eigenvalue {
+  position: absolute;
+  top: 0;
+  right: 0;
+  font-size: 10px;
+  width: 100px;
+  border: 1px solid black;
+  padding: 5px;
+  background: #fff;
+  z-index: 99;
+  h5 {
+    line-height: 16px;
+    height: 16px;
+  }
+}
+</style>

+ 1013 - 0
jg/src/views/laserRangeFinder/components/PlotOfFit 叶片轮廓拟合图 .vue

@@ -0,0 +1,1013 @@
+<template>
+  <div class="chartsContent">
+    <el-card class="boxchart" shadow="never" v-if="type === 'LeafRootOutline'">
+      <div slot="header" class="clearfix">
+        <h4 style="color: black; font-size: 16px; font-weight: 700">
+          叶片轮廓拟合图
+        </h4>
+        <div style="font-size: 12px; color: #666">
+          <!-- 江西大唐国际新能源有限公司\金华山风电场\01#风机 2024/3/1 11:00:00 -->
+        </div>
+      </div>
+      <div class="line-chart" :ref="`chart${keys}`"></div>
+    </el-card>
+    <el-card
+      class="boxchart"
+      shadow="never"
+      v-else-if="type === 'LeafTipProfile'"
+    >
+      <div slot="header" class="clearfix">
+        <h4 style="color: black; font-size: 16px; font-weight: 700">
+          叶根轮廓拟合图
+        </h4>
+        <!-- <div style="font-size: 12px; color: #666">
+          江西大唐国际新能源有限公司\金华山风电场\01#风机 2024/3/1 11:00:00
+        </div> -->
+      </div>
+      <div class="line-chart" :ref="`chart${keys}`" style="width: 100%"></div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import * as echarts from "echarts"; // 导入 echarts 库
+import screenfull from "screenfull";
+
+export default {
+  props: {
+    keys: {
+      type: String,
+      default: "",
+    },
+    type: {
+      default: "",
+    },
+    LeafRootOutlineData: {
+      // 叶根轮廓拟合图数据
+      type: Object,
+      default: {},
+    },
+  },
+  data() {
+    return {
+      currentIndex: 0, // 默认索引
+      tableData: [], // 数据
+      originalChartStyle: {}, // 用于存储原始样式
+      // 控制标注的显示/隐藏
+      markPointVisible: false,
+      markLineVisible: false,
+    };
+  },
+  watch: {
+    LeafRootOutlineData: {
+      handler(newVal, oldVal) {
+        console.log("newVal, oldVal LeafRootOutlineData", newVal, oldVal);
+        this.updateChart(); // 更新图表
+      },
+      deep: true, // 深度监听
+      immediate: true, // 立即触发
+    },
+    // 监听标注的显示状态变化
+    markPointVisible(newVal, oldVal) {
+      if (newVal !== oldVal) {
+        this.updateChart();
+      }
+    },
+    markLineVisible(newVal, oldVal) {
+      if (newVal !== oldVal) {
+        this.updateChart(); // 更新图表
+      }
+    },
+  },
+  mounted() {
+    this.initializeChart();
+    // 监听键盘事件
+    window.addEventListener("keydown", this.handleKeyDown);
+  },
+  destroyed() {
+    // 移除键盘事件监听
+    window.removeEventListener("keydown", this.handleKeyDown);
+    if (this.chartInstance) {
+      this.chartInstance.dispose(); // 销毁图表实例
+      this.chartInstance = null;
+    }
+  },
+  methods: {
+    handleResize() {
+      if (this.chartInstance) {
+        this.chartInstance.resize();
+      }
+    },
+    // 初始化图表
+    initializeChart() {
+      this.$nextTick(() => {
+        const chartDom = this.$refs[`chart${this.keys}`];
+        this.chartInstance = echarts.init(chartDom);
+
+        if (this.LeafRootOutlineData?.first_blade?.ydata?.length > 0) {
+          this.updateChart();
+          // 保存初始样式
+          this.originalChartStyle = {
+            width: chartDom.style.width,
+            height: chartDom.style.height,
+            backgroundColor: chartDom.style.backgroundColor,
+          };
+        }
+      });
+    },
+updateChart() {
+  console.log("=== LeafRootOutlineData 详细结构 ===");
+  console.log("数据类型:", this.type);
+  console.log(
+    "完整数据:",
+    JSON.parse(JSON.stringify(this.LeafRootOutlineData))
+  );
+
+  if (!this.chartInstance) {
+    console.warn("图表实例未初始化,无法更新图表");
+    this.initializeChart();
+    return;
+  }
+
+  // === 关键修改:只在叶片轮廓拟合图中进行X轴和Y轴偏移 ===
+  let centerXOffset = 0;
+  let centerYOffset = 0;
+  
+  if (this.type === "LeafRootOutline") {
+    // 获取叶片1中心点作为坐标零点
+    if (
+      this.LeafRootOutlineData?.blade_center?.xdata?.length > 0 &&
+      this.LeafRootOutlineData?.blade_center?.xdata[0] !== undefined &&
+      this.LeafRootOutlineData?.blade_center?.ydata?.length > 0 &&
+      this.LeafRootOutlineData?.blade_center?.ydata[0] !== undefined
+    ) {
+      centerXOffset = this.LeafRootOutlineData.blade_center.xdata[0];
+      centerYOffset = this.LeafRootOutlineData.blade_center.ydata[0];
+      console.log("叶片轮廓拟合图 - 使用叶片1中心点作为坐标零点:", {
+        X偏移量: centerXOffset.toFixed(4),
+        Y偏移量: centerYOffset.toFixed(4)
+      });
+    } else {
+      console.log("叶片轮廓拟合图 - 没有中心点数据,坐标轴不进行偏移");
+    }
+  }
+
+  // 1) 原始数据 → 四舍五入到4位(保持数值类型)
+  const xRawOriginal = (this.LeafRootOutlineData?.first_blade?.xdata || []).map(
+    (v) => Number(Number(v).toFixed(4))
+  );
+
+  // 处理基础3条叶片数据(叶根和叶片都有的)
+  const y1Raw = this.LeafRootOutlineData.first_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+  const y2Raw = this.LeafRootOutlineData.second_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+  const y3Raw = this.LeafRootOutlineData.third_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+
+  // 2) 根据类型决定是否处理旋转叶片数据
+  let y4Raw, y5Raw, y6Raw;
+  let hasRotateData = false;
+  let allRawY = [y1Raw, y2Raw, y3Raw];
+
+  // 只有在叶片轮廓拟合图中才处理旋转叶片数据
+  if (this.type === "LeafRootOutline") {
+    // 检查旋转叶片数据是否存在,存在则处理
+    if (this.LeafRootOutlineData?.first_rotate_blade?.ydata?.length > 0) {
+      y4Raw = this.LeafRootOutlineData.first_rotate_blade.ydata.map((v) =>
+        Number(Number(v).toFixed(4))
+      );
+      allRawY.push(y4Raw);
+      hasRotateData = true;
+    }
+
+    if (this.LeafRootOutlineData?.second_rotate_blade?.ydata?.length > 0) {
+      y5Raw = this.LeafRootOutlineData.second_rotate_blade.ydata.map((v) =>
+        Number(Number(v).toFixed(4))
+      );
+      allRawY.push(y5Raw);
+      hasRotateData = true;
+    }
+
+    if (this.LeafRootOutlineData?.third_rotate_blade?.ydata?.length > 0) {
+      y6Raw = this.LeafRootOutlineData.third_rotate_blade.ydata.map((v) =>
+        Number(Number(v).toFixed(4))
+      );
+      allRawY.push(y6Raw);
+      hasRotateData = true;
+    }
+  }
+
+  // 3) 计算 minValue(叶根轮廓拟合图使用)
+  const allMinValues = allRawY.map((arr) => Math.min(...arr));
+  const minYAmongAll = Math.min(...allMinValues);
+  const minValue = Number((minYAmongAll - 0.1).toFixed(4));
+
+  // 4) Y数据根据类型决定是否偏移
+  let y1, y2, y3;
+  if (this.type === "LeafRootOutline") {
+    // 叶片轮廓拟合图:Y轴也进行偏移
+    y1 = y1Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+    y2 = y2Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+    y3 = y3Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+  } else {
+    // 叶根轮廓拟合图:保持原来的归一化逻辑
+    y1 = y1Raw.map(v => Number((v - minValue).toFixed(4)));
+    y2 = y2Raw.map(v => Number((v - minValue).toFixed(4)));
+    y3 = y3Raw.map(v => Number((v - minValue).toFixed(4)));
+  }
+
+  // 5) 根据类型决定是否归一化旋转叶片数据
+  let y4, y5, y6;
+  if (hasRotateData && this.type === "LeafRootOutline") {
+    if (y4Raw) y4 = y4Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+    if (y5Raw) y5 = y5Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+    if (y6Raw) y6 = y6Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+  }
+
+  // 6) 基于"偏移后的数据"计算等比例范围
+  const allY = [...y1, ...y2, ...y3];
+  if (hasRotateData && this.type === "LeafRootOutline") {
+    if (y4) allY.push(...y4);
+    if (y5) allY.push(...y5);
+    if (y6) allY.push(...y6);
+  }
+
+  // === 关键修改:对X数据进行偏移 ===
+  const xRaw = this.type === "LeafRootOutline"
+    ? xRawOriginal.map(v => Number((v - centerXOffset).toFixed(4))) // 叶片轮廓拟合图偏移
+    : xRawOriginal; // 叶根轮廓拟合图保持原样
+
+  const minX = Math.min(...xRaw);
+  const maxX = Math.max(...xRaw);
+  const xRange = Number((maxX - minX).toFixed(4));
+
+  const minY = Math.min(...allY);
+  const maxY = Math.max(...allY);
+  const yRange = Number((maxY - minY).toFixed(4));
+  
+  const { clientWidth: w, clientHeight: h } = this.chartInstance.getDom();
+  const aspectRatio = w / h;
+
+  // 让单位像素一致:目标 yRange = xRange / (w/h)
+  const targetYRange = Number((xRange / aspectRatio).toFixed(4));
+
+  // === 重要修改:针对拟合圆的特殊处理 ===
+  // 如果是叶根轮廓拟合图且有拟合圆,需要保持纵横比1:1
+  let yMin = this.type === "LeafRootOutline" ? minY : 0; // 叶片轮廓拟合图允许负数
+  let yMax = this.type === "LeafRootOutline" 
+    ? Number(Math.max(Math.abs(maxY), Math.abs(minY), targetYRange).toFixed(4))
+    : Number(Math.max(maxY, targetYRange).toFixed(4));
+
+  // 检查是否有拟合圆数据
+  const hasCircleData =
+    this.type === "LeafTipProfile" &&
+    (this.LeafRootOutlineData?.first_circle ||
+      this.LeafRootOutlineData?.second_circle ||
+      this.LeafRootOutlineData?.third_circle);
+
+  // === 关键修改:计算拟合圆的真实范围 ===
+  let circleXMin = Infinity,
+    circleXMax = -Infinity;
+  let circleYMin = Infinity,
+    circleYMax = -Infinity;
+  let circleNormalizedYMin = Infinity,
+    circleNormalizedYMax = -Infinity;
+
+  if (hasCircleData) {
+    // 计算所有拟合圆的实际范围
+    const circleConfigs = [
+      { key: "first_circle" },
+      { key: "second_circle" },
+      { key: "third_circle" },
+    ];
+
+    circleConfigs.forEach((config) => {
+      const circleData = this.LeafRootOutlineData[config.key];
+      if (circleData?.xdata?.length > 0 && circleData?.ydata?.length > 0) {
+        const thisCircleXMin = Math.min(...circleData.xdata);
+        const thisCircleXMax = Math.max(...circleData.xdata);
+        const thisCircleYMin = Math.min(...circleData.ydata);
+        const thisCircleYMax = Math.max(...circleData.ydata);
+
+        circleXMin = Math.min(circleXMin, thisCircleXMin);
+        circleXMax = Math.max(circleXMax, thisCircleXMax);
+        circleYMin = Math.min(circleYMin, thisCircleYMin);
+        circleYMax = Math.max(circleYMax, thisCircleYMax);
+
+        // 计算归一化后的Y范围(叶根轮廓拟合图使用)
+        const thisNormalizedYMin = thisCircleYMin - minValue;
+        const thisNormalizedYMax = thisCircleYMax - minValue;
+        circleNormalizedYMin = Math.min(
+          circleNormalizedYMin,
+          thisNormalizedYMin
+        );
+        circleNormalizedYMax = Math.max(
+          circleNormalizedYMax,
+          thisNormalizedYMax
+        );
+      }
+    });
+
+    console.log("叶根轮廓拟合图 - 拟合圆实际范围:", {
+      circleXMin: circleXMin.toFixed(4),
+      circleXMax: circleXMax.toFixed(4),
+      circleYMin: circleYMin.toFixed(4),
+      circleYMax: circleYMax.toFixed(4),
+      circleNormalizedYMin: circleNormalizedYMin.toFixed(4),
+      circleNormalizedYMax: circleNormalizedYMax.toFixed(4),
+    });
+
+    // 对于拟合圆,我们需要保持1:1的纵横比,让圆形不被压扁
+    // 计算拟合圆的X和Y范围
+    const circleXRange = circleXMax - circleXMin;
+    const circleNormalizedYRange = circleNormalizedYMax - circleNormalizedYMin;
+
+    // 取X和Y范围中的较大值作为基准
+    const baseRange = Math.max(circleXRange, circleNormalizedYRange);
+
+    // 确保Y轴范围足够大以显示拟合圆
+    yMax = Math.max(maxY, baseRange, targetYRange);
+
+    console.log("叶根轮廓拟合图 - 拟合圆模式:强制保持1:1纵横比", {
+      circleXRange: circleXRange.toFixed(4),
+      circleNormalizedYRange: circleNormalizedYRange.toFixed(4),
+      baseRange: baseRange.toFixed(4),
+      maxY: maxY.toFixed(4),
+      targetYRange: targetYRange.toFixed(4),
+      finalYMax: yMax.toFixed(4),
+    });
+  }
+
+  // === 关键修改:调整坐标轴显示范围 ===
+  // 计算所有需要显示的数据的X范围(包括拟合圆)
+  const allDisplayXMin = Math.min(
+    minX,
+    circleXMin !== Infinity ? circleXMin : minX
+  );
+  const allDisplayXMax = Math.max(
+    maxX,
+    circleXMax !== -Infinity ? circleXMax : maxX
+  );
+  const allDisplayXRange = allDisplayXMax - allDisplayXMin;
+
+  // 为显示增加10%的边距
+  const xMargin = allDisplayXRange * 0.1;
+  const yMargin = yMax * 0.1;
+
+  // === 关键修改:调整X轴和Y轴显示范围 ===
+  let xAxisMin = this.type === "LeafRootOutline" 
+    ? allDisplayXMin - xMargin // 叶片轮廓拟合图允许负数
+    : Math.max(0, allDisplayXMin - xMargin); // 叶根轮廓拟合图从0开始
+  
+  let xAxisMax = allDisplayXMax + xMargin;
+  
+  let yAxisMin = this.type === "LeafRootOutline" 
+    ? minY - yMargin // 叶片轮廓拟合图允许负数
+    : 0; // 叶根轮廓拟合图从0开始
+  
+  let yAxisMax = yMax + yMargin;
+  
+  // 对于叶片轮廓拟合图,确保Y轴对称(正负范围相等)
+  if (this.type === "LeafRootOutline") {
+    const maxAbsY = Math.max(Math.abs(yAxisMin), Math.abs(yAxisMax));
+    yAxisMin = -maxAbsY;
+    yAxisMax = maxAbsY;
+  }
+
+  // 调整X轴最大值为整洁数值(只在叶片轮廓拟合图中)
+  if (this.type === "LeafRootOutline") {
+    const adjustedXAxisMax = Math.ceil(xAxisMax * 10) / 10;
+    xAxisMax = adjustedXAxisMax + 0.02; // 增加0.02的边距
+    
+    console.log("叶片轮廓拟合图 - 调整X轴最大值为整洁数值:", {
+      原始X轴最大值: xAxisMax.toFixed(4),
+      调整后X轴最大值: adjustedXAxisMax.toFixed(1),
+      最终X轴最大值: xAxisMax.toFixed(2)
+    });
+  }
+
+  console.log("坐标轴显示范围:", {
+    原始X范围: `${minX.toFixed(4)}-${maxX.toFixed(4)}`,
+    原始Y范围: `${minY.toFixed(4)}-${maxY.toFixed(4)}`,
+    最终X范围: `${xAxisMin.toFixed(4)}-${xAxisMax.toFixed(4)}`,
+    最终Y范围: `${yAxisMin.toFixed(4)}-${yAxisMax.toFixed(4)}`,
+    X轴偏移量: this.type === "LeafRootOutline" ? centerXOffset.toFixed(4) : "无偏移",
+    Y轴偏移量: this.type === "LeafRootOutline" ? centerYOffset.toFixed(4) : "无偏移",
+  });
+
+  // 生成所有Y轴标签
+  const yLabels = Array.from(new Set(allY.map((v) => v.toFixed(1))));
+  const xLabels = xRaw.map((v) => v.toFixed(1));
+
+  // 准备中心点数据 - 判断逻辑
+  const centerSeries = [];
+
+  // 定义颜色配置
+  const baseColors = ["#F44336", "#4CAF50", "#FFA726"]; // 基础叶片颜色
+  const testColors = ["#FF0000", "#00FF00", "#0000FF"]; // 测试颜色
+
+  // 如果blade_center存在且有数据,使用实际数据
+  if (
+    this.LeafRootOutlineData?.blade_center?.xdata?.length > 0 &&
+    this.LeafRootOutlineData?.blade_center?.ydata?.length > 0
+  ) {
+    const centerData = this.LeafRootOutlineData.blade_center;
+    console.log("使用实际的blade_center数据:", centerData);
+
+    // 为叶片1-3添加中心点
+    for (
+      let i = 0;
+      i < Math.min(3, centerData.xdata.length, centerData.ydata.length);
+      i++
+    ) {
+      // === 关键修改:只在叶片轮廓拟合图中偏移中心点数据 ===
+      const centerX = this.type === "LeafRootOutline"
+        ? Number((centerData.xdata[i] - centerXOffset).toFixed(4))
+        : Number(centerData.xdata[i].toFixed(4));
+      
+      let centerY;
+      if (this.type === "LeafRootOutline") {
+        // 叶片轮廓拟合图:Y轴也偏移
+        centerY = Number((centerData.ydata[i] - centerYOffset).toFixed(4));
+      } else {
+        // 叶根轮廓拟合图:保持原来的归一化逻辑
+        centerY = Number((centerData.ydata[i] - minValue).toFixed(4));
+      }
+      
+      centerSeries.push({
+        name:
+          this.keys === "blade_tip"
+            ? `叶根${i + 1}中心点`
+            : `叶片${i + 1}中心点`,
+        type: "scatter",
+        symbolSize: 10,
+        itemStyle: { color: baseColors[i] },
+        data: [[centerX, centerY]],
+      });
+      
+      // 特别打印叶片1中心点位置
+      if (i === 0) {
+        console.log(`${this.type} - 叶片1中心点位置: X=${centerX.toFixed(4)}, Y=${centerY.toFixed(4)}`);
+      }
+    }
+
+    // 只有在叶片轮廓拟合图且有旋转数据时,才为旋转叶片添加中心点
+    if (this.type === "LeafRootOutline" && hasRotateData) {
+      for (
+        let i = 3;
+        i < Math.min(6, centerData.xdata.length, centerData.ydata.length);
+        i++
+      ) {
+        const centerX = Number((centerData.xdata[i] - centerXOffset).toFixed(4));
+        const centerY = Number((centerData.ydata[i] - centerYOffset).toFixed(4));
+        
+        centerSeries.push({
+          name: `旋转叶片${i - 2}中心点`,
+          type: "scatter",
+          symbolSize: 10,
+          itemStyle: { color: baseColors[i - 3] },
+          data: [[centerX, centerY]],
+        });
+      }
+    }
+  } else {
+    // 如果没有blade_center,使用固定数据
+    console.log("blade_center不存在或数据为空,使用固定测试数据");
+    const testBladeCenter = {
+      xdata: [1.1409272443980873, 1.1486257802831674, 1.1449090600730372],
+      ydata: [88.97949196195555, 88.9672705736207, 88.98638594209639],
+    };
+
+    // 根据类型决定添加多少个中心点
+    const pointCount = 3;
+    for (let i = 0; i < pointCount; i++) {
+      const centerX = this.type === "LeafRootOutline"
+        ? Number((testBladeCenter.xdata[i] - centerXOffset).toFixed(4))
+        : Number(testBladeCenter.xdata[i].toFixed(4));
+      
+      let centerY;
+      if (this.type === "LeafRootOutline") {
+        centerY = Number((testBladeCenter.ydata[i] - centerYOffset).toFixed(4));
+      } else {
+        centerY = Number((testBladeCenter.ydata[i] - minValue).toFixed(4));
+      }
+      
+      centerSeries.push({
+        name:
+          this.keys === "blade_tip"
+            ? `叶根${i + 1}中心点(测试)`
+            : `叶片${i + 1}中心点(测试)`,
+        type: "scatter",
+        symbolSize: 12,
+        itemStyle: { color: testColors[i] },
+        data: [[centerX, centerY]],
+      });
+    }
+  }
+
+  // === 新增:处理拟合圆数据(只针对叶根轮廓拟合图)===
+  const circleSeries = [];
+  if (this.type === "LeafTipProfile") {
+    // 定义拟合圆名称和颜色
+    const circleConfigs = [
+      { key: "first_circle", name: "叶根1拟合圆", color: "#F44336" },
+      { key: "second_circle", name: "叶根2拟合圆", color: "#4CAF50" },
+      { key: "third_circle", name: "叶根3拟合圆", color: "#FFA726" },
+    ];
+
+    // 循环处理三个拟合圆数据
+    circleConfigs.forEach((config, index) => {
+      const circleData = this.LeafRootOutlineData[config.key];
+
+      if (circleData?.xdata?.length > 0 && circleData?.ydata?.length > 0) {
+        console.log(`处理${config.name}数据:`, circleData);
+
+        // 处理拟合圆数据点 - 保持原始比例
+        const circlePoints = circleData.xdata.map((x, i) => [
+          Number(x.toFixed(4)),
+          Number((circleData.ydata[i] - minValue).toFixed(4)),
+        ]);
+
+        // 计算拟合圆的范围,用于检查是否保持圆形
+        const circleXMin = Math.min(...circleData.xdata);
+        const circleXMax = Math.max(...circleData.xdata);
+        const circleYMin = Math.min(...circleData.ydata);
+        const circleYMax = Math.max(...circleData.ydata);
+        const circleXRange = circleXMax - circleXMin;
+        const circleYRange = circleYMax - circleYMin;
+
+        console.log(
+          `${config.name}范围: X(${circleXRange.toFixed(
+            4
+          )}), Y(${circleYRange.toFixed(4)})`
+        );
+
+        circleSeries.push({
+          name: config.name,
+          type: "line",
+          showSymbol: false,
+          lineStyle: {
+            width: 2,
+            type: "dashed", // 虚线区分
+            color: config.color,
+          },
+          itemStyle: { color: config.color },
+          data: circlePoints,
+          smooth: true, // 拟合圆需要平滑
+        });
+      } else {
+        console.log(`${config.name}数据不存在或为空`);
+      }
+    });
+  }
+
+  // === 关键修改:旋转叶片数据也需要使用偏移后的X和Y数据 ===
+  // 准备所有叶片系列
+  const series = [
+    // 基础叶片1-3轮廓
+    {
+      name: this.keys === "blade_tip" ? "叶根1轮廓" : "叶片1轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#F44336" },
+      data: xRaw.map((x, i) => [x, y1[i]]),
+      smooth: true,
+    },
+    {
+      name: this.keys === "blade_tip" ? "叶根2轮廓" : "叶片2轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#4CAF50" },
+      data: xRaw.map((x, i) => [x, y2[i]]),
+      smooth: true,
+    },
+    {
+      name: this.keys === "blade_tip" ? "叶根3轮廓" : "叶片3轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#FFA726" },
+      data: xRaw.map((x, i) => [x, y3[i]]),
+      smooth: true,
+    },
+  ];
+
+  // 动态图例数据
+  const legendData = [
+    this.keys === "blade_tip" ? "叶根1轮廓" : "叶片1轮廓",
+    this.keys === "blade_tip" ? "叶根2轮廓" : "叶片2轮廓",
+    this.keys === "blade_tip" ? "叶根3轮廓" : "叶片3轮廓",
+  ];
+
+  // 动态添加旋转叶片系列(仅在叶片轮廓拟合图中)
+  if (this.type === "LeafRootOutline" && hasRotateData) {
+    // 添加旋转叶片4-6轮廓
+    const rotateSeries = [];
+
+    if (y4) {
+      rotateSeries.push({
+        name: "旋转叶片1轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" }, // 虚线区分
+        itemStyle: { color: "#F44336" },
+        // 关键:使用相同的偏移后的X和Y数据
+        data: xRaw.map((x, i) => [x, y4[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片1轮廓");
+    }
+
+    if (y5) {
+      rotateSeries.push({
+        name: "旋转叶片2轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" },
+        itemStyle: { color: "#4CAF50" },
+        data: xRaw.map((x, i) => [x, y5[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片2轮廓");
+    }
+
+    if (y6) {
+      rotateSeries.push({
+        name: "旋转叶片3轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" },
+        itemStyle: { color: "#FFA726" },
+        data: xRaw.map((x, i) => [x, y6[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片3轮廓");
+    }
+
+    // 将旋转叶片系列添加到主系列中
+    series.push(...rotateSeries);
+  }
+
+  // 添加拟合圆系列(仅在叶根轮廓拟合图中)
+  if (this.type === "LeafTipProfile" && circleSeries.length > 0) {
+    series.push(...circleSeries);
+    // 将拟合圆添加到图例
+    circleSeries.forEach((circle) => {
+      legendData.push(circle.name);
+    });
+  }
+
+  // 添加中心点系列
+  series.push(...centerSeries);
+
+  // 动态设置颜色和图例
+  let colors = ["#F44336", "#4CAF50", "#FFA726"];
+
+  if (this.type === "LeafRootOutline" && hasRotateData) {
+    colors = [...colors, "#F44336", "#4CAF50", "#FFA726"];
+  }
+
+  if (this.type === "LeafTipProfile" && circleSeries.length > 0) {
+    // 为叶根轮廓拟合图添加拟合圆的颜色
+    colors = [...colors, "#F44336", "#4CAF50", "#FFA726"];
+  }
+
+  // === 关键修改:为两种图表类型分别设置Y轴配置 ===
+  let yAxisConfig;
+  if (this.type === "LeafTipProfile") {
+    // 对于叶根轮廓拟合图,创建规则的Y轴刻度(保持原样)
+    // 计算需要多少个0.2的间隔来覆盖Y轴范围
+    const interval = 0.2; // 固定间隔0.2
+    const tickCount = Math.ceil(yAxisMax / interval);
+
+    // 生成刻度值数组:0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, ...
+    const ticks = [];
+    for (let i = 0; i <= tickCount; i++) {
+      ticks.push(i * interval);
+    }
+
+    // 调整Y轴最大值,使其是0.2的整数倍
+    const adjustedYAxisMax = Math.ceil(yAxisMax / interval) * interval;
+
+    console.log("叶根轮廓拟合图 - 规则Y轴刻度:", {
+      原始Y轴最大值: yAxisMax.toFixed(4),
+      调整后Y轴最大值: adjustedYAxisMax.toFixed(4),
+      刻度间隔: interval,
+      刻度数量: tickCount + 1,
+      刻度值: ticks.map((v) => v.toFixed(1)),
+    });
+
+    yAxisConfig = {
+      type: "value",
+      name: "距离(m)",
+      nameLocation: "middle",
+      nameTextStyle: { fontWeight: "bold", padding: [0, 0, 40, 0] },
+      min: 0,
+      max: adjustedYAxisMax,
+      interval: interval,
+      axisLabel: {
+        formatter: function (value) {
+          // 显示小数点后1位
+          return value.toFixed(1);
+        },
+      },
+    };
+  } else {
+    // 叶片轮廓拟合图:Y轴也允许负数
+    yAxisConfig = {
+      type: "value",
+      name: "距离(m)",
+      nameLocation: "middle",
+      nameTextStyle: { fontWeight: "bold", padding: [0, 0, 40, 0] },
+      min: yAxisMin,
+      max: yAxisMax,
+      // 设置Y轴刻度间隔,使其与X轴匹配
+      interval: 0.2,
+      axisLabel: {
+        formatter: function (value) {
+          // 显示小数点后1位,允许负数
+          return value.toFixed(1);
+        },
+      },
+    };
+  }
+
+  // === 关键修改:设置坐标轴显示格式 ===
+  const option = {
+    grid: { left: 80, right: 40, top: 40, bottom: 60 },
+    color: colors,
+    toolbox: {
+      feature: {
+        dataZoom: { yAxisIndex: "none" },
+        restore: {},
+        saveAsImage: {},
+        myCustomTool1: {
+          show: true,
+          title: "标注",
+          icon: `image://${new URL(
+            "@/assets/analyse/mark.png",
+            import.meta.url
+          )}`,
+          onclick: () => this.WhetherToDisplay(),
+        },
+        myCustomTool2: {
+          show: true,
+          title: "全屏",
+          icon: `image://${new URL(
+            "@/assets/analyse/fullScreen.png",
+            import.meta.url
+          )}`,
+          onclick: () => this.fullScreen(),
+        },
+        myCustomTool3: {
+          show: true,
+          title: "退出全屏",
+          icon: `image://${new URL(
+            "@/assets/analyse/exitFullScreen.png",
+            import.meta.url
+          )}`,
+          onclick: () => this.exitFullScreen(),
+        },
+      },
+    },
+    xAxis: {
+      type: "value",
+      name: "距离(m)",
+      nameLocation: "middle",
+      nameTextStyle: { fontWeight: "bold", padding: [20, 0, 0, 0] },
+      min: xAxisMin,
+      max: xAxisMax,
+      splitNumber: 15, // 保持原来的15个刻度
+      data: [...new Set(xLabels)],
+      splitLine: { show: true, lineStyle: { color: "rgb(220,220,220)" } },
+      // 设置X轴刻度显示格式
+      axisLabel: {
+        formatter: function (value) {
+          // 显示小数点后1位,如-1.0, -0.8, 0.0, 0.2, 1.6, 2.6等
+          return value.toFixed(1);
+        }
+      },
+      // 设置X轴刻度间隔
+      interval: 0.2,
+    },
+    yAxis: yAxisConfig,
+    tooltip: {
+      trigger: "axis",
+      valueFormatter: (v) => (typeof v === "number" ? v.toFixed(4) : v),
+      position: (pt) => [pt[0], "10%"],
+      confine: false,
+      appendToBody: true,
+    },
+    legend: {
+      data: legendData,
+      left: 0,
+      top: 0,
+    },
+    series: series,
+  };
+
+  this.chartInstance.setOption(option, true);
+
+  // ======== 动态高度计算 ========
+  this.$nextTick(() => {
+    const maxYLabelLen = [...new Set(yLabels)].length;
+    const chartDom = this.$refs[`chart${this.keys}`];
+    const chartWidth = chartDom.clientWidth;
+    const grid =
+      option.grid && option.grid[0]
+        ? option.grid[0]
+        : { left: 0, right: 0 };
+    const xAxisWidth =
+      chartWidth - (parseInt(grid.left) || 0) - (parseInt(grid.right) || 0);
+    const xAxisWidthPerLabel = xAxisWidth / 15;
+
+    // 默认高度
+    let baseHeight = 400;
+
+    // 如果 y 轴的刻度文本比 x 轴长,则增加高度
+    if (maxYLabelLen > [...new Set(xLabels)].length) {
+      baseHeight = maxYLabelLen * xAxisWidthPerLabel;
+    } else if (maxYLabelLen < [...new Set(xLabels)].length) {
+      const xAxisWidthPerLabelAll =
+        xAxisWidth / [...new Set(xLabels)].length;
+      baseHeight = maxYLabelLen * xAxisWidthPerLabelAll;
+    }
+
+    // 如果是拟合圆模式,需要保持1:1的比例
+    if (hasCircleData) {
+      // 根据X和Y轴范围的比例计算合适的高度,保持1:1比例
+      const xDisplayRange = xAxisMax - xAxisMin;
+      const yDisplayRange = yAxisMax - yAxisMin;
+      const rangeRatio = xDisplayRange / yDisplayRange;
+
+      // 保持1:1比例所需的高度
+      const heightFor1to1 = chartWidth / rangeRatio;
+      baseHeight = Math.max(baseHeight, heightFor1to1);
+
+      console.log("拟合圆模式:调整高度以保持1:1比例", {
+        xDisplayRange: xDisplayRange.toFixed(4),
+        yDisplayRange: yDisplayRange.toFixed(4),
+        rangeRatio: rangeRatio.toFixed(4),
+        chartWidth,
+        heightFor1to1: heightFor1to1.toFixed(0),
+        finalHeight: baseHeight,
+      });
+    }
+
+    chartDom.style.height = baseHeight + "px";
+    console.log(
+      "每个刻度线的距离",
+      xAxisWidthPerLabel,
+      `chart${this.keys}`,
+      baseHeight,
+      "当前类型:",
+      this.type,
+      "渲染系列数量:",
+      legendData.length,
+      "X范围:",
+      xAxisMin.toFixed(2),
+      "-",
+      xAxisMax.toFixed(2),
+      "Y范围:",
+      yAxisMin.toFixed(2),
+      "-",
+      yAxisMax.toFixed(2)
+    );
+
+    // 重新调整 ECharts 大小
+    this.chartInstance.resize();
+  });
+
+  // 防止重复绑定 resize 事件
+  if (this._onResizeEqualScale) {
+    window.removeEventListener("resize", this._onResizeEqualScale);
+  }
+  this._onResizeEqualScale = () => this.updateChart();
+  window.addEventListener("resize", this._onResizeEqualScale);
+},
+    // 标注是否显示
+    WhetherToDisplay() {
+      // 切换显示状态
+      this.markPointVisible = !this.markPointVisible;
+      this.markLineVisible = !this.markLineVisible;
+    },
+    previousRow() {
+      let newIndex =
+        this.currentIndex > 0
+          ? this.currentIndex - 1
+          : this.tableData.length - 1;
+      this.$emit("update:currentIndex", newIndex);
+    },
+    nextRow() {
+      console.log("下一条");
+      let newIndex =
+        this.currentIndex < this.tableData.length - 1
+          ? this.currentIndex + 1
+          : 0;
+      this.$emit("update:currentIndex", newIndex);
+    },
+    toggleFullScreen() {
+      const chartDom = this.$refs[`chart${this.keys}`];
+      if (screenfull.isEnabled) {
+        screenfull.toggle(chartDom);
+      }
+    },
+    fullScreen() {
+      const chartDom = this.$refs[`chart${this.keys}`];
+      if (screenfull.isEnabled) {
+        // 设置全屏样式
+        chartDom.style.position = "absolute";
+        chartDom.style.top = 0;
+        chartDom.style.left = 0;
+        chartDom.style.width = "100vw";
+        chartDom.style.height = "100vh";
+        chartDom.style.backgroundColor = "#ffffff";
+
+        // 进入全屏
+        screenfull.request(chartDom);
+        this.chartInstance.resize();
+
+        // 监听全屏变化
+        screenfull.on("change", this.handleFullScreenChange);
+      }
+    },
+    exitFullScreen() {
+      const chartDom = this.$refs[`chart${this.keys}`];
+      if (screenfull.isEnabled) {
+        screenfull.exit();
+        // 监听全屏变化
+        screenfull.on("change", this.handleFullScreenChange);
+      }
+    },
+    // 处理全屏变化的回调
+    handleFullScreenChange() {
+      const chartDom = this.$refs[`chart${this.keys}`];
+      if (!screenfull.isFullscreen) {
+        // 退出全屏时恢复样式
+        chartDom.style.position = this.originalChartStyle.position || "";
+        chartDom.style.top = this.originalChartStyle.top || "";
+        chartDom.style.left = this.originalChartStyle.left || "";
+        chartDom.style.width = this.originalChartStyle.width || "100%";
+        chartDom.style.height = this.originalChartStyle.height || "400px";
+        chartDom.style.backgroundColor =
+          this.originalChartStyle.backgroundColor || "#fff";
+
+        // 调整图表尺寸
+        this.chartInstance.resize();
+
+        // 可选:移除事件监听(如果不再需要)
+        screenfull.off("change", this.handleFullScreenChange);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep .el-card__body {
+  width: 100%;
+  // height: 250px;
+  position: relative;
+}
+.chartsContent {
+  .boxchart {
+    overflow: hidden !important;
+    :deep(.el-card__body) {
+      width: 100%;
+      overflow: hidden !important;
+    }
+  }
+}
+
+.line-chart {
+  width: 100%;
+  // height: 400px;
+  background-color: #fff;
+  position: relative;
+}
+.line-chart > div {
+  width: 100%;
+  height: 100%;
+}
+.eigenvalue {
+  position: absolute;
+  top: 0;
+  right: 0;
+  font-size: 10px;
+  width: 100px;
+  border: 1px solid black;
+  padding: 5px;
+  background: #fff;
+  z-index: 99;
+  h5 {
+    line-height: 16px;
+    height: 16px;
+  }
+}
+</style>

+ 522 - 638
jg/src/views/laserRangeFinder/components/PlotOfFit.vue

@@ -115,677 +115,561 @@ export default {
         }
       });
     },
-    updateChart() {
-      console.log("=== LeafRootOutlineData 详细结构 ===");
-      console.log("数据类型:", this.type);
-      console.log(
-        "完整数据:",
-        JSON.parse(JSON.stringify(this.LeafRootOutlineData))
-      );
-
-      if (!this.chartInstance) {
-        console.warn("图表实例未初始化,无法更新图表");
-        this.initializeChart();
-        return;
-      }
+updateChart() {
+  console.log("=== LeafRootOutlineData 详细结构 ===");
+  console.log("数据类型:", this.type);
+  console.log(
+    "完整数据:",
+    JSON.parse(JSON.stringify(this.LeafRootOutlineData))
+  );
+
+  if (!this.chartInstance) {
+    console.warn("图表实例未初始化,无法更新图表");
+    this.initializeChart();
+    return;
+  }
 
-      // 1) 原始数据 → 四舍五入到4位(保持数值类型)
-      const xRaw = (this.LeafRootOutlineData?.first_blade?.xdata || []).map(
-        (v) => Number(Number(v).toFixed(4))
-      );
+  // === 修改点 1:坐标零点偏移计算 ===
+  // 两种类型都以叶根1中心点作为零点进行偏移
+  let centerXOffset = 0;
+  let centerYOffset = 0;
+
+  if (this.type === "LeafRootOutline" || this.type === "LeafTipProfile") {
+    // 获取叶片1中心点作为坐标零点
+    if (
+      this.LeafRootOutlineData?.blade_center?.xdata?.length > 0 &&
+      this.LeafRootOutlineData?.blade_center?.xdata[0] !== undefined &&
+      this.LeafRootOutlineData?.blade_center?.ydata?.length > 0 &&
+      this.LeafRootOutlineData?.blade_center?.ydata[0] !== undefined
+    ) {
+      centerXOffset = this.LeafRootOutlineData.blade_center.xdata[0];
+      centerYOffset = this.LeafRootOutlineData.blade_center.ydata[0];
+      console.log("使用叶根1中心点作为坐标零点:", {
+        X偏移量: centerXOffset.toFixed(4),
+        Y偏移量: centerYOffset.toFixed(4)
+      });
+    } else {
+      console.warn("没有中心点数据,坐标轴不进行偏移");
+    }
+  }
 
-      // 处理基础3条叶片数据(叶根和叶片都有的)
-      const y1Raw = this.LeafRootOutlineData.first_blade.ydata.map((v) =>
+  // 1) 原始数据 → 四舍五入到4位(保持数值类型)
+  const xRawOriginal = (this.LeafRootOutlineData?.first_blade?.xdata || []).map(
+    (v) => Number(Number(v).toFixed(4))
+  );
+
+  // 处理基础3条叶片数据
+  const y1Raw = this.LeafRootOutlineData.first_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+  const y2Raw = this.LeafRootOutlineData.second_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+  const y3Raw = this.LeafRootOutlineData.third_blade.ydata.map((v) =>
+    Number(Number(v).toFixed(4))
+  );
+
+  // 2) 根据类型决定是否处理旋转叶片数据
+  let y4Raw, y5Raw, y6Raw;
+  let hasRotateData = false;
+  let allRawY = [y1Raw, y2Raw, y3Raw];
+
+  // 只有在叶片轮廓拟合图中才处理旋转叶片数据
+  if (this.type === "LeafRootOutline") {
+    // 检查旋转叶片数据是否存在,存在则处理
+    if (this.LeafRootOutlineData?.first_rotate_blade?.ydata?.length > 0) {
+      y4Raw = this.LeafRootOutlineData.first_rotate_blade.ydata.map((v) =>
         Number(Number(v).toFixed(4))
       );
-      const y2Raw = this.LeafRootOutlineData.second_blade.ydata.map((v) =>
+      allRawY.push(y4Raw);
+      hasRotateData = true;
+    }
+
+    if (this.LeafRootOutlineData?.second_rotate_blade?.ydata?.length > 0) {
+      y5Raw = this.LeafRootOutlineData.second_rotate_blade.ydata.map((v) =>
         Number(Number(v).toFixed(4))
       );
-      const y3Raw = this.LeafRootOutlineData.third_blade.ydata.map((v) =>
+      allRawY.push(y5Raw);
+      hasRotateData = true;
+    }
+
+    if (this.LeafRootOutlineData?.third_rotate_blade?.ydata?.length > 0) {
+      y6Raw = this.LeafRootOutlineData.third_rotate_blade.ydata.map((v) =>
         Number(Number(v).toFixed(4))
       );
+      allRawY.push(y6Raw);
+      hasRotateData = true;
+    }
+  }
 
-      // 2) 根据类型决定是否处理旋转叶片数据
-      let y4Raw, y5Raw, y6Raw;
-      let hasRotateData = false;
-      let allRawY = [y1Raw, y2Raw, y3Raw];
-
-      // 只有在叶片轮廓拟合图中才处理旋转叶片数据
-      if (this.type === "LeafRootOutline") {
-        // 检查旋转叶片数据是否存在,存在则处理
-        if (this.LeafRootOutlineData?.first_rotate_blade?.ydata?.length > 0) {
-          y4Raw = this.LeafRootOutlineData.first_rotate_blade.ydata.map((v) =>
-            Number(Number(v).toFixed(4))
-          );
-          allRawY.push(y4Raw);
-          hasRotateData = true;
-        }
-
-        if (this.LeafRootOutlineData?.second_rotate_blade?.ydata?.length > 0) {
-          y5Raw = this.LeafRootOutlineData.second_rotate_blade.ydata.map((v) =>
-            Number(Number(v).toFixed(4))
-          );
-          allRawY.push(y5Raw);
-          hasRotateData = true;
-        }
-
-        if (this.LeafRootOutlineData?.third_rotate_blade?.ydata?.length > 0) {
-          y6Raw = this.LeafRootOutlineData.third_rotate_blade.ydata.map((v) =>
-            Number(Number(v).toFixed(4))
-          );
-          allRawY.push(y6Raw);
-          hasRotateData = true;
-        }
-      }
-
-      // 3) 计算 minValue
-      const allMinValues = allRawY.map((arr) => Math.min(...arr));
-      const minYAmongAll = Math.min(...allMinValues);
-      const minValue = Number((minYAmongAll - 0.1).toFixed(4));
-
-      // 4) 归一化基础Y数据
-      const y1 = y1Raw.map((v) => Number((v - minValue).toFixed(4)));
-      const y2 = y2Raw.map((v) => Number((v - minValue).toFixed(4)));
-      const y3 = y3Raw.map((v) => Number((v - minValue).toFixed(4)));
-
-      // 5) 根据类型决定是否归一化旋转叶片数据
-      let y4, y5, y6;
-      if (hasRotateData && this.type === "LeafRootOutline") {
-        if (y4Raw) y4 = y4Raw.map((v) => Number((v - minValue).toFixed(4)));
-        if (y5Raw) y5 = y5Raw.map((v) => Number((v - minValue).toFixed(4)));
-        if (y6Raw) y6 = y6Raw.map((v) => Number((v - minValue).toFixed(4)));
-      }
-
-      // 6) 基于"归一化后的数据"计算等比例范围
-      const allY = [...y1, ...y2, ...y3];
-      if (hasRotateData && this.type === "LeafRootOutline") {
-        if (y4) allY.push(...y4);
-        if (y5) allY.push(...y5);
-        if (y6) allY.push(...y6);
-      }
+  // 3) 计算 minValue(已废弃,但保留变量)
+  const allMinValues = allRawY.map((arr) => Math.min(...arr));
+  const minYAmongAll = Math.min(...allMinValues);
+  const minValue = Number((minYAmongAll - 0.1).toFixed(4));
+
+  // 4) Y数据根据类型决定偏移方式
+  let y1, y2, y3;
+  
+  // === 修改点 2:Y数据全部改为使用 centerYOffset 偏移 ===
+  if (this.type === "LeafRootOutline" || this.type === "LeafTipProfile") {
+    // 叶片轮廓拟合图和叶根轮廓拟合图:Y轴都进行偏移
+    y1 = y1Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+    y2 = y2Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+    y3 = y3Raw.map(v => Number((v - centerYOffset).toFixed(4)));
+  } else {
+    // 理论上不会执行,保留原始 minValue 归一化逻辑
+    y1 = y1Raw.map(v => Number((v - minValue).toFixed(4)));
+    y2 = y2Raw.map(v => Number((v - minValue).toFixed(4)));
+    y3 = y3Raw.map(v => Number((v - minValue).toFixed(4)));
+  }
 
-      const minX = Math.min(...xRaw);
-      const maxX = Math.max(...xRaw);
-      const xRange = Number((maxX - minX).toFixed(4));
-
-      const maxY = Math.max(...allY);
-      const { clientWidth: w, clientHeight: h } = this.chartInstance.getDom();
-      const aspectRatio = w / h;
-
-      // 让单位像素一致:目标 yRange = xRange / (w/h)
-      const targetYRange = Number((xRange / aspectRatio).toFixed(4));
-
-      // === 重要修改:针对拟合圆的特殊处理 ===
-      // 如果是叶根轮廓拟合图且有拟合圆,需要保持纵横比1:1
-      let yMin = 0;
-      let yMax = Number(Math.max(maxY, targetYRange).toFixed(4));
-
-      // 检查是否有拟合圆数据
-      const hasCircleData =
-        this.type === "LeafTipProfile" &&
-        (this.LeafRootOutlineData?.first_circle ||
-          this.LeafRootOutlineData?.second_circle ||
-          this.LeafRootOutlineData?.third_circle);
-
-      // === 关键修改:计算拟合圆的真实范围 ===
-      let circleXMin = Infinity,
-        circleXMax = -Infinity;
-      let circleYMin = Infinity,
-        circleYMax = -Infinity;
-      let circleNormalizedYMin = Infinity,
-        circleNormalizedYMax = -Infinity;
-
-      if (hasCircleData) {
-        // 计算所有拟合圆的实际范围
-        const circleConfigs = [
-          { key: "first_circle" },
-          { key: "second_circle" },
-          { key: "third_circle" },
-        ];
-
-        circleConfigs.forEach((config) => {
-          const circleData = this.LeafRootOutlineData[config.key];
-          if (circleData?.xdata?.length > 0 && circleData?.ydata?.length > 0) {
-            const thisCircleXMin = Math.min(...circleData.xdata);
-            const thisCircleXMax = Math.max(...circleData.xdata);
-            const thisCircleYMin = Math.min(...circleData.ydata);
-            const thisCircleYMax = Math.max(...circleData.ydata);
-
-            circleXMin = Math.min(circleXMin, thisCircleXMin);
-            circleXMax = Math.max(circleXMax, thisCircleXMax);
-            circleYMin = Math.min(circleYMin, thisCircleYMin);
-            circleYMax = Math.max(circleYMax, thisCircleYMax);
-
-            // 计算归一化后的Y范围
-            const thisNormalizedYMin = thisCircleYMin - minValue;
-            const thisNormalizedYMax = thisCircleYMax - minValue;
-            circleNormalizedYMin = Math.min(
-              circleNormalizedYMin,
-              thisNormalizedYMin
-            );
-            circleNormalizedYMax = Math.max(
-              circleNormalizedYMax,
-              thisNormalizedYMax
-            );
-          }
-        });
+  // 5) 根据类型决定是否归一化旋转叶片数据
+  let y4, y5, y6;
+  if (hasRotateData && this.type === "LeafRootOutline") {
+    if (y4Raw) y4 = y4Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+    if (y5Raw) y5 = y5Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+    if (y6Raw) y6 = y6Raw.map((v) => Number((v - centerYOffset).toFixed(4)));
+  }
 
-        console.log("拟合圆实际范围:", {
-          circleXMin: circleXMin.toFixed(4),
-          circleXMax: circleXMax.toFixed(4),
-          circleYMin: circleYMin.toFixed(4),
-          circleYMax: circleYMax.toFixed(4),
-          circleNormalizedYMin: circleNormalizedYMin.toFixed(4),
-          circleNormalizedYMax: circleNormalizedYMax.toFixed(4),
-        });
+  // 6) 基于"偏移后的数据"计算等比例范围
+  const allY = [...y1, ...y2, ...y3];
+  if (hasRotateData && this.type === "LeafRootOutline") {
+    if (y4) allY.push(...y4);
+    if (y5) allY.push(...y5);
+    if (y6) allY.push(...y6);
+  }
 
-        // 对于拟合圆,我们需要保持1:1的纵横比,让圆形不被压扁
-        // 计算拟合圆的X和Y范围
-        const circleXRange = circleXMax - circleXMin;
-        const circleNormalizedYRange =
-          circleNormalizedYMax - circleNormalizedYMin;
-
-        // 取X和Y范围中的较大值作为基准
-        const baseRange = Math.max(circleXRange, circleNormalizedYRange);
-
-        // 确保Y轴范围足够大以显示拟合圆
-        yMax = Math.max(maxY, baseRange, targetYRange);
-
-        console.log("拟合圆模式:强制保持1:1纵横比", {
-          circleXRange: circleXRange.toFixed(4),
-          circleNormalizedYRange: circleNormalizedYRange.toFixed(4),
-          baseRange: baseRange.toFixed(4),
-          maxY: maxY.toFixed(4),
-          targetYRange: targetYRange.toFixed(4),
-          finalYMax: yMax.toFixed(4),
+  // === 关键修改:对X数据进行偏移 ===
+  const xRaw = (this.type === "LeafRootOutline" || this.type === "LeafTipProfile")
+    ? xRawOriginal.map(v => Number((v - centerXOffset).toFixed(4))) // 两种类型都偏移
+    : xRawOriginal; // 其他情况保持原样
+
+  const minX = Math.min(...xRaw);
+  const maxX = Math.max(...xRaw);
+  const xRange = Number((maxX - minX).toFixed(4));
+
+  const minY = Math.min(...allY);
+  const maxY = Math.max(...allY);
+  
+  const { clientWidth: w, clientHeight: h } = this.chartInstance.getDom();
+  const aspectRatio = w / h;
+  const targetYRange = Number((xRange / aspectRatio).toFixed(4));
+
+  // 检查是否有拟合圆数据
+  const hasCircleData =
+    this.type === "LeafTipProfile" &&
+    (this.LeafRootOutlineData?.first_circle ||
+      this.LeafRootOutlineData?.second_circle ||
+      this.LeafRootOutlineData?.third_circle);
+
+  // === 关键修改:计算拟合圆的真实范围 ===
+  let circleXMinGlobal = Infinity,
+    circleXMaxGlobal = -Infinity;
+  let circleNormalizedYMinGlobal = Infinity,
+    circleNormalizedYMaxGlobal = -Infinity;
+
+  // === 新增:处理拟合圆数据(只针对 LeafTipProfile)===
+  const circleSeries = [];
+  if (this.type === "LeafTipProfile") {
+    const circleConfigs = [
+      { key: "first_circle", name: "叶根1拟合圆", color: "#F44336" },
+      { key: "second_circle", name: "叶根2拟合圆", color: "#4CAF50" },
+      { key: "third_circle", name: "叶根3拟合圆", color: "#FFA726" },
+    ];
+
+    circleConfigs.forEach((config, index) => {
+      const circleData = this.LeafRootOutlineData[config.key];
+
+      if (circleData?.xdata?.length > 0 && circleData?.ydata?.length > 0) {
+        
+        // === 修改点 3:拟合圆数据使用 centerYOffset 偏移 ===
+        const circlePoints = circleData.xdata.map((x, i) => [
+          Number((x - centerXOffset).toFixed(4)),  // X轴使用 centerXOffset 偏移
+          Number((circleData.ydata[i] - centerYOffset).toFixed(4)),  // Y轴使用 centerYOffset 偏移
+        ]);
+
+        // === 计算偏移后的拟合圆Y值范围 ===
+        const normalizedYValues = circleData.ydata.map(y => y - centerYOffset);
+        const normalizedXValues = circleData.xdata.map(x => x - centerXOffset);
+        
+        const thisNormalizedYMin = Math.min(...normalizedYValues);
+        const thisNormalizedYMax = Math.max(...normalizedYValues);
+        const thisNormalizedXMin = Math.min(...normalizedXValues);
+        const thisNormalizedXMax = Math.max(...normalizedXValues);
+
+        // 更新全局范围
+        circleXMinGlobal = Math.min(circleXMinGlobal, thisNormalizedXMin);
+        circleXMaxGlobal = Math.max(circleXMaxGlobal, thisNormalizedXMax);
+        circleNormalizedYMinGlobal = Math.min(circleNormalizedYMinGlobal, thisNormalizedYMin);
+        circleNormalizedYMaxGlobal = Math.max(circleNormalizedYMaxGlobal, thisNormalizedYMax);
+
+        circleSeries.push({
+          name: config.name,
+          type: "line",
+          showSymbol: false,
+          lineStyle: {
+            width: 2,
+            type: "dashed", // 虚线区分
+            color: config.color,
+          },
+          itemStyle: { color: config.color },
+          data: circlePoints,
+          smooth: true, // 拟合圆需要平滑
         });
       }
+    });
+  }
 
-      // === 关键修改:调整X轴显示范围,确保拟合圆完全显示 ===
-      // 计算所有需要显示的数据的X范围(包括拟合圆)
-      const allDisplayXMin = Math.min(
-        minX,
-        circleXMin !== Infinity ? circleXMin : minX
-      );
-      const allDisplayXMax = Math.max(
-        maxX,
-        circleXMax !== -Infinity ? circleXMax : maxX
-      );
-      const allDisplayXRange = allDisplayXMax - allDisplayXMin;
-
-      // 为显示增加10%的边距
-      const xMargin = allDisplayXRange * 0.1;
-      const yMargin = yMax * 0.1;
+  // === 关键修改:调整坐标轴显示范围 - 计算实际数据边界 ===
+  // 计算所有需要显示的数据的X范围(包括拟合圆)
+  const allDisplayXMin = Math.min(
+    minX,
+    circleXMinGlobal !== Infinity ? circleXMinGlobal : minX
+  );
+  const allDisplayXMax = Math.max(
+    maxX,
+    circleXMaxGlobal !== -Infinity ? circleXMaxGlobal : maxX
+  );
+  const allDisplayXRange = allDisplayXMax - allDisplayXMin;
+
+  // 计算所有需要显示的数据的Y范围(包括拟合圆)
+  const allDisplayYMin = Math.min(
+    minY,
+    circleNormalizedYMinGlobal !== Infinity ? circleNormalizedYMinGlobal : minY
+  );
+  const allDisplayYMax = Math.max(
+    maxY,
+    circleNormalizedYMaxGlobal !== -Infinity ? circleNormalizedYMaxGlobal : maxY
+  );
+  const allDisplayYRange = allDisplayYMax - allDisplayYMin;
+
+  // 为显示增加10%的边距
+  const xMargin = allDisplayXRange * 0.1;
+  const yMargin = allDisplayYRange * 0.1;
+
+  // 1. 初始计算轴系边界 (包含边距)
+  let xAxisMin = allDisplayXMin - xMargin;
+  let xAxisMax = allDisplayXMax + xMargin;
+  let yAxisMin = allDisplayYMin - yMargin;
+  let yAxisMax = allDisplayYMax + yMargin;
+
+  // X轴范围处理逻辑
+  if (allDisplayXMin >= 0) {
+    xAxisMin = 0;
+  }
 
-      const xAxisMin = Math.max(0, allDisplayXMin - xMargin); // X轴从0开始
-      const xAxisMax = allDisplayXMax + xMargin;
-      const yAxisMax = yMax + yMargin;
+  // 调整X轴最大值为整洁数值(只在叶片轮廓拟合图中)
+  if (this.type === "LeafRootOutline") {
+    const adjustedXAxisMax = Math.ceil(xAxisMax * 10) / 10;
+    xAxisMax = adjustedXAxisMax + 0.02; // 增加0.02的边距
+  }
 
-      console.log("坐标轴显示范围:", {
-        原始X范围: `${minX.toFixed(4)}-${maxX.toFixed(4)}`,
-        拟合圆X范围: `${circleXMin.toFixed(4)}-${circleXMax.toFixed(4)}`,
-        最终X范围: `${xAxisMin.toFixed(4)}-${xAxisMax.toFixed(4)}`,
-        Y轴范围: `0-${yAxisMax.toFixed(4)}`,
+  // Y轴范围处理逻辑
+  if (allDisplayYMin >= 0) {
+    yAxisMin = 0;
+  }
+  
+  console.log("坐标轴显示范围:", {
+    最终X范围: `${xAxisMin.toFixed(4)}-${xAxisMax.toFixed(4)}`,
+    最终Y范围: `${yAxisMin.toFixed(4)}-${yAxisMax.toFixed(4)}`,
+    实际数据X最小值: allDisplayXMin.toFixed(4),
+    实际数据Y最小值: allDisplayYMin.toFixed(4),
+  });
+
+  // 生成所有Y轴标签
+  const yLabels = Array.from(new Set(allY.map((v) => v.toFixed(1))));
+  const xLabels = xRaw.map((v) => v.toFixed(1));
+
+  // 准备中心点数据
+  const centerSeries = [];
+  const baseColors = ["#F44336", "#4CAF50", "#FFA726"]; // 基础叶片颜色
+  const testColors = ["#FF0000", "#00FF00", "#0000FF"]; // 测试颜色
+
+  // === 修改点 4:中心点数据偏移逻辑扩展到 LeafTipProfile ===
+  if (
+    this.LeafRootOutlineData?.blade_center?.xdata?.length > 0 &&
+    this.LeafRootOutlineData?.blade_center?.ydata?.length > 0
+  ) {
+    const centerData = this.LeafRootOutlineData.blade_center;
+    const isOffsetType = (this.type === "LeafRootOutline" || this.type === "LeafTipProfile");
+    
+    // 为叶片1-3添加中心点
+    for (
+      let i = 0;
+      i < Math.min(3, centerData.xdata.length, centerData.ydata.length);
+      i++
+    ) {
+      const centerX = isOffsetType
+        ? Number((centerData.xdata[i] - centerXOffset).toFixed(4))
+        : Number(centerData.xdata[i].toFixed(4));
+
+      let centerY = isOffsetType
+        ? Number((centerData.ydata[i] - centerYOffset).toFixed(4))
+        : Number((centerData.ydata[i] - minValue).toFixed(4)); // 理论上不会执行
+
+      centerSeries.push({
+        name: this.keys === "blade_tip" ? `叶根${i + 1}中心点` : `叶片${i + 1}中心点`,
+        type: "scatter",
+        symbolSize: 10,
+        itemStyle: { color: baseColors[i] },
+        data: [[centerX, centerY]],
       });
+    }
 
-      // === 关键修改:根据X轴范围动态设置Y轴刻度(只针对叶根轮廓拟合图)===
-      // 生成所有Y轴标签
-      const yLabels = Array.from(new Set(allY.map((v) => v.toFixed(1))));
-      const xLabels = xRaw.map((v) => v.toFixed(1));
-
-      // 准备中心点数据 - 判断逻辑
-      const centerSeries = [];
-
-      // 定义颜色配置
-      const baseColors = ["#F44336", "#4CAF50", "#FFA726"]; // 基础叶片颜色
-      const testColors = ["#FF0000", "#00FF00", "#0000FF"]; // 测试颜色
-
-      // 如果blade_center存在且有数据,使用实际数据
-      if (
-        this.LeafRootOutlineData?.blade_center?.xdata?.length > 0 &&
-        this.LeafRootOutlineData?.blade_center?.ydata?.length > 0
+    // 只有在叶片轮廓拟合图且有旋转数据时,才为旋转叶片添加中心点
+    if (this.type === "LeafRootOutline" && hasRotateData) {
+      for (
+        let i = 3;
+        i < Math.min(6, centerData.xdata.length, centerData.ydata.length);
+        i++
       ) {
-        const centerData = this.LeafRootOutlineData.blade_center;
-        console.log("使用实际的blade_center数据:", centerData);
-
-        // 为叶片1-3添加中心点
-        for (
-          let i = 0;
-          i < Math.min(3, centerData.xdata.length, centerData.ydata.length);
-          i++
-        ) {
-          centerSeries.push({
-            name:
-              this.keys === "blade_tip"
-                ? `叶根${i + 1}中心点`
-                : `叶片${i + 1}中心点`,
-            type: "scatter",
-            symbolSize: 10,
-            itemStyle: { color: baseColors[i] },
-            data: [
-              [
-                Number(centerData.xdata[i].toFixed(4)),
-                Number((centerData.ydata[i] - minValue).toFixed(4)),
-              ],
-            ],
-          });
-        }
-
-        // 只有在叶片轮廓拟合图且有旋转数据时,才为旋转叶片添加中心点
-        if (this.type === "LeafRootOutline" && hasRotateData) {
-          for (
-            let i = 3;
-            i < Math.min(6, centerData.xdata.length, centerData.ydata.length);
-            i++
-          ) {
-            centerSeries.push({
-              name: `旋转叶片${i - 2}中心点`,
-              type: "scatter",
-              symbolSize: 10,
-              itemStyle: { color: baseColors[i - 3] },
-              data: [
-                [
-                  Number(centerData.xdata[i].toFixed(4)),
-                  Number((centerData.ydata[i] - minValue).toFixed(4)),
-                ],
-              ],
-            });
-          }
-        }
-      } else {
-        // 如果没有blade_center,使用固定数据
-        console.log("blade_center不存在或数据为空,使用固定测试数据");
-        const testBladeCenter = {
-          xdata: [1.1409272443980873, 1.1486257802831674, 1.1449090600730372],
-          ydata: [88.97949196195555, 88.9672705736207, 88.98638594209639],
-        };
-
-        // 根据类型决定添加多少个中心点
-        const pointCount = 3;
-        for (let i = 0; i < pointCount; i++) {
-          const centerY = Number(
-            (testBladeCenter.ydata[i] - minValue).toFixed(4)
-          );
-          centerSeries.push({
-            name:
-              this.keys === "blade_tip"
-                ? `叶根${i + 1}中心点(测试)`
-                : `叶片${i + 1}中心点(测试)`,
-            type: "scatter",
-            symbolSize: 12,
-            itemStyle: { color: testColors[i] },
-            data: [[Number(testBladeCenter.xdata[i].toFixed(4)), centerY]],
-          });
-        }
-      }
-
-      // === 新增:处理拟合圆数据(只针对叶根轮廓拟合图) ===
-      const circleSeries = [];
-      if (this.type === "LeafTipProfile") {
-        // 定义拟合圆名称和颜色
-        const circleConfigs = [
-          { key: "first_circle", name: "叶根1拟合圆", color: "#F44336" },
-          { key: "second_circle", name: "叶根2拟合圆", color: "#4CAF50" },
-          { key: "third_circle", name: "叶根3拟合圆", color: "#FFA726" },
-        ];
-
-        // 循环处理三个拟合圆数据
-        circleConfigs.forEach((config, index) => {
-          const circleData = this.LeafRootOutlineData[config.key];
-
-          if (circleData?.xdata?.length > 0 && circleData?.ydata?.length > 0) {
-            console.log(`处理${config.name}数据:`, circleData);
-
-            // 处理拟合圆数据点 - 保持原始比例
-            const circlePoints = circleData.xdata.map((x, i) => [
-              Number(x.toFixed(4)),
-              Number((circleData.ydata[i] - minValue).toFixed(4)),
-            ]);
-
-            // 计算拟合圆的范围,用于检查是否保持圆形
-            const circleXMin = Math.min(...circleData.xdata);
-            const circleXMax = Math.max(...circleData.xdata);
-            const circleYMin = Math.min(...circleData.ydata);
-            const circleYMax = Math.max(...circleData.ydata);
-            const circleXRange = circleXMax - circleXMin;
-            const circleYRange = circleYMax - circleYMin;
-
-            console.log(
-              `${config.name}范围: X(${circleXRange.toFixed(
-                4
-              )}), Y(${circleYRange.toFixed(4)})`
-            );
-
-            circleSeries.push({
-              name: config.name,
-              type: "line",
-              showSymbol: false,
-              lineStyle: {
-                width: 2,
-                type: "dashed", // 虚线区分
-                color: config.color,
-              },
-              itemStyle: { color: config.color },
-              data: circlePoints,
-              smooth: true, // 拟合圆需要平滑
-            });
-          } else {
-            console.log(`${config.name}数据不存在或为空`);
-          }
+        const centerX = Number((centerData.xdata[i] - centerXOffset).toFixed(4));
+        const centerY = Number((centerData.ydata[i] - centerYOffset).toFixed(4));
+
+        centerSeries.push({
+          name: `旋转叶片${i - 2}中心点`,
+          type: "scatter",
+          symbolSize: 10,
+          itemStyle: { color: baseColors[i - 3] },
+          data: [[centerX, centerY]],
         });
       }
+    }
+  } else {
+    // 测试数据逻辑...
+    const testBladeCenter = {
+      xdata: [1.1409272443980873, 1.1486257802831674, 1.1449090600730372],
+      ydata: [88.97949196195555, 88.9672705736207, 88.98638594209639],
+    };
+    const pointCount = 3;
+    const isOffsetType = (this.type === "LeafRootOutline" || this.type === "LeafTipProfile");
+
+    for (let i = 0; i < pointCount; i++) {
+      const centerX = isOffsetType
+        ? Number((testBladeCenter.xdata[i] - centerXOffset).toFixed(4))
+        : Number(testBladeCenter.xdata[i].toFixed(4));
+      
+      let centerY = isOffsetType
+        ? Number((testBladeCenter.ydata[i] - centerYOffset).toFixed(4))
+        : Number((testBladeCenter.ydata[i] - minValue).toFixed(4));
+
+      centerSeries.push({
+        name: this.keys === "blade_tip" ? `叶根${i + 1}中心点(测试)` : `叶片${i + 1}中心点(测试)`,
+        type: "scatter",
+        symbolSize: 12,
+        itemStyle: { color: testColors[i] },
+        data: [[centerX, centerY]],
+      });
+    }
+  }
 
-      // 准备所有叶片系列
-      const series = [
-        // 基础叶片1-3轮廓
-        {
-          name: this.keys === "blade_tip" ? "叶根1轮廓" : "叶片1轮廓",
-          type: "line",
-          showSymbol: false,
-          lineStyle: { width: 2, type: "solid" },
-          itemStyle: { color: "#F44336" },
-          data: xRaw.map((x, i) => [x, y1[i]]),
-          smooth: true,
-        },
-        {
-          name: this.keys === "blade_tip" ? "叶根2轮廓" : "叶片2轮廓",
-          type: "line",
-          showSymbol: false,
-          lineStyle: { width: 2, type: "solid" },
-          itemStyle: { color: "#4CAF50" },
-          data: xRaw.map((x, i) => [x, y2[i]]),
-          smooth: true,
-        },
-        {
-          name: this.keys === "blade_tip" ? "叶根3轮廓" : "叶片3轮廓",
-          type: "line",
-          showSymbol: false,
-          lineStyle: { width: 2, type: "solid" },
-          itemStyle: { color: "#FFA726" },
-          data: xRaw.map((x, i) => [x, y3[i]]),
-          smooth: true,
-        },
-      ];
-
-      // 动态图例数据
-      const legendData = [
-        this.keys === "blade_tip" ? "叶根1轮廓" : "叶片1轮廓",
-        this.keys === "blade_tip" ? "叶根2轮廓" : "叶片2轮廓",
-        this.keys === "blade_tip" ? "叶根3轮廓" : "叶片3轮廓",
-      ];
-
-      // 动态添加旋转叶片系列(仅在叶片轮廓拟合图中)
-      if (this.type === "LeafRootOutline" && hasRotateData) {
-        // 添加旋转叶片4-6轮廓
-        const rotateSeries = [];
-
-        if (y4) {
-          rotateSeries.push({
-            name: "旋转叶片1轮廓",
-            type: "line",
-            showSymbol: false,
-            lineStyle: { width: 2, type: "dashed" }, // 虚线区分
-            itemStyle: { color: "#F44336" },
-            data: xRaw.map((x, i) => [x, y4[i]]),
-            smooth: true,
-          });
-          legendData.push("旋转叶片1轮廓");
-        }
-
-        if (y5) {
-          rotateSeries.push({
-            name: "旋转叶片2轮廓",
-            type: "line",
-            showSymbol: false,
-            lineStyle: { width: 2, type: "dashed" },
-            itemStyle: { color: "#4CAF50" },
-            data: xRaw.map((x, i) => [x, y5[i]]),
-            smooth: true,
-          });
-          legendData.push("旋转叶片2轮廓");
-        }
-
-        if (y6) {
-          rotateSeries.push({
-            name: "旋转叶片3轮廓",
-            type: "line",
-            showSymbol: false,
-            lineStyle: { width: 2, type: "dashed" },
-            itemStyle: { color: "#FFA726" },
-            data: xRaw.map((x, i) => [x, y6[i]]),
-            smooth: true,
-          });
-          legendData.push("旋转叶片3轮廓");
-        }
-
-        // 将旋转叶片系列添加到主系列中
-        series.push(...rotateSeries);
-      }
-
-      // 添加拟合圆系列(仅在叶根轮廓拟合图中)
-      if (this.type === "LeafTipProfile" && circleSeries.length > 0) {
-        series.push(...circleSeries);
-        // 将拟合圆添加到图例
-        circleSeries.forEach((circle) => {
-          legendData.push(circle.name);
-        });
-      }
-
-      // 添加中心点系列
-      series.push(...centerSeries);
-
-      // 动态设置颜色和图例
-      let colors = ["#F44336", "#4CAF50", "#FFA726"];
-
-      if (this.type === "LeafRootOutline" && hasRotateData) {
-        colors = [...colors, "#F44336", "#4CAF50", "#FFA726"];
-      }
-
-      if (this.type === "LeafTipProfile" && circleSeries.length > 0) {
-        // 为叶根轮廓拟合图添加拟合圆的颜色
-        colors = [...colors, "#F44336", "#4CAF50", "#FFA726"];
-      }
-
-      // === 关键修改:为叶根轮廓拟合图创建规则的Y轴刻度 ===
-      let yAxisConfig;
-      if (this.type === "LeafTipProfile") {
-        // 对于叶根轮廓拟合图,创建规则的Y轴刻度
-        // 计算需要多少个0.2的间隔来覆盖Y轴范围
-        const interval = 0.2; // 固定间隔0.2
-        const tickCount = Math.ceil(yAxisMax / interval);
-
-        // 生成刻度值数组:0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, ...
-        const ticks = [];
-        for (let i = 0; i <= tickCount; i++) {
-          ticks.push(i * interval);
-        }
-
-        // 调整Y轴最大值,使其是0.2的整数倍
-        const adjustedYAxisMax = Math.ceil(yAxisMax / interval) * interval;
+  // 准备所有叶片系列
+  const series = [
+    {
+      name: this.keys === "blade_tip" ? "叶根1轮廓" : "叶片1轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#F44336" },
+      data: xRaw.map((x, i) => [x, y1[i]]),
+      smooth: true,
+    },
+    {
+      name: this.keys === "blade_tip" ? "叶根2轮廓" : "叶片2轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#4CAF50" },
+      data: xRaw.map((x, i) => [x, y2[i]]),
+      smooth: true,
+    },
+    {
+      name: this.keys === "blade_tip" ? "叶根3轮廓" : "叶片3轮廓",
+      type: "line",
+      showSymbol: false,
+      lineStyle: { width: 2, type: "solid" },
+      itemStyle: { color: "#FFA726" },
+      data: xRaw.map((x, i) => [x, y3[i]]),
+      smooth: true,
+    },
+  ];
+
+  const legendData = [
+    this.keys === "blade_tip" ? "叶根1轮廓" : "叶片1轮廓",
+    this.keys === "blade_tip" ? "叶根2轮廓" : "叶片2轮廓",
+    this.keys === "blade_tip" ? "叶根3轮廓" : "叶片3轮廓",
+  ];
+
+  if (this.type === "LeafRootOutline" && hasRotateData) {
+    const rotateSeries = [];
+    if (y4) {
+      rotateSeries.push({
+        name: "旋转叶片1轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" },
+        itemStyle: { color: "#F44336" },
+        data: xRaw.map((x, i) => [x, y4[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片1轮廓");
+    }
+    if (y5) {
+      rotateSeries.push({
+        name: "旋转叶片2轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" },
+        itemStyle: { color: "#4CAF50" },
+        data: xRaw.map((x, i) => [x, y5[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片2轮廓");
+    }
+    if (y6) {
+      rotateSeries.push({
+        name: "旋转叶片3轮廓",
+        type: "line",
+        showSymbol: false,
+        lineStyle: { width: 2, type: "dashed" },
+        itemStyle: { color: "#FFA726" },
+        data: xRaw.map((x, i) => [x, y6[i]]),
+        smooth: true,
+      });
+      legendData.push("旋转叶片3轮廓");
+    }
+    series.push(...rotateSeries);
+  }
 
-        console.log("叶根轮廓拟合图 - 规则Y轴刻度:", {
-          原始Y轴最大值: yAxisMax.toFixed(4),
-          调整后Y轴最大值: adjustedYAxisMax.toFixed(4),
-          刻度间隔: interval,
-          刻度数量: tickCount + 1,
-          刻度值: ticks.map((v) => v.toFixed(1)),
-        });
+  if (this.type === "LeafTipProfile" && circleSeries.length > 0) {
+    series.push(...circleSeries);
+    circleSeries.forEach((circle) => {
+      legendData.push(circle.name);
+    });
+  }
+  series.push(...centerSeries);
 
-        yAxisConfig = {
-          type: "value",
-          name: "距离(m)",
-          nameLocation: "middle",
-          nameTextStyle: { fontWeight: "bold", padding: [0, 0, 40, 0] },
-          min: 0,
-          max: adjustedYAxisMax,
-          interval: interval,
-          axisLabel: {
-            formatter: function (value) {
-              // 显示小数点后1位
-              return value.toFixed(1);
-            },
-          },
-        };
-      } else {
-        // 其他类型图表保持原来的逻辑
-        yAxisConfig = {
-          type: "value",
-          name: "距离(m)",
-          nameLocation: "middle",
-          nameTextStyle: { fontWeight: "bold", padding: [0, 0, 40, 0] },
-          min: yMin,
-          max: yAxisMax,
-          axisLabel: {
-            formatter: function (value) {
-              return value.toFixed(1);
-            },
-          },
-        };
-      }
+  let colors = ["#F44336", "#4CAF50", "#FFA726"];
+  if ((this.type === "LeafRootOutline" && hasRotateData) || (this.type === "LeafTipProfile" && circleSeries.length > 0)) {
+    colors = [...colors, "#F44336", "#4CAF50", "#FFA726"];
+  }
 
-      const option = {
-        grid: { left: 80, right: 40, top: 40, bottom: 60 },
-        color: colors,
-        toolbox: {
-          feature: {
-            dataZoom: { yAxisIndex: "none" },
-            restore: {},
-            saveAsImage: {},
-            myCustomTool1: {
-              show: true,
-              title: "标注",
-              icon: `image://${new URL(
-                "@/assets/analyse/mark.png",
-                import.meta.url
-              )}`,
-              onclick: () => this.WhetherToDisplay(),
-            },
-            myCustomTool2: {
-              show: true,
-              title: "全屏",
-              icon: `image://${new URL(
-                "@/assets/analyse/fullScreen.png",
-                import.meta.url
-              )}`,
-              onclick: () => this.fullScreen(),
-            },
-            myCustomTool3: {
-              show: true,
-              title: "退出全屏",
-              icon: `image://${new URL(
-                "@/assets/analyse/exitFullScreen.png",
-                import.meta.url
-              )}`,
-              onclick: () => this.exitFullScreen(),
-            },
-          },
-        },
-        xAxis: {
-          type: "value",
-          name: "距离(m)",
-          nameLocation: "middle",
-          nameTextStyle: { fontWeight: "bold", padding: [20, 0, 0, 0] },
-          min: xAxisMin, // 使用调整后的最小值
-          max: xAxisMax, // 使用调整后的最大值
-          splitNumber: 15, // 保持原来的15个刻度
-          data: [...new Set(xLabels)],
-          splitLine: { show: true, lineStyle: { color: "rgb(220,220,220)" } },
+  // === Y轴配置 ===
+  const yAxisConfig = {
+    type: "value",
+    name: "距离(m)",
+    nameLocation: "middle",
+    nameTextStyle: { fontWeight: "bold", padding: [0, 0, 40, 0] },
+    min: yAxisMin,
+    max: yAxisMax,
+    interval: 0.2,
+    axisLabel: {
+      formatter: function (value) {
+        return value.toFixed(1);
+      },
+    },
+  };
+
+  const option = {
+    grid: { left: 80, right: 40, top: 40, bottom: 60 },
+    color: colors,
+    toolbox: {
+      feature: {
+        dataZoom: { yAxisIndex: "none" },
+        restore: {},
+        saveAsImage: {},
+        myCustomTool1: {
+          show: true,
+          title: "标注",
+          icon: `image://${new URL("@/assets/analyse/mark.png", import.meta.url)}`,
+          onclick: () => this.WhetherToDisplay(),
         },
-        yAxis: yAxisConfig,
-        tooltip: {
-          trigger: "axis",
-          valueFormatter: (v) => (typeof v === "number" ? v.toFixed(4) : v),
-          position: (pt) => [pt[0], "10%"],
-          confine: false, // 允许tooltip超出图表区域
-          appendToBody: true, // 将tooltip附加到body,避免被父容器遮挡
+        myCustomTool2: {
+          show: true,
+          title: "全屏",
+          icon: `image://${new URL("@/assets/analyse/fullScreen.png", import.meta.url)}`,
+          onclick: () => this.fullScreen(),
         },
-        legend: {
-          data: legendData,
-          left: 0,
-          top: 0,
+        myCustomTool3: {
+          show: true,
+          title: "退出全屏",
+          icon: `image://${new URL("@/assets/analyse/exitFullScreen.png", import.meta.url)}`,
+          onclick: () => this.exitFullScreen(),
         },
-        series: series,
-      };
-
-      this.chartInstance.setOption(option, true);
-
-      // ======== 动态高度计算 ========
-      this.$nextTick(() => {
-        const maxYLabelLen = [...new Set(yLabels)].length;
-        const chartDom = this.$refs[`chart${this.keys}`];
-        const chartWidth = chartDom.clientWidth;
-        const grid =
-          option.grid && option.grid[0]
-            ? option.grid[0]
-            : { left: 0, right: 0 };
-        const xAxisWidth =
-          chartWidth - (parseInt(grid.left) || 0) - (parseInt(grid.right) || 0);
-        const xAxisWidthPerLabel = xAxisWidth / 15;
-
-        // 默认高度
-        let baseHeight = 400;
-
-        // 如果 y 轴的刻度文本比 x 轴长,则增加高度
-        if (maxYLabelLen > [...new Set(xLabels)].length) {
-          baseHeight = maxYLabelLen * xAxisWidthPerLabel;
-        } else if (maxYLabelLen < [...new Set(xLabels)].length) {
-          const xAxisWidthPerLabelAll =
-            xAxisWidth / [...new Set(xLabels)].length;
-          baseHeight = maxYLabelLen * xAxisWidthPerLabelAll;
+      },
+    },
+    xAxis: {
+      type: "value",
+      name: "距离(m)",
+      nameLocation: "middle",
+      nameTextStyle: { fontWeight: "bold", padding: [20, 0, 0, 0] },
+      min: xAxisMin, 
+      max: xAxisMax,
+      splitNumber: 15,
+      data: [...new Set(xLabels)],
+      splitLine: { show: true, lineStyle: { color: "rgb(220,220,220)" } },
+      axisLabel: {
+        formatter: function (value) {
+          return value.toFixed(1);
         }
+      },
+      interval: 0.2,
+    },
+    yAxis: yAxisConfig,
+    tooltip: {
+      trigger: "axis",
+      valueFormatter: (v) => (typeof v === "number" ? v.toFixed(4) : v),
+      position: (pt) => [pt[0], "10%"],
+      confine: false,
+      appendToBody: true,
+    },
+    legend: {
+      data: legendData,
+      left: 0,
+      top: 0,
+    },
+    series: series,
+  };
+
+  this.chartInstance.setOption(option, true);
+
+  // ======== 动态高度计算 ========
+  this.$nextTick(() => {
+    const maxYLabelLen = [...new Set(yLabels)].length;
+    const chartDom = this.$refs[`chart${this.keys}`];
+    const chartWidth = chartDom.clientWidth;
+    const grid = option.grid && option.grid[0] ? option.grid[0] : { left: 0, right: 0 };
+    const xAxisWidth = chartWidth - (parseInt(grid.left) || 0) - (parseInt(grid.right) || 0);
+    const xAxisWidthPerLabel = xAxisWidth / 15;
+
+    let baseHeight = 400;
+
+    if (maxYLabelLen > [...new Set(xLabels)].length) {
+      baseHeight = maxYLabelLen * xAxisWidthPerLabel;
+    } else if (maxYLabelLen < [...new Set(xLabels)].length) {
+      const xAxisWidthPerLabelAll = xAxisWidth / [...new Set(xLabels)].length;
+      baseHeight = maxYLabelLen * xAxisWidthPerLabelAll;
+    }
 
-        // 如果是拟合圆模式,需要保持1:1的比例
-        if (hasCircleData) {
-          // 根据X和Y轴范围的比例计算合适的高度,保持1:1比例
-          const xDisplayRange = xAxisMax - xAxisMin;
-          const yDisplayRange = yAxisMax - yMin;
-          const rangeRatio = xDisplayRange / yDisplayRange;
-
-          // 保持1:1比例所需的高度
-          const heightFor1to1 = chartWidth / rangeRatio;
-          baseHeight = Math.max(baseHeight, heightFor1to1);
-
-          console.log("拟合圆模式:调整高度以保持1:1比例", {
-            xDisplayRange: xDisplayRange.toFixed(4),
-            yDisplayRange: yDisplayRange.toFixed(4),
-            rangeRatio: rangeRatio.toFixed(4),
-            chartWidth,
-            heightFor1to1: heightFor1to1.toFixed(0),
-            finalHeight: baseHeight,
-          });
-        }
+    // 拟合圆模式保持1:1比例
+    if (hasCircleData) {
+      const xDisplayRange = xAxisMax - xAxisMin;
+      const yDisplayRange = yAxisMax - yAxisMin;
+      const rangeRatio = xDisplayRange / yDisplayRange;
+      const heightFor1to1 = chartWidth / rangeRatio;
+      baseHeight = Math.max(baseHeight, heightFor1to1);
+    }
 
-        chartDom.style.height = baseHeight + "px";
-        console.log(
-          "每个刻度线的距离",
-          xAxisWidthPerLabel,
-          `chart${this.keys}`,
-          baseHeight,
-          "当前类型:",
-          this.type,
-          "渲染系列数量:",
-          legendData.length,
-          "X范围:",
-          xAxisMin.toFixed(2),
-          "-",
-          xAxisMax.toFixed(2),
-          "Y范围:",
-          yMin.toFixed(2),
-          "-",
-          yAxisMax.toFixed(2)
-        );
-
-        // 重新调整 ECharts 大小
-        this.chartInstance.resize();
-      });
+    chartDom.style.height = baseHeight + "px";
+    this.chartInstance.resize();
+  });
 
-      // 防止重复绑定 resize 事件
-      if (this._onResizeEqualScale) {
-        window.removeEventListener("resize", this._onResizeEqualScale);
-      }
-      this._onResizeEqualScale = () => this.updateChart();
-      window.addEventListener("resize", this._onResizeEqualScale);
-    },
+  if (this._onResizeEqualScale) {
+    window.removeEventListener("resize", this._onResizeEqualScale);
+  }
+  this._onResizeEqualScale = () => this.updateChart();
+  window.addEventListener("resize", this._onResizeEqualScale);
+},
     // 标注是否显示
     WhetherToDisplay() {
       // 切换显示状态

+ 47 - 122
jg/src/views/laserRangeFinder/index.vue

@@ -1,5 +1,4 @@
 <template>
-  <!-- 激光测距仪页面 -->
   <div class="global-variable">
     <el-card class="box-card">
       <div>
@@ -61,29 +60,6 @@
                   </el-input>
                 </el-form-item></el-col
               >
-
-              <!-- <el-col :span="11"
-                ><el-form-item
-                  label="切割阈值:"
-                  prop="threshold"
-                  type="number"
-                  label-position="left"
-                  :rules="[
-                    {
-                      required: true,
-                      message: '请输入切割阈值',
-                      trigger: 'blur',
-                    },
-                  ]"
-                >
-                  <el-input
-                    v-model="formLabelAlign.threshold"
-                    placeholder="请输入切割阈值"
-                  >
-                    <template #append>°/度</template>
-                  </el-input>
-                </el-form-item></el-col
-              > -->
             </el-row>
           </el-form>
         </div>
@@ -154,58 +130,31 @@
       </div>
       <div class="stepTwo" v-if="stepsActive === 1">
         <div>
-          <!-- <el-empty
-            :image-size="300"
-            :image="loadingGif"
-            element-loading-background="rgba(255, 255, 255, 0.3)"
-            class="loadingView"
-            description=" "
-          /> -->
-          <!-- <div
-            style="
-              font-size: 16px;
-              font-weight: bold;
-              text-align: center;
-              color: #2c78da;
-            "
-          >
-            数据测量中...
-          </div> -->
           <div class="loadingLoad"></div>
           <div class="loader"></div>
         </div>
       </div>
       <div class="stepThree" v-if="stepsActive === 2">
         <div class="searchbox">
-          <el-collapse
-            v-model="activeNames"
+          <div
+            class="search-header"
             v-if="tabActiveName !== 'copy' && tabActiveName !== 'init'"
           >
-            <el-collapse-item title="数据筛选" name="1">
-              <template #title>
-                <div class="titleLeft">数据筛选</div>
-                <div class="titleRight">
-                  <el-button type="primary" @click.stop="searchTableData">
-                    查询
-                  </el-button>
-                  <el-button type="primary" @click.stop="resetTableData">
-                    重置
-                  </el-button>
-                  <el-button
-                    v-if="tabActiveName === 'list'"
-                    type="primary"
-                    @click.stop="onSubmit"
-                  >
-                    导出
-                  </el-button>
-                </div>
-              </template>
+            <div
+              class="titleLeft"
+              style="font-size: 16px; font-weight: bold; margin-bottom: 15px"
+            >
+              数据筛选
+            </div>
+
+            <div class="yangshi">
               <el-form
                 :inline="true"
                 :model="formInline"
                 class="demo-form-inline"
+                v-if="tabActiveName !== 'copy' && tabActiveName !== 'init'"
               >
-                <el-row :gutter="10">
+                <el-row :gutter="240">
                   <el-col :xs="16" :sm="8" :md="7" :lg="6" :xl="4">
                     <el-form-item label="场站">
                       <el-select
@@ -220,20 +169,6 @@
                         >
                         </el-option>
                       </el-select>
-                      <!-- <selecttree
-                        style="width: 220px"
-                        placeholder="请选择场站"
-                        :list="parentOpt"
-                        type="1"
-                        v-model="formInline.companyCode"
-                        @change="parentChange"
-                        :defaultParentProps="{
-                          children: 'children',
-                          label: 'companyName',
-                          value: 'codeNumber',
-                        }"
-                      >
-                      </selecttree> -->
                     </el-form-item>
                   </el-col>
                   <el-col :xs="16" :sm="8" :md="7" :lg="6" :xl="4">
@@ -252,22 +187,28 @@
                       </el-select>
                     </el-form-item>
                   </el-col>
-                  <!-- <el-col :xs="24" :sm="14" :md="12" :lg="10" :xl="6">
-                    <el-form-item label="时间">
-                      <el-date-picker
-                        v-model="formInline.timevalue"
-                        type="daterange"
-                        range-separator="至"
-                        start-placeholder="开始日期"
-                        end-placeholder="结束日期"
-                      >
-                      </el-date-picker>
-                    </el-form-item>
-                  </el-col> -->
                 </el-row>
               </el-form>
-            </el-collapse-item>
-          </el-collapse>
+              <div
+                class="titleRight"
+                style="display: flex; margin-bottom: 15px"
+              >
+                <el-button type="primary" @click.stop="searchTableData">
+                  查询
+                </el-button>
+                <el-button type="primary" @click.stop="resetTableData">
+                  重置
+                </el-button>
+                <el-button
+                  v-if="tabActiveName === 'list'"
+                  type="primary"
+                  @click.stop="onSubmit"
+                >
+                  导出
+                </el-button>
+              </div>
+            </div>
+          </div>
         </div>
         <div class="main-body">
           <div class="data-map">
@@ -293,7 +234,6 @@
                       v-if="!LeafRootOutlineData.original_plot"
                     ></el-empty>
                     <div v-else>
-                      <!-- detailsMsg -->
                       <el-alert type="info" :closable="false">
                         <div
                           style="
@@ -390,7 +330,6 @@
                           }},测量时间{{ detailsMsg[0] }}
                         </div>
                       </el-alert>
-                      <!-- 叶根拟合图 -->
                       <PlotOfFit
                         v-if="
                           LeafRootOutlineData.blade_root?.first_blade?.ydata
@@ -401,7 +340,6 @@
                         keys="blade_root"
                         :LeafRootOutlineData="LeafRootOutlineData.blade_root"
                       ></PlotOfFit>
-                      <!-- 叶尖拟合图 -->
                       <PlotOfFit
                         v-if="
                           LeafRootOutlineData.blade_tip?.first_blade?.ydata
@@ -491,7 +429,7 @@ export default {
       pathFileName: "",
       loadingGif,
       chartKey: 0, // 用于强制重新渲染子组件
-      activeNames: ["1"],
+      // activeNames: ["1"], // 移除 activeNames
       tabActiveName: "init",
       formInline: {
         companyCode: "", //单位
@@ -690,29 +628,6 @@ export default {
       this.formInline.timevalue = "";
       this.tableData = this.defaultData;
     },
-    //加时间条件过滤
-    // searchTableData() {
-    //   const { companyCode, unitvalue, timevalue } = this.formInline;
-
-    //   if (!companyCode && !unitvalue && (!timevalue || timevalue.length < 2)) {
-    //     this.tableData = this.defaultData;
-    //     return;
-    //   }
-
-    //   this.tableData = this.defaultData.filter((item) => {
-    //     const matchCompany = companyCode ? item["场站"] === companyCode : true;
-    //     const matchUnit = unitvalue ? item["风机编号"] === unitvalue : true;
-
-    //     let matchTime = true;
-    //     if (timevalue && timevalue.length === 2) {
-    //       const [start, end] = timevalue.map((t) => new Date(t));
-    //       const itemTime = new Date(item["采集时间"]);
-    //       matchTime = itemTime >= start && itemTime <= end;
-    //     }
-
-    //     return matchCompany && matchUnit && matchTime;
-    //   });
-    // },
     handleInitCurrentChange(val, ind) {
       this.currentInitRow = val; // 处理当前选中行
       this.currentInitIndex = ind; // 更新当前索引
@@ -815,18 +730,22 @@ export default {
     width: 180px;
   }
 
-  ::v-deep .el-collapse-item__header {
+  /* 移除与 el-collapse 相关的样式穿透 */
+  /* ::v-deep .el-collapse-item__header {
     position: relative !important;
-  }
+  } */
   .titleLeft {
     font-size: 16px;
     font-weight: bold;
   }
   .titleRight {
     display: flex;
-    position: absolute;
-    right: 50px;
+    /* position: absolute; */ /* 移除绝对定位 */
+    /* right: 50px; */
   }
+  /* el-collapse {
+    display: flex;
+  } */
 }
 .dialog-actions {
   text-align: right;
@@ -977,4 +896,10 @@ export default {
     background-position: top, center;
   }
 }
+
+.yangshi{
+  display: flex;
+  justify-content: space-between;
+  width: 100%;
+}
 </style>