<template>
    <div class="chart-container">
        <div id="mainzftdj" class="chart" ref="chartRef"></div>
        <div v-if="loading" class="loading-overlay">
            <div class="loading-spinner"></div>
            <span>加载中...</span>
        </div>
    </div>
</template>

<script>
import * as echarts from "echarts";
import { getdjZft } from "@/api/optimization/initialization";
import { text } from "d3";

export default {
    name: "HistogramGraph",
    props: {
        jh: {
            type: String,
            default: "",
        },
        jhs: {
            type: String,
            default: ''
        },
        // 美化配置选项
        theme: {
            type: String,
            default: "modern", // modern, elegant, vibrant
            validator: value => ["modern", "elegant", "vibrant"].includes(value)
        }
    },
    data() {
        return {
            mockData: {},
            myChart: null,
            initRetryCount: 0,
            maxRetryCount: 5,
            resizeObserver: null,
            loading: false,
            debounceTimer: null,
            lastStackedAreas: null,
            lastChartConfig: null,
            lastXAxisLabels: null,
            lastDepthIntervals: null,
            currentGraphicElements: [],
        };
    },
    computed: {
        // 根据主题获取颜色配置
        colorScheme() {
            const schemes = {
                modern: {
                    primary: "#3B82F6",
                    secondary: "#10B981",
                    accent: "#F59E0B",
                    background: "#F8FAFC",
                    text: "#1F2937",
                    border: "#E5E7EB",
                    gradient: {
                        start: "#3B82F6",
                        end: "#1D4ED8"
                    }
                },
                elegant: {
                    primary: "#6366F1",
                    secondary: "#8B5CF6",
                    accent: "#EC4899",
                    background: "#FAFAFA",
                    text: "#374151",
                    border: "#D1D5DB",
                    gradient: {
                        start: "#6366F1",
                        end: "#4F46E5"
                    }
                },
                vibrant: {
                    primary: "#EF4444",
                    secondary: "#06B6D4",
                    accent: "#F97316",
                    background: "#FEFEFE",
                    text: "#111827",
                    border: "#F3F4F6",
                    gradient: {
                        start: "#EF4444",
                        end: "#DC2626"
                    }
                }
            };
            return schemes[this.theme];
        }
    },
    watch: {
        jh: {
            handler(newVal) {
                // 不自动刷新，等待父级触发 loadData
            },
            immediate: false
        }
    },
    mounted() {
        // 初始化空图表，不拉数据；等待父组件触发 loadData
        this.initChart();
        this.setupEventListeners();
    },
    beforeDestroy() {
        this.cleanup();
    },
    methods: {
        // 初始化图表
        async initChart() {
            try {
                this.loading = true;

                const chartDom = this.$refs.chartRef;
                if (!chartDom) {
                    throw new Error("未找到图表容器 DOM");
                }

                this.setChartDimensions(chartDom);

                // 重试机制优化
                if (this.shouldRetry()) {
                    this.scheduleRetry();
                    return;
                }

                this.resetRetryCount();
                this.disposeChart();
                this.createChart(chartDom);

                const mockData = await this.getList();
                if (!this.hasValidData(mockData)) {
                    this.renderEmpty(chartDom);
                    return;
                }

                await this.renderRealData(mockData);

            } catch (error) {
                console.error("图表初始化失败:", error);
                this.handleError(error);
            } finally {
                this.loading = false;
            }
        },

        // 设置图表尺寸
        setChartDimensions(chartDom) {
            const viewportWidth = window.innerWidth;
            const viewportHeight = window.innerHeight;
            const availableHeight = viewportHeight - 120;
            const availableWidth = viewportWidth - 80;
            chartDom.style.width = `${availableWidth}px`;
            chartDom.style.height = `${availableHeight}px`;
            chartDom.offsetHeight; // 强制重排
        },

        // 检查是否需要重试
        shouldRetry() {
            const viewportWidth = window.innerWidth;
            const viewportHeight = window.innerHeight;
            const availableHeight = viewportHeight - 120;
            const availableWidth = viewportWidth - 80;
            return (availableWidth <= 0 || availableHeight <= 0) && this.initRetryCount < this.maxRetryCount;
        },

        // 安排重试
        scheduleRetry() {
            this.initRetryCount++;
            setTimeout(() => this.initChart(), 500);
        },
        // 重置重试计数
        resetRetryCount() {
            this.initRetryCount = 0;
        },
        // 销毁图表
        disposeChart() {
            if (this.myChart) {
                this.myChart.dispose();
            }
        },
        // 创建图表实例
        createChart(chartDom) {
            this.myChart = echarts.init(chartDom, null, {
                renderer: 'canvas',
                useDirtyRect: true
            });
        },
        // 检查数据有效性
        hasValidData(mockData) {
            return mockData &&
                mockData.wellData &&
                mockData.wellData.depthLine &&
                mockData.wellData.depthLine.length > 0;
        },
        // 设置事件监听器
        setupEventListeners() {
            window.addEventListener("resize", this.handleResize);
            this.observeParentResize();
        },
        // 清理资源
        cleanup() {
            window.removeEventListener("resize", this.handleResize);
            if (this.myChart) {
                this.myChart.dispose();
            }
            if (this.resizeObserver) {
                this.resizeObserver.disconnect();
            }
            if (this.debounceTimer) {
                clearTimeout(this.debounceTimer);
            }
        },
        // 观察父容器大小变化
        observeParentResize() {
            const parentDom = this.$refs.chartRef?.parentElement;
            if (parentDom && window.ResizeObserver) {
                this.resizeObserver = new ResizeObserver(() => {
                    this.debouncedResize();
                });
                this.resizeObserver.observe(parentDom);
            }
        },

        // 获取数据
        async getList() {
            try {
                const res = await getdjZft({
                    jhs: `${this.jh},${this.jhs}`
                });
                this.mockData = res?.mockData || {};
                return this.mockData;
            } catch (error) {
                console.error("获取数据失败:", error);
                throw error;
            }
        },
        // 供父组件在切换到本tab时调用
        async loadData() {
            await this.initChart();
        },

        // 处理窗口大小变化
        handleResize() {
            this.debouncedResize();
        },

        // 防抖处理resize
        debouncedResize() {
            if (this.debounceTimer) {
                clearTimeout(this.debounceTimer);
            }
            this.debounceTimer = setTimeout(() => {
                this.performResize();
            }, 200);
        },

        // 执行resize操作
        performResize() {
            if (this.myChart) {
                const chartDom = this.$refs.chartRef;
                if (chartDom) {
                    this.setChartDimensions(chartDom);
                }
                this.myChart.resize();
                if (this.lastStackedAreas && this.lastChartConfig && this.lastXAxisLabels) {
                    this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
                }
                if (this.lastDepthIntervals && this.lastXAxisLabels && this.lastChartConfig) {
                    this.drawJhSeparators(this.lastDepthIntervals, this.lastXAxisLabels, this.lastChartConfig);
                }
                if (this.lastXAxisLabels && this.lastChartConfig) {
                    this.drawCategoryEdgeLines(this.lastXAxisLabels, this.lastChartConfig);
                    this.drawTopBandSvg(this.lastXAxisLabels, this.lastChartConfig, this.lastStackedAreas);
                }
            }
        },

        // 刷新图表
        async refreshChart() {
            if (this.myChart) {
                await this.initChart();
            }
        },

        // 渲染真实数据
        async renderRealData(mockData) {
            try {
                const { wellData } = mockData;
                console.log(wellData, 'wellData');
                // 调试信息：打印深度区间数据
                if (wellData.depthIntervals && wellData.depthIntervals.length > 0) {
                    console.log('深度区间数据:', wellData.depthIntervals.map(item => ({
                        井号: item.jh,
                        型号: item.x,
                        尺寸: item.ztcc,
                        进尺: item.jc,
                        深度区间: item.interval,
                        占位: item.placeholder,
                        计算高度: item.jc !== undefined && item.jc !== null ? item.jc : (item.interval - item.placeholder)
                    })));
                }
                const xAxisLabels = wellData.depthLine.map((point) => point.x);
                try { window.__hist_xLabels = xAxisLabels; } catch (e) { }
                const option = {
                    ...this.getDefaultChartOption(),
                    xAxis: this.createXAxis(xAxisLabels),
                    yAxis: this.createYAxis(mockData.chartConfig),
                    series: this.createSeries(wellData)
                };
                this.myChart.setOption(option, true);
                // 确保图表完全渲染后再resize
                this.$nextTick(() => {
                    this.myChart.resize();
                    this.lastStackedAreas = wellData.stackedAreas;
                    this.lastChartConfig = mockData.chartConfig;
                    this.lastXAxisLabels = xAxisLabels;
                    this.drawStratumLabels(this.lastStackedAreas, this.lastChartConfig, this.lastXAxisLabels);
                    this.lastDepthIntervals = wellData.depthIntervals || [];
                    this.drawJhSeparators(this.lastDepthIntervals, this.lastXAxisLabels, this.lastChartConfig);
                    // 在顶部为每个类目绘制左右两条短竖线
                    this.drawCategoryEdgeLines(this.lastXAxisLabels, this.lastChartConfig);
                    // 顶部段内根据 x 和 y2 渲染 SVG 纹理
                    this.drawTopBandSvg(this.lastXAxisLabels, this.lastChartConfig, this.lastStackedAreas);
                });
            } catch (error) {
                console.error("渲染数据失败:", error);
                this.handleError(error);
            }
        },
        // 获取默认图表配置
        getDefaultChartOption() {
            const colors = this.colorScheme;
            return {
                title: { text: "", subtext: "" },
                aria: { enabled: false },
                backgroundColor: colors.background,
                tooltip: {
                    trigger: "axis",
                    axisPointer: {
                        type: "cross",
                        label: { backgroundColor: colors.primary },
                        crossStyle: { color: colors.border }
                    },
                    backgroundColor: 'rgba(255,255,255,0.95)',
                    borderColor: colors.border,
                    borderWidth: 1,
                    textStyle: { color: colors.text },
                    extraCssText: 'box-shadow: 0 4px 12px rgba(0,0,0,0.15); border-radius: 8px;',
                    formatter: (params) => {
                        if (!params || params.length === 0) return '';
                        const dataIndex = params[0].dataIndex;
                        const depthInterval = this.mockData?.wellData?.depthIntervals?.[dataIndex];
                        if (!depthInterval) {
                            // 如果没有depthInterval数据，使用默认格式
                            let result = `<div style="font-weight: 600; margin-bottom: 8px; color: ${colors.primary};">${params[0].axisValue}</div>`;
                            params.forEach(param => {
                                const color = param.color;
                                result += `<div style="margin: 4px 0;">
                                    <span style="display: inline-block; width: 10px; height: 10px; background-color: ${color}; border-radius: 50%; margin-right: 8px;"></span>
                                    <span style="font-weight: 500;">${param.seriesName}:</span>
                                    <span style="margin-left: 8px; font-weight: 600;">${param.value}</span>
                                </div>`;
                            });
                            return result;
                        }
                        // 显示井号信息
                        let result = `<div style="font-weight: 600; margin-bottom: 8px; color: ${colors.primary};">${depthInterval.jh || depthInterval.x}</div>`;

                        // 计算深度区间显示
                        const startDepth = depthInterval.placeholder || 0;
                        const height = depthInterval.jc !== undefined && depthInterval.jc !== null
                            ? depthInterval.jc
                            : (depthInterval.interval - depthInterval.placeholder);
                        const endDepth = startDepth + height;
                        const depthRange = `${startDepth}-${endDepth}`;

                        // 显示详细信息
                        result += `<div style="margin: 4px 0; padding: 4px 0; border-top: 1px solid ${colors.border};">
                            <div style="margin: 2px 0;"><span style="font-weight: 500;">型号:</span> <span style="margin-left: 8px; font-weight: 600;">${depthInterval.x || '-'}</span></div>
                            <div style="margin: 2px 0;"><span style="font-weight: 500;">尺寸mm:</span> <span style="margin-left: 8px; font-weight: 600;">${depthInterval.ztcc || '-'}</span></div>
                            <div style="margin: 2px 0;"><span style="font-weight: 500;">进尺m:</span> <span style="margin-left: 8px; font-weight: 600;">${depthInterval.jc !== undefined && depthInterval.jc !== null ? depthInterval.jc : (depthInterval.interval - depthInterval.placeholder)}</span></div>
                            <div style="margin: 2px 0;"><span style="font-weight: 500;">深度区间:</span> <span style="margin-left: 8px; font-weight: 600;">${depthRange}</span></div>
                        </div>`;
                        // 只显示非地层信息的系列数据（过滤掉地层相关的系列）
                        // params.forEach(param => {
                        //     // 过滤掉地层相关的系列名称
                        //     if (param.seriesName && !param.seriesName.includes('地层') && param.seriesName !== '占位') {
                        //         const color = param.color;
                        //         result += `<div style="margin: 4px 0;">
                        //             <span style="display: inline-block; width: 10px; height: 10px; background-color: ${color}; border-radius: 50%; margin-right: 8px;"></span>
                        //             <span style="font-weight: 500;">${param.seriesName}:</span>
                        //             <span style="margin-left: 8px; font-weight: 600;">${param.value}</span>
                        //         </div>`;
                        //     }
                        // });

                        return result;
                    }
                },
                grid: {
                    top: 10,
                    left: "4%",
                    right: "4%",
                    bottom: "10%",
                    containLabel: true,
                    show: false,
                },
                animation: true,
                animationDuration: 1500,
                animationEasing: 'cubicOut',
                animationDelay: function (idx) {
                    return idx * 100;
                }
            };
        },

        // 处理区域系列
        async processAreaSeries(wellData, xAxisLabels) {
            const stackedAreas = wellData?.stackedAreas || [];
            // 兼容旧格式：数组（所有井已按全局顺序平铺）
            if (Array.isArray(stackedAreas)) {
                return await Promise.all(
                    stackedAreas
                        .filter(area => area.svg !== null)
                        .map(async (area) => {
                            let areaStyle = { opacity: 0.25 };  // 降低透明度，确保柱状图和折线图可见
                            if (area.svg) {
                                try {
                                    const svgImage = await this.createSvgImage(area.svg);
                                    areaStyle.color = { image: svgImage, repeat: "repeat" };
                                } catch (error) {
                                    console.error('SVG转换失败:', error);
                                }
                            }
                            return {
                                name: area.name,
                                type: "line",
                                xAxisIndex: 1,
                                z: -10,
                                zlevel: -1,
                                stack: "总量",
                                symbol: "none",
                                showSymbol: false,
                                areaStyle: areaStyle,
                                lineStyle: { width: 0 },
                                data: area.points.map((point) => (point && point.y2 != null) ? point.y2 : point.y),
                            };
                        })
                );
            }
            // 新格式：对象，key 为井号，每口井内是该井的地层数组
            const totalLen = Array.isArray(xAxisLabels) ? xAxisLabels.length : 0;
            console.log(totalLen, 'totalLen');
            // 全局 x 标签 -> 索引数组 映射
            const xToIndices = new Map();
            console.log(xToIndices, 'xToIndices');
            (xAxisLabels || []).forEach((x, idx) => {
                const key = String(x);
                if (!xToIndices.has(key)) xToIndices.set(key, []);
                xToIndices.get(key).push(idx);
            });
            const buildNullArray = (len) => Array.from({ length: len }, () => null);
            console.log(buildNullArray, 'buildNullArray');
            const results = [];
            for (const [jh, layers] of Object.entries(stackedAreas)) {
                if (!Array.isArray(layers) || layers.length === 0) continue;
                // 估算该井的横向覆盖范围：取该井所有层的所有点对应的全局索引的 min/max
                const indicesForJh = [];
                const missingInXAxis = [];
                for (const area of layers) {
                    for (const p of (area?.points || [])) {
                        const arr = xToIndices.get(String(p?.x)) || [];
                        if (arr.length === 0) {
                            missingInXAxis.push({ x: p?.x, jh, areaName: area?.name });
                        } else {
                            indicesForJh.push(...arr);
                        }
                    }
                }
                const startIdx = Math.min(...indicesForJh);
                const endIdx = Math.max(...indicesForJh);
                for (const area of (layers || [])) {
                    if (area == null) continue;
                    let areaStyle = { opacity: 0.25 };  // 降低透明度，确保柱状图和折线图可见
                    if (area.svg) {
                        try {
                            const svgImage = await this.createSvgImage(area.svg);
                            areaStyle.color = { image: svgImage, repeat: "repeat" };
                        } catch (error) {
                            console.error('SVG转换失败:', error);
                        }
                    }
                    const data = buildNullArray(totalLen);
                    // 把该层每个点的 y2/y 填到该点 x 对应的全局索引中，仅限落在该井的覆盖范围内
                    const outOfRangePoints = [];
                    for (const p of (area.points || [])) {
                        const yVal = (p && p.y2 != null) ? p.y2 : p?.y;
                        const cands = xToIndices.get(String(p?.x)) || [];
                        if (cands.length === 0) continue;
                        let placed = false;
                        cands.forEach(ix => {
                            if (ix >= startIdx && ix <= endIdx) {
                                data[ix] = yVal;
                                placed = true;
                            }
                        });
                        if (!placed) {
                            outOfRangePoints.push({ x: p?.x, cands, jh, areaName: area?.name, startIdx, endIdx });
                        }
                    }
                    results.push({
                        name: area.name,
                        type: "line",
                        xAxisIndex: 1,
                        z: -10,
                        zlevel: -1,
                        stack: "总量",
                        symbol: "none",
                        showSymbol: false,
                        areaStyle: areaStyle,
                        lineStyle: { width: 0 },
                        data
                    });
                    // 仅在有异常时输出调试信息，方便定位 x 匹配问题
                    if (missingInXAxis.length > 0 || outOfRangePoints.length > 0) {
                        // 使用 console.group 让日志更清晰
                        console.groupCollapsed && console.groupCollapsed(`层定位告警: 井号=${jh}`);
                        if (missingInXAxis.length > 0) {
                            console.warn('x 不在 xAxisLabels 中:', missingInXAxis);
                        }
                        if (outOfRangePoints.length > 0) {
                            console.warn('x 命中但不在井段范围内:', outOfRangePoints);
                            console.info('井段范围:', { jh, startIdx, endIdx });
                        }
                        console.groupEnd && console.groupEnd();
                    }
                }
            }
            return results;
        },
        // 创建X轴配置
        createXAxis(xAxisLabels) {
            const colors = this.colorScheme;
            return [
                {
                    type: "category",
                    boundaryGap: true,
                    position: "top",
                    data: xAxisLabels,
                    axisLabel: {
                        interval: 0,
                        rotate: 0,
                        margin: 12,
                        align: "center",
                        fontSize: 13,
                        color: colors.text,
                        fontWeight: 500
                    },
                    axisTick: {
                        alignWithLabel: true,
                        length: 6,
                        lineStyle: { color: colors.border }
                    },
                    splitLine: { show: false },
                    axisLine: {
                        show: true,
                        lineStyle: {
                            color: colors.border,
                            width: 2
                        }
                    }
                },
                {
                    type: "category",
                    boundaryGap: false,
                    position: "top",
                    show: false,
                    data: xAxisLabels
                },
            ];
        },
        // 创建Y轴配置
        createYAxis(chartConfig) {
            const colors = this.colorScheme;
            return [
                {
                    type: "value",
                    name: "井深(m)",
                    nameTextStyle: {
                        color: colors.text,
                        fontSize: 13,
                        fontWeight: 600,
                        padding: [0, 0, 0, 8]
                    },
                    min: chartConfig.yAxis.min,
                    max: chartConfig.yAxis.max,
                    interval: chartConfig.yAxis.interval,
                    inverse: true,
                    axisLabel: {
                        formatter: "{value}",
                        fontSize: 12,
                        color: colors.text,
                        fontWeight: 500
                    },
                    splitLine: {
                        show: true,
                        lineStyle: {
                            color: colors.border,
                            type: 'dashed',
                            opacity: 0.3
                        }
                    },
                    axisLine: {
                        show: true,
                        lineStyle: {
                            color: colors.border,
                            width: 2
                        }
                    },
                    axisTick: {
                        show: true,
                        lineStyle: { color: colors.border }
                    }
                },
                {
                    type: "value",
                    name: "深度(m)",
                    nameTextStyle: {
                        color: colors.text,
                        fontSize: 13,
                        fontWeight: 600,
                        padding: [0, 8, 0, 0]
                    },
                    min: chartConfig.yAxis2.min,
                    max: chartConfig.yAxis2.max,
                    interval: chartConfig.yAxis2.interval,
                    position: "right",
                    axisLabel: {
                        formatter: "{value}",
                        fontSize: 12,
                        color: colors.text,
                        fontWeight: 500
                    },
                    splitLine: { show: false },
                    axisLine: {
                        show: true,
                        lineStyle: {
                            color: colors.border,
                            width: 2
                        }
                    },
                    axisTick: {
                        show: true,
                        lineStyle: { color: colors.border }
                    }
                },
            ];
        },
        // 创建系列配置
        createSeries(wellData, areaSeries) {
            const colors = this.colorScheme;
            return [
                {
                    name: "井深数据",
                    type: "line",
                    yAxisIndex: 1,
                    z: 10,
                    zlevel: 0,
                    symbol: "circle",
                    symbolSize: 10,
                    itemStyle: {
                        color: colors.accent,
                        borderColor: '#fff',
                        borderWidth: 3,
                        shadowColor: 'rgba(0,0,0,0.2)',
                        shadowBlur: 8
                    },
                    lineStyle: {
                        color: colors.accent,
                        width: 3,
                        type: 'solid',
                        shadowColor: 'rgba(0,0,0,0.1)',
                        shadowBlur: 4
                    },
                    label: {
                        show: true,
                        position: "top",
                        formatter: "{c}",
                        fontSize: 13,
                        fontWeight: 600,
                        color: colors.accent,
                        backgroundColor: "rgba(255,255,255,0.95)",
                        padding: [6, 8],
                        borderRadius: 6,
                        borderColor: colors.accent,
                        borderWidth: 2,
                        shadowColor: 'rgba(0,0,0,0.1)',
                        shadowBlur: 4
                    },
                    data: wellData.depthLine.map((point) => point.y),
                },
                {
                    name: "占位",
                    type: "bar",
                    stack: "total",
                    z: 5,
                    zlevel: 0,
                    silent: true,
                    barWidth: "8%",
                    itemStyle: {
                        borderColor: "transparent",
                        color: "transparent"
                    },
                    emphasis: {
                        itemStyle: {
                            borderColor: "transparent",
                            color: "transparent"
                        }
                    },
                    data: wellData.depthIntervals.map((item) => item.placeholder),
                },
                {
                    name: "深度区间",
                    type: "bar",
                    stack: "total",
                    z: 5,
                    zlevel: 0,
                    barWidth: "6%",
                    label: {
                        show: true,
                        position: 'insideTop',
                        color: '#fff',
                        fontSize: 11,
                        fontWeight: 600,
                        backgroundColor: 'rgba(0,0,0,0.1)',
                        padding: [2, 3],
                        borderRadius: 4,
                        borderColor: 'rgba(255,255,255,0.3)',
                        borderWidth: 1,
                        formatter: (params) => {
                            const di = wellData.depthIntervals[params.dataIndex];
                            return di && di.ztcc !== undefined ? di.ztcc : params.data;
                        }
                    },
                    itemStyle: {
                        color: {
                            type: 'linear',
                            x: 0,
                            y: 0,
                            x2: 0,
                            y2: 1,
                            colorStops: [
                                { offset: 0, color: colors.gradient.start },
                                { offset: 1, color: colors.gradient.end }
                            ]
                        },
                        borderRadius: [4, 4, 0, 0],
                        shadowColor: 'rgba(0,0,0,0.2)',
                        shadowBlur: 8,
                        shadowOffsetY: 2
                    },
                    emphasis: {
                        itemStyle: {
                            color: {
                                type: 'linear',
                                x: 0,
                                y: 0,
                                x2: 0,
                                y2: 1,
                                colorStops: [
                                    { offset: 0, color: this.adjustColor(colors.gradient.start, 1.2) },
                                    { offset: 1, color: this.adjustColor(colors.gradient.end, 1.2) }
                                ]
                            },
                            shadowBlur: 12,
                            shadowOffsetY: 4
                        }
                    },
                    // 使用 jc（进尺）作为柱子的高度，如果没有 jc 则使用 interval - placeholder 计算
                    data: wellData.depthIntervals.map((item) => {
                        // 优先使用 jc（进尺），如果没有则计算 interval - placeholder
                        return item.jc !== undefined && item.jc !== null ? item.jc : (item.interval - item.placeholder);
                    }),
                },
                // 底部显示 placeholder 数值的透明条，用于放置底部标签
                {
                    name: '深度区间-底部标签',
                    type: 'bar',
                    z: 5,
                    zlevel: 0,
                    barGap: '-100%',
                    barWidth: '6%',
                    itemStyle: { color: 'transparent', borderColor: 'transparent' },
                    emphasis: { itemStyle: { color: 'transparent', borderColor: 'transparent' } },
                    label: {
                        show: true,
                        position: 'insideBottom',
                        color: '#fff',
                        fontSize: 11,
                        fontWeight: 600,
                        backgroundColor: 'rgba(0,0,0,0.1)',
                        padding: [2, 3],
                        borderRadius: 4,
                        borderColor: 'rgba(255,255,255,0.3)',
                        borderWidth: 1,
                        distance: 0,
                        formatter: (params) => {
                            const di = wellData.depthIntervals[params.dataIndex];
                            // 显示深度区间，格式为：开始深度-结束深度 或 interval值
                            if (di && di.placeholder !== undefined && di.jc !== undefined) {
                                const endDepth = di.placeholder + (di.jc !== null ? di.jc : (di.interval - di.placeholder));
                                return `${di.placeholder}-${endDepth}`;
                            }
                            return di && di.interval !== undefined ? di.interval : params.data;
                        }
                    },
                    // 使用相同的计算方式，确保标签位置正确
                    data: wellData.depthIntervals.map((item) => {
                        return item.jc !== undefined && item.jc !== null ? item.jc : (item.interval - item.placeholder);
                    })
                }
            ];
        },

        // 颜色调整工具方法
        adjustColor(color, factor) {
            if (color.startsWith('#')) {
                const r = parseInt(color.slice(1, 3), 16);
                const g = parseInt(color.slice(3, 5), 16);
                const b = parseInt(color.slice(5, 7), 16);
                const newR = Math.min(255, Math.round(r * factor));
                const newG = Math.min(255, Math.round(g * factor));
                const newB = Math.min(255, Math.round(b * factor));
                return `rgb(${newR}, ${newG}, ${newB})`;
            }
            return color;
        },
        // 渲染空状态
        renderEmpty(chartDom) {
            const colors = this.colorScheme;
            chartDom.innerHTML = `
                <div class="empty-state" style="
                    width: 100%; 
                    height: 100%; 
                    display: flex; 
                    flex-direction: column;
                    align-items: center; 
                    justify-content: center; 
                    color: ${colors.text};
                    font-size: 16px;
                    background: ${colors.background};
                    border-radius: 12px;
                    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
                ">
                    <div style="
                        font-size: 48px; 
                        margin-bottom: 16px; 
                        opacity: 0.6;
                        color: ${colors.primary};
                    ">📊</div>
                    <div style="
                        font-size: 18px; 
                        color: ${colors.text};
                        font-weight: 500;
                    ">暂无数据</div>
                    <div style="
                        font-size: 14px; 
                        color: ${colors.text};
                        opacity: 0.6;
                        margin-top: 8px;
                    ">请检查数据配置</div>
                </div>
            `;
        },

        // 处理错误
        handleError(error) {
            console.error("图表错误:", error);
        },

        // 创建SVG图片
        createSvgImage(svgString) {
            return new Promise((resolve, reject) => {
                const svgBlob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });
                const svgUrl = URL.createObjectURL(svgBlob);
                const img = new Image();
                img.onload = () => {
                    URL.revokeObjectURL(svgUrl);
                    resolve(img);
                };
                img.onerror = (e) => {
                    URL.revokeObjectURL(svgUrl);
                    reject(e);
                };
                img.src = svgUrl;
            });
        },

        // 使用像素坐标绘制地层标签（每口井的每个地层都标注名称）
        drawStratumLabels(stackedAreas, chartConfig, xAxisLabels) {
            if (!this.myChart || !stackedAreas) return;

            // 清空当前 graphic
            this.myChart.setOption({ graphic: { elements: [] } });

            const graphics = [];
            const depthIntervals = this.mockData?.wellData?.depthIntervals || [];

            // 如果为老格式（全局数组），保持原有从右侧标注的策略
            if (Array.isArray(stackedAreas)) {
                if (stackedAreas.length === 0) return;
                let currentDepth = chartConfig.yAxis.min;
                const lastXIndex = Math.max(0, (xAxisLabels?.length || 1) - 1);
                const xOffset = 16;
                stackedAreas.forEach((area) => {
                    if (!area || !area.points || area.points.length === 0) return;
                    let thickness;
                    let centerDepth;
                    if (area.sjdjsd != null && area.sjhd != null) {
                        // 业务规则：当 sjdjsd 等于 sjhd 时，厚度即为 sjdjsd 本身，从 0 到 sjdjsd
                        if (Number(area.sjdjsd) === Number(area.sjhd)) {
                            thickness = Number(area.sjdjsd);
                            centerDepth = thickness / 2;
                        } else {
                            thickness = Math.abs(Number(area.sjdjsd) - Number(area.sjhd));
                            centerDepth = (Number(area.sjdjsd) + Number(area.sjhd)) / 2;
                        }
                    } else {
                        const p0 = area.points[0];
                        const y = Number(p0?.y);
                        const y2 = p0?.y2 != null ? Number(p0.y2) : null;
                        if (y2 != null && y2 === y) {
                            // y2 即为厚度，从 0 到 y2
                            thickness = y2;
                            centerDepth = thickness / 2;
                        } else if (y2 != null && !Number.isNaN(y)) {
                            thickness = Math.abs(y2 - y);
                            centerDepth = (y2 + y) / 2;
                        } else if (!Number.isNaN(y)) {
                            thickness = y;
                            centerDepth = thickness / 2;
                        } else {
                            thickness = 0;
                            centerDepth = chartConfig?.yAxis?.min || 0;
                        }
                    }
                    const pixelRight = this.myChart.convertToPixel({ xAxisIndex: 0, yAxisIndex: 0 }, [lastXIndex, centerDepth]);
                    if (!pixelRight || !Array.isArray(pixelRight) || pixelRight.length < 2) return;
                    const [pxRight, py] = pixelRight;
                    graphics.push({
                        type: 'text',
                        position: [pxRight + xOffset, py],
                        style: {
                            text: area.name,
                            fontSize: 12,
                            fontWeight: 600,
                            fill: '#333',
                            stroke: '#fff',
                            lineWidth: 2,
                            backgroundColor: 'transparent',
                            align: 'left',
                            verticalAlign: 'middle'
                        },
                        z: 50,
                        zlevel: 1,
                        bounding: 'raw',
                        silent: true
                    });
                    currentDepth += thickness;
                });
                this.currentGraphicElements = graphics;
                this.myChart.setOption({ graphic: { elements: graphics } });
                return;
            }

            // 新格式：按井号分组对象。先按 depthIntervals 顺序识别每口井对应的 x 轴段
            const segments = [];
            let currentJh = null;
            let currentMin = Infinity;
            let currentMax = -Infinity;
            let started = false;
            for (let i = 0; i < depthIntervals.length; i++) {
                const { jh } = depthIntervals[i] || {};
                const idx = i; // 使用 depthIntervals 顺序索引作为 x 轴位置
                if (!started) {
                    currentJh = jh;
                    currentMin = currentMax = idx;
                    started = true;
                    continue;
                }
                if (jh === currentJh) {
                    currentMin = Math.min(currentMin, idx);
                    currentMax = Math.max(currentMax, idx);
                } else {
                    segments.push({ jh: currentJh, startIdx: Math.min(currentMin, currentMax), endIdx: Math.max(currentMin, currentMax) });
                    currentJh = jh;
                    currentMin = currentMax = idx;
                }
            }
            if (started) {
                segments.push({ jh: currentJh, startIdx: Math.min(currentMin, currentMax), endIdx: Math.max(currentMin, currentMax) });
            }

            // 对每个井段，遍历该井的每个地层，按其 points 的实际 x 位置放置标签
            // 将相同 x 标签的所有全局索引都存储起来，便于按井段范围内精确匹配
            const xIndexMap = new Map(); // key: x 标签, value: 索引数组
            (xAxisLabels || []).forEach((x, idx) => {
                const key = String(x);
                if (!xIndexMap.has(key)) xIndexMap.set(key, []);
                xIndexMap.get(key).push(idx);
            });

            segments.forEach(seg => {
                const layers = stackedAreas[seg.jh] || [];
                if (!Array.isArray(layers) || layers.length === 0) return;

                layers.forEach(area => {
                    if (!area) return;

                    // 选取该层的第一个点（通常为该井的首个测点，如 HT2465）用于横向定位
                    let pointForX = null;
                    if (Array.isArray(area.points) && area.points.length > 0) {
                        // 优先选择在本井段 [startIdx, endIdx] 范围内能匹配到的 x
                        pointForX = area.points.find(p => {
                            const arr = xIndexMap.get(String(p?.x));
                            if (!arr || arr.length === 0) return false;
                            return arr.some(ix => ix >= seg.startIdx && ix <= seg.endIdx);
                        }) || area.points[0];
                    }

                    // 计算中心深度（厚度规则：当 y2==y 或 sjdjsd==sjhd 时，厚度= y2，从 0 到 y2）
                    let centerDepth;
                    if (area.sjdjsd != null && area.sjhd != null) {
                        if (Number(area.sjdjsd) === Number(area.sjhd)) {
                            centerDepth = Number(area.sjdjsd) / 2;
                        } else {
                            centerDepth = (Number(area.sjdjsd) + Number(area.sjhd)) / 2;
                        }
                    } else if (pointForX) {
                        const py1 = Number(pointForX.y);
                        const py2 = pointForX.y2 != null ? Number(pointForX.y2) : null;
                        if (py2 != null && py2 === py1) {
                            centerDepth = py2 / 2;
                        } else if (py2 != null) {
                            centerDepth = (py1 + py2) / 2;
                        } else if (!Number.isNaN(py1)) {
                            centerDepth = py1 / 2;
                        } else {
                            centerDepth = chartConfig?.yAxis?.min || 0;
                        }
                    } else {
                        centerDepth = chartConfig?.yAxis?.min || 0;
                    }

                    // 计算横向像素：若能找到该点的 x 在 xAxis 中的索引，就用该索引；否则退回到该井段的中点
                    let xIndex = null;
                    if (pointForX && xIndexMap.has(String(pointForX.x))) {
                        const candidates = xIndexMap.get(String(pointForX.x)) || [];
                        // 找到位于当前井段范围内的索引；如没有则回退到第一个
                        const inSeg = candidates.find(ix => ix >= seg.startIdx && ix <= seg.endIdx);
                        xIndex = inSeg != null ? inSeg : candidates[0];
                    } else {
                        xIndex = (seg.startIdx + seg.endIdx) / 2;
                    }

                    const pixel = this.myChart.convertToPixel({ xAxisIndex: 0, yAxisIndex: 0 }, [xIndex, centerDepth]);
                    if (!pixel || !Array.isArray(pixel) || pixel.length < 2) return;
                    const [px, py] = pixel;

                    graphics.push({
                        type: 'text',
                        position: [px, py],
                        style: {
                            text: area.name || '',
                            fontSize: 12,
                            fontWeight: 600,
                            fill: '#111827',
                            stroke: 'rgba(255,255,255,0.9)',
                            lineWidth: 3,
                            backgroundColor: 'transparent',
                            align: 'center',
                            verticalAlign: 'middle'
                        },
                        z: 50,
                        zlevel: 1,
                        bounding: 'raw',
                        silent: true
                    });
                });
            });

            this.currentGraphicElements = graphics;
            this.myChart.setOption({ graphic: { elements: graphics } });
        },

        // 根据 depthIntervals 的顺序按 jh 分段，绘制虚线与顶部井号
        drawJhSeparators(depthIntervals, xAxisLabels, chartConfig) {
            if (!this.myChart || !depthIntervals || depthIntervals.length === 0) return;

            // 扫描 depthIntervals 顺序，形成段
            const segments = [];
            let currentJh = null;
            let currentMin = Infinity;
            let currentMax = -Infinity;
            let started = false;
            for (let i = 0; i < depthIntervals.length; i++) {
                // 直接使用在 depthIntervals 中的顺序索引作为 x 轴位置，
                // 以避免相同 x 标签造成的覆盖与错位
                const { jh } = depthIntervals[i];
                const idx = i;
                if (!started) {
                    currentJh = jh;
                    currentMin = currentMax = idx;
                    started = true;
                    continue;
                }
                if (jh === currentJh) {
                    currentMin = Math.min(currentMin, idx);
                    currentMax = Math.max(currentMax, idx);
                } else {
                    segments.push({ jh: currentJh, startIdx: Math.min(currentMin, currentMax), endIdx: Math.max(currentMin, currentMax) });
                    // 开始新段
                    currentJh = jh;
                    currentMin = currentMax = idx;
                }
            }
            if (started) {
                segments.push({ jh: currentJh, startIdx: Math.min(currentMin, currentMax), endIdx: Math.max(currentMin, currentMax) });
            }

            const graphics = [];
            // 垂直范围（像素）——考虑 y 轴 inverse，取像素最小为顶部、最大为底部
            const yMinPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.min);
            const yMaxPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.max);
            if (yMinPx === null || yMaxPx === null) {
                console.warn('convertToPixel 返回 null 值，跳过绘制井号分隔符');
                return;
            }
            const yTopPx = Math.min(yMinPx, yMaxPx);
            const yBottomPx = Math.max(yMinPx, yMaxPx);
            // 计算顶部短虚线的长度和位置（只在顶部显示）
            const plotHeight = Math.abs(yBottomPx - yTopPx);
            const stemLen = Math.max(30, Math.min(120, plotHeight * 0.12));
            const extraHead = Math.max(10, Math.min(60, plotHeight * 0.05));
            const yStemStart = yTopPx - (extraHead + stemLen);
            const yStemEnd = yTopPx - 1;

            // 边界虚线（段与段之间），只在顶部显示短虚线，显示在最上层
            for (let i = 0; i < segments.length - 1; i++) {
                const leftEnd = segments[i].endIdx;
                const rightStart = segments[i + 1].startIdx;
                const pxLeft = this.myChart.convertToPixel({ xAxisIndex: 0 }, leftEnd);
                const pxRight = this.myChart.convertToPixel({ xAxisIndex: 0 }, rightStart);
                if (pxLeft === null || pxRight === null) {
                    console.warn('convertToPixel 返回 null 值，跳过绘制边界虚线');
                    continue;
                }
                const midX = (pxLeft + pxRight) / 2;
                graphics.push({
                    type: 'line',
                    shape: { x1: midX, y1: yStemStart, x2: midX, y2: yStemEnd },
                    style: { stroke: '#bbb', lineDash: [8, 6], lineWidth: 1.5 },
                    silent: true,
                    z: 200,
                    zlevel: 20
                });
            }

            // 每段顶部显示 jh（居中），带背景标签并做简单防重叠处理
            let lastLabelRight = -Infinity;
            let rowShift = 0; // 逐行上移避免覆盖
            segments.forEach((seg, idx) => {
                if (!seg.jh) return;
                const pxStart = this.myChart.convertToPixel({ xAxisIndex: 0 }, seg.startIdx);
                const pxEnd = this.myChart.convertToPixel({ xAxisIndex: 0 }, seg.endIdx);
                if (pxStart === null || pxEnd === null) {
                    console.warn('convertToPixel 返回 null 值，跳过绘制井号标签');
                    return;
                }
                const midX = (pxStart + pxEnd) / 2;
                let topY = yTopPx - 30; // 再上移，避免遮挡

                // 估算标签宽度用于避免与上一个重叠
                const fontSize = 12;
                const paddingH = 6;
                const estimatedWidth = seg.jh.length * fontSize * 0.6 + paddingH * 2 + 10;
                const labelLeft = midX - estimatedWidth / 2;
                const labelRight = midX + estimatedWidth / 2;
                if (labelLeft < lastLabelRight) {
                    rowShift += 18; // 叠一行
                } else {
                    rowShift = 0;
                }
                lastLabelRight = Math.max(lastLabelRight, labelRight);
                topY -= rowShift;
                const labelWidth = Math.max(estimatedWidth, 80);
                const labelHeight = 22;
                const pointerSize = 6;

                graphics.push({
                    type: 'group',
                    x: midX - labelWidth / 2,
                    y: topY - labelHeight,
                    z: 101,
                    zlevel: 10,
                    silent: true,
                    children: [
                        {
                            type: 'rect',
                            shape: { x: 0, y: 0, width: labelWidth, height: labelHeight, r: 8 },
                            style: {
                                fill: '#2563eb',
                                stroke: '#1e40af',
                                lineWidth: 1.5,
                                shadowBlur: 6,
                                shadowColor: 'rgba(37,99,235,0.35)'
                            }
                        },
                        {
                            type: 'polygon',
                            shape: {
                                points: [
                                    [labelWidth / 2 - pointerSize, labelHeight],
                                    [labelWidth / 2 + pointerSize, labelHeight],
                                    [labelWidth / 2, labelHeight + pointerSize]
                                ]
                            },
                            style: { fill: '#2563eb', stroke: '#1e40af' }
                        },
                        {
                            type: 'text',
                            style: {
                                x: labelWidth / 2,
                                y: labelHeight / 2,
                                text: seg.jh,
                                fill: '#fff',
                                fontSize: fontSize + 1,
                                fontWeight: 700,
                                align: 'center',
                                verticalAlign: 'middle'
                            }
                        }
                    ]
                });
            });

            // 叠加到现有 graphic 上（保留原有 graphic）
            const prevElements = Array.isArray(this.currentGraphicElements) ? this.currentGraphicElements : [];
            const merged = prevElements.concat(graphics);
            this.currentGraphicElements = merged;
            this.myChart.setOption({ graphic: { elements: merged } });
        },

        // 为每个 x 类目在左右各画一条黑色竖线（仅顶部短竖线）
        drawCategoryEdgeLines(xAxisLabels, chartConfig) {
            if (!this.myChart || !Array.isArray(xAxisLabels) || xAxisLabels.length === 0) return;

            const yMinPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.min);
            const yMaxPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.max);
            if (yMinPx === null || yMaxPx === null) return;
            const yTopPx = Math.min(yMinPx, yMaxPx);
            const yBottomPx = Math.max(yMinPx, yMaxPx);
            // 只在上方画短竖线：长度占绘图区高度的 12%，并限制在 30-120 像素
            const plotHeight = Math.abs(yBottomPx - yTopPx);
            const stemLen = Math.max(30, Math.min(120, plotHeight * 0.12));
            // 仅保留上方的线：整段都在 top 之上
            const extraHead = Math.max(10, Math.min(60, plotHeight * 0.05));
            const yStemStart = yTopPx - (extraHead + stemLen);
            const yStemEnd = yTopPx - 1;

            const graphics = [];
            const n = xAxisLabels.length;
            // 计算每个类目的像素中心
            const centers = [];
            for (let i = 0; i < n; i++) {
                const cx = this.myChart.convertToPixel({ xAxisIndex: 0 }, i);
                if (cx != null) centers.push(cx);
            }
            if (centers.length > 0) {
                // 第一个点左侧边界：用前两个中心的半步估计
                let firstEdge;
                if (centers.length >= 2) {
                    firstEdge = centers[0] - (centers[1] - centers[0]) / 2;
                } else {
                    // 只有一个点时，给一个合理的固定偏移
                    firstEdge = centers[0] - 40;
                }
                graphics.push({
                    type: 'line',
                    shape: { x1: firstEdge, y1: yStemStart, x2: firstEdge, y2: yStemEnd },
                    style: { stroke: '#bbb', lineWidth: 1.5 },
                    silent: true,
                    z: 120,
                    zlevel: 10
                });
                // 相邻两点之间的中点
                for (let i = 0; i < centers.length - 1; i++) {
                    const mid = (centers[i] + centers[i + 1]) / 2;
                    graphics.push({
                        type: 'line',
                        shape: { x1: mid, y1: yStemStart, x2: mid, y2: yStemEnd },
                        style: { stroke: '#bbb', lineWidth: 1.5 },
                        silent: true,
                        z: 120,
                        zlevel: 10
                    });
                }

                // 右侧最后一个边界线：对称估算半步并绘制（补齐“最后那条线”）
                let lastEdge;
                if (centers.length >= 2) {
                    lastEdge = centers[centers.length - 1] + (centers[centers.length - 1] - centers[centers.length - 2]) / 2;
                } else {
                    lastEdge = centers[0] + 40;
                }
                graphics.push({
                    type: 'line',
                    shape: { x1: lastEdge, y1: yStemStart, x2: lastEdge, y2: yStemEnd },
                    style: { stroke: '#bbb', lineWidth: 1.5 },
                    silent: true,
                    z: 120,
                    zlevel: 10
                });

                // 顶部段标签：第一个段使用第一个 x 标签，之后每个段用对应中心的标签
                const boundaries = [firstEdge];
                for (let i = 0; i < centers.length - 1; i++) {
                    boundaries.push((centers[i] + centers[i + 1]) / 2);
                }
                const labelY = yStemStart - 8;
                for (let i = 0; i < boundaries.length - 1; i++) {
                    const midX = (boundaries[i] + boundaries[i + 1]) / 2;
                    const label = String(xAxisLabels[i] ?? '');
                    graphics.push({
                        type: 'text',
                        position: [midX, labelY],
                        style: {
                            text: label,
                            fontSize: 12,
                            fontWeight: 600,
                            fill: '#333',
                            backgroundColor: 'rgba(255,255,255,0.85)',
                            padding: [2, 4],
                            borderRadius: 4,
                            align: 'center',
                            verticalAlign: 'bottom'
                        },
                        z: 121,
                        zlevel: 10,
                        silent: true,
                        bounding: 'raw'
                    });
                }
            }

            const prev = Array.isArray(this.currentGraphicElements) ? this.currentGraphicElements : [];
            const merged = prev.concat(graphics);
            this.currentGraphicElements = merged;
            this.myChart.setOption({ graphic: { elements: merged } });
        },

        // 图内根据 x 和 y2 渲染 SVG 纹理（每段使用该 x 在 stackedAreas 中最浅层 y2 对应的 svg），从顶部填充到 y2 深度
        async drawTopBandSvg(xAxisLabels, chartConfig, stackedAreas) {
            if (!this.myChart || !Array.isArray(xAxisLabels) || !stackedAreas) return;

            // 计算每个类目的像素中心
            const centers = [];
            for (let i = 0; i < xAxisLabels.length; i++) {
                const cx = this.myChart.convertToPixel({ xAxisIndex: 0 }, i);
                if (cx != null) centers.push(cx);
            }
            if (centers.length === 0) return;

            // 计算段边界（第一个左边界 + 各中点）
            let firstEdge;
            if (centers.length >= 2) {
                firstEdge = centers[0] - (centers[1] - centers[0]) / 2;
            } else {
                firstEdge = centers[0] - 40;
            }
            const boundaries = [firstEdge];
            for (let i = 0; i < centers.length - 1; i++) {
                boundaries.push((centers[i] + centers[i + 1]) / 2);
            }

            // 图内纵向像素范围：从图内顶部到 y2 所在像素
            const yMinPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.min);
            const yMaxPx = this.myChart.convertToPixel({ yAxisIndex: 0 }, chartConfig.yAxis.max);
            if (yMinPx == null || yMaxPx == null) return;
            const yTopPx = Math.min(yMinPx, yMaxPx);
            const plotHeight = Math.abs(yMaxPx - yMinPx);

            // 摊平 stackedAreas 以便按 x 查找图层（保留全部层，用于全部渲染）
            const allLayers = [];
            if (Array.isArray(stackedAreas)) {
                for (const l of stackedAreas) if (l) allLayers.push(l);
            } else {
                for (const layers of Object.values(stackedAreas)) {
                    if (Array.isArray(layers)) allLayers.push(...layers.filter(Boolean));
                }
            }

            const graphics = [];

            // 仅在每口井的最后一列标注层名称
            const depthIntervals = this.mockData?.wellData?.depthIntervals || [];
            const lastIndexByJh = new Map();
            for (let idx = 0; idx < depthIntervals.length; idx++) {
                const jhVal = depthIntervals[idx]?.jh;
                if (jhVal != null) lastIndexByJh.set(jhVal, idx);
            }

            for (let i = 0; i < xAxisLabels.length; i++) {
                const xLabel = String(xAxisLabels[i]);
                const left = boundaries[i];
                const right = (i < boundaries.length - 1) ? boundaries[i + 1] : left + (centers[1] ? (centers[1] - centers[0]) : 80);
                const width = Math.max(10, right - left);
                const currentJh = depthIntervals[i]?.jh;
                const isLastColumnOfJh = currentJh != null && lastIndexByJh.get(currentJh) === i;

                // 找到包含该 x 的所有层，提取该 x 对应点的 y2；若有重叠（相同 y2）则只保留一次
                const y2ToLayer = new Map();
                for (const layer of allLayers) {
                    const pts = Array.isArray(layer?.points) ? layer.points : [];
                    const p = pts.find(p0 => String(p0?.x) === xLabel);
                    if (!p) continue;
                    const y2val = Number(p?.y2 ?? layer?.sjdjsd);
                    if (Number.isNaN(y2val)) continue;
                    if (!y2ToLayer.has(y2val)) y2ToLayer.set(y2val, layer);
                }
                const sortedY2 = Array.from(y2ToLayer.keys()).sort((a, b) => a - b);

                // 如果是该井的最后一列，获取该井对应的地层数据用于显示地层名称
                let currentJhLayers = [];
                if (isLastColumnOfJh && currentJh && !Array.isArray(stackedAreas) && stackedAreas[currentJh]) {
                    currentJhLayers = Array.isArray(stackedAreas[currentJh]) ? stackedAreas[currentJh] : [];
                }

                let prevBottom = null; // 上一个片段的底（y2），为空则从图内顶部开始
                for (const y2val of sortedY2) {
                    const layer = y2ToLayer.get(y2val);
                    const yTopDepth = prevBottom == null ? chartConfig?.yAxis?.min : prevBottom;
                    const yBottomDepth = y2val;

                    const yPixTop = this.myChart.convertToPixel({ yAxisIndex: 0 }, yTopDepth);
                    const yPixBottom = this.myChart.convertToPixel({ yAxisIndex: 0 }, yBottomDepth);
                    if (yPixTop == null || yPixBottom == null) { prevBottom = y2val; continue; }

                    const rectTop = Math.min(yPixTop, yPixBottom);
                    const rectBottom = Math.max(yPixTop, yPixBottom);
                    const y1pix = Math.max(yTopPx, rectTop);
                    const y2pix = Math.min(Math.max(yMinPx, yMaxPx), rectBottom);
                    const height = Math.max(0, y2pix - y1pix);
                    if (height > 0) {
                        let fill = '#d0d3d8';
                        if (layer?.svg) {
                            try {
                                const img = await this.createSvgImage(layer.svg);
                                fill = { image: img, repeat: 'repeat' };
                            } catch (e) { /* ignore */ }
                        }
                        graphics.push({
                            type: 'rect',
                            shape: { x: left, y: y1pix, width, height },
                            style: {
                                fill,
                                stroke: 'rgba(0,0,0,0.12)',
                                lineWidth: 1,
                                opacity: 0.4  // 降低背景透明度，确保柱状图和折线图可见
                            },
                            silent: true,
                            z: -100,
                            zlevel: -1,
                            __band: true
                        });
                    }
                    prevBottom = y2val;
                }

                // 在该井的最后一列才标注地层名称，使用该井对应的地层数据
                if (isLastColumnOfJh && currentJhLayers.length > 0) {
                    // 构建该井地层的深度映射，用于确定每个地层的显示位置
                    const jhLayerDepthMap = new Map();
                    for (const jhLayer of currentJhLayers) {
                        if (!jhLayer) continue;
                        // 计算地层的深度范围
                        let topDepth, bottomDepth;
                        if (jhLayer.sjdjsd != null && jhLayer.sjhd != null) {
                            if (Number(jhLayer.sjdjsd) === Number(jhLayer.sjhd)) {
                                topDepth = 0;
                                bottomDepth = Number(jhLayer.sjdjsd);
                            } else {
                                topDepth = Number(jhLayer.sjhd);
                                bottomDepth = Number(jhLayer.sjdjsd);
                            }
                        } else if (Array.isArray(jhLayer.points) && jhLayer.points.length > 0) {
                            const p = jhLayer.points[0];
                            const py1 = Number(p?.y);
                            const py2 = p?.y2 != null ? Number(p.y2) : null;
                            if (py2 != null && py2 === py1) {
                                topDepth = 0;
                                bottomDepth = py2;
                            } else if (py2 != null) {
                                topDepth = Math.min(py1, py2);
                                bottomDepth = Math.max(py1, py2);
                            } else if (!Number.isNaN(py1)) {
                                topDepth = 0;
                                bottomDepth = py1;
                            } else {
                                continue;
                            }
                        } else {
                            continue;
                        }
                        const centerDepth = (topDepth + bottomDepth) / 2;
                        jhLayerDepthMap.set(centerDepth, jhLayer);
                    }

                    // 按深度排序，从上到下显示地层名称
                    const sortedDepths = Array.from(jhLayerDepthMap.keys()).sort((a, b) => a - b);
                    for (const centerDepth of sortedDepths) {
                        const jhLayer = jhLayerDepthMap.get(centerDepth);
                        if (!jhLayer || !jhLayer.name) continue;

                        // 计算该地层的显示位置
                        let topDepth, bottomDepth;
                        if (jhLayer.sjdjsd != null && jhLayer.sjhd != null) {
                            if (Number(jhLayer.sjdjsd) === Number(jhLayer.sjhd)) {
                                topDepth = 0;
                                bottomDepth = Number(jhLayer.sjdjsd);
                            } else {
                                topDepth = Number(jhLayer.sjhd);
                                bottomDepth = Number(jhLayer.sjdjsd);
                            }
                        } else if (Array.isArray(jhLayer.points) && jhLayer.points.length > 0) {
                            const p = jhLayer.points[0];
                            const py1 = Number(p?.y);
                            const py2 = p?.y2 != null ? Number(p.y2) : null;
                            if (py2 != null && py2 === py1) {
                                topDepth = 0;
                                bottomDepth = py2;
                            } else if (py2 != null) {
                                topDepth = Math.min(py1, py2);
                                bottomDepth = Math.max(py1, py2);
                            } else if (!Number.isNaN(py1)) {
                                topDepth = 0;
                                bottomDepth = py1;
                            } else {
                                continue;
                            }
                        } else {
                            continue;
                        }

                        const yPixTop = this.myChart.convertToPixel({ yAxisIndex: 0 }, topDepth);
                        const yPixBottom = this.myChart.convertToPixel({ yAxisIndex: 0 }, bottomDepth);
                        if (yPixTop == null || yPixBottom == null) continue;

                        const rectTop = Math.min(yPixTop, yPixBottom);
                        const rectBottom = Math.max(yPixTop, yPixBottom);
                        const y1pix = Math.max(yTopPx, rectTop);
                        const y2pix = Math.min(Math.max(yMinPx, yMaxPx), rectBottom);
                        const height = Math.max(0, y2pix - y1pix);
                        if (height > 0) {
                            const midX = left + width / 2;
                            const midY = y1pix + height / 2;
                            const labelText = String(jhLayer.name || '');
                            if (labelText) {
                                graphics.push({
                                    type: 'text',
                                    position: [midX, midY],
                                    style: {
                                        text: labelText,
                                        fontSize: 12,
                                        fontWeight: 600,
                                        fill: '#111827',
                                        stroke: 'rgba(255,255,255,0.9)',
                                        lineWidth: 3,
                                        align: 'center',
                                        verticalAlign: 'middle'
                                    },
                                    silent: true,
                                    z: 50,
                                    zlevel: 1,
                                    __band: true,
                                    bounding: 'raw'
                                });
                            }
                        }
                    }
                }
            }

            // 合并到当前 graphic 上：先移除旧 band，再追加新的，避免重复渲染
            const prev = Array.isArray(this.currentGraphicElements) ? this.currentGraphicElements : [];
            const kept = prev.filter(el => !el.__band);
            const merged = kept.concat(graphics);
            this.currentGraphicElements = merged;
            this.myChart.setOption({ graphic: { elements: merged } });
        }
    },
};
</script>

<style lang="scss" scoped>
/* 容器样式优化 */
.chart-container {
    width: 100%;
    height: 100vh;
    padding: 0 20px;
    margin: 0;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    position: relative;
}

/* 井号显示样式 */
.well-number-display {
    position: absolute;
    top: 16px;
    left: 16px;
    z-index: 5;
    background: transparent;
    padding: 8px 12px;
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    transition: all 0.3s ease;
    opacity: 0.9;
}

.well-number-display:hover {
    opacity: 1;
}

.well-label {
    color: #6b7280;
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
}

.well-number {
    color: #3b82f6;
    font-size: 14px;
    font-weight: 600;
}

/* 图表容器样式 */
.chart {
    flex: 1;
    width: 100%;
    height: 100%;
    min-height: 400px;
    display: block;
    border-radius: 16px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
    border: 1px solid rgba(255, 255, 255, 0.8);
    backdrop-filter: blur(10px);
    transition: all 0.3s ease;
}

.chart:hover {
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
    /* transform: translateY(-2px); */
}

/* 加载状态样式 */
.loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.95);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 10;
    border-radius: 16px;
    backdrop-filter: blur(10px);
}

.loading-spinner {
    width: 48px;
    height: 48px;
    border: 4px solid #f3f4f6;
    border-top: 4px solid #3b82f6;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin-bottom: 16px;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

/* 响应式优化 */
@media (max-width: 768px) {
    .chart-container {
        padding: 0 10px;
    }

    .chart {
        min-height: 300px;
        border-radius: 12px;
    }
}

/* 深色模式支持 */
@media (prefers-color-scheme: dark) {
    .chart {
        /* background: linear-gradient(135deg, #1f2937 0%, #111827 100%); */
        /* box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); */
        border: 1px solid rgba(255, 255, 255, 0.1);
    }

    /*     
    .chart:hover {
        box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
    } */

    .loading-overlay {
        background: rgba(17, 24, 39, 0.95);
    }
}

/* 动画效果 */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(20px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.chart-container {
    animation: fadeIn 0.6s ease-out;
}
</style>