<template>
  <div class="app-container">
    <div class="containerBlock">
      <!-- 添加加载状态和错误提示 -->
      <div v-if="loadingError" class="error-message">
        {{ loadingError }}
      </div>
      <div class="toolbar" v-if="isWidgetReady">
        <!-- 左侧内容 -->
        <div class="toolbar-left">
          <!-- 左侧可以留空，或者将来添加其他控件 -->
        </div>
        <!-- 右侧按钮组 -->
        <div class="toolbar-right">
          <div class="color-maps">
            <el-select v-model="currentColorMap" @change="switchColorMap" size="small">
              <el-option v-for="map in colorMaps" :key="map.value" :label="map.label" :value="map.value">
                <span class="color-map-option">
                  <span class="color-map-preview" :class="map.value"></span>
                  {{ map.label }}
                </span>
              </el-option>
            </el-select>
          </div>
          <toolbar-controls :plots="plots" :data-loaded="isWidgetReady" :show-line-style-panel="showLineStylePanel"
            @toggleLineStylePanel="toggleLineStylePanel" @exporting="exporting = $event"
            @closePrintDialog="showPrintDialog = false" />

          <el-tooltip content="绘制文本" placement="bottom" effect="light">
            <el-button @click="toggleDrawText" :class="{ 'active': isDrawingText }">
              <i class="el-icon-edit-outline"></i>
            </el-button>
          </el-tooltip>
          <el-tooltip content="绘制线条" placement="bottom" effect="light">
            <el-button @click="toggleLineStylePanel" :class="{ 'active': showLineStylePanel }">
              <i class="el-icon-edit"></i>
            </el-button>
          </el-tooltip>
        </div>
      </div>
      <div class="split-container">
        <div class="sync-section" ref="topScroll" @scroll="onScroll('top')">
          <div class="zoom-wrapper" ref="topWrapper" :style="{ width: (zoomScale * 100) + '%' }">
            <canvas ref="plot" id="canvasTop" class="plot-canvas" />
          </div>
        </div>
        <div class="sync-section" ref="bottomScroll" @scroll="onScroll('bottom')">
          <div class="zoom-wrapper" ref="bottomWrapper" :style="{ width: (zoomScale * 100) + '%' }">
            <canvas ref="plot2" id="canvasBottom" class="plot-canvas" />
          </div>
        </div>
      </div>
      <!-- 添加鼠标悬停专用覆盖层 -->
      <div ref="hoverLayer" class="hover-layer"></div>
      <!-- 自定义右键菜单 -->
      <div v-if="contextMenu.visible" class="context-menu" :style="{
        left: `${contextMenu.x}px`,
        top: `${contextMenu.y}px`
      }" @mouseleave="hideContextMenu">
        <div v-for="(item, index) in contextMenuItems" :key="index">
          <div v-if="item.type === 'separator'" class="context-menu-separator">
          </div>
          <div v-else class="context-menu-item" :class="{ disabled: !isMenuItemEnabled(item.action) }"
            @click="handleMenuAction(item.action)">
            <span>
              <i :class="getElementIcon(item.icon)" class="mr-2"></i>
              {{ item.text }}
            </span>
            <span class="shortcut" v-if="item.shortcut">{{ item.shortcut }}</span>
          </div>
        </div>
      </div>
      <!-- 文本样式面板 -->
      <div class="style-panel text-style-panel" :class="{ 'style-panel-visible': showTextStylePanel }">
        <div class="style-panel-header">
          <h3>文本样式</h3>
          <el-button icon="el-icon-close" size="mini" circle @click="showTextStylePanel = false"></el-button>
        </div>
        <div class="style-content">
          <!-- 填充样式部分 -->
          <div class="style-section-title">填充样式</div>
          <div class="style-item">
            <span class="style-label">颜色：</span>
            <el-color-picker v-model="fillStyle.color" show-alpha @change="updateFillStyle">
            </el-color-picker>
          </div>
          <div class="style-item">
            <span class="style-label">样式：</span>
            <el-select v-model="fillStyle.pattern" placeholder="选择填充样式" @change="updateFillStyle">
              <el-option v-for="(pattern, key) in fillPatterns" :key="key" :label="key" :value="key">
                <div class="pattern-preview-fill" :style="getFillPatternStyle(key)"></div>
              </el-option>
            </el-select>
          </div>
          <div class="style-divider"></div>
          <!-- 线条样式部分 -->
          <div class="style-section-title">线条样式</div>
          <div class="style-item">
            <span class="style-label">颜色：</span>
            <el-color-picker v-model="lineStyle.color" show-alpha @change="updateLineStyle">
            </el-color-picker>
          </div>
          <div class="style-item">
            <span class="style-label">宽度：</span>
            <el-slider v-model="lineStyle.width" :min="1" :max="12" show-input @change="updateLineStyle">
            </el-slider>
          </div>
          <div class="style-item">
            <span class="style-label">样式：</span>
            <el-select v-model="lineStyle.pattern" placeholder="选择线条样式" @change="updateLineStyle">
              <el-option v-for="(pattern, key) in linePatterns" :key="key" :label="key" :value="key">
                <div class="pattern-preview-line" :style="getLinePatternStyle(key)"></div>
              </el-option>
            </el-select>
          </div>
          <!-- 分隔线 -->
          <div class="style-divider"></div>
          <div class="style-section-title">文本样式</div>
          <div class="style-item">
            <span class="style-label">颜色：</span>
            <el-color-picker v-model="textStyle.color" show-alpha @change="updateTextStyle">
            </el-color-picker>
          </div>
          <div class="style-item">
            <span class="style-label">大小：</span>
            <el-slider v-model="textStyle.size" :min="8" :max="60" show-input @change="handleFontSizeChange">
            </el-slider>
          </div>
          <div class="style-item">
            <span class="style-label">字体：</span>
            <el-select v-model="textStyle.font" placeholder="选择字体" @change="handleFontChange">
              <el-option v-for="(font, index) in Object.keys(TEXT_PATTERNS)" :key="index" :label="font" :value="font"
                :style="{ fontFamily: font }">
                {{ font }}
              </el-option>
            </el-select>
          </div>
          <div class="style-item">
            <span class="style-label">对齐：</span>
            <div class="text-style-buttons">
              <el-button-group style="width: 100%">
                <el-button style="min-width: 20%; max-width: 20%" :type="textStyle.align === 'left' ? 'primary' : ''"
                  @click="textStyle.align = 'left'; updateTextStyle()" title="左对齐">
                  <i class="el-icon-s-fold"></i>
                </el-button>
                <el-button style="min-width: 20%; max-width: 20%" :type="textStyle.align === 'center' ? 'primary' : ''"
                  @click="textStyle.align = 'center'; updateTextStyle()" title="居中对齐">
                  <i class="el-icon-menu"></i>
                </el-button>
                <el-button style="min-width: 20%; max-width: 20%" :type="textStyle.align === 'right' ? 'primary' : ''"
                  @click="textStyle.align = 'right'; updateTextStyle()" title="右对齐">
                  <i class="el-icon-s-unfold"></i>
                </el-button>
                <!-- 粗体按钮 -->
                <el-button style="min-width: 20%; max-width: 20%" :type="textStyle.bold ? 'primary' : ''"
                  @click="textStyle.bold = !textStyle.bold; updateTextStyle()" title="粗体">
                  <span style="font-weight: bold">B</span>
                </el-button>
                <!-- 斜体按钮 -->
                <el-button style="min-width: 20%; max-width: 20%" :type="textStyle.italic ? 'primary' : ''"
                  @click="textStyle.italic = !textStyle.italic; updateTextStyle()" title="斜体">
                  <span style="font-style: italic">I</span>
                </el-button>
              </el-button-group>
            </div>
          </div>
          <!-- 添加属性部分 -->
          <div class="style-divider"></div>
          <div class="style-section-title">属性</div>
          <div class="style-item">
            <span class="style-label">边框圆角：</span>
            <el-input-number v-model="textStyle.borderRadius" :min="0" :max="30" size="small"
              @change="handleBorderRadiusChange">
            </el-input-number>
          </div>
          <div class="style-item">
            <el-checkbox v-model="textStyle.fixedFont" @change="handleFixedFontChange">
              固定字体
            </el-checkbox>
          </div>
        </div>
      </div>
      <!-- 线条样式面板 -->
      <div class="style-panel line-style-panel" :class="{ 'style-panel-visible': showLineStylePanel }">
        <div class="style-panel-header">
          <h3>线条样式</h3>
          <el-button icon="el-icon-close" size="mini" circle @click="showLineStylePanel = false"></el-button>
        </div>
        <div class="style-content">
          <div class="style-item">
            <span class="style-label">颜色：</span>
            <el-color-picker v-model="lineStyle.color" show-alpha @change="updateLineStyle">
            </el-color-picker>
          </div>
          <div class="style-item">
            <span class="style-label">样式：</span>
            <el-select v-model="lineStyle.pattern" placeholder="选择线条样式" @change="updateLineStyle">
              <el-option v-for="(pattern, key) in linePatterns" :key="key" :label="key" :value="key">
                <div class="pattern-preview-line" :style="getLinePatternStyle(key)"></div>
              </el-option>
            </el-select>
          </div>
          <div class="style-item">
            <span class="style-label">宽度：</span>
            <el-slider v-model="lineStyle.width" :min="1" :max="12" show-input @change="updateLineStyle">
            </el-slider>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { SeismicWidget } from '@int/geotoolkit/seismic/widgets/SeismicWidget';
import { SeismicColors } from '@int/geotoolkit/seismic/util/SeismicColors';
import { SeismicPipeline } from '@int/geotoolkit/seismic/pipeline/SeismicPipeline';
import { SegyReader } from '@int/geotoolkit/seismic/data/SegyReader';
import { LocalFile } from '@int/geotoolkit/seismic/data/LocalFile';
import { Plot } from '@int/geotoolkit/plot/Plot';
import { getToken } from '@/utils/auth';
import { Group } from '@int/geotoolkit/scene/Group';
import { Paint } from '@int/geotoolkit/controls/tools/Paint';
import { PaintMode } from '@int/geotoolkit/controls/tools/PaintMode';
import { EditEvents } from '@int/geotoolkit/controls/tools/EditEvents';
import { EditMode } from '@int/geotoolkit/controls/tools/EditMode';
import { Selection, Events as SelectionEvents } from '@int/geotoolkit/controls/tools/Selection';
import { TextStyle } from '@int/geotoolkit/attributes/TextStyle';
import { LineStyle } from '@int/geotoolkit/attributes/LineStyle';
import { FillStyle } from '@int/geotoolkit/attributes/FillStyle';
import { Text } from '@int/geotoolkit/scene/shapes/Text';
import { NormalizationType } from '@int/geotoolkit/seismic/pipeline/NormalizationType';
import { NoSnapPicking } from '@int/geotoolkit/seismic/data/snap/NoSnapPicking';
import { SnapPicker } from '@int/geotoolkit/seismic/data/snap/SnapPicker';
import { ColorBarLocation } from '@int/geotoolkit/controls/shapes/ColorBarLocation';
import { Alignment as BoxLayoutAlignment } from '@int/geotoolkit/layout/BoxLayout';
import { LINE_PATTERNS, FILL_PATTERNS, TEXT_PATTERNS, LINESTYLE_PATTERNS, IMAGE_PATTERNS, LS_KEYS, FS_KEYS, TS_KEYS } from '@/api/Patterns.js';
import { SizeMode } from '@int/geotoolkit/scene/shapes/Text';
import { RgbaColor } from '@int/geotoolkit/util/RgbaColor';
import { AutoNumberFormat } from '@int/geotoolkit/util/AutoNumberFormat';
// 导入新的组件
import ToolbarControls from '@/components/ToolbarControls.vue';
import LineStylePanel from '@/components/LineStylePanel.vue';
import { CrossHair, Events as CrossHairEvents } from '@int/geotoolkit/controls/tools/CrossHair';
import { TaperFilterProcess } from '@int/geotoolkit/seismic/analysis/filters/TaperFilterProcess';
import { AGC } from '@int/geotoolkit/seismic/pipeline/processor/AGC';
import { Reverse } from '@int/geotoolkit/seismic/pipeline/processor/Reverse';
import { Path } from '@int/geotoolkit/scene/shapes/Path';
import { Rect } from '@int/geotoolkit/util/Rect';

// 线条样式模式常量
const TEXT_PATTERN_KEYS = Object.keys(TEXT_PATTERNS);
const FILL_PATTERN_KEYS = Object.keys(FILL_PATTERNS);
const LINE_PATTERN_KEYS = Object.keys(LINE_PATTERNS);

// 在export default前添加interpolate函数
const interpolate = function (target, startIndex, endIndex, startColor, endColor) {
  // 添加参数验证
  if (!target || !Array.isArray(target)) {
    console.error('interpolate: target必须是数组');
    return;
  }

  if (typeof startIndex !== 'number' || typeof endIndex !== 'number' ||
    startIndex < 0 || endIndex >= target.length || startIndex > endIndex) {
    console.error(`interpolate: 索引无效 - startIndex: ${startIndex}, endIndex: ${endIndex}, target.length: ${target.length}`);
    return;
  }

  if (!startColor || !endColor ||
    typeof startColor.R !== 'number' || typeof startColor.G !== 'number' || typeof startColor.B !== 'number' ||
    typeof endColor.R !== 'number' || typeof endColor.G !== 'number' || typeof endColor.B !== 'number') {
    console.error('interpolate: 颜色必须包含有效的RGB值');
    return;
  }

  const offset = startIndex;
  const stop = (endIndex - startIndex);
  let r, g, b;

  const stepR = (endColor.R - startColor.R) / (stop);
  const stepG = (endColor.G - startColor.G) / (stop);
  const stepB = (endColor.B - startColor.B) / (stop);

  try {
    for (let i = 0; i <= stop; ++i) {
      r = startColor.R + i * stepR;
      g = startColor.G + i * stepG;
      b = startColor.B + i * stepB;
      target[offset + i] = new RgbaColor(
        Math.round(r < 255 ? r : 255),
        Math.round(g < 255 ? g : 255),
        Math.round(b < 255 ? b : 255),
        255
      );
    }
  } catch (error) {
    console.error(`interpolate: 创建颜色时出错 - ${error.message}`);
  }
};

export default {
  name: "seismic",
  components: {
    ToolbarControls,
    LineStylePanel
  },
  data() {
    return {
      plots: null,
      plotsBottom: null,
      _seismicWidget: null,
      _seismicWidgetBottom: null,
      pipeline: null,
      pipelineBottom: null,
      // zoom & scroll sync
      zoomScale: 1,
      baseCanvasHeight: 800,
      _isSyncingScroll: false,
      _isSyncingInternalScroll: false,
      _isDraggingTop: false,
      _isDraggingBottom: false,
      _zoomHooked: false,
      _isSyncingZoom: false,
      isHovering: false,
      cursorInfo: {
        depth: null,
        trace: null,
        value: null
      },
      showCursorInfo: true,
      isWidgetReady: false,
      loadingError: null,
      _headers: [],
      _colorMap: null,
      savedLineAnnotations: [],
      // savedLineAnnotations: [{
      //   properties: {
      //     x: [2390.510986101919, 2313.4866975512905, 2307.7161482461947, 2303.4509596293847, 2298.934877564527, 
      //         2295.924156187955, 2292.9134348113835, 2290.404500330907, 2287.8955658504306, 2283.63037723362, 
      //         2280.870549305096, 2278.612508272667, 2275.852680344143, 2274.347319655857, 2272.8419589675714, 
      //         2271.8383851753806, 2271.8383851753806, 2272.340172071476, 2273.092852415619, 2274.8491065519524, 
      //         2276.8562541363335, 2280.3687624090007, 2287.6446724023826, 2292.6625413633355, 2298.4330906684318, 
      //         2307.2143613500994, 2313.7375909993384, 2320.511714096625, 2325.7804765056253, 2333.307279947055, 
      //         2344.095698213104, 2349.8662475182, 2356.1385837193916, 2365.421641297154, 2373.450231634679, 
      //         2382.231502316347, 2389.7583057577763, 2403.3065519523498, 2422.625347452019, 2433.915552614163, 
      //         2443.1986101919256, 2449.470946393117, 2457.75043017869, 2469.5424222369293, 2475.8147584381204, 
      //         2488.861217736598, 2508.6818001323627, 2522.731833223031, 2536.530972865652, 2547.0684976836533, 
      //         2628.1070814030445],
      //     y: [2.5366336633663367, 2.5056105610561055, 2.506930693069307, 2.5095709570957094, 2.516831683168317, 
      //         2.5227722772277223, 2.5346534653465347, 2.545214521452145, 2.5597359735973595, 2.586138613861386, 
      //         2.6046204620462046, 2.625082508250825, 2.6547854785478546, 2.6785478547854784, 2.707590759075907, 
      //         2.7326732673267324, 2.758415841584158, 2.801980198019802, 2.834983498349835, 2.8666666666666667, 
      //         2.89042904290429, 2.925412541254125, 2.9788778877887787, 3.0072607260726074, 3.0323432343234322, 
      //         3.0613861386138614, 3.0792079207920793, 3.094389438943894, 3.104290429042904, 3.1135313531353135, 
      //         3.124092409240924, 3.1273927392739274, 3.13003300330033, 3.130693069306931, 3.131353135313531, 
      //         3.131353135313531, 3.131353135313531, 3.132673267326733, 3.1353135313531353, 3.1366336633663363, 
      //         3.1372937293729373, 3.137953795379538, 3.1392739273927392, 3.141254125412541, 3.141254125412541, 
      //         3.1399339933993398, 3.1392739273927392, 3.1392739273927392, 3.1392739273927392, 3.1392739273927392, 
      //         3.1392739273927392],
      //     linestyle: {
      //       Lx: "#0351ad",
      //       fA: 2
      //     }
      //   },
      //   bounds: {
      //     x: 2271.8383851753806,
      //     y: 2.5056105610561055,
      //     width: 356.2686962276639,
      //     height: 0.6356435643564353
      //   }
      // }],
      // Add missing reactive properties
      showLineStylePanel: false,
      showTextStylePanel: false,
      isDrawingText: false,
      savedAnnotations: [],
      // 添加模拟数据
      // savedAnnotations: [{
      //   type: "unknown",
      //   text: "发发发",
      //   properties: {
      //     id: null,
      //     name: "",
      //     cssclass: null,
      //     selectable: true,
      //     visible: true,
      //     tag: null,
      //     localtransform: null,
      //     clipstyle: null,
      //     responsivestyle: null,
      //     renderingfilter: null,
      //     scalescrollstrategy: {},
      //     linestyle: {
      //       links: {
      //         Invalidate: {
      //           yn: new Array(45).fill(null),
      //           stack: 0,
      //           gDa: false
      //         }
      //       },
      //       silent: false,
      //       u3: false,
      //       uL: 45,
      //       Ek: 1,
      //       Lx: "#0351ad",
      //       Zr: null,
      //       Jeb: null,
      //       xVa: [],
      //       fA: 2,
      //       Ewa: {
      //         x: false,
      //         y: false
      //       },
      //       XGa: "round",
      //       UGa: "butt",
      //       Cs: null,
      //       Td: null
      //     },
      //     fillstyle: {
      //       links: {
      //         Invalidate: {
      //           yn: new Array(45).fill(null),
      //           stack: 0,
      //           gDa: false
      //         }
      //       },
      //       silent: false,
      //       u3: false,
      //       uL: 45,
      //       Ek: 0,
      //       Lx: "#c7e1f6",
      //       Zr: null,
      //       Jeb: null,
      //       iO: false,
      //       zk: null
      //     },
      //     ax: 2408.8262078093985,
      //     ay: 0.7689768976897691,
      //     width: 66,
      //     height: 22,
      //     rotationangle: 0,
      //     alignment: 5,
      //     sizeisindevicespace: true,
      //     preserveaspectratio: false,
      //     ispointingup: true,
      //     preservereadingorientation: true,
      //     preserverightangle: true,
      //     useminmaxdimensions: false,
      //     mindimension: null,
      //     maxdimension: null,
      //     layoutstyle: null,
      //     text: "发发发",
      //     textstyle: {
      //       links: {
      //         Invalidate: {
      //           yn: [null],
      //           stack: 0,
      //           gDa: false
      //         }
      //       },
      //       silent: false,
      //       u3: false,
      //       uL: 1,
      //       Ek: 0,
      //       Lx: "#000000",
      //       Zr: null,
      //       Jeb: null,
      //       lH: "22px Sans-serif",
      //       Cua: "middle",
      //       Vf: "left",
      //       y9: "100%",
      //       hS: true,
      //       E2: true,
      //       ofa: {
      //         fontweight: "normal",
      //         fontsize: "22px",
      //         fontfamily: "Sans-serif",
      //         fontlineheight: "normal",
      //         fontstyle: "normal"
      //       },
      //       Km: null,
      //       iGa: "Sans-serif",
      //       eZ: "22px",
      //       c3: "normal",
      //       b3: "normal"
      //     },
      //     bounds: {
      //       readOnly: true,
      //       x: 2326.031369953673,
      //       y: 0.6963696369636965,
      //       width: 165.58967571144967,
      //       height: 0.1452145214521452
      //     },
      //     layout: {
      //       readOnly: false,
      //       x: 0,
      //       y: 0,
      //       width: 66,
      //       height: 22
      //     },
      //     sizemode: 5,
      //     userheight: 30.00000000000003,
      //     userwidth: 99.99999999999989,
      //     radius: 10,
      //     padding: 0,
      //     transform: "none",
      //     ellipsisstring: "..."
      //   },
      //   bounds: {
      //     readOnly: true,
      //     x: 2326.031369953673,
      //     y: 0.6963696369636965,
      //     width: 165.58967571144967,
      //     height: 0.1452145214521452
      //   }
      // }],
      // 添加鼠标悬停相关的数据
      cursorInfo: {
        depth: null,
        trace: null,
        value: null
      },
      showCursorInfo: true,
      isHovering: false,
      // 添加画笔工具相关属性
      pencilTool: null,
      selectedShape: null,
      selectedShapes: [],
      annotationLayer: null,
      pencilState: {
        isDrawing: false,
        currentPath: null,
        lastPoint: null,
        paths: []
      },
      pencilConfig: {
        minDistance: 2,  // 减小最小距离使绘制更流畅
        lineWidth: 2,
        lineColor: '#0351ad',
        linePattern: 'Solid'
      },
      // 更新颜色映射选择器
      currentColorMap: 'WhiteBlack', // 默认使用黑白渐变
      colorMaps: [
        { value: 'WhiteBlack', label: '黑白渐变' },
        { value: 'CustomGrayScale', label: '灰度渐变' },
        { value: 'CustomRedScale', label: '红色渐变' },
        { value: 'BlueWhiteRed', label: '蓝白红渐变' },
        // { value: 'Rainbow', label: '彩虹渐变' },
        // { value: 'Jet', label: 'Jet渐变' },
        // { value: 'Hot', label: '热力图' },
        // { value: 'Cool', label: '冷色图' }
      ], // 可用的颜色映射
      textStyle: {
        color: '#000000',
        size: 22,
        font: 'Sans-serif',
        bold: false,
        italic: false,
        align: 'left',
        wrap: true,
        ellipsis: true,
        borderRadius: 10,
        fixedFont: false,
      },
      lineStyle: {
        color: '#0351ad',
        width: 2,
        pattern: 'Solid'
      },
      fillStyle: {
        color: '#c7e1f6',
        pattern: 'Solid',
        opacity: 100
      },
      fillPatterns: IMAGE_PATTERNS,
      TEXT_PATTERNS: TEXT_PATTERNS,
      FILL_PATTERNS: FILL_PATTERNS,
      LINE_PATTERNS: LINE_PATTERNS,
      LINESTYLE_PATTERNS: LINESTYLE_PATTERNS,
      linePatterns: LINESTYLE_PATTERNS,
      initialLineStyle: null,
      initialTextStyle: null,
      initialFillStyle: null,
      textPatterns: {
        'None': [0, 10],
        'Solid': [],
        'Dash': [20, 4],
        'Dot': [2, 4],
        'DashDot': [20, 4, 2, 4],
        'DashDotDot': [20, 4, 2, 4, 2, 4]
      },
      isWidgetReady: false,
      loadingError: null,
      pipeline: null,
      colorProvider: null,
      // 右键菜单相关数据
      contextMenu: {
        visible: false,
        x: 0,
        y: 0
      },
      contextMenuItems: [
        {
          text: '撤销',
          icon: 'mdi-undo',
          shortcut: 'Ctrl+Z',
          action: 'undo'
        },
        {
          text: '重做',
          icon: 'mdi-redo',
          shortcut: 'Ctrl+Y',
          action: 'redo'
        },
        { type: 'separator' },
        {
          text: '复制',
          icon: 'mdi-content-copy',
          shortcut: 'Ctrl+C',
          action: 'copy'
        },
        {
          text: '粘贴',
          icon: 'mdi-content-paste',
          shortcut: 'Ctrl+V',
          action: 'paste'
        },
        {
          text: '删除',
          icon: 'mdi-delete',
          shortcut: 'Del',
          action: 'delete'
        }
      ],
      clipboard: null, // 用于存储复制的路径
      undoStack: [], // 撤销栈
      redoStack: [], // 重做栈
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.createScene(this.$refs.plot);
    });

    if (this.$refs.plot) {
      // 添加右键菜单事件监听
      this.$refs.plot.addEventListener('contextmenu', this.showContextMenu);
      document.addEventListener('click', this.hideContextMenu);
      // 添加键盘事件监听
      window.addEventListener('keydown', this.handleKeyDown);

      // 鼠标悬停相关事件
      this.$refs.plot.addEventListener('mouseenter', () => {
        this.isHovering = true;
      });

      this.$refs.plot.addEventListener('mouseleave', () => {
        this.isHovering = false;
        // 清除定时器
        if (this.timerInterval) {
          clearTimeout(this.timerInterval);
          this.timerInterval = null;
        }
      });

      this.$refs.plot.addEventListener('mousemove', this.handleMouseMove);
    }

    if (this.$refs.plot2) {
      this.$refs.plot2.addEventListener('contextmenu', this.showContextMenu);
      this.$refs.plot2.addEventListener('mousemove', this.handleMouseMove);
    }
  },
  methods: {
    // 创建下半屏镜像视图
    initSecondWidget(canvas) {
      try {
        this.plotsBottom = new Plot({
          'canvasElement': canvas,
          'root': this._seismicWidgetBottom = new SeismicWidget(null, {
            'layouttype': 'inside',
            'tools': {
              'crosshair': { 'enabled': true },
              // 禁用内部滚动条
              'scrollbar': {
                'enabled': false,
                'visible': false,
                'horizontal': { 'enabled': false, 'visible': false },
                'vertical': { 'enabled': false, 'visible': false }
              }
            },
            'colorbar': {
              'axis': { 'size': 20, 'autolabelrotation': true, 'tickgenerator': { 'edge': { 'tickvisible': false, 'labelvisible': false } } },
              'title': { 'size': 0 },
              'colorbox': { 'size': 10 },
              'visible': true,
              'location': ColorBarLocation.West,
              'maxheight': '80%',
              'alignment': BoxLayoutAlignment.Center,
              'width': 60
            },
            'statusbar': {
              'visible': true,
              'location': 'bottom',
              'alignment': 'left',
              'size': 25,
              'sections': { 'time': { 'visible': true, 'width': '100px' }, 'trace': { 'visible': true, 'width': '120px' }, 'value': { 'visible': true, 'width': '120px' } },
              'info': (widget, x, y, sample) => {
                if (!sample) return { 'time': '', 'trace': '', 'value': '' };
                const autoFormat = new AutoNumberFormat(4);
                const time = sample.location && sample.location.y != null ? autoFormat.format(Math.round(sample.location.y * 100) / 100.0) : '';
                const traceNumber = sample.traceNumber != null ? (sample.traceNumber + 1).toString() : '';
                const value = sample.sampleValue != null ? sample.sampleValue.toFixed(3) : '';
                return { 'time': `Time: ${time}`, 'trace': `Trace: ${traceNumber}`, 'value': `Value: ${value}` };
              }
            },
            'axes': {
              'samples': { 'title': { 'visible': false }, 'visible': true, 'labelformat': '%.0f', 'labelvisible': true, 'tickgenerator': { 'edge': { 'tickvisible': true, 'labelvisible': true } } },
              'headers': { 'fields': [], 'options': { 'minimumSpan': 100 } }
            }
          })
        });

        if (this._dataReader && this._dataStatistics && this._fileName && this._colorMap) {
          try {
            const pipelineBottom = new SeismicPipeline(this._fileName, this._dataReader, this._dataStatistics)
              .setColorMap(this._colorMap)
              .setOptions({
                'normalization': { 'type': NormalizationType.RMS, 'scale': 0.4 },
                'plot': { 'type': { 'Wiggle': false, 'InterpolatedDensity': true }, 'decimationSpacing': 5 },
                'colors': { 'colorMap': this._colorMap }
              });

            try { pipelineBottom.addTraceProcessor(new TaperFilterProcess({ 'apply': false, 'name': 'TaperFilter' })); } catch (e) { }
            try { pipelineBottom.addTraceProcessor(new AGC({ 'apply': false, 'name': 'AGC' })); } catch (e) { }
            try { pipelineBottom.addTraceProcessor(new Reverse({ 'apply': false, 'name': 'Reverse' })); } catch (e) { }

            this.pipelineBottom = pipelineBottom;
            this._seismicWidgetBottom.setPipeline(pipelineBottom);
            this._seismicWidgetBottom.setOptions({ 'axes': { 'headers': { 'fields': this._headers }, 'samples': { 'title': { 'visible': true, 'text': pipelineBottom.getName() } } } });
            this._seismicWidgetBottom.fitToBounds();

            // 立即显示滚动条
            this.$nextTick(() => {
              this.forceShowScrollbar(this._seismicWidgetBottom);
              // 强制重绘
              if (this._seismicWidgetBottom.invalidate) {
                this._seismicWidgetBottom.invalidate();
              }
            });
          } catch (e) {
            console.warn('初始化下半屏流水线失败:', e);
          }
        }
      } catch (error) {
        console.error('创建下半屏视图失败:', error);
      }
    },

    // 同步滚动条（左右与上下）
    onScroll(origin) {
      if (this._isSyncingScroll) return;
      const topEl = this.$refs.topScroll;
      const bottomEl = this.$refs.bottomScroll;
      if (!topEl || !bottomEl) return;

      this._isSyncingScroll = true;
      if (origin === 'top') {
        bottomEl.scrollLeft = topEl.scrollLeft;
        bottomEl.scrollTop = topEl.scrollTop;
        // 同步内部滚动条 - 使用正确的 GeoToolkit-js 2 方法
        this.syncInternalScrollbars(this._seismicWidget, this._seismicWidgetBottom);
      } else if (origin === 'bottom') {
        topEl.scrollLeft = bottomEl.scrollLeft;
        topEl.scrollTop = bottomEl.scrollTop;
        // 同步内部滚动条 - 使用正确的 GeoToolkit-js 2 方法
        this.syncInternalScrollbars(this._seismicWidgetBottom, this._seismicWidget);
      }
      this._isSyncingScroll = false;
    },

    // 同步内部滚动条 - 简化版本
    syncInternalScrollbars(sourceWidget, targetWidget) {
      try {
        if (!sourceWidget || !targetWidget) return;

        // 获取源widget的当前视图范围
        const sourceLimits = sourceWidget.getModelLimits();
        if (!sourceLimits) return;

        // 设置目标widget的视图范围，使其与源widget保持一致
        targetWidget.setModelLimits(sourceLimits);

        // 强制重绘
        if (targetWidget.invalidate) {
          targetWidget.invalidate();
        }

        // 强制显示和更新滚动条
        this.forceShowScrollbar(targetWidget);

        // 延迟再次尝试更新滚动条
        setTimeout(() => {
          this.forceShowScrollbar(targetWidget);
        }, 100);

        // 再次延迟更新
        setTimeout(() => {
          this.forceShowScrollbar(targetWidget);
        }, 300);

      } catch (e) {
        console.warn('同步内部滚动条失败:', e);
      }
    },

    // 直接同步滚动条位置 - 简化版本
    syncScrollbarPositions() {
      try {
        if (!this._seismicWidget || !this._seismicWidgetBottom) return;

        console.log('开始同步滚动条位置...');

        // 获取两个widget的工具管理器
        const topToolManager = this._seismicWidget.getTool && this._seismicWidget.getTool();
        const bottomToolManager = this._seismicWidgetBottom.getTool && this._seismicWidgetBottom.getTool();

        if (!topToolManager || !bottomToolManager) {
          console.log('无法获取工具管理器');
          return;
        }

        // 获取滚动条工具
        let topScrollbarTool = null;
        let bottomScrollbarTool = null;

        // 尝试标准方法名
        if (topToolManager.getScrollbarTool) {
          topScrollbarTool = topToolManager.getScrollbarTool();
        } else if (topToolManager.getScrollbar) {
          topScrollbarTool = topToolManager.getScrollbar();
        } else if (topToolManager.scrollbar) {
          topScrollbarTool = topToolManager.scrollbar;
        }

        if (bottomToolManager.getScrollbarTool) {
          bottomScrollbarTool = bottomToolManager.getScrollbarTool();
        } else if (bottomToolManager.getScrollbar) {
          bottomScrollbarTool = bottomToolManager.getScrollbar();
        } else if (bottomToolManager.scrollbar) {
          bottomScrollbarTool = bottomToolManager.scrollbar;
        }

        // 尝试混淆的方法名
        if (!topScrollbarTool) {
          const topMethodNames = Object.getOwnPropertyNames(topToolManager);
          for (const methodName of topMethodNames) {
            if (methodName !== '__ob__') {
              try {
                const method = topToolManager[methodName];
                if (typeof method === 'function') {
                  const result = method.call(topToolManager);
                  if (result && typeof result === 'object') {
                    const resultMethods = Object.getOwnPropertyNames(result);
                    const scrollbarMethods = resultMethods.filter(name =>
                      name.toLowerCase().includes('scroll') ||
                      name.toLowerCase().includes('bar') ||
                      name.toLowerCase().includes('horizontal') ||
                      name.toLowerCase().includes('vertical')
                    );
                    if (scrollbarMethods.length > 0) {
                      topScrollbarTool = result;
                      console.log('上图找到滚动条工具，方法名:', methodName);
                      break;
                    }
                  }
                }
              } catch (e) {
                // 忽略调用错误
              }
            }
          }
        }

        if (!bottomScrollbarTool) {
          const bottomMethodNames = Object.getOwnPropertyNames(bottomToolManager);
          for (const methodName of bottomMethodNames) {
            if (methodName !== '__ob__') {
              try {
                const method = bottomToolManager[methodName];
                if (typeof method === 'function') {
                  const result = method.call(bottomToolManager);
                  if (result && typeof result === 'object') {
                    const resultMethods = Object.getOwnPropertyNames(result);
                    const scrollbarMethods = resultMethods.filter(name =>
                      name.toLowerCase().includes('scroll') ||
                      name.toLowerCase().includes('bar') ||
                      name.toLowerCase().includes('horizontal') ||
                      name.toLowerCase().includes('vertical')
                    );
                    if (scrollbarMethods.length > 0) {
                      bottomScrollbarTool = result;
                      console.log('下图找到滚动条工具，方法名:', methodName);
                      break;
                    }
                  }
                }
              } catch (e) {
                // 忽略调用错误
              }
            }
          }
        }

        if (topScrollbarTool && bottomScrollbarTool) {
          console.log('滚动条工具获取成功，开始同步位置');

          // 获取上图的滚动条位置
          const topHScrollbar = topScrollbarTool.getHorizontalScrollbar && topScrollbarTool.getHorizontalScrollbar();
          const topVScrollbar = topScrollbarTool.getVerticalScrollbar && topScrollbarTool.getVerticalScrollbar();

          const bottomHScrollbar = bottomScrollbarTool.getHorizontalScrollbar && bottomScrollbarTool.getHorizontalScrollbar();
          const bottomVScrollbar = bottomScrollbarTool.getVerticalScrollbar && bottomScrollbarTool.getVerticalScrollbar();

          console.log('滚动条对象状态:', {
            topH: !!topHScrollbar,
            topV: !!topVScrollbar,
            bottomH: !!bottomHScrollbar,
            bottomV: !!bottomVScrollbar
          });

          if (topHScrollbar && bottomHScrollbar) {
            // 同步水平滚动条位置
            const topHValue = topHScrollbar.getValue && topHScrollbar.getValue();
            console.log('上图水平滚动条位置:', topHValue);
            if (topHValue !== undefined && bottomHScrollbar.setValue) {
              bottomHScrollbar.setValue(topHValue);
              console.log('水平滚动条位置已同步:', topHValue);
            }
          }

          if (topVScrollbar && bottomVScrollbar) {
            // 同步垂直滚动条位置
            const topVValue = topVScrollbar.getValue && topVScrollbar.getValue();
            console.log('上图垂直滚动条位置:', topVValue);
            if (topVValue !== undefined && bottomVScrollbar.setValue) {
              bottomVScrollbar.setValue(topVValue);
              console.log('垂直滚动条位置已同步:', topVValue);
            }
          }

          // 强制更新
          if (bottomScrollbarTool.update) {
            bottomScrollbarTool.update();
            console.log('滚动条工具已更新');
          }

          if (this._seismicWidgetBottom.invalidate) {
            this._seismicWidgetBottom.invalidate();
            console.log('Widget已重绘');
          }

          console.log('滚动条同步完成');
        } else {
          console.log('无法获取滚动条工具');
        }
      } catch (e) {
        console.warn('同步滚动条位置失败:', e);
      }
    },

    // 强制更新滚动条位置 - 改为无操作（依赖model limits同步）
    forceUpdateScrollbarPosition(widget, limits) {
      return; // 不再尝试直接操纵滚动条
    },

    // 更新内部滚动条工具 - 改为无操作
    updateWidgetScrollbar(widget) {
      return;
    },

    // 尝试更新滚动条 - 改为无操作
    tryUpdateScrollbar(widget) {
      return;
    },

    // 强制显示滚动条 - 改为无操作
    forceShowScrollbar(widget) {
      return;
    },

    // 统一解析滚动条工具的助手（保留，但优先返回 null）
    resolveScrollbarTool(toolManager) {
      try {
        if (!toolManager) return null;
        // 直接返回 null，明确不依赖滚动条工具
        return null;
      } catch (e) {
        // ignore
      }
      return null;
    },

    // 立即显示滚动条 - 新增方法
    showScrollbarsImmediately() {
      try {
        console.log('立即显示滚动条...');

        // 强制显示两个widget的滚动条
        if (this._seismicWidget) {
          this.forceShowScrollbar(this._seismicWidget);
        }
        if (this._seismicWidgetBottom) {
          this.forceShowScrollbar(this._seismicWidgetBottom);
        }

        // 强制重绘两个widget
        if (this._seismicWidget && this._seismicWidget.invalidate) {
          this._seismicWidget.invalidate();
        }
        if (this._seismicWidgetBottom && this._seismicWidgetBottom.invalidate) {
          this._seismicWidgetBottom.invalidate();
        }

        // 延迟再次尝试，确保滚动条显示
        setTimeout(() => {
          if (this._seismicWidget) {
            this.forceShowScrollbar(this._seismicWidget);
            if (this._seismicWidget.invalidate) {
              this._seismicWidget.invalidate();
            }
          }
          if (this._seismicWidgetBottom) {
            this.forceShowScrollbar(this._seismicWidgetBottom);
            if (this._seismicWidgetBottom.invalidate) {
              this._seismicWidgetBottom.invalidate();
            }
          }
        }, 200);

        console.log('滚动条立即显示完成');
      } catch (e) {
        console.warn('立即显示滚动条失败:', e);
      }
    },

    // 强制重新配置滚动条 - 新增方法
    forceReconfigureScrollbars() {
      try {
        console.log('强制重新配置滚动条...');

        if (this._seismicWidget) {
          // 重新设置滚动条配置
          this._seismicWidget.setOptions({
            'tools': {
              'scrollbar': {
                'enabled': true,
                'visible': true,
                'alwaysVisible': true,
                'horizontal': {
                  'enabled': true,
                  'visible': true,
                  'alwaysVisible': true
                },
                'vertical': {
                  'enabled': true,
                  'visible': true,
                  'alwaysVisible': true
                }
              }
            }
          });

          if (this._seismicWidget.invalidate) {
            this._seismicWidget.invalidate();
          }
        }

        if (this._seismicWidgetBottom) {
          // 重新设置滚动条配置
          this._seismicWidgetBottom.setOptions({
            'tools': {
              'scrollbar': {
                'enabled': true,
                'visible': true,
                'alwaysVisible': true,
                'horizontal': {
                  'enabled': true,
                  'visible': true,
                  'alwaysVisible': true
                },
                'vertical': {
                  'enabled': true,
                  'visible': true,
                  'alwaysVisible': true
                }
              }
            }
          });

          if (this._seismicWidgetBottom.invalidate) {
            this._seismicWidgetBottom.invalidate();
          }
        }

        console.log('滚动条重新配置完成');
      } catch (e) {
        console.warn('强制重新配置滚动条失败:', e);
      }
    },

    // 尝试强制初始化滚动条 - 新增方法
    tryForceInitScrollbars() {
      try {
        console.log('尝试强制初始化滚动条...');

        if (this._seismicWidget) {
          // 方法1: 尝试触发滚动条创建
          if (this._seismicWidget.invalidate) {
            this._seismicWidget.invalidate();
          }
          if (this._seismicWidget.redraw) {
            this._seismicWidget.redraw();
          }

          // 方法2: 尝试设置视图范围来触发滚动条
          const currentLimits = this._seismicWidget.getModelLimits && this._seismicWidget.getModelLimits();
          if (currentLimits) {
            // 稍微调整视图范围来触发滚动条更新
            const newLimits = {
              xmin: currentLimits.xmin,
              xmax: currentLimits.xmax,
              ymin: currentLimits.ymin,
              ymax: currentLimits.ymax
            };
            this._seismicWidget.setModelLimits && this._seismicWidget.setModelLimits(newLimits);
          }

          // 方法3: 尝试触发鼠标事件来初始化滚动条
          const canvas = this._seismicWidget.getCanvas && this._seismicWidget.getCanvas();
          if (canvas) {
            // 模拟鼠标移动事件
            const mouseEvent = new MouseEvent('mousemove', {
              clientX: 100,
              clientY: 100,
              bubbles: true
            });
            canvas.dispatchEvent(mouseEvent);
          }
        }

        if (this._seismicWidgetBottom) {
          // 方法1: 尝试触发滚动条创建
          if (this._seismicWidgetBottom.invalidate) {
            this._seismicWidgetBottom.invalidate();
          }
          if (this._seismicWidgetBottom.redraw) {
            this._seismicWidgetBottom.redraw();
          }

          // 方法2: 尝试设置视图范围来触发滚动条
          const currentLimits = this._seismicWidgetBottom.getModelLimits && this._seismicWidgetBottom.getModelLimits();
          if (currentLimits) {
            // 稍微调整视图范围来触发滚动条更新
            const newLimits = {
              xmin: currentLimits.xmin,
              xmax: currentLimits.xmax,
              ymin: currentLimits.ymin,
              ymax: currentLimits.ymax
            };
            this._seismicWidgetBottom.setModelLimits && this._seismicWidgetBottom.setModelLimits(newLimits);
          }

          // 方法3: 尝试触发鼠标事件来初始化滚动条
          const canvas = this._seismicWidgetBottom.getCanvas && this._seismicWidgetBottom.getCanvas();
          if (canvas) {
            // 模拟鼠标移动事件
            const mouseEvent = new MouseEvent('mousemove', {
              clientX: 100,
              clientY: 100,
              bubbles: true
            });
            canvas.dispatchEvent(mouseEvent);
          }
        }

        console.log('强制初始化滚动条完成');
      } catch (e) {
        console.warn('强制初始化滚动条失败:', e);
      }
    },

    // 尝试通过 DOM 元素访问滚动条 - 新增方法
    tryAccessScrollbarViaDOM() {
      try {
        console.log('尝试通过 DOM 元素访问滚动条...');

        // 查找包含滚动条的 DOM 元素
        const topScroll = this.$refs.topScroll;
        const bottomScroll = this.$refs.bottomScroll;
        const topWrapper = this.$refs.topWrapper;
        const bottomWrapper = this.$refs.bottomWrapper;

        if (topScroll) {
          console.log('上图滚动容器元素:', topScroll);
          console.log('上图滚动容器子元素:', topScroll.children);
          console.log('上图滚动容器类名:', topScroll.className);

          // 查找滚动条相关的 DOM 元素
          const scrollbarElements = topScroll.querySelectorAll('[class*="scroll"], [class*="bar"], [id*="scroll"], [id*="bar"]');
          console.log('上图滚动条相关元素:', scrollbarElements);

          for (const element of scrollbarElements) {
            console.log('上图滚动条元素:', element);
            console.log('上图滚动条元素类名:', element.className);
            console.log('上图滚动条元素ID:', element.id);
          }

          // 检查是否有原生滚动条
          console.log('上图容器滚动属性:', {
            scrollLeft: topScroll.scrollLeft,
            scrollTop: topScroll.scrollTop,
            scrollWidth: topScroll.scrollWidth,
            scrollHeight: topScroll.scrollHeight,
            clientWidth: topScroll.clientWidth,
            clientHeight: topScroll.clientHeight
          });
        }

        if (bottomScroll) {
          console.log('下图滚动容器元素:', bottomScroll);
          console.log('下图滚动容器子元素:', bottomScroll.children);
          console.log('下图滚动容器类名:', bottomScroll.className);

          // 查找滚动条相关的 DOM 元素
          const scrollbarElements = bottomScroll.querySelectorAll('[class*="scroll"], [class*="bar"], [id*="scroll"], [id*="bar"]');
          console.log('下图滚动条相关元素:', scrollbarElements);

          for (const element of scrollbarElements) {
            console.log('下图滚动条元素:', element);
            console.log('下图滚动条元素类名:', element.className);
            console.log('下图滚动条元素ID:', element.id);
          }

          // 检查是否有原生滚动条
          console.log('下图容器滚动属性:', {
            scrollLeft: bottomScroll.scrollLeft,
            scrollTop: bottomScroll.scrollTop,
            scrollWidth: bottomScroll.scrollWidth,
            scrollHeight: bottomScroll.scrollHeight,
            clientWidth: bottomScroll.clientWidth,
            clientHeight: bottomScroll.clientHeight
          });
        }

        // 检查整个文档中的滚动条相关元素
        const allScrollbarElements = document.querySelectorAll('[class*="scroll"], [class*="bar"], [id*="scroll"], [id*="bar"]');
        console.log('文档中所有滚动条相关元素:', allScrollbarElements);

        for (const element of allScrollbarElements) {
          console.log('滚动条元素:', element);
          console.log('滚动条元素类名:', element.className);
          console.log('滚动条元素ID:', element.id);
          console.log('滚动条元素标签名:', element.tagName);
        }

        console.log('通过 DOM 元素访问滚动条完成');
      } catch (e) {
        console.warn('通过 DOM 元素访问滚动条失败:', e);
      }
    },

    // 尝试直接访问滚动条 - 新增方法
    tryDirectScrollbarAccess() {
      try {
        console.log('尝试直接访问滚动条...');

        if (this._seismicWidget) {
          // 尝试直接访问widget的滚动条属性
          const widgetProps = Object.getOwnPropertyNames(this._seismicWidget);
          console.log('上图widget属性:', widgetProps);

          // 查找可能包含滚动条的属性
          for (const prop of widgetProps) {
            if (prop.toLowerCase().includes('scroll') || prop.toLowerCase().includes('bar')) {
              try {
                const value = this._seismicWidget[prop];
                if (value && typeof value === 'object') {
                  console.log(`上图属性 ${prop} 的方法:`, Object.getOwnPropertyNames(value));
                }
              } catch (e) {
                // 忽略访问错误
              }
            }
          }

          // 检查widget的所有方法
          const widgetMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(this._seismicWidget));
          console.log('上图widget方法:', widgetMethods);

          // 查找可能包含滚动条的方法
          for (const method of widgetMethods) {
            if (method.toLowerCase().includes('scroll') || method.toLowerCase().includes('bar')) {
              console.log(`上图方法 ${method} 可能存在滚动条相关功能`);
            }
          }
        }

        if (this._seismicWidgetBottom) {
          // 尝试直接访问widget的滚动条属性
          const widgetProps = Object.getOwnPropertyNames(this._seismicWidgetBottom);
          console.log('下图widget属性:', widgetProps);

          // 查找可能包含滚动条的属性
          for (const prop of widgetProps) {
            if (prop.toLowerCase().includes('scroll') || prop.toLowerCase().includes('bar')) {
              try {
                const value = this._seismicWidgetBottom[prop];
                if (value && typeof value === 'object') {
                  console.log(`下图属性 ${prop} 的方法:`, Object.getOwnPropertyNames(value));
                }
              } catch (e) {
                // 忽略访问错误
              }
            }
          }

          // 检查widget的所有方法
          const widgetMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(this._seismicWidgetBottom));
          console.log('下图widget方法:', widgetMethods);

          // 查找可能包含滚动条的方法
          for (const method of widgetMethods) {
            if (method.toLowerCase().includes('scroll') || method.toLowerCase().includes('bar')) {
              console.log(`下图方法 ${method} 可能存在滚动条相关功能`);
            }
          }
        }

        console.log('直接访问滚动条完成');
      } catch (e) {
        console.warn('直接访问滚动条失败:', e);
      }
    },

    // 尝试通过 widget 方法访问滚动条 - 新增方法
    tryAccessScrollbarViaWidgetMethods() {
      try {
        console.log('尝试通过 widget 方法访问滚动条...');

        if (this._seismicWidget) {
          console.log('=== 分析上图 widget 方法 ===');

          // 尝试调用一些可能相关的方法
          const methodsToTry = [
            'getOptions',
            'setOptions',
            'updateLayout',
            'getClassName',
            'setProperties',
            'getTableHeaders'
          ];

          for (const methodName of methodsToTry) {
            try {
              if (this._seismicWidget[methodName] && typeof this._seismicWidget[methodName] === 'function') {
                const result = this._seismicWidget[methodName]();
                console.log(`上图方法 ${methodName} 结果:`, result);

                if (result && typeof result === 'object') {
                  const resultProps = Object.getOwnPropertyNames(result);
                  console.log(`上图方法 ${methodName} 返回对象的属性:`, resultProps);

                  // 查找滚动条相关的属性
                  const scrollbarProps = resultProps.filter(prop =>
                    prop.toLowerCase().includes('scroll') ||
                    prop.toLowerCase().includes('bar') ||
                    prop.toLowerCase().includes('tool')
                  );

                  if (scrollbarProps.length > 0) {
                    console.log(`上图方法 ${methodName} 包含滚动条相关属性:`, scrollbarProps);
                  }
                }
              }
            } catch (e) {
              console.log(`上图方法 ${methodName} 调用失败:`, e.message);
            }
          }
        }

        if (this._seismicWidgetBottom) {
          console.log('=== 分析下图 widget 方法 ===');

          // 尝试调用一些可能相关的方法
          const methodsToTry = [
            'getOptions',
            'setOptions',
            'updateLayout',
            'getClassName',
            'setProperties',
            'getTableHeaders'
          ];

          for (const methodName of methodsToTry) {
            try {
              if (this._seismicWidgetBottom[methodName] && typeof this._seismicWidgetBottom[methodName] === 'function') {
                const result = this._seismicWidgetBottom[methodName]();
                console.log(`下图方法 ${methodName} 结果:`, result);

                if (result && typeof result === 'object') {
                  const resultProps = Object.getOwnPropertyNames(result);
                  console.log(`下图方法 ${methodName} 返回对象的属性:`, resultProps);

                  // 查找滚动条相关的属性
                  const scrollbarProps = resultProps.filter(prop =>
                    prop.toLowerCase().includes('scroll') ||
                    prop.toLowerCase().includes('bar') ||
                    prop.toLowerCase().includes('tool')
                  );

                  if (scrollbarProps.length > 0) {
                    console.log(`下图方法 ${methodName} 包含滚动条相关属性:`, scrollbarProps);
                  }
                }
              }
            } catch (e) {
              console.log(`下图方法 ${methodName} 调用失败:`, e.message);
            }
          }
        }

        console.log('通过 widget 方法访问滚动条完成');
      } catch (e) {
        console.warn('通过 widget 方法访问滚动条失败:', e);
      }
    },

    // 设置内部滚动条同步 - 重新设计
    setupInternalScrollbarSync() {
      console.log('setupInternalScrollbarSync 被调用');
      console.log('_seismicWidget:', this._seismicWidget);
      console.log('_seismicWidgetBottom:', this._seismicWidgetBottom);

      if (!this._seismicWidget || !this._seismicWidgetBottom) {
        console.warn('Widget 未准备好，无法设置内部滚动条同步');
        return;
      }

      try {
        const self = this;
        console.log('开始设置内部滚动条同步...');

        // 先强制同步一次，确保两个图显示相同的内容
        this.forceSyncViews();

        // 暂时禁用定时器同步，避免死循环
        console.log('定时器同步已禁用，避免死循环');
        /*
        this._internalScrollSyncTimer = setInterval(() => {
          if (!self._isSyncingInternalScroll && self._seismicWidget && self._seismicWidgetBottom) {
            self._isSyncingInternalScroll = true;
            try {
              // 获取上半屏的当前视图范围
              const topLimits = self._seismicWidget.getModelLimits();
              if (topLimits) {
                // 设置下半屏的视图范围
                self._seismicWidgetBottom.setModelLimits(topLimits);
                // 强制重绘
                if (self._seismicWidgetBottom.invalidate) {
                  self._seismicWidgetBottom.invalidate();
                }
                // 强制显示和更新滚动条
                self.forceShowScrollbar(self._seismicWidgetBottom);
              }
            } catch (e) {
              console.warn('定时器同步内部滚动条失败:', e);
            } finally {
              self._isSyncingInternalScroll = false;
            }
          }
        }, 500); // 每500ms同步一次，减少频率避免死循环
        */

        // 为两个图添加鼠标事件监听
        this.setupMouseEventSync();

        // 设置滚动条事件监听器
        this.setupScrollbarEventListeners();

        console.log('内部滚动条同步设置完成 - 重新设计版本');
      } catch (e) {
        console.warn('设置内部滚动条同步失败:', e);
      }
    },

    // 设置滚动条事件监听器 - 改为依赖 wheel/drag 与 model limits，同步无需滚动条工具
    setupScrollbarEventListeners() {
      try {
        const self = this;

        // 使用已有 wheel/drag 事件与 setModelLimits 钩子即可实现同步
        this.setupMouseEventSync();

        console.log('滚动条事件监听器设置完成');
      } catch (e) {
        console.warn('设置滚动条事件监听器失败:', e);
      }
    },

    // 从上图同步到下图 - 改进版本
    syncFromTopToBottom() {
      if (!this._seismicWidget || !this._seismicWidgetBottom) return;

      this._isSyncingInternalScroll = true;
      try {
        const topLimits = this._seismicWidget.getModelLimits();
        if (topLimits) {
          this._seismicWidgetBottom.setModelLimits(topLimits);
          this._seismicWidgetBottom.invalidate();
          this.forceShowScrollbar(this._seismicWidgetBottom);
        }
      } catch (e) {
        console.warn('从上图同步到下图失败:', e);
      } finally {
        this._isSyncingInternalScroll = false;
      }
    },

    // 从下图同步到上图 - 改进版本
    syncFromBottomToTop() {
      if (!this._seismicWidget || !this._seismicWidgetBottom) return;

      this._isSyncingInternalScroll = true;
      try {
        const bottomLimits = this._seismicWidgetBottom.getModelLimits();
        if (bottomLimits) {
          this._seismicWidget.setModelLimits(bottomLimits);
          this._seismicWidget.invalidate();
          this.forceShowScrollbar(this._seismicWidget);
        }
      } catch (e) {
        console.warn('从下图同步到上图失败:', e);
      } finally {
        this._isSyncingInternalScroll = false;
      }
    },

    // 强制同步两个图的视图
    forceSyncViews() {
      try {
        console.log('强制同步两个图的视图...');

        if (!this._seismicWidget || !this._seismicWidgetBottom) return;

        // 获取上图当前的视图范围
        const topLimits = this._seismicWidget.getModelLimits();
        if (topLimits) {
          // 设置下图的视图范围
          this._seismicWidgetBottom.setModelLimits(topLimits);
          if (this._seismicWidgetBottom.invalidate) {
            this._seismicWidgetBottom.invalidate();
          }
          // 强制显示和更新滚动条
          this.forceShowScrollbar(this._seismicWidgetBottom);

          // 延迟再次尝试更新滚动条
          setTimeout(() => {
            this.forceShowScrollbar(this._seismicWidgetBottom);
            if (this._seismicWidgetBottom.invalidate) {
              this._seismicWidgetBottom.invalidate();
            }
          }, 200);

          console.log('强制同步完成');
        }
      } catch (e) {
        console.warn('强制同步视图失败:', e);
      }
    },

    // 让顶部/底部视图缩放同步
    ensureZoomSyncHook() {
      if (this._zoomHooked) return;
      const top = this._seismicWidget;
      const bottom = this._seismicWidgetBottom;
      if (!top || !bottom || !top.setModelLimits || !bottom.setModelLimits) return;

      try {
        const self = this;
        const originalTop = top.setModelLimits.bind(top);
        const originalBottom = bottom.setModelLimits.bind(bottom);

        top.setModelLimits = function (rect) {
          const result = originalTop(rect);
          if (!self._isSyncingZoom) {
            self._isSyncingZoom = true;
            try {
              originalBottom(rect);
              if (bottom.invalidate) bottom.invalidate();
              if (self.updateWidgetScrollbar) self.updateWidgetScrollbar(bottom);
            } finally {
              self._isSyncingZoom = false;
            }
          }
          return result;
        };

        bottom.setModelLimits = function (rect) {
          const result = originalBottom(rect);
          if (!self._isSyncingZoom) {
            self._isSyncingZoom = true;
            try {
              originalTop(rect);
              if (top.invalidate) top.invalidate();
              if (self.updateWidgetScrollbar) self.updateWidgetScrollbar(top);
            } finally {
              self._isSyncingZoom = false;
            }
          }
          return result;
        };

        this._zoomHooked = true;
      } catch (e) {
        console.warn('设置缩放同步钩子失败:', e);
      }
    },

    // 设置鼠标事件同步
    setupMouseEventSync() {
      try {
        const self = this;

        // 监听上图canvas的鼠标事件
        if (this.$refs.plot) {
          this.$refs.plot.addEventListener('wheel', (event) => {
            if (!self._isSyncingInternalScroll) {
              // 延迟同步，让滚动完成后再同步
              setTimeout(() => {
                self.syncInternalScrollbars(self._seismicWidget, self._seismicWidgetBottom);
              }, 50);
            }
          });

          this.$refs.plot.addEventListener('mousedown', (event) => {
            self._isDraggingTop = true;
          });

          this.$refs.plot.addEventListener('mousemove', (event) => {
            if (self._isDraggingTop && !self._isSyncingInternalScroll) {
              setTimeout(() => {
                self.syncInternalScrollbars(self._seismicWidget, self._seismicWidgetBottom);
              }, 50);
            }
          });

          this.$refs.plot.addEventListener('mouseup', () => {
            self._isDraggingTop = false;
          });
        }

        // 监听下图canvas的鼠标事件
        if (this.$refs.plot2) {
          this.$refs.plot2.addEventListener('wheel', (event) => {
            if (!self._isSyncingInternalScroll) {
              // 延迟同步，让滚动完成后再同步
              setTimeout(() => {
                self.syncInternalScrollbars(self._seismicWidgetBottom, self._seismicWidget);
              }, 50);
            }
          });

          this.$refs.plot2.addEventListener('mousedown', (event) => {
            self._isDraggingBottom = true;
          });

          this.$refs.plot2.addEventListener('mousemove', (event) => {
            if (self._isDraggingBottom && !self._isSyncingInternalScroll) {
              setTimeout(() => {
                self.syncInternalScrollbars(self._seismicWidgetBottom, self._seismicWidget);
              }, 50);
            }
          });

          this.$refs.plot2.addEventListener('mouseup', () => {
            self._isDraggingBottom = false;
          });
        }

        console.log('鼠标事件同步设置完成');
      } catch (e) {
        console.warn('设置鼠标事件同步失败:', e);
      }
    },

    // 设置鼠标事件监听器
    setupMouseEventListeners() {
      try {
        const self = this;

        // 监听上图canvas的鼠标事件
        if (this.$refs.plot) {
          this.$refs.plot.addEventListener('wheel', (event) => {
            if (!self._isSyncingInternalScroll) {
              // 延迟同步，让滚动完成后再同步
              setTimeout(() => {
                self.syncFromTopToBottom();
              }, 10);
            }
          });

          this.$refs.plot.addEventListener('mousedown', (event) => {
            // 检查是否点击在滚动条上
            if (self.isClickOnScrollbar(event, 'top')) {
              self._isDraggingTop = true;
            }
          });

          this.$refs.plot.addEventListener('mousemove', (event) => {
            if (self._isDraggingTop && !self._isSyncingInternalScroll) {
              setTimeout(() => {
                self.syncFromTopToBottom();
              }, 10);
            }
          });

          this.$refs.plot.addEventListener('mouseup', () => {
            self._isDraggingTop = false;
          });
        }

        // 监听下图canvas的鼠标事件
        if (this.$refs.plot2) {
          this.$refs.plot2.addEventListener('wheel', (event) => {
            if (!self._isSyncingInternalScroll) {
              // 延迟同步，让滚动完成后再同步
              setTimeout(() => {
                self.syncFromBottomToTop();
              }, 10);
            }
          });

          this.$refs.plot2.addEventListener('mousedown', (event) => {
            // 检查是否点击在滚动条上
            if (self.isClickOnScrollbar(event, 'bottom')) {
              self._isDraggingBottom = true;
            }
          });

          this.$refs.plot2.addEventListener('mousemove', (event) => {
            if (self._isDraggingBottom && !self._isSyncingInternalScroll) {
              setTimeout(() => {
                self.syncFromBottomToTop();
              }, 10);
            }
          });

          this.$refs.plot2.addEventListener('mouseup', () => {
            self._isDraggingBottom = false;
          });
        }

        console.log('鼠标事件监听器设置完成');
      } catch (e) {
        console.warn('设置鼠标事件监听器失败:', e);
      }
    },

    // 检查是否点击在滚动条上
    isClickOnScrollbar(event, widgetType) {
      // 简单的滚动条检测逻辑
      const rect = event.target.getBoundingClientRect();
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;

      // 检查是否在滚动条区域（右侧和底部边缘）
      const isOnVerticalScrollbar = x > rect.width - 20; // 右侧20px区域
      const isOnHorizontalScrollbar = y > rect.height - 20; // 底部20px区域

      return isOnVerticalScrollbar || isOnHorizontalScrollbar;
    },

    // 比较两个模型范围是否相等
    areLimitsEqual(limits1, limits2) {
      if (!limits1 || !limits2) return false;
      const tolerance = 0.001; // 允许的误差范围
      return Math.abs(limits1.getLeft() - limits2.getLeft()) < tolerance &&
        Math.abs(limits1.getTop() - limits2.getTop()) < tolerance &&
        Math.abs(limits1.getRight() - limits2.getRight()) < tolerance &&
        Math.abs(limits1.getBottom() - limits2.getBottom()) < tolerance;
    },

    // 强制同步两个widget
    forceSyncWidgets() {
      if (!this._seismicWidget || !this._seismicWidgetBottom) return;

      try {
        // 获取上图当前的模型范围
        const topLimits = this._seismicWidget.getModelLimits();
        if (topLimits) {
          // 设置下图的模型范围
          this._seismicWidgetBottom.setModelLimits(topLimits);

          // 强制更新滚动条位置
          this.forceUpdateScrollbarPosition(this._seismicWidgetBottom, topLimits);

          // 重绘
          this._seismicWidgetBottom.invalidate();

          // 延迟再次更新，确保同步生效
          setTimeout(() => {
            this.forceUpdateScrollbarPosition(this._seismicWidgetBottom, topLimits);
            this._seismicWidgetBottom.invalidate();
          }, 50);

          console.log('强制同步widget完成', {
            topLimits: {
              left: topLimits.getLeft(),
              top: topLimits.getTop(),
              right: topLimits.getRight(),
              bottom: topLimits.getBottom()
            }
          });
        }
      } catch (e) {
        console.warn('强制同步widget失败:', e);
      }
    },

    // 调试方法：检查滚动条状态
    debugScrollbarStatus() {
      console.log('=== 滚动条状态调试 ===');

      if (this._seismicWidget) {
        const topToolManager = this._seismicWidget.getTool && this._seismicWidget.getTool();
        if (topToolManager) {
          console.log('上图工具管理器方法:', Object.getOwnPropertyNames(topToolManager));

          // 尝试获取滚动条工具
          let topScrollbarTool = null;
          if (topToolManager.getScrollbarTool) {
            topScrollbarTool = topToolManager.getScrollbarTool();
          } else if (topToolManager.getScrollbar) {
            topScrollbarTool = topToolManager.getScrollbar();
          } else if (topToolManager.scrollbar) {
            topScrollbarTool = topToolManager.scrollbar;
          }

          console.log('上图滚动条工具:', {
            exists: !!topScrollbarTool,
            methods: topScrollbarTool ? Object.getOwnPropertyNames(topScrollbarTool) : [],
            visible: topScrollbarTool ? (topScrollbarTool.isVisible ? topScrollbarTool.isVisible() : 'isVisible方法不存在') : false,
            modelLimits: this._seismicWidget.getModelLimits()
          });
        }
      }

      if (this._seismicWidgetBottom) {
        const bottomToolManager = this._seismicWidgetBottom.getTool && this._seismicWidgetBottom.getTool();
        if (bottomToolManager) {
          console.log('下图工具管理器方法:', Object.getOwnPropertyNames(bottomToolManager));

          // 尝试获取滚动条工具
          let bottomScrollbarTool = null;
          if (bottomToolManager.getScrollbarTool) {
            bottomScrollbarTool = bottomToolManager.getScrollbarTool();
          } else if (bottomToolManager.getScrollbar) {
            bottomScrollbarTool = bottomToolManager.getScrollbar();
          } else if (bottomToolManager.scrollbar) {
            bottomScrollbarTool = bottomToolManager.scrollbar;
          }

          console.log('下图滚动条工具:', {
            exists: !!bottomScrollbarTool,
            methods: bottomScrollbarTool ? Object.getOwnPropertyNames(bottomScrollbarTool) : [],
            visible: bottomScrollbarTool ? (bottomScrollbarTool.isVisible ? bottomScrollbarTool.isVisible() : 'isVisible方法不存在') : false,
            modelLimits: this._seismicWidgetBottom.getModelLimits()
          });
        }
      }

      if (this._seismicWidgetBottom) {
        const bottomToolManager = this._seismicWidgetBottom.getTool && this._seismicWidgetBottom.getTool();
        if (bottomToolManager && bottomToolManager.getScrollbarTool) {
          const bottomScrollbarTool = bottomToolManager.getScrollbarTool();
          console.log('下图滚动条工具:', {
            exists: !!bottomScrollbarTool,
            visible: bottomScrollbarTool ? bottomScrollbarTool.isVisible && bottomScrollbarTool.isVisible() : false,
            modelLimits: this._seismicWidgetBottom.getModelLimits()
          });
        }
      }

      console.log('=== 调试结束 ===');
    },

    // 添加手动同步按钮（用于测试）
    addManualSyncButton() {
      console.log('开始添加手动同步按钮...');

      // 创建一个测试按钮
      const button = document.createElement('button');
      button.textContent = '测试滚动条';
      button.style.position = 'fixed';
      button.style.top = '50px';
      button.style.right = '10px';
      button.style.zIndex = '9999';
      button.style.padding = '10px';
      button.style.backgroundColor = '#ff4444';
      button.style.color = 'white';
      button.style.border = 'none';
      button.style.borderRadius = '4px';
      button.style.cursor = 'pointer';
      button.style.fontSize = '14px';

      button.addEventListener('click', () => {
        console.log('=== 手动同步按钮被点击 ===');

        // 简化的测试
        console.log('1. 检查widget状态');
        console.log('上图widget:', !!this._seismicWidget);
        console.log('下图widget:', !!this._seismicWidgetBottom);

        console.log('2. 尝试通过 DOM 元素访问滚动条');
        this.tryAccessScrollbarViaDOM();

        console.log('3. 尝试直接访问滚动条');
        this.tryDirectScrollbarAccess();

        console.log('4. 尝试通过 widget 方法访问滚动条');
        this.tryAccessScrollbarViaWidgetMethods();

        console.log('5. 调试滚动条状态');
        this.debugScrollbarStatus();

        console.log('=== 测试完成 ===');
      });

      document.body.appendChild(button);
      console.log('手动同步按钮已添加到页面');

      // 同时在控制台输出一个全局函数，方便调试
      window.testScrollbarSync = () => {
        console.log('=== 通过全局函数测试滚动条同步 ===');
        console.log('1. 检查widget状态');
        console.log('上图widget:', !!this._seismicWidget);
        console.log('下图widget:', !!this._seismicWidgetBottom);

        console.log('2. 尝试通过 DOM 元素访问滚动条');
        this.tryAccessScrollbarViaDOM();

        console.log('3. 尝试直接访问滚动条');
        this.tryDirectScrollbarAccess();

        console.log('4. 调试滚动条状态');
        this.debugScrollbarStatus();

        console.log('=== 全局函数测试完成 ===');
      };

      console.log('手动同步按钮已添加，也可以通过 window.testScrollbarSync() 来测试');
    },

    // 清理定时器
    clearScrollSyncTimer() {
      if (this._internalScrollSyncTimer) {
        clearInterval(this._internalScrollSyncTimer);
        this._internalScrollSyncTimer = null;
        console.log('滚动条同步定时器已清理');
      }
    },

    // 直接同步滚动条位置
    directScrollbarSync() {
      if (!this._seismicWidget || !this._seismicWidgetBottom) return;

      try {
        console.log('开始直接同步滚动条位置');

        // 获取上图的滚动条工具
        const topToolManager = this._seismicWidget.getTool && this._seismicWidget.getTool();
        const bottomToolManager = this._seismicWidgetBottom.getTool && this._seismicWidgetBottom.getTool();

        console.log('工具管理器状态:', {
          topToolManager: !!topToolManager,
          bottomToolManager: !!bottomToolManager,
          topWidget: !!this._seismicWidget,
          bottomWidget: !!this._seismicWidgetBottom
        });

        if (!topToolManager || !bottomToolManager) {
          console.warn('无法获取工具管理器');
          return;
        }

        // 检查工具管理器的所有可用方法
        console.log('上图工具管理器方法:', Object.getOwnPropertyNames(topToolManager));
        console.log('下图工具管理器方法:', Object.getOwnPropertyNames(bottomToolManager));

        // 尝试多种可能的滚动条访问方法
        let topScrollbarTool = null;
        let bottomScrollbarTool = null;

        // 方法1: getScrollbarTool
        if (topToolManager.getScrollbarTool) {
          topScrollbarTool = topToolManager.getScrollbarTool();
          console.log('上图方法1 (getScrollbarTool) 结果:', !!topScrollbarTool);
        }
        if (bottomToolManager.getScrollbarTool) {
          bottomScrollbarTool = bottomToolManager.getScrollbarTool();
          console.log('下图方法1 (getScrollbarTool) 结果:', !!bottomScrollbarTool);
        }

        // 方法2: getScrollbar
        if (!topScrollbarTool && topToolManager.getScrollbar) {
          topScrollbarTool = topToolManager.getScrollbar();
          console.log('上图方法2 (getScrollbar) 结果:', !!topScrollbarTool);
        }
        if (!bottomScrollbarTool && bottomToolManager.getScrollbar) {
          bottomScrollbarTool = bottomToolManager.getScrollbar();
          console.log('下图方法2 (getScrollbar) 结果:', !!bottomScrollbarTool);
        }

        // 方法3: scrollbar 属性
        if (!topScrollbarTool && topToolManager.scrollbar) {
          topScrollbarTool = topToolManager.scrollbar;
          console.log('上图方法3 (scrollbar属性) 结果:', !!topScrollbarTool);
        }
        if (!bottomScrollbarTool && bottomToolManager.scrollbar) {
          bottomScrollbarTool = bottomToolManager.scrollbar();
          console.log('下图方法3 (scrollbar属性) 结果:', !!bottomScrollbarTool);
        }

        // 方法4: 直接访问 scrollbar 相关属性
        if (!topScrollbarTool) {
          const topScrollbarProps = Object.getOwnPropertyNames(topToolManager).filter(name =>
            name.toLowerCase().includes('scroll') || name.toLowerCase().includes('bar')
          );
          console.log('上图包含scroll/bar的属性:', topScrollbarProps);

          for (const prop of topScrollbarProps) {
            const value = topToolManager[prop];
            if (value && typeof value === 'object') {
              console.log(`上图属性 ${prop} 的方法:`, Object.getOwnPropertyNames(value));
              topScrollbarTool = value;
              break;
            }
          }
        }

        if (!bottomScrollbarTool) {
          const bottomScrollbarProps = Object.getOwnPropertyNames(bottomToolManager).filter(name =>
            name.toLowerCase().includes('scroll') || name.toLowerCase().includes('bar')
          );
          console.log('下图包含scroll/bar的属性:', bottomScrollbarProps);

          for (const prop of bottomScrollbarProps) {
            const value = bottomToolManager[prop];
            if (value && typeof value === 'object') {
              console.log(`下图属性 ${prop} 的方法:`, Object.getOwnPropertyNames(value));
              bottomScrollbarTool = value;
              break;
            }
          }
        }

        // 方法5: 深度探索对象内部结构
        if (!topScrollbarTool) {
          console.log('开始深度探索上图对象内部结构...');
          let topExploredCount = 0;
          let topTotalProperties = Object.getOwnPropertyNames(topToolManager).length;

          console.log(`上图工具管理器共有 ${topTotalProperties} 个属性`);

          for (const propName of Object.getOwnPropertyNames(topToolManager)) {
            try {
              const propValue = topToolManager[propName];
              console.log(`检查上图属性 ${propName}:`, typeof propValue, propValue);

              // 探索非null的对象属性
              if (propValue && typeof propValue === 'object' && propValue !== null) {
                topExploredCount++;
                console.log(`探索上图对象属性 ${topExploredCount}/${topTotalProperties}: ${propName}`);

                // 获取对象的所有属性
                const objectProps = Object.getOwnPropertyNames(propValue);
                console.log(`  上图对象 ${propName} 的属性 (${objectProps.length}个):`, objectProps);

                // 检查是否包含滚动条相关属性
                const scrollbarProps = objectProps.filter(name =>
                  name.toLowerCase().includes('scroll') ||
                  name.toLowerCase().includes('bar') ||
                  name.toLowerCase().includes('horizontal') ||
                  name.toLowerCase().includes('vertical') ||
                  name.toLowerCase().includes('sb') ||
                  name.toLowerCase().includes('scrollbar')
                );

                if (scrollbarProps.length > 0) {
                  console.log(`  🎯 上图找到滚动条相关属性:`, scrollbarProps);

                  // 进一步探索这些属性
                  for (const scrollbarProp of scrollbarProps) {
                    const scrollbarValue = propValue[scrollbarProp];
                    console.log(`    上图滚动条属性 ${scrollbarProp}:`, typeof scrollbarValue, scrollbarValue);

                    if (scrollbarValue && typeof scrollbarValue === 'object') {
                      const scrollbarMethods = Object.getOwnPropertyNames(scrollbarValue);
                      console.log(`      上图滚动条对象方法 (${scrollbarMethods.length}个):`, scrollbarMethods);

                      // 检查是否有滚动条相关方法
                      const relevantMethods = scrollbarMethods.filter(name =>
                        name.toLowerCase().includes('scroll') ||
                        name.toLowerCase().includes('bar') ||
                        name.toLowerCase().includes('horizontal') ||
                        name.toLowerCase().includes('vertical') ||
                        name.toLowerCase().includes('update') ||
                        name.toLowerCase().includes('set') ||
                        name.toLowerCase().includes('get')
                      );

                      if (relevantMethods.length > 0) {
                        console.log(`      🎯 上图找到滚动条相关方法:`, relevantMethods);
                        console.log(`      📍 上图通过路径 ${propName}.${scrollbarProp} 找到滚动条工具`);
                        topScrollbarTool = scrollbarValue;
                        break;
                      }
                    }
                  }

                  if (topScrollbarTool) break;
                }

                // 如果这个对象本身看起来像滚动条工具
                if (propName.toLowerCase().includes('scroll') ||
                  propName.toLowerCase().includes('bar') ||
                  propName === 'sb') {
                  console.log(`  🎯 上图属性名 ${propName} 看起来像滚动条相关`);

                  if (propValue && typeof propValue === 'object') {
                    const propMethods = Object.getOwnPropertyNames(propValue);
                    console.log(`    上图属性 ${propName} 的方法 (${propMethods.length}个):`, propMethods);

                    const relevantMethods = propMethods.filter(name =>
                      name.toLowerCase().includes('scroll') ||
                      name.toLowerCase().includes('bar') ||
                      name.toLowerCase().includes('horizontal') ||
                      name.toLowerCase().includes('vertical') ||
                      name.toLowerCase().includes('update') ||
                      name.toLowerCase().includes('set') ||
                      name.toLowerCase().includes('get')
                    );

                    if (relevantMethods.length > 0) {
                      console.log(`    🎯 上图找到滚动条相关方法:`, relevantMethods);
                      console.log(`    📍 上图通过属性 ${propName} 找到滚动条工具`);
                      topScrollbarTool = propValue;
                      break;
                    }
                  }
                }
              } else if (propValue === null) {
                console.log(`  上图属性 ${propName} 为 null，可能是未初始化的滚动条工具`);
              }
            } catch (e) {
              console.log(`  探索上图属性 ${propName} 失败:`, e.message);
            }
          }

          console.log(`上图深度探索完成统计:`);
          console.log(`  上图总属性数: ${topTotalProperties}`);
          console.log(`  上图探索的对象属性数: ${topExploredCount}`);
          console.log(`  上图找到滚动条工具: ${topScrollbarTool ? '是' : '否'}`);
        }

        if (!bottomScrollbarTool) {
          console.log('开始深度探索下图对象内部结构...');
          let bottomExploredCount = 0;
          let bottomTotalProperties = Object.getOwnPropertyNames(bottomToolManager).length;

          console.log(`下图工具管理器共有 ${bottomTotalProperties} 个属性`);

          for (const propName of Object.getOwnPropertyNames(bottomToolManager)) {
            try {
              const propValue = bottomToolManager[propName];
              console.log(`检查下图属性 ${propName}:`, typeof propValue, propValue);

              // 探索非null的对象属性
              if (propValue && typeof propValue === 'object' && propValue !== null) {
                bottomExploredCount++;
                console.log(`探索下图对象属性 ${bottomExploredCount}/${bottomTotalProperties}: ${propName}`);

                // 获取对象的所有属性
                const objectProps = Object.getOwnPropertyNames(propValue);
                console.log(`  下图对象 ${propName} 的属性 (${objectProps.length}个):`, objectProps);

                // 检查是否包含滚动条相关属性
                const scrollbarProps = objectProps.filter(name =>
                  name.toLowerCase().includes('scroll') ||
                  name.toLowerCase().includes('bar') ||
                  name.toLowerCase().includes('horizontal') ||
                  name.toLowerCase().includes('vertical') ||
                  name.toLowerCase().includes('sb') ||
                  name.toLowerCase().includes('scrollbar')
                );

                if (scrollbarProps.length > 0) {
                  console.log(`  🎯 下图找到滚动条相关属性:`, scrollbarProps);

                  // 进一步探索这些属性
                  for (const scrollbarProp of scrollbarProps) {
                    const scrollbarValue = propValue[scrollbarProp];
                    console.log(`    下图滚动条属性 ${scrollbarProp}:`, typeof scrollbarValue, scrollbarValue);

                    if (scrollbarValue && typeof scrollbarValue === 'object') {
                      const scrollbarMethods = Object.getOwnPropertyNames(scrollbarValue);
                      console.log(`      下图滚动条对象方法 (${scrollbarMethods.length}个):`, scrollbarMethods);

                      // 检查是否有滚动条相关方法
                      const relevantMethods = scrollbarMethods.filter(name =>
                        name.toLowerCase().includes('scroll') ||
                        name.toLowerCase().includes('bar') ||
                        name.toLowerCase().includes('horizontal') ||
                        name.toLowerCase().includes('vertical') ||
                        name.toLowerCase().includes('update') ||
                        name.toLowerCase().includes('set') ||
                        name.toLowerCase().includes('get')
                      );

                      if (relevantMethods.length > 0) {
                        console.log(`      🎯 下图找到滚动条相关方法:`, relevantMethods);
                        console.log(`      📍 下图通过路径 ${propName}.${scrollbarProp} 找到滚动条工具`);
                        bottomScrollbarTool = scrollbarValue;
                        break;
                      }
                    }
                  }

                  if (bottomScrollbarTool) break;
                }

                // 如果这个对象本身看起来像滚动条工具
                if (propName.toLowerCase().includes('scroll') ||
                  propName.toLowerCase().includes('bar') ||
                  propName === 'sb') {
                  console.log(`  🎯 下图属性名 ${propName} 看起来像滚动条相关`);

                  if (propValue && typeof propValue === 'object') {
                    const propMethods = Object.getOwnPropertyNames(propValue);
                    console.log(`    下图属性 ${propName} 的方法 (${propMethods.length}个):`, propMethods);

                    const relevantMethods = propMethods.filter(name =>
                      name.toLowerCase().includes('scroll') ||
                      name.toLowerCase().includes('bar') ||
                      name.toLowerCase().includes('horizontal') ||
                      name.toLowerCase().includes('vertical') ||
                      name.toLowerCase().includes('update') ||
                      name.toLowerCase().includes('set') ||
                      name.toLowerCase().includes('get')
                    );

                    if (relevantMethods.length > 0) {
                      console.log(`    🎯 下图找到滚动条相关方法:`, relevantMethods);
                      console.log(`    📍 下图通过属性 ${propName} 找到滚动条工具`);
                      bottomScrollbarTool = propValue;
                      break;
                    }
                  }
                }
              } else if (propValue === null) {
                console.log(`  下图属性 ${propName} 为 null，可能是未初始化的滚动条工具`);
              }
            } catch (e) {
              console.log(`  探索下图属性 ${propName} 失败:`, e.message);
            }
          }

          console.log(`下图深度探索完成统计:`);
          console.log(`  下图总属性数: ${bottomTotalProperties}`);
          console.log(`  下图探索的对象属性数: ${bottomExploredCount}`);
          console.log(`  下图找到滚动条工具: ${bottomScrollbarTool ? '是' : '否'}`);
        }

        console.log('滚动条工具状态:', {
          topScrollbarTool: !!topScrollbarTool,
          bottomScrollbarTool: !!bottomScrollbarTool
        });

        if (!topScrollbarTool || !bottomScrollbarTool) {
          console.error('所有方法都无法获取滚动条工具');
          return;
        }

        console.log('滚动条工具获取成功，开始同步位置');

        // 获取上图的滚动条位置
        const topHScrollbar = topScrollbarTool.getHorizontalScrollbar && topScrollbarTool.getHorizontalScrollbar();
        const topVScrollbar = topScrollbarTool.getVerticalScrollbar && topScrollbarTool.getVerticalScrollbar();

        const bottomHScrollbar = bottomScrollbarTool.getHorizontalScrollbar && bottomScrollbarTool.getHorizontalScrollbar();
        const bottomVScrollbar = bottomScrollbarTool.getVerticalScrollbar && bottomScrollbarTool.getVerticalScrollbar();

        console.log('滚动条对象状态:', {
          topH: !!topHScrollbar,
          topV: !!topVScrollbar,
          bottomH: !!bottomHScrollbar,
          bottomV: !!bottomVScrollbar
        });

        if (topHScrollbar && bottomHScrollbar) {
          // 同步水平滚动条位置
          const topHValue = topHScrollbar.getValue && topHScrollbar.getValue();
          console.log('上图水平滚动条位置:', topHValue);

          if (topHValue !== undefined && bottomHScrollbar.setValue) {
            bottomHScrollbar.setValue(topHValue);
            console.log('水平滚动条位置已同步:', topHValue);
          } else {
            console.warn('无法获取或设置水平滚动条位置');
          }
        }

        if (topVScrollbar && bottomVScrollbar) {
          // 同步垂直滚动条位置
          const topVValue = topVScrollbar.getValue && topVScrollbar.getValue();
          console.log('上图垂直滚动条位置:', topVValue);

          if (topVValue !== undefined && bottomVScrollbar.setValue) {
            bottomVScrollbar.setValue(topVValue);
            console.log('垂直滚动条位置已同步:', topVValue);
          } else {
            console.warn('无法获取或设置垂直滚动条位置');
          }
        }

        // 强制更新
        if (bottomScrollbarTool.update) {
          bottomScrollbarTool.update();
          console.log('滚动条工具已更新');
        }

        if (this._seismicWidgetBottom.invalidate) {
          this._seismicWidgetBottom.invalidate();
          console.log('Widget已重绘');
        }

        console.log('直接滚动条同步完成');
      } catch (e) {
        console.error('直接同步滚动条位置失败:', e);
        console.error('错误堆栈:', e.stack);
      }
    },

    // 分析滚动条状态
    analyzeScrollbarStatus() {
      console.log('=== 分析滚动条状态 ===');

      if (this._seismicWidget && this._seismicWidgetBottom) {
        const topToolManager = this._seismicWidget.getTool && this._seismicWidget.getTool();
        const bottomToolManager = this._seismicWidgetBottom.getTool && this._seismicWidgetBottom.getTool();

        if (topToolManager && bottomToolManager) {
          console.log('上图工具管理器方法:', Object.getOwnPropertyNames(topToolManager));
          console.log('下图工具管理器方法:', Object.getOwnPropertyNames(bottomToolManager));

          // 深度分析每个混淆的方法
          console.log('=== 深度分析上图工具管理器 ===');
          for (const methodName of Object.getOwnPropertyNames(topToolManager)) {
            try {
              const method = topToolManager[methodName];
              if (typeof method === 'function') {
                console.log(`分析上图方法: ${methodName}`);
                const result = method.call(topToolManager);
                if (result && typeof result === 'object') {
                  const resultMethods = Object.getOwnPropertyNames(result);
                  console.log(`  方法 ${methodName} 返回对象的方法:`, resultMethods);

                  // 检查是否包含滚动条相关方法
                  const scrollbarMethods = resultMethods.filter(name =>
                    name.toLowerCase().includes('scroll') ||
                    name.toLowerCase().includes('bar') ||
                    name.toLowerCase().includes('horizontal') ||
                    name.toLowerCase().includes('vertical')
                  );

                  if (scrollbarMethods.length > 0) {
                    console.log(`  🎯 找到滚动条相关方法:`, scrollbarMethods);
                  }
                }
              }
            } catch (e) {
              // 忽略调用错误
            }
          }

          console.log('=== 深度分析下图工具管理器 ===');
          for (const methodName of Object.getOwnPropertyNames(bottomToolManager)) {
            try {
              const method = bottomToolManager[methodName];
              if (typeof method === 'function') {
                console.log(`分析下图方法: ${methodName}`);
                const result = method.call(bottomToolManager);
                if (result && typeof result === 'object') {
                  const resultMethods = Object.getOwnPropertyNames(result);
                  console.log(`  方法 ${methodName} 返回对象的方法:`, resultMethods);

                  // 检查是否包含滚动条相关方法
                  const scrollbarMethods = resultMethods.filter(name =>
                    name.toLowerCase().includes('scroll') ||
                    name.toLowerCase().includes('bar') ||
                    name.toLowerCase().includes('horizontal') ||
                    name.toLowerCase().includes('vertical')
                  );

                  if (scrollbarMethods.length > 0) {
                    console.log(`  🎯 找到滚动条相关方法:`, scrollbarMethods);
                  }
                }
              }
            } catch (e) {
              // 忽略调用错误
            }
          }
        }
      }

      console.log('=== 分析完成 ===');
    },

    createScene(canvas) {
      try {
        const autoFormat = new AutoNumberFormat(4);
        // 创建 Plot 实例，同时创建 SeismicWidget
        this.plots = new Plot({
          'canvasElement': canvas,
          'root': this._seismicWidget = new SeismicWidget(null, {
            'layouttype': 'inside',
            'tools': {
              'crosshair': { 'enabled': true },
              // 禁用内部滚动条，改用外部容器滚动
              'scrollbar': {
                'enabled': false,
                'visible': false,
                'horizontal': { 'enabled': false, 'visible': false },
                'vertical': { 'enabled': false, 'visible': false }
              }
            },
            'colorbar': {
              'axis': {
                'size': 20,
                'autolabelrotation': true,
                'tickgenerator': {
                  'edge': {
                    'tickvisible': false,
                    'labelvisible': false
                  }
                }
              },
              'title': {
                'size': 0
              },
              'colorbox': {
                'size': 10
              },
              'visible': true,
              'location': ColorBarLocation.West,  // 改为左侧
              'maxheight': '80%',
              'alignment': BoxLayoutAlignment.Center,  // 改为居中对齐
              'width': 60
            },
            'statusbar': {
              'visible': true,
              'location': 'bottom',
              'alignment': 'left',
              'size': 25,
              'sections': {
                'time': {
                  'visible': true,
                  'width': '100px'
                },
                'trace': {
                  'visible': true,
                  'width': '120px'
                },
                'value': {
                  'visible': true,
                  'width': '120px'
                }
              },
              // 修改状态栏信息显示格式
              'info': (widget, x, y, sample) => {
                if (!sample) return {
                  'time': '',
                  'trace': '',
                  'value': ''
                };

                let time = '';
                let traceNumber = '';
                let value = '';

                if (sample.location && sample.location.y != null) {
                  // 深度值保持2位小数
                  time = autoFormat.format(Math.round(sample.location.y * 100) / 100.0);
                }
                if (sample.traceNumber != null) {
                  // 道集号使用原始值+1
                  traceNumber = (sample.traceNumber + 1).toString();
                }
                if (sample.sampleValue != null) {
                  // 采样值保持3位小数
                  value = sample.sampleValue.toFixed(3);
                }

                return {
                  'time': `Time: ${time}`,
                  'trace': `Trace: ${traceNumber}`,
                  'value': `Value: ${value}`
                };
              }
            },
            'axes': {
              'samples': {
                'title': {
                  'visible': false  // 先设置为false，等pipeline加载后再更新
                },
                'visible': true,
                'labelformat': '%.0f',
                'labelvisible': true,
                'tickgenerator': {
                  'edge': {
                    'tickvisible': true,
                    'labelvisible': true
                  }
                }
              },
              'headers': {
                'fields': [],  // 先设置为空数组，等pipeline加载后再更新
                'options': {
                  'minimumSpan': 100
                }
              }
            }
          })
        });

        // 初始化颜色提供者
        this.colorProvider = SeismicColors.getDefault();

        // 注册自定义颜色映射
        this.registerColorMaps(this.colorProvider);

        // 初始化默认的颜色映射，使用256色以获得更平滑的渐变
        this._colorMap = this.colorProvider.createNamedColorMap('WhiteBlack', 256);

        // 加载数据
        this.$nextTick(() => {
          this.handleFileSelect(this.plots).then(() => {
            // 数据加载完成后更新轴标题
            if (this.pipeline && this._seismicWidget) {
              this._seismicWidget.setOptions({
                'axes': {
                  'samples': {
                    'title': {
                      'visible': true,
                      'text': this.pipeline.getName()
                    }
                  },
                  'headers': {
                    'fields': this._headers
                  }
                }
              });
            }
            // 初始化注释工具
            this.initAnnotationTools(this._seismicWidget);

            // 初始化下半屏
            if (this.$refs.plot2) {
              this.initSecondWidget(this.$refs.plot2);
              this.ensureZoomSyncHook();

              this.$nextTick(() => {
                // 基于 model limits 的同步
                this.setupInternalScrollbarSync();
                this.forceSyncWidgets();
              });
            }

            // 初始化缩放基础高度
            this.$nextTick(() => {
              const ch = this.$refs.plot && (this.$refs.plot.clientHeight || 0);
              if (ch > 0) this.baseCanvasHeight = ch;
            });
          });
        });
      } catch (error) {
        this.loadingError = `创建场景失败: ${error.message}`;
        console.error('Error creating scene:', error);
      }
    },

    handleFileSelect(plot) {
      let url = process.env.VUE_APP_BASE_API + "/ndy/dz/getSegyDataFile?fileName=density.segy";
      let fileName = 'density.segy';

      return fetch(url, {
        headers: {
          Authorization: "Bearer " + getToken()
        }
      })
        .then((response) => {
          if (!response.ok) {
            throw new Error(`网络请求失败: ${response.status} ${response.statusText}`);
          }
          return response.blob();
        })
        .then((blob) => {
          if (!blob || blob.size === 0) {
            throw new Error('获取到的文件数据为空');
          }

          let filesObj = new File([blob], fileName, { type: blob.type, lastModified: Date.now() });
          const file = new LocalFile(filesObj);

          const segyReader = new SegyReader(file);
          return new Promise((resolve, reject) => {
            segyReader.loadMetaData((reader) => {
              if (reader instanceof Error) {
                this.loadingError = `加载元数据失败: ${reader.message}`;
                reject(reader);
                return;
              }

              // 获取 CDP 字段
              const knownHeaders = reader.getTraceHeaderFields();
              let cdpHeader = null;
              this._headers = [];

              knownHeaders.forEach((field) => {
                if (field.getName() === 'CDP') {
                  cdpHeader = field;
                }
                this._headers.push({
                  'visible': field.getName() === 'CDP',
                  'name': field.getName(),
                  'color': 'black'
                });
              });

              // 保存reader与文件名，供下半屏使用
              this._dataReader = reader;
              this._fileName = fileName;

              reader.readDataSetStatistics((reader, statistics) => {
                if (!statistics) {
                  this.loadingError = '无法获取数据集统计信息';
                  reject(new Error('无法获取数据集统计信息'));
                  return;
                }

                // 保存statistics供下半屏使用
                this._dataStatistics = statistics;

                const pipeline = new SeismicPipeline(fileName, reader, statistics)
                  .setColorMap(this._colorMap)
                  .setOptions({
                    'normalization': {
                      'type': NormalizationType.RMS,
                      'scale': 0.4
                    },
                    'plot': {
                      'type': {
                        'Wiggle': false,
                        'InterpolatedDensity': true
                      },
                      'decimationSpacing': 5
                    },
                    'colors': {
                      'colorMap': this._colorMap
                    }
                  });

                // Set the pipeline first
                this.pipeline = pipeline;
                this._seismicWidget.setPipeline(pipeline);

                // Then set widget options
                this._seismicWidget.setOptions({
                  'axes': {
                    'headers': {
                      'fields': this._headers
                    },
                    'samples': {
                      'title': {
                        'visible': true,
                        'text': pipeline.getName()
                      }
                    }
                  }
                });

                // Now add processors one by one
                try {
                  pipeline.addTraceProcessor(new TaperFilterProcess({
                    'apply': false,
                    'name': 'TaperFilter'
                  }));
                } catch (e) {
                  console.warn('Failed to add TaperFilter:', e);
                }

                try {
                  pipeline.addTraceProcessor(new AGC({
                    'apply': false,
                    'name': 'AGC'
                  }));
                } catch (e) {
                  console.warn('Failed to add AGC:', e);
                }

                try {
                  pipeline.addTraceProcessor(new Reverse({
                    'apply': false,
                    'name': 'Reverse'
                  }));
                } catch (e) {
                  console.warn('Failed to add Reverse:', e);
                }

                this._seismicWidget.fitToBounds();

                // 强制显示滚动条
                // 不再依赖滚动条工具
                this.$nextTick(() => { });

                this.isWidgetReady = true;
                resolve();
              });
            });
          });
        })
        .catch(error => {
          this.loadingError = `获取地震数据失败: ${error.message}`;
          console.error('Error fetching seismic data:', error);
          throw error;
        });
    },

    handleMouseMove(event) {
      if (!this._seismicWidget || !this.isHovering) return;

      // 使用内置状态栏，不需要额外的处理逻辑
    },

    onFileOpen(evt, plot, fileInfo) {
      evt.stopPropagation();
      evt.preventDefault();
      const files = evt.target.files;
      return this.handleFileSelect(this.plots);
    },

    initAnnotationTools(widget) {
      if (!this.checkWidgetStatus()) {
        console.error('Widget status check failed');
        return;
      }

      try {
        // 创建注释层
        this.annotations = new Group();
        const overlayLayer = widget.getOverlayLayer();
        if (!overlayLayer) {
          throw new Error('无法获取覆盖层');
        }
        overlayLayer.addChild(this.annotations);

        // 创建注释工具
        this.annotationTool = new Paint({
          'layer': widget.getManipulatorLayer(),
          'node': {
            'radius': 10,
            'fillstyle': new FillStyle('#c7e1f6'),
            'linestyle': new LineStyle({
              'color': '#0351ad',
              'width': 2
            }),
            'textbox': {
              'border': true,
              'borderradius': 10,
              'fixedsize': false,
              'wordwrap': true,
              'padding': 5
            },
            'selectable': true,
            'movable': true,
            'editable': true
          },
          'handles': {
            'anchor': {
              'fillstyle': new FillStyle('#8be73d'),
              'linestyle': new LineStyle('#0351ad')
            }
          }
        });

        // 添加选择工具
        const selectionTool = new Selection()
          .setNodeFilter((nodes) => nodes.filter((node) =>
            this.annotations.indexOfChild(node) >= 0))
          .addListener(SelectionEvents.onPick, (tool, eventArgs) => {
            if (!this.annotationTool.isEnabled() && !this.pencilTool?.isEnabled()) return;

            const selection = eventArgs.getSelection();
            const length = selection.length;

            if (length === 0) {
              if (this.annotationTool.getMode() === PaintMode.Edit) {
                this.annotationTool.editNode(null);
              }
              if (this.pencilTool && this.pencilTool.getMode() === PaintMode.Edit) {
                this.pencilTool.editNode(null);
              }
            } else if (length > 0) {
              const selectedNode = selection[length - 1];
              const currentTool = this.annotationTool.isEnabled() ? this.annotationTool :
                (this.pencilTool && this.pencilTool.isEnabled() ? this.pencilTool : null);

              if (currentTool && selectedNode !== currentTool.getShape()) {
                currentTool.setEditMode(EditMode.EditNode);
                currentTool.editNode(selectedNode);
                this.selectedShape = selectedNode;
                eventArgs.stopPropagation(true, true);
              }
            }
          });

        const toolManager = widget.getTool();
        if (!toolManager) {
          throw new Error('无法获取工具管理器');
        }

        // 清除现有工具
        try {
          toolManager.remove(this.annotationTool);
          toolManager.remove(selectionTool);
        } catch (e) {
          // 忽略错误，工具可能尚未添加
        }

        // 添加工具
        toolManager.insert(0, selectionTool);
        toolManager.insert(0, this.annotationTool);

        // 添加事件监听
        this.annotationTool
          .addListener(EditEvents.Start, (tool, command) => {
            const node = command.getNode();
            if (node) {
              this.annotations.addChild(node);
              console.log('开始编辑:', {
                type: node.getType ? node.getType() : '未知类型',
                properties: node.getProperties()
              });
            }
          })
          .addListener(EditEvents.End, (tool, node) => {
            if (node) {
              tool.setEditMode(EditMode.EditNode);
              tool.editNode(node);
              this.selectedShape = node;
              this.saveAnnotation(node);
              console.log('编辑完成:', {
                type: node.getType ? node.getType() : '未知类型',
                properties: node.getProperties()
              });
            }
            this.requestRepaint();
          });

        // 初始化工具状态
        this.annotationTool.editNode(null);
        this.annotationTool.setEnabled(false);

        // 设置就绪状态
        this.isWidgetReady = true;
        console.log('注释工具初始化完成');

        // 恢复保存的标注
        this.restoreAnnotations();
      } catch (error) {
        console.error('初始化注释工具时出错:', error);
        this.loadingError = `初始化注释工具失败: ${error.message}`;
      }
    },

    toggleDrawText() {
      if (!this.checkWidgetStatus() || !this.isWidgetReady) {
        console.warn('Widget or annotation tools not ready');
        return;
      }

      if (!this.annotationTool) {
        console.warn('注释工具未初始化');
        return;
      }

      this.isDrawingText = !this.isDrawingText;
      this.showTextStylePanel = this.isDrawingText;

      if (this.isDrawingText) {
        // 确保文本大小为22px
        this.textStyle.size = 22;

        // 创建完整的字体字符串，确保包含字体大小
        const fontString = `${this.textStyle.bold ? 'bold ' : ''}${this.textStyle.italic ? 'italic ' : ''}${this.textStyle.size}px ${this.textStyle.font}`;

        // 先设置属性
        const textProperties = {
          'editmode': EditMode.Create,
          'mode': PaintMode.Text,
          'node': {
            'textstyle': new TextStyle({
              color: this.textStyle.color,
              size: this.textStyle.size,
              font: fontString, // 使用完整的字体字符串
              alignment: this.textStyle.align,
              bold: this.textStyle.bold,
              italic: this.textStyle.italic
            }),
            'textbox': {
              'border': this.textStyle.borderRadius > 0,
              'borderradius': this.textStyle.borderRadius,
              'padding': this.textStyle.borderRadius > 0 ? this.textStyle.borderRadius : 5,
              'fixedsize': this.textStyle.fixedFont
            },
            'selectable': true,
            'movable': true,
            'editable': true,
            'preserveontextfinish': true,
            'preserveonblur': true,
            'autofocus': true,
            'sizemode': this.textStyle.fixedFont ?
              (SizeMode.FixedWidth | SizeMode.FixedHeight) :
              SizeMode.WrappedWidth
          }
        };

        console.log('文本绘制工具配置:', textProperties);
        this.annotationTool.setProperties(textProperties);

        // 添加事件监听器来打印文本绘制数据
        this.annotationTool.addListener(EditEvents.Start, (tool, command) => {
          const node = command.getNode();
          const textStyle = node.getTextStyle ? node.getTextStyle() : null;
          console.log('开始绘制文本:', {
            tool: tool.getMode(),
            node: {
              type: node.getType ? node.getType() : 'unknown',
              properties: node.getProperties(),
              bounds: node.getBounds ? node.getBounds() : null
            },
            textStyle: {
              font: textStyle ? textStyle.getFont() : null,
              color: textStyle ? textStyle.getColor() : null,
              size: textStyle ? textStyle.size || this.textStyle.size : this.textStyle.size,
              alignment: textStyle ? textStyle.getAlignment() : null
            },
            currentToolConfig: {
              mode: tool.getMode(),
              editMode: tool.getEditMode(),
              isEnabled: tool.isEnabled()
            }
          });
        });

        this.annotationTool.addListener(EditEvents.Change, (tool, event) => {
          const node = tool.getShape();
          if (node) {
            const textStyle = node.getTextStyle ? node.getTextStyle() : null;
            const previousState = node._previousState || {};
            console.log('文本绘制更新:', {
              previous: {
                properties: previousState.properties || {},
                textStyle: previousState.textStyle || {}
              },
              current: {
                properties: node.getProperties(),
                bounds: node.getBounds ? node.getBounds() : null,
                textStyle: {
                  font: textStyle ? textStyle.getFont() : null,
                  color: textStyle ? textStyle.getColor() : null,
                  size: textStyle ? textStyle.size || this.textStyle.size : this.textStyle.size,
                  alignment: textStyle ? textStyle.getAlignment() : null
                }
              },
              changes: this.detectChanges(previousState, node)
            });
            // 保存当前状态用于下次比较
            node._previousState = {
              properties: { ...node.getProperties() },
              textStyle: textStyle ? {
                font: textStyle.getFont(),
                color: textStyle.getColor(),
                size: textStyle.size,
                alignment: textStyle.getAlignment()
              } : {}
            };
          }
        });

        this.annotationTool.addListener(EditEvents.End, (tool, node) => {
          if (node) {
            let text = '';
            if (typeof node.getText === 'function') {
              text = node.getText();
            } else if (node.text) {
              text = node.text;
            } else if (node.getProperties && node.getProperties().text) {
              text = node.getProperties().text;
            }

            const textStyle = node.getTextStyle ? node.getTextStyle() : null;
            console.log('文本绘制完成:', {
              node: {
                type: node.getType ? node.getType() : 'unknown',
                text: text,
                properties: node.getProperties(),
                bounds: node.getBounds ? node.getBounds() : null
              },
              styles: {
                text: {
                  font: textStyle ? textStyle.getFont() : null,
                  color: textStyle ? textStyle.getColor() : null,
                  size: textStyle ? textStyle.size || this.textStyle.size : this.textStyle.size,
                  alignment: textStyle ? textStyle.getAlignment() : null
                },
                line: node.getLineStyle ? node.getLineStyle() : null,
                fill: node.getFillStyle ? node.getFillStyle() : null
              },
              validation: {
                isValid: Boolean(node && node.getText),
                hasRequiredProperties: Boolean(
                  node.getProperties().ax !== undefined &&
                  node.getProperties().ay !== undefined
                ),
                hasStyles: Boolean(textStyle)
              }
            });
          }
          this.requestRepaint();
        });

        this.annotationTool.setEnabled(true);
      } else {
        this.annotationTool.setEnabled(false);
        this.annotationTool.editNode(null);
      }
    },

    removeAnnotation() {
      if (this.annotationTool && this.annotationTool.isEnabled() &&
        this.annotationTool.getMode() === PaintMode.Edit &&
        this.annotationTool.getShape()) {
        if (Array.isArray(this.annotationTool.getShape())) {
          this.annotationTool.getShape().forEach((shape) => shape.dispose());
        } else {
          this.annotationTool.getShape().dispose();
        }
        this.annotationTool.editNode(null);
      }
    },

    updateAllStyles() {
      if (this.annotationTool && this.annotationTool.getShape()) {
        const shape = this.annotationTool.getShape();

        // 创建完整的字体字符串
        const fontString = `${this.textStyle.bold ? 'bold ' : ''}${this.textStyle.italic ? 'italic ' : ''}${this.textStyle.size}px ${this.textStyle.font}`;

        // 创建基本文本样式
        const textStyle = new TextStyle({
          'font': fontString,
          'color': this.textStyle.color,
          'alignment': this.textStyle.align
        });

        // 创建线条样式
        const lineStyle = new LineStyle({
          'color': this.lineStyle.color,
          'width': this.lineStyle.width,
          'pattern': this.getProcessedLinePattern(this.lineStyle.pattern)
        });

        // 创建填充样式
        const fillStyle = new FillStyle(
          this.fillStyle.color,
          this.fillPatterns[this.fillStyle.pattern]
        );

        // 设置形状的所有属性
        const shapeProperties = {
          'textstyle': textStyle,
          'linestyle': lineStyle,
          'fillstyle': fillStyle,
          'sizemode': this.textStyle.fixedFont ?
            (SizeMode.FixedWidth | SizeMode.FixedHeight) :
            SizeMode.WrappedWidth,
          'textbox': {
            'border': this.textStyle.borderRadius > 0,
            'borderradius': this.textStyle.borderRadius,
            'padding': this.textStyle.borderRadius > 0 ? this.textStyle.borderRadius : 5
          }
        };

        // 在形状上设置所有属性
        shape.setProperties(shapeProperties);

        // 在工具上设置属性
        this.annotationTool.setProperties({
          'textbox': shapeProperties.textbox,
          'sizemode': shapeProperties.sizemode
        });

        // 打印更新后的样式数据
        console.log('样式更新:', {
          type: shape.getType ? shape.getType() : '未知类型',
          text: shape.getText ? shape.getText() : null,
          properties: shape.getProperties(),
          textStyle: {
            font: fontString,
            color: this.textStyle.color,
            size: this.textStyle.size,
            alignment: this.textStyle.align,
            bold: this.textStyle.bold,
            italic: this.textStyle.italic
          },
          lineStyle: {
            color: this.lineStyle.color,
            width: this.lineStyle.width,
            pattern: this.lineStyle.pattern
          },
          fillStyle: {
            color: this.fillStyle.color,
            pattern: this.fillStyle.pattern
          }
        });

        // 强制重绘
        if (shape.invalidate) {
          shape.invalidate();
        }
      }
    },

    // 修改字体大小变化处理方法
    handleFontSizeChange(value) {
      this.textStyle.size = value;
      this.updateAllStyles();

      // 更新所有已绘制的文本
      if (this.annotations) {
        const children = this.annotations.getChildren();
        if (children) {
          children.forEach(shape => {
            if (shape.getText) {
              const fontString = `${this.textStyle.bold ? 'bold ' : ''}${this.textStyle.italic ? 'italic ' : ''}${value}px ${this.textStyle.font}`;
              const textStyle = new TextStyle({
                font: fontString,
                color: this.textStyle.color,
                alignment: this.textStyle.align
              });

              shape.setProperties({
                'textstyle': textStyle
              });

              // 打印更新的文本数据
              console.log('更新已存在的文本:', {
                text: shape.getText(),
                properties: shape.getProperties(),
                textStyle: {
                  font: fontString,
                  size: value,
                  color: this.textStyle.color,
                  alignment: this.textStyle.align
                }
              });
            }
          });
        }
        this.requestRepaint();
      }
    },

    // 修改字体变化处理方法
    handleFontChange(value) {
      this.textStyle.font = value;
      this.updateAllStyles();

      // 更新所有已绘制的文本
      if (this.annotations) {
        const children = this.annotations.getChildren();
        if (children) {
          children.forEach(shape => {
            if (shape.getText) {
              const fontString = `${this.textStyle.bold ? 'bold ' : ''}${this.textStyle.italic ? 'italic ' : ''}${this.textStyle.size}px ${value}`;
              const textStyle = new TextStyle({
                font: fontString,
                color: this.textStyle.color,
                alignment: this.textStyle.align
              });

              shape.setProperties({
                'textstyle': textStyle
              });

              // 打印更新的文本数据
              console.log('更新已存在的文本:', {
                text: shape.getText(),
                properties: shape.getProperties(),
                textStyle: {
                  font: fontString,
                  color: this.textStyle.color,
                  alignment: this.textStyle.align
                }
              });
            }
          });
        }
        this.requestRepaint();
      }
    },

    // 修改字体样式处理方法
    handleFontStyleChange() {
      this.updateAllStyles();
    },

    updateTextStyle() {
      this.updateAllStyles();
    },

    updateLineStyle() {
      // 创建新的线条样式
      const lineStyle = new LineStyle({
        color: this.lineStyle.color,
        width: this.lineStyle.width,
        pattern: this.getProcessedLinePattern(this.lineStyle.pattern)
      });

      // 如果pencilTool正在使用，更新其属性
      if (this.pencilTool && this.pencilTool.isEnabled()) {
        this.pencilTool.setProperties({
          'node': {
            'linestyle': lineStyle
          }
        });

        // 如果有选中的形状，也更新它的样式
        if (this.selectedShape) {
          this.selectedShape.setProperties({
            'linestyle': lineStyle
          });

          // 打印更新后的线条样式数据
          console.log('线条样式更新:', {
            type: this.selectedShape.getType ? this.selectedShape.getType() : '未知类型',
            properties: this.selectedShape.getProperties(),
            lineStyle: {
              color: this.lineStyle.color,
              width: this.lineStyle.width,
              pattern: this.lineStyle.pattern
            }
          });

          this.requestRepaint();
        }
      }

      // 更新所有已绘制的线条
      if (this.annotations) {
        const children = this.annotations.getChildren();
        if (children) {
          children.forEach(shape => {
            if (shape instanceof Path) {
              shape.setProperties({
                'linestyle': lineStyle
              });

              // 打印每个更新的线条数据
              console.log('更新已存在的线条:', {
                type: shape.getType ? shape.getType() : '未知类型',
                properties: shape.getProperties(),
                lineStyle: {
                  color: this.lineStyle.color,
                  width: this.lineStyle.width,
                  pattern: this.lineStyle.pattern
                }
              });
            }
          });
        }
        this.requestRepaint();
      }
    },

    updateFillStyle() {
      this.updateAllStyles();
    },

    getFillPatternStyle(key) {
      // 基本样式对象
      const baseStyle = {
        height: '24px',
        width: '100%',
        marginTop: '5px',
        marginBottom: '5px',
        border: '1px solid #ddd',
        background: 'white' // 设置白色背景以便更好显示样式
      };

      // 如果是Solid模式，直接使用设置的颜色
      if (key === 'Solid') {
        return {
          ...baseStyle,
          background: this.fillStyle.color
        };
      }

      // 如果是None，显示透明背景
      if (key === 'None') {
        return {
          ...baseStyle,
          background: 'transparent'
        };
      }

      // 使用FILL_PATTERNS中的URL作为背景
      if (this.FILL_PATTERNS && this.FILL_PATTERNS[key]) {
        return {
          ...baseStyle,
          backgroundImage: `url(${this.FILL_PATTERNS[key]})`,
          backgroundRepeat: 'repeat',
          backgroundSize: 'auto'
        };
      }

      // 默认返回基本样式
      return baseStyle;
    },

    getLinePatternStyle(key) {
      let dashStyle = '';

      // 使用处理后的线条模式
      const patternArray = this.getProcessedLinePattern(key);
      if (patternArray && patternArray.length > 0) {
        dashStyle = patternArray.join('px ') + 'px';
      }

      return {
        background: 'transparent',
        backgroundImage: `url(${this.LINE_PATTERNS[key]})`,
        backgroundRepeat: 'no-repeat',
        backgroundSize: 'contain',
        backgroundPosition: 'center',
        height: '20px',
        width: '100%',
        margin: '5px 0'
      };
    },

    getProcessedLinePattern(pattern) {
      // 如果pattern是数组，直接返回
      if (Array.isArray(pattern)) {
        return pattern;
      }

      // 如果pattern是LINESTYLE_PATTERNS的键，使用该值
      if (this.linePatterns && this.linePatterns[pattern]) {
        return this.linePatterns[pattern];
      }

      // 根据常见的模式名称提供默认数组
      if (typeof pattern === 'string') {
        switch (pattern) {
          case 'Dash':
            return [20, 4];
          case 'Dot':
            return [2, 4];
          case 'DashDot':
            return [20, 4, 2, 4];
          case 'DashDotDot':
            return [20, 4, 2, 4, 2, 4];
          case 'ShortDash':
            return [10, 4];
          case 'LongDash':
            return [40, 4];
          case 'DashLongDash':
            return [20, 4, 40, 4];
          case 'Solid':
          case 'None':
          default:
            return []; // 默认为实线
        }
      }

      // 默认返回空数组（实线）
      console.log('使用默认实线模式，无法识别模式:', pattern);
      return [];
    },

    debounce(fn, delay = 300) {
      let timer = null;
      return (...args) => {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
          fn.apply(this, args);
        }, delay);
      };
    },

    checkWidgetStatus() {
      if (!this._seismicWidget) {
        console.warn('Widget未初始化');
        this.loadingError = 'Widget未初始化';
        return false;
      }

      // 检查widget的关键方法是否可用
      const requiredMethods = ['setPipeline', 'fitToBounds', 'getOverlayLayer', 'getManipulatorLayer', 'getTool', 'invalidate'];
      for (const method of requiredMethods) {
        if (typeof this._seismicWidget[method] !== 'function') {
          console.error(`Widget缺少关键方法: ${method}`);
          this.loadingError = `Widget初始化不完整，缺少方法: ${method}`;
          return false;
        }
      }

      try {
        // 验证freezeupdate设置是否正常工作
        this._seismicWidget.setOptions({ 'freezeupdate': false });
      } catch (error) {
        console.error('设置widget选项失败:', error);
        this.loadingError = `Widget选项设置失败: ${error.message}`;
        return false;
      }

      return true;
    },

    // 修改边框圆角更新方法
    handleBorderRadiusChange(value) {
      // 确保值为数字
      const radius = parseInt(value) || 0;
      this.textStyle.borderRadius = radius;
      this.updateAllStyles();
    },

    // 修改固定字体更新方法
    handleFixedFontChange(value) {
      this.textStyle.fixedFont = value;
      this.updateAllStyles();
    },

    // 添加清除所有工具状态的方法
    clearAllTools() {
      this.showTextStylePanel = false;
      this.showLineStylePanel = false;
      this.isDrawingText = false;

      if (this.annotationTool) {
        this.annotationTool.setEnabled(false);
        this.annotationTool.editNode(null);
      }

      if (this.pencilTool) {
        this.pencilTool.setEnabled(false);
        const widget = this.plots.getRoot();
        if (widget && widget.getTool()) {
          widget.getTool().remove(this.pencilTool);
        }
      }

      this.requestRepaint();
    },

    // 修改请求重绘的方法
    requestRepaint() {
      // 只调用有invalidate方法的对象
      if (this._seismicWidget) {
        this._seismicWidget.invalidate();
      }
      if (this.annotations) {
        this.annotations.invalidate();
      }
      if (this.plots && this.plots.getRoot()) {
        this.plots.getRoot().invalidate();
      }
    },

    // 添加更新选择视觉反馈的方法
    updateSelectionVisualFeedback() {
      // 更新所有形状的选中状态
      if (this.annotationLayer) {
        const children = this.annotationLayer.getChildren();
        if (children) {
          children.forEach(shape => {
            const isSelected = this.selectedShapes.indexOf(shape) >= 0;
            shape.setProperties({
              'selected': isSelected
            });
          });
        }
      }
      this.requestRepaint();
    },

    // 添加切换颜色映射的方法
    switchColorMap(colorMapName) {
      if (!this.pipeline || !this.colorProvider) {
        console.error('Pipeline or colorProvider not initialized');
        return;
      }

      this.currentColorMap = colorMapName;

      try {
        // 创建新的颜色映射
        const colorMap = this.colorProvider.createNamedColorMap(colorMapName, 256);
        if (!colorMap) {
          console.error(`创建颜色映射失败: ${colorMapName}可能未正确注册`);
          return;
        }

        // 设置两个pipeline的颜色映射
        this.pipeline.setColorMap(colorMap);
        if (this.pipelineBottom) this.pipelineBottom.setColorMap(colorMap);

        // 更新widget的颜色映射
        if (this._seismicWidget) {
          this._seismicWidget.setOptions({
            'colors': {
              'colorMap': colorMap
            }
          });

          // 强制重绘
          this._seismicWidget.invalidate();
          this._seismicWidget.fitToBounds();
        }

        if (this._seismicWidgetBottom) {
          this._seismicWidgetBottom.setOptions({ 'colors': { 'colorMap': colorMap } });
          this._seismicWidgetBottom.invalidate();
          this._seismicWidgetBottom.fitToBounds();
        }

        // 如果plots对象存在redraw方法，使用它来触发重绘
        if (this.plots && typeof this.plots.redraw === 'function') {
          this.plots.redraw();
        }

        console.log(`成功切换到颜色映射: ${colorMapName}`);
      } catch (error) {
        console.error(`切换颜色映射失败: ${error.message}`);
      }
    },

    // 添加注册颜色映射的方法
    registerColorMaps(colorProvider) {
      if (!colorProvider) {
        console.error('colorProvider为空，无法注册颜色映射');
        return;
      }

      try {
        // 注册黑白渐变色映射（与seismicplot一致）
        colorProvider.register('WhiteBlack', (map) => {
          if (!map) {
            console.error('WhiteBlack映射对象为空');
            return;
          }

          const colors = new Array(256);

          try {
            // 白色到黑色的渐变
            interpolate(colors, 0, 255, {
              A: 255,
              R: 255,
              G: 255,
              B: 255
            }, {
              A: 255,
              R: 0,
              G: 0,
              B: 0
            });

            map.set(colors);
          } catch (error) {
            console.error('设置WhiteBlack颜色映射失败:', error);
          }
        });

        // 注册灰度渐变色映射
        colorProvider.register('CustomGrayScale', (map) => {
          if (!map) {
            console.error('CustomGrayScale映射对象为空');
            return;
          }

          const colors = new Array(256);

          try {
            // -4000到181范围保持纯白色
            interpolate(colors, 0, 110, {
              A: 255,
              R: 255,
              G: 255,
              B: 255
            }, {
              A: 255,
              R: 255,
              G: 255,
              B: 255
            });

            // 181开始，从(253,253,253)开始到566
            interpolate(colors, 111, 120, {
              A: 255,
              R: 253,
              G: 253,
              B: 253
            }, {
              A: 255,
              R: 240,
              G: 240,
              B: 240
            });

            // 566开始，颜色开始变深
            interpolate(colors, 121, 160, {
              A: 255,
              R: 240,
              G: 240,
              B: 240
            }, {
              A: 255,
              R: 180,
              G: 180,
              B: 180
            });

            // 继续渐变到深色
            interpolate(colors, 161, 255, {
              A: 255,
              R: 180,
              G: 180,
              B: 180
            }, {
              A: 255,
              R: 6,
              G: 6,
              B: 6
            });

            map.set(colors);
          } catch (error) {
            console.error('设置CustomGrayScale颜色映射失败:', error);
          }
        });

        // 注册新的红色系列渐变映射
        colorProvider.register('CustomRedScale', (map) => {
          if (!map) {
            console.error('CustomRedScale映射对象为空');
            return;
          }

          const colors = new Array(256);

          try {
            // 第1段：起始红色到红棕色 (0-20%)
            interpolate(colors, 0, 40, {
              A: 255,
              R: 246,
              G: 40,
              B: 26
            }, {
              A: 255,
              R: 221,
              G: 139,
              B: 102
            });

            // 第2段：红棕色到浅褐色 (20-40%)
            interpolate(colors, 41, 84, {
              A: 255,
              R: 221,
              G: 139,
              B: 102
            }, {
              A: 255,
              R: 215,
              G: 198,
              B: 146
            });

            // 第3段：浅褐色到白色 (40-60%)
            interpolate(colors, 85, 126, {
              A: 255,
              R: 215,
              G: 198,
              B: 146
            }, {
              A: 255,
              R: 251,
              G: 250,
              B: 255
            });

            // 第4段：白色到灰紫色 (60-75%)
            interpolate(colors, 127, 168, {
              A: 255,
              R: 251,
              G: 250,
              B: 255
            }, {
              A: 255,
              R: 110,
              G: 110,
              B: 138
            });

            // 第5段：灰紫色到深灰 (75-90%)
            interpolate(colors, 169, 210, {
              A: 255,
              R: 110,
              G: 110,
              B: 138
            }, {
              A: 255,
              R: 50,
              G: 49,
              B: 54
            });

            // 第6段：保持深灰到结束 (90-100%)
            interpolate(colors, 211, 255, {
              A: 255,
              R: 50,
              G: 49,
              B: 54
            }, {
              A: 255,
              R: 50,
              G: 49,
              B: 54
            });

            map.set(colors);
          } catch (error) {
            console.error('设置CustomRedScale颜色映射失败:', error);
          }
        });

        // 注册多段颜色渐变
        colorProvider.register('BlueWhiteRed', (map) => {
          if (!map) {
            console.error('BlueWhiteRed映射对象为空');
            return;
          }

          const colors = new Array(256);

          try {
            // 第一段：253, 27, 21 到 255, 205, 203 (0-63)
            interpolate(colors, 0, 63, {
              A: 255,
              R: 254,
              G: 13,
              B: 6
            }, {
              A: 255,
              R: 255,
              G: 205,
              B: 203
            });

            // 第二段：255, 205, 203 到 255, 251, 251 (64-127)
            interpolate(colors, 64, 127, {
              A: 255,
              R: 255,
              G: 205,
              B: 203
            }, {
              A: 255,
              R: 255,
              G: 251,
              B: 251
            });

            // 第三段：255, 251, 251 到 206, 207, 255 (128-191)
            interpolate(colors, 128, 191, {
              A: 255,
              R: 255,
              G: 251,
              B: 251
            }, {
              A: 255,
              R: 206,
              G: 207,
              B: 255
            });

            // 第四段：206, 207, 255 到 30, 38, 253 (192-255)
            interpolate(colors, 192, 255, {
              A: 255,
              R: 206,
              G: 207,
              B: 255
            }, {
              A: 255,
              R: 9,
              G: 25,
              B: 254
            });

            map.set(colors);
          } catch (error) {
            console.error('设置BlueWhiteRed颜色映射失败:', error);
          }
        });


        console.log('颜色映射注册成功');
      } catch (error) {
        console.error('注册颜色映射失败:', error);
      }
    },

    toggleLineStylePanel() {
      // 如果工具已经激活，则停用
      if (this.showLineStylePanel) {
        this.deactivatePencilTool();
        return;
      }

      this.clearAllTools();
      this.showLineStylePanel = true;

      if (!this.checkWidgetStatus() || !this.isWidgetReady) return;

      const widget = this.plots.getRoot();
      if (!widget) return;

      // 确保注释层存在
      if (!this.annotations) {
        this.annotations = new Group();
        widget.getOverlayLayer().addChild(this.annotations);
        this.annotations.setVisible(true);
      }

      // 创建或更新铅笔工具
      if (!this.pencilTool) {
        const lineStyle = new LineStyle({
          color: this.lineStyle.color,
          width: this.lineStyle.width,
          pattern: this.getProcessedLinePattern(this.lineStyle.pattern)
        });

        const pencilProperties = {
          'layer': widget.getManipulatorLayer(),
          'mode': PaintMode.Pencil,
          'editmode': EditMode.Create,
          'node': {
            'linestyle': lineStyle,
            'selectable': true,
            'movable': true,
            'editable': true
          }
        };

        console.log('线条绘制工具配置:', pencilProperties);
        this.pencilTool = new Paint(pencilProperties);

        // 添加事件监听
        this.pencilTool
          .addListener(EditEvents.Start, (tool, command) => {
            const node = command.getNode();
            console.log('开始绘制线条:', {
              tool: tool.getMode(),
              properties: node.getProperties()
            });
            this.annotations.addChild(node);
          })
          .addListener(EditEvents.Change, (tool, event) => {
            const node = tool.getShape();
            if (node) {
              console.log('线条绘制更新:', {
                properties: node.getProperties(),
                bounds: node.getBounds ? node.getBounds() : null
              });
            }
          })
          .addListener(EditEvents.End, (tool, node) => {
            if (node) {
              console.log('线条绘制完成:', {
                properties: node.getProperties(),
                bounds: node.getBounds ? node.getBounds() : null
              });
            }

            if (node && this.annotations.indexOfChild(node) === -1) {
              this.annotations.addChild(node);
            }

            tool.setEditMode(EditMode.EditNode);
            tool.editNode(node);
            this.selectedShape = node;
            this.requestRepaint();
          });
      }

      // 设置工具为活动状态
      this.pencilTool.setMode(PaintMode.Pencil);
      this.pencilTool.setEditMode(EditMode.Create);

      // 获取工具管理器并添加工具
      const toolManager = widget.getTool();

      try {
        toolManager.remove(this.pencilTool);
      } catch (e) {
        // 忽略错误，工具可能已经被移除
      }

      toolManager.insert(0, this.pencilTool);
      this.pencilTool.setEnabled(true);
    },

    deactivatePencilTool() {
      this.showLineStylePanel = false;
      if (this.pencilTool) {
        this.pencilTool.setEnabled(false);
        const widget = this.plots.getRoot();
        if (widget && widget.getTool()) {
          try {
            widget.getTool().remove(this.pencilTool);
          } catch (e) {
            // 忽略错误，工具可能已经被移除
          }
        }

        // 清除选中的形状
        this.selectedShape = null;
      }
    },

    zoomIn() {
      if (!this._seismicWidget || !this.isWidgetReady) return;

      try {
        const currentLimits = this._seismicWidget.getModelLimits();
        if (currentLimits && !currentLimits.isEmpty()) {
          const center = currentLimits.getCenter();
          const zoomFactor = 1.2;
          const newWidth = currentLimits.getWidth() / zoomFactor;
          const newHeight = currentLimits.getHeight() / zoomFactor;

          const left = center.x - newWidth / 2;
          const top = center.y - newHeight / 2;
          const right = center.x + newWidth / 2;
          const bottom = center.y + newHeight / 2;

          const scaledRect = new Rect(left, top, right, bottom);

          // 同步设置两个widget的模型范围
          this._seismicWidget.setModelLimits(scaledRect);
          if (this._seismicWidgetBottom) {
            this._seismicWidgetBottom.setModelLimits(scaledRect);
          }

          // 更新滚动条
          // 外层容器通过宽度放大，产生水平滚动条
          this.zoomScale = Math.min(5, this.zoomScale * zoomFactor);

          // 强制重绘
          this._seismicWidget.invalidate();
          if (this._seismicWidgetBottom) {
            this._seismicWidgetBottom.invalidate();
          }
        }
      } catch (error) {
        console.error('放大失败:', error);
      }
    },

    zoomOut() {
      if (!this._seismicWidget || !this.isWidgetReady) return;

      try {
        const currentLimits = this._seismicWidget.getModelLimits();
        if (currentLimits && !currentLimits.isEmpty()) {
          const center = currentLimits.getCenter();
          const zoomFactor = 1.2;
          const newWidth = currentLimits.getWidth() * zoomFactor;
          const newHeight = currentLimits.getHeight() * zoomFactor;

          const left = center.x - newWidth / 2;
          const top = center.y - newHeight / 2;
          const right = center.x + newWidth / 2;
          const bottom = center.y + newHeight / 2;

          const scaledRect = new Rect(left, top, right, bottom);

          // 同步设置两个widget的模型范围
          this._seismicWidget.setModelLimits(scaledRect);
          if (this._seismicWidgetBottom) {
            this._seismicWidgetBottom.setModelLimits(scaledRect);
          }

          // 更新滚动条
          // 外层容器宽度缩小
          this.zoomScale = Math.max(1, this.zoomScale / zoomFactor);

          // 强制重绘
          this._seismicWidget.invalidate();
          if (this._seismicWidgetBottom) {
            this._seismicWidgetBottom.invalidate();
          }
        }
      } catch (error) {
        console.error('缩小失败:', error);
      }
    },

    async exportToPDF(data) {
      if (!this.plots || !this.isWidgetReady) {
        this.$message.warning('请等待数据加载完成');
        return;
      }

      try {
        // 处理PDF导出逻辑...
        this.$message.success('PDF导出成功');
      } catch (error) {
        console.error('导出PDF时发生错误:', error);
        this.$message.error('导出PDF失败: ' + error.message);
      } finally {
        // 确保无论导出成功还是失败，都关闭弹窗
        this.showPrintDialog = false;
      }
    },

    /**
     * 显示右键菜单
     */
    showContextMenu(event) {
      event.preventDefault();

      // 获取当前活动的工具
      const activeTool = this.pencilTool && this.pencilTool.isEnabled() ? this.pencilTool :
        (this.annotationTool && this.annotationTool.isEnabled() ? this.annotationTool : null);

      // 如果没有活动工具，则不显示菜单
      if (!activeTool) {
        console.log('No active tool');
        return;
      }

      // 获取当前选中的形状
      const currentShape = activeTool.getShape();
      if (!currentShape) {
        console.log('No shape selected');
        return;
      }

      // 获取画布相对于视口的位置
      const rect = this.$refs.plot.getBoundingClientRect();

      // 计算相对于画布的坐标
      this.contextMenu.x = event.clientX - rect.left;
      this.contextMenu.y = event.clientY - rect.top;
      this.contextMenu.visible = true;

      // 记录当前右键菜单使用的工具
      this._contextMenuTool = activeTool;

      console.log('Context menu shown:', {
        x: this.contextMenu.x,
        y: this.contextMenu.y,
        tool: activeTool.getMode(),
        shape: currentShape ? currentShape.getType() : null
      });

      event.stopPropagation();
    },

    /**
     * 隐藏右键菜单
     */
    hideContextMenu() {
      if (this.contextMenu.visible) {
        this.contextMenu.visible = false;
        this._contextMenuTool = null;
        console.log('Context menu hidden');
      }
    },

    /**
     * 检查菜单项是否可用
     */
    isMenuItemEnabled(action) {
      // 获取当前活动的工具
      const tool = this._contextMenuTool;

      if (!tool) return false;

      switch (action) {
        case 'undo':
          // 使用工具的getHistory方法获取历史记录对象
          return tool.getHistory && tool.getHistory() && tool.getHistory().canUndo();
        case 'redo':
          // 使用工具的getHistory方法获取历史记录对象
          return tool.getHistory && tool.getHistory() && tool.getHistory().canRedo();
        case 'copy':
        case 'delete':
          return tool.getShape() != null;
        case 'paste':
          return this.clipboard !== null;
        default:
          return true;
      }
    },

    /**
     * 处理菜单动作
     */
    handleMenuAction(action) {
      if (!this.isMenuItemEnabled(action)) return;

      const tool = this._contextMenuTool;

      if (!tool) {
        this.hideContextMenu();
        return;
      }

      switch (action) {
        case 'undo':
          // 使用工具的undo方法或history对象的undo方法
          if (tool.undo) {
            tool.undo();
          } else if (tool.getHistory && tool.getHistory()) {
            tool.getHistory().undo();
          }
          break;
        case 'redo':
          // 使用工具的redo方法或history对象的redo方法
          if (tool.redo) {
            tool.redo();
          } else if (tool.getHistory && tool.getHistory()) {
            tool.getHistory().redo();
          }
          break;
        case 'copy':
          this.copyShape(tool);
          break;
        case 'paste':
          this.pasteShape();
          break;
        case 'delete':
          this.deleteShape(tool);
          break;
      }

      this.hideContextMenu();
      this.requestRepaint();
    },

    copyShape(tool) {
      const shape = tool.getShape();
      if (!shape) return;

      // 存储形状的克隆
      this.clipboard = Array.isArray(shape) ?
        shape.map(node => node.clone()) :
        [shape.clone()];
    },

    pasteShape() {
      if (!this.clipboard || this.clipboard.length === 0) return;

      // 创建偏移量，以便粘贴的形状不会完全覆盖原始形状
      const offset = 20;

      // 克隆并移动复制的形状
      this.clipboard.forEach(node => {
        const clone = node.clone();

        // 移动克隆的形状
        if (clone.translate) {
          clone.translate(offset, offset);
        }

        // 添加到注释层
        this.annotations.addChild(clone);
      });

      this.requestRepaint();
    },

    deleteShape(tool) {
      const shape = tool.getShape();
      if (!shape) return;

      // 如果是数组，删除所有选中的形状
      if (Array.isArray(shape)) {
        shape.forEach(node => {
          const index = this.annotations.indexOfChild(node);
          if (index >= 0) {
            this.annotations.removeChild(node);
          }
        });
      } else {
        // 删除单个形状
        const index = this.annotations.indexOfChild(shape);
        if (index >= 0) {
          this.annotations.removeChild(shape);
        }
      }

      // 清除工具当前编辑的节点
      tool.editNode(null);

      this.requestRepaint();
    },

    handleKeyDown(event) {
      // 检查是否有活动的工具
      const activeTool = this.pencilTool && this.pencilTool.isEnabled() ? this.pencilTool :
        (this.annotationTool && this.annotationTool.isEnabled() ? this.annotationTool : null);

      if (!activeTool) return;

      // 获取历史记录对象
      const history = activeTool.getHistory && activeTool.getHistory();

      // Ctrl+Z: 撤销
      if (event.ctrlKey && event.key === 'z') {
        if (activeTool.undo) {
          activeTool.undo();
          this.requestRepaint();
          event.preventDefault();
        } else if (history && history.canUndo && history.canUndo()) {
          history.undo();
          this.requestRepaint();
          event.preventDefault();
        }
      }

      // Ctrl+Y: 重做
      else if (event.ctrlKey && event.key === 'y') {
        if (activeTool.redo) {
          activeTool.redo();
          this.requestRepaint();
          event.preventDefault();
        } else if (history && history.canRedo && history.canRedo()) {
          history.redo();
          this.requestRepaint();
          event.preventDefault();
        }
      }

      // Delete: 删除
      else if (event.key === 'Delete') {
        if (activeTool.getShape()) {
          this.deleteShape(activeTool);
          event.preventDefault();
        }
      }
    },

    // 添加一个新方法，用于切换形状的编辑状态
    toggleShapeEditMode(shape) {
      if (!shape) return;

      // 获取活动工具
      const activeTool = this.pencilTool && this.pencilTool.isEnabled() ? this.pencilTool :
        (this.annotationTool && this.annotationTool.isEnabled() ? this.annotationTool : null);

      if (!activeTool) return;

      // 如果当前不是编辑模式，则切换到编辑模式
      if (activeTool.getMode() !== PaintMode.Edit) {
        activeTool.setMode(PaintMode.Edit);
      }

      // 如果当前编辑的不是这个形状，则开始编辑这个形状
      if (activeTool.getShape() !== shape) {
        activeTool.setEditMode(EditMode.EditNode);
        activeTool.editNode(shape);
        this.selectedShape = shape;
      }

      this.requestRepaint();
    },

    getElementIcon(mdiIcon) {
      // 将Vuetify的mdi图标转换为Element UI图标
      const iconMap = {
        'mdi-undo': 'el-icon-refresh-left',
        'mdi-redo': 'el-icon-refresh-right',
        'mdi-content-copy': 'el-icon-document-copy',
        'mdi-content-paste': 'el-icon-document-add',
        'mdi-delete': 'el-icon-delete'
      };

      return iconMap[mdiIcon] || 'el-icon-warning';
    },

    // 添加鼠标悬停相关事件
    initCursorTools() {
      // 实现鼠标悬停相关事件的初始化逻辑
    },

    // 添加鼠标移动处理方法
    handleMouseMove(event) {
      if (!this._seismicWidget || !this.isHovering) return;

      // 使用内置状态栏，不需要额外的处理逻辑
    },

    // 添加保存标注数据的方法
    saveAnnotation(node) {
      if (!node) {
        console.warn('无法保存标注：节点为空');
        return;
      }

      try {
        // 获取文本样式
        const textStyle = node.getTextStyle ? node.getTextStyle() : null;
        let fontSize = 22; // 默认字体大小

        // 从字体字符串中提取字体大小
        if (textStyle && textStyle.getFont) {
          const fontString = textStyle.getFont();
          const fontSizeMatch = fontString.match(/(\d+)px/);
          if (fontSizeMatch) {
            fontSize = parseInt(fontSizeMatch[1], 10);
          }
        }

        // 构建标注数据
        const annotationData = {
          type: node.getType ? node.getType() : 'text',
          text: node.getText ? node.getText() : '',
          properties: node.getProperties(),
          position: {
            x: node.getProperties().ax,
            y: node.getProperties().ay
          },
          styles: {
            textStyle: {
              font: textStyle ? textStyle.getFont() : '',
              color: textStyle ? textStyle.getColor() : '#000000',
              size: fontSize,
              alignment: textStyle ? textStyle.getAlignment() : 'left',
              bold: textStyle ? Boolean(textStyle.getFont().includes('bold')) : false,
              italic: textStyle ? Boolean(textStyle.getFont().includes('italic')) : false
            },
            lineStyle: {
              color: node.getLineStyle ? node.getLineStyle().getColor() : '#000000',
              width: node.getLineStyle ? node.getLineStyle().getWidth() : 1,
              pattern: node.getLineStyle ? node.getLineStyle().getPattern() : []
            },
            fillStyle: {
              color: node.getFillStyle ? node.getFillStyle().getColor() : 'transparent',
              pattern: node.getFillStyle ? node.getFillStyle().getPattern() : 'Solid'
            }
          }
        };

        // 验证数据
        const validation = {
          isValid: Boolean(node && node.getText),
          hasRequiredProperties: Boolean(
            node.getProperties().ax !== undefined &&
            node.getProperties().ay !== undefined
          ),
          hasStyles: Boolean(textStyle && node.getLineStyle && node.getFillStyle)
        };

        console.log('标注数据验证:', validation);

        if (Object.values(validation).every(v => v)) {
          this.savedAnnotations.push(annotationData);
          console.log('标注数据已保存:', {
            data: annotationData,
            totalAnnotations: this.savedAnnotations.length
          });
        } else {
          console.warn('标注数据验证失败:', validation);
        }
      } catch (error) {
        console.error('保存标注数据时出错:', {
          error: error.message,
          stack: error.stack,
          node: node ? {
            type: node.getType ? node.getType() : 'unknown',
            properties: node.getProperties ? node.getProperties() : null
          } : null
        });
      }
    },

    // 添加恢复标注数据的方法
    restoreAnnotations() {
      // 先恢复文本标注
      if (!this.annotations || !this._seismicWidget || !this.savedAnnotations) {
        console.warn('无法恢复标注：缺少必要组件', {
          hasAnnotations: Boolean(this.annotations),
          hasWidget: Boolean(this._seismicWidget),
          hasSavedData: Boolean(this.savedAnnotations),
          savedAnnotationsCount: this.savedAnnotations ? this.savedAnnotations.length : 0
        });
        return;
      }

      try {
        console.log('开始恢复文本标注:', {
          totalAnnotations: this.savedAnnotations.length
        });

        // 恢复文本标注
        this.savedAnnotations.forEach((data, index) => {
          try {
            const textNode = new Text({
              text: data.text || data.properties.text,
              x: data.properties.ax,
              y: data.properties.ay,
              width: data.properties.width || 66,
              height: data.properties.height || 22,
              sizemode: data.properties.sizemode || 5,
              selectable: true,
              movable: true,
              editable: true,
              preserveaspectratio: data.properties.preserveaspectratio || false
            });

            const fullProperties = {
              ...data.properties,
              textstyle: new TextStyle({
                color: data.properties.textstyle.Lx,
                font: data.properties.textstyle.lH,
                alignment: data.properties.textstyle.Vf
              }),
              linestyle: new LineStyle({
                color: data.properties.linestyle.Lx,
                width: data.properties.linestyle.fA,
                pattern: []
              }),
              fillstyle: new FillStyle(data.properties.fillstyle.Lx)
            };

            textNode.setProperties(fullProperties);
            this.annotations.addChild(textNode);

            console.log(`恢复文本标注 ${index + 1}/${this.savedAnnotations.length}:`, {
              text: data.text || data.properties.text,
              position: { x: data.properties.ax, y: data.properties.ay }
            });
          } catch (error) {
            console.error(`恢复文本标注 ${index + 1} 时出错:`, {
              error: error.message,
              annotationData: data
            });
          }
        });

        // 恢复线条标注
        this.restoreLineAnnotations();

        // 强制重绘
        this.requestRepaint();

        // 调整视图以显示所有标注
        if (this._seismicWidget && typeof this._seismicWidget.fitToBounds === 'function') {
          this._seismicWidget.fitToBounds();
        }
      } catch (error) {
        console.error('恢复标注数据时出错:', {
          error: error.message,
          stack: error.stack
        });
      }
    },

    // 添加恢复线条标注的方法
    restoreLineAnnotations() {
      if (!this.annotations || !this._seismicWidget || !this.savedLineAnnotations) {
        console.warn('无法恢复线条标注：缺少必要组件');
        return;
      }

      try {
        console.log('开始恢复线条标注:', {
          totalLines: this.savedLineAnnotations.length
        });

        this.savedLineAnnotations.forEach((data, index) => {
          try {
            // 创建路径对象
            const path = new Path();

            // 使用 moveTo 移动到第一个点
            if (data.properties.x.length > 0) {
              path.moveTo(data.properties.x[0], data.properties.y[0]);

              // 使用 lineTo 连接后续的点
              for (let i = 1; i < data.properties.x.length; i++) {
                path.lineTo(data.properties.x[i], data.properties.y[i]);
              }
            }

            // 设置线条样式
            const lineStyle = new LineStyle({
              color: data.properties.linestyle.Lx || '#0351ad',
              width: data.properties.linestyle.fA || 2,
              pattern: []
            });

            // 设置属性
            path.setProperties({
              linestyle: lineStyle,
              selectable: true,
              movable: true,
              editable: true
            });

            // 添加到标注层
            this.annotations.addChild(path);

            console.log(`恢复线条标注 ${index + 1}/${this.savedLineAnnotations.length}:`, {
              points: data.properties.x.length,
              style: lineStyle,
              bounds: data.bounds
            });
          } catch (error) {
            console.error(`恢复线条标注 ${index + 1} 时出错:`, {
              error: error.message,
              data: data
            });
          }
        });

        // 强制重绘
        this.requestRepaint();

        // 调整视图以显示所有标注
        if (this._seismicWidget && typeof this._seismicWidget.fitToBounds === 'function') {
          this._seismicWidget.fitToBounds();
        }
      } catch (error) {
        console.error('恢复线条标注时出错:', {
          error: error.message,
          stack: error.stack
        });
      }
    },

    // 添加在指定位置创建文本的方法
    createTextAtPosition() {
      if (!this._seismicWidget || !this.annotations) {
        console.warn('Widget or annotations layer not ready');
        return;
      }

      try {
        // 创建文本节点
        const textNode = new Text({
          text: "地震",
          x: 826.370447661679,  // 指定的x坐标
          y: 2.1615720524017465, // 指定的y坐标
          width: 100,
          height: 30,
          sizemode: SizeMode.WrappedWidth,
          selectable: true,
          movable: true,
          editable: true
        });

        // 设置文本样式
        textNode.setProperties({
          'textstyle': new TextStyle({
            color: 'rgba(200, 109, 109, 1)',
            font: 'bold 22px Arial Black',
            alignment: 'left'
          }),
          'linestyle': new LineStyle({
            color: 'rgba(100, 158, 227, 1)',
            width: 3,
            pattern: []
          }),
          'fillstyle': new FillStyle({
            color: 'rgba(30, 70, 102, 1)'
          })
        });

        // 添加到标注层
        this.annotations.addChild(textNode);

        // 强制重绘
        this._seismicWidget.invalidate();

        console.log('文本标注已创建在指定位置');
      } catch (error) {
        console.error('创建文本标注时出错:', error);
      }
    },

    // 添加新的辅助方法
    detectChanges(previousState, currentNode) {
      if (!previousState || !currentNode) return {};

      const changes = {};
      const currentProps = currentNode.getProperties();

      // 检查属性变化
      if (previousState.properties) {
        changes.properties = {};
        for (const key in currentProps) {
          if (JSON.stringify(previousState.properties[key]) !== JSON.stringify(currentProps[key])) {
            changes.properties[key] = {
              from: previousState.properties[key],
              to: currentProps[key]
            };
          }
        }
      }

      // 检查文本样式变化
      if (previousState.textStyle && currentNode.getTextStyle) {
        const currentTextStyle = currentNode.getTextStyle();
        changes.textStyle = {};

        if (previousState.textStyle.font !== currentTextStyle.getFont()) {
          changes.textStyle.font = {
            from: previousState.textStyle.font,
            to: currentTextStyle.getFont()
          };
        }

        if (previousState.textStyle.color !== currentTextStyle.getColor()) {
          changes.textStyle.color = {
            from: previousState.textStyle.color,
            to: currentTextStyle.getColor()
          };
        }

        if (previousState.textStyle.size !== currentTextStyle.size) {
          changes.textStyle.size = {
            from: previousState.textStyle.size,
            to: currentTextStyle.size
          };
        }

        if (previousState.textStyle.alignment !== currentTextStyle.getAlignment()) {
          changes.textStyle.alignment = {
            from: previousState.textStyle.alignment,
            to: currentTextStyle.getAlignment()
          };
        }
      }

      return changes;
    }
  },

  beforeDestroy() {
    // 清理滚动条同步定时器
    this.clearScrollSyncTimer();

    // 清理资源
    if (this.plots) {
      this.plots.dispose();
    }
    if (this.annotationTool) {
      this.annotationTool.dispose();
    }
    if (this.pencilTool) {
      this.pencilTool.dispose();
    }

    if (this.$refs.plot) {
      this.$refs.plot.removeEventListener('contextmenu', this.showContextMenu);
      document.removeEventListener('click', this.hideContextMenu);
      // 移除键盘事件监听
      window.removeEventListener('keydown', this.handleKeyDown);

      // 移除鼠标悬停相关事件
      this.$refs.plot.removeEventListener('mouseenter', () => {
        this.isHovering = true;
      });
      this.$refs.plot.removeEventListener('mouseleave', () => {
        this.isHovering = false;
      });
      this.$refs.plot.removeEventListener('mousemove', this.handleMouseMove);
    }

    if (this.timerInterval) {
      clearTimeout(this.timerInterval);
    }
  }
}
</script>

<style>
/* 双画布容器与滚动/缩放 */
.split-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sync-section {
  width: 100%;
  height: calc(42vh - 20px);
  overflow: auto;
  border: 1px solid #eee;
  background: #fff;
}

.zoom-wrapper {
  width: 100%;
  min-width: 100%;
}

.plot-canvas {
  width: 100% !important;
  height: calc(85vh - 35px) !important;
  margin-top: 20px;
}

.toolbar {
  padding: 10px;
  border-bottom: 1px solid #ddd;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-grow: 1;
}

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-left: auto;
}

/* 统一按钮样式 */
.toolbar .el-button {
  width: 40px;
  height: 40px;
  padding: 10px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 0;
}

.toolbar .el-button [class^="el-icon-"] {
  font-size: 16px;
  margin: 0;
}

.toolbar .el-button:not(.el-button--text) {
  border: 1px solid #ddd;
  background-color: #fff;
}

.toolbar .el-button-group .el-button {
  margin-right: -1px;
}

.toolbar .el-button-group .el-button:first-child {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.toolbar .el-button-group .el-button:last-child {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  margin-right: 0;
}

.toolbar .el-button-group .el-button:not(:first-child):not(:last-child) {
  border-radius: 0;
}

.toolbar .el-button:hover {
  background-color: #e6e6e6;
}

.toolbar .el-button.active {
  background-color: #e6e6e6;
  border-color: #adadad;
  color: #409EFF;
}

/* 鼠标悬停信息面板样式 */
.cursor-info-panel {
  display: none;
}

.cs_status_bar {
  display: none;
}

.info-pill {
  display: none;
}

/* 鼠标悬停覆盖层样式 */
.hover-layer {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  cursor: crosshair;
  background-color: transparent;
  pointer-events: none;
}

/* 样式面板相关样式 */
.style-panel {
  position: fixed;
  right: -300px;
  top: 0;
  width: 300px;
  height: 100vh;
  background-color: #fff;
  box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
  transition: right 0.3s ease;
  z-index: 1000;
  overflow-y: auto;
}

.style-panel-visible {
  right: 0;
}

.style-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  border-bottom: 1px solid #ddd;
}

.style-panel-header h3 {
  margin: 0;
  font-size: 16px;
}

.style-content {
  padding: 15px;
}

.style-section-title {
  font-weight: bold;
  margin: 10px 0;
  color: #333;
}

.style-item {
  margin-bottom: 15px;
}

.style-label {
  display: block;
  margin-bottom: 5px;
  color: #666;
}

.style-divider {
  height: 1px;
  background-color: #eee;
  margin: 15px 0;
}

.text-style-buttons {
  display: flex;
  gap: 5px;
}

.pattern-preview-fill {
  width: 100%;
  height: 24px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

/* 调整滑块和输入框的样式 */
.el-slider {
  margin-top: 8px;
}

.el-input-number {
  width: 100%;
}

.el-select {
  width: 100%;
}

.el-color-picker {
  width: 100%;
}

/* 添加错误和加载状态样式 */
.error-message {
  color: red;
  padding: 10px;
  margin: 10px;
  background-color: #fff3f3;
  border: 1px solid #ffa7a7;
  border-radius: 4px;
}

.loading-message {
  text-align: center;
  padding: 20px;
  color: #666;
}

.color-maps {
  margin-right: 10px;
}

.color-maps .el-select {
  width: 140px;
}

.color-maps-label {
  margin-right: 8px;
  font-size: 14px;
  color: #666;
}

.toolbar-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.is-active {
  background-color: #e6e6e6;
  border-color: #adadad;
}

.context-menu {
  position: fixed;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  z-index: 1001;
  padding: 5px 0;
}

.context-menu-separator {
  height: 1px;
  background-color: #eee;
  margin: 5px 0;
}

.context-menu-item {
  padding: 8px 16px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 14px;
  color: #333;
}

.context-menu-item:hover {
  background-color: #f5f5f5;
}

.context-menu-item.disabled {
  color: #999;
  cursor: not-allowed;
}

.context-menu-item.disabled:hover {
  background-color: transparent;
}

.shortcut {
  font-size: 12px;
  color: #999;
  margin-left: 16px;
}

.pattern-preview-line {
  width: 100%;
  height: 20px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

/* 响应式布局调整 */
@media (max-width: 768px) {
  .toolbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .toolbar-left,
  .toolbar-right {
    width: 100%;
    margin: 5px 0;
  }

  .toolbar-right {
    margin-top: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }

  .color-maps {
    margin-right: 0;
  }
}

.color-map-option {
  display: flex;
  align-items: center;
  gap: 8px;
}

.color-map-preview {
  width: 40px;
  height: 20px;
  border: 1px solid #ddd;
  border-radius: 2px;
}

.WhiteBlack {
  background: linear-gradient(to right, white, black);
}

.CustomGrayScale {
  background: linear-gradient(to right,
      rgb(255, 255, 255) 50%,
      /* -4000到181保持白色 */
      rgb(253, 253, 253) 55%,
      /* 181开始的颜色 */
      rgb(240, 240, 240) 65%,
      /* 到566的颜色 */
      rgb(180, 180, 180) 80%,
      /* 566后的过渡色 */
      rgb(6, 6, 6) 100%
      /* 最终颜色 */
    );
}

.CustomRedScale {
  background: linear-gradient(to right, #F62814, #DD8B66, #D7C692, #FBFAFF, #6E6E8A, #323136);
}

.BlueWhiteRed {
  background: linear-gradient(to right, #0000FF, #FFFFFF, #FF0000);
}

.Rainbow {
  background: linear-gradient(to right, #FF0000, #FFFF00, #00FF00, #00FFFF, #0000FF, #FF00FF, #FF0000);
}

.Jet {
  background: linear-gradient(to right, #00008F, #0000FF, #00FFFF, #00FF00, #FFFF00, #FF7F00, #FF0000, #7F0000);
}

.Hot {
  background: linear-gradient(to right, #000000, #FF0000, #FFFF00, #FFFFFF);
}

.Cool {
  background: linear-gradient(to right, #00FFFF, #FF00FF);
}

/* 在style标签中添加 */
.cs_status_bar {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cs_status_bar section {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 状态栏样式优化 */
.cs_status_bar {
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
  font-size: 12px !important;
  font-family: monospace !important;
}

.cs_status_bar section {
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
  padding: 0 5px !important;
  max-width: 120px !important;
}

.cs_status_bar section span {
  display: inline-block !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
  max-width: 100% !important;
}

/* 确保状态栏容器不会过度扩展 */
.gt-statusbar {
  max-width: 100% !important;
  overflow: hidden !important;
}

.gt-statusbar-section {
  max-width: 120px !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}

/* 状态栏样式 */
.gt-statusbar {
  font-family: monospace !important;
  font-size: 12px !important;
  background-color: #f5f5f5 !important;
  border-top: 1px solid #ddd !important;
  height: 25px !important;
  line-height: 25px !important;
  padding: 0 10px !important;
}

.gt-statusbar-section {
  display: inline-block !important;
  margin-right: 15px !important;
  min-width: 80px !important;
  max-width: 80px !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}

.gt-statusbar-section:last-child {
  margin-right: 0 !important;
}
</style>
