opo-态势总览分析 V1.9edit icon

作者:
Fadinghaze
Fork(复制)
下载
嵌入
BUG反馈
index.html
style.css
index.js
现在支持上传本地图片了!
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>江苏省OPO可视化调度平台 - 态势总览分析 V1.9</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    
    <style>
        /* ==================== 1. 全局与背景 ==================== */
        :root {
            --color-clue: #007aff;  /* 蓝 */
            --color-case: #30d158;  /* 绿 */
            --color-organ: #bf5af2; /* 紫 */
            --color-trans: #00f0ff; /* 青 */
            
            --tech-bg: #050b16;
            --text-main: #ffffff;
            --text-sub: #8fb4d9;
            
            /* 筛选器专用色 */
            --input-bg: rgba(20, 40, 70, 0.8);
            --input-border: #284875;
            --active-blue: #007aff;
        }

        body {
            margin: 0; padding: 0;
            background-color: var(--tech-bg);
            font-family: "Microsoft YaHei", sans-serif;
            color: var(--text-main);
            height: 100vh; width: 100vw;
            overflow: hidden;
        }

        .bg-layer {
            position: absolute; top: 0; left: 0; width: 100%; height: 100%;
            background-image: radial-gradient(circle at 50% 50%, #112240 0%, #02050a 100%),
                              url('https://api.mapbox.com/styles/v1/mapbox/dark-v10/static/118.78,32.07,7,0/1600x1200?access_token=pk.eyJ1IjoiZGVtb3VzZXIiLCJhIjoiY2x4eH..."');
            background-size: cover; filter: blur(4px); transform: scale(1.05);
            z-index: 0;
        }

        /* ==================== 2. 容器与通用样式 ==================== */
        .analysis-modal {
            position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
            width: 90vw; height: 90vh;
            background: rgba(10, 20, 35, 0.95);
            border: 1px solid var(--color-trans);
            box-shadow: 0 0 50px rgba(0, 240, 255, 0.15);
            border-radius: 8px;
            display: flex; flex-direction: column;
            z-index: 100;
            backdrop-filter: blur(10px);
        }

        .modal-header {
            height: 60px; border-bottom: 1px solid rgba(255,255,255,0.1);
            display: flex; align-items: center; justify-content: space-between;
            padding: 0 25px; background: linear-gradient(90deg, rgba(0,240,255,0.1) 0%, transparent 100%);
        }
        .mh-title { font-size: 20px; font-weight: bold; color: #fff; letter-spacing: 2px; display: flex; align-items: center; gap: 10px; }
        .mh-title::before { content: ''; width: 4px; height: 20px; background: var(--color-trans); display: block; box-shadow: 0 0 10px var(--color-trans); }
        .mh-close { width: 32px; height: 32px; border: 1px solid rgba(255,69,58,0.5); background: rgba(255,69,58,0.1); color: #ff453a; border-radius: 4px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: 0.3s; }
        .mh-close:hover { background: #ff453a; color: #fff; }

        .modal-body { flex: 1; padding: 0 20px 20px 20px; display: flex; flex-direction: column; gap: 15px; overflow-y: auto; }

        .panel-box {
            background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.05); border-radius: 6px;
            padding: 15px; display: flex; flex-direction: column; position: relative;
        }
        .panel-box::after { content: ''; position: absolute; top: 0; right: 0; width: 10px; height: 10px; border-top: 2px solid var(--color-trans); border-right: 2px solid var(--color-trans); }
        .box-title { font-size: 14px; color: var(--text-sub); margin-bottom: 15px; font-weight: bold; display: flex; justify-content: space-between; align-items: center; border-left: 3px solid var(--color-clue); padding-left: 8px; line-height: 1; }

        /* ==================== 3. 筛选控制栏 (V1.9 E-Charts Style) ==================== */
        .filter-bar {
            display: flex; align-items: center; gap: 20px; /* 左对齐+间距 */
            padding: 15px 5px; border-bottom: 1px dashed rgba(255,255,255,0.1); margin-bottom: 5px;
        }
        
        .fb-item { display: flex; align-items: center; gap: 8px; }
        .fb-label { font-size: 13px; color: #ddd; white-space: nowrap; }
        
        /* 区域选择 */
        .region-select {
            background: var(--input-bg); border: 1px solid var(--input-border); color: #fff;
            padding: 5px 10px; border-radius: 4px; font-size: 13px; outline: none; cursor: pointer; min-width: 140px;
        }

        /* E-Charts 风格时间组件容器 */
        .time-picker-container { display: flex; align-items: center; position: relative; }
        
        /* 左侧:输入框显示区 */
        .tp-display {
            background: var(--input-bg); border: 1px solid var(--input-border);
            border-radius: 4px 0 0 4px; 
            padding: 5px 12px; font-size: 13px; color: #fff;
            width: 160px; cursor: pointer; position: relative;
            display: flex; align-items: center; gap: 8px;
        }
        .tp-display:hover { border-color: var(--active-blue); }
        .tp-icon { color: var(--color-trans); }

        /* 右侧:类型切换按钮组 */
        .tp-toggles { display: flex; }
        .tp-btn {
            background: transparent; border: 1px solid var(--input-border); border-left: none;
            color: #aaa; padding: 5px 12px; font-size: 13px; cursor: pointer; transition: 0.2s;
        }
        .tp-btn:last-child { border-radius: 0 4px 4px 0; }
        .tp-btn:hover { color: #fff; }
        .tp-btn.active { background: var(--active-blue); color: #fff; border-color: var(--active-blue); font-weight: bold; }

        /* 下拉面板 */
        .tp-popup {
            position: absolute; top: 100%; left: 0; margin-top: 5px;
            width: 280px; background: #0f223d; border: 1px solid var(--input-border);
            box-shadow: 0 4px 20px rgba(0,0,0,0.5); z-index: 50; border-radius: 4px;
            display: none; flex-direction: column;
        }
        .tp-popup.show { display: flex; }
        
        .tp-pop-header { 
            display: flex; justify-content: space-between; align-items: center; padding: 10px; 
            border-bottom: 1px solid rgba(255,255,255,0.1); color: #fff; font-size: 14px; 
        }
        .tp-pop-arrow { cursor: pointer; color: #aaa; padding: 0 5px; }
        .tp-pop-arrow:hover { color: #fff; }

        .tp-pop-grid { display: grid; padding: 10px; gap: 8px; }
        /* 月度 grid */
        .grid-month { grid-template-columns: repeat(4, 1fr); } 
        /* 季度 grid */
        .grid-quarter { grid-template-columns: repeat(2, 1fr); }
        
        .tp-grid-item {
            text-align: center; padding: 8px 0; font-size: 12px; color: #ccc; border-radius: 4px; cursor: pointer;
        }
        .tp-grid-item:hover { background: rgba(255,255,255,0.1); color: #fff; }
        .tp-grid-item.active { background: var(--active-blue); color: #fff; }

        /* ==================== ROW 1: KPI 指标 ==================== */
        .kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; height: 120px; }
        .kpi-card { 
            background: linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(0,0,0,0.3) 100%); 
            display: flex; flex-direction: column; justify-content: center; padding: 0 25px; 
            border: 1px solid rgba(255,255,255,0.1); border-radius: 6px; position: relative; overflow: hidden; 
        }
        .kpi-icon-bg { position: absolute; right: 10px; bottom: -10px; font-size: 70px; opacity: 0.1; color: #fff; transform: rotate(-15deg); }
        .kpi-lbl { font-size: 14px; color: #fff; margin-bottom: 8px; font-weight: 500; text-shadow: 0 0 5px rgba(0,0,0,0.5); }
        .kpi-num { font-family: Impact, sans-serif; font-size: 36px; color: #fff; letter-spacing: 1px; line-height: 1; text-shadow: 0 0 10px rgba(0,0,0,0.5); }
        .kpi-trend { font-size: 12px; margin-top: 10px; display: flex; align-items: center; gap: 5px; color: #ddd; }
        
        .c-clue { color: var(--color-clue); }
        .c-case { color: var(--color-case); }
        .c-organ { color: var(--color-organ); }
        .c-trans { color: var(--color-trans); }

        /* ==================== ROW 2: 中部图表 ==================== */
        .mid-row { display: flex; gap: 20px; height: 350px; }
        .mid-left { flex: 2; } 
        .mid-right { flex: 3; } 

        /* 漏斗 (V1.7 样式) */
        .funnel-container { flex: 1; display: flex; flex-direction: column; gap: 15px; padding: 0 10px; justify-content: center; }
        .funnel-block { display: flex; flex-direction: column; gap: 4px; padding: 10px; border-radius: 8px; border: 1px solid transparent; transition: all 0.4s ease; cursor: pointer; position: relative; opacity: 0.5; filter: grayscale(0.5); }
        .funnel-block:hover { opacity: 0.8; filter: grayscale(0.2); }
        .funnel-block.active-block-upper { opacity: 1; filter: grayscale(0); background: rgba(0, 122, 255, 0.1); border-color: var(--color-case); box-shadow: inset 0 0 20px rgba(0, 122, 255, 0.1), 0 0 15px rgba(48, 209, 88, 0.3); }
        .funnel-block.active-block-lower { opacity: 1; filter: grayscale(0); background: rgba(191, 90, 242, 0.1); border-color: var(--color-trans); box-shadow: inset 0 0 20px rgba(191, 90, 242, 0.1), 0 0 15px rgba(0, 240, 255, 0.3); }
        .funnel-step { display: flex; align-items: center; justify-content: center; position: relative; height: 40px; color: #fff; font-weight: bold; clip-path: polygon(2% 0%, 98% 0%, 92% 100%, 8% 100%); margin: 0 auto; box-shadow: 0 4px 10px rgba(0,0,0,0.3); }
        .fs-content { display: flex; align-items: center; gap: 15px; z-index: 2; text-shadow: 0 1px 3px rgba(0,0,0,0.8); }
        .fs-name { font-size: 13px; opacity: 0.9; }
        .fs-val { font-family: monospace; font-size: 16px; color: #fff; }
        .fs-1 { width: 95%; background: linear-gradient(90deg, #003870 0%, var(--color-clue) 50%, #003870 100%); }
        .fs-2 { width: 80%; background: linear-gradient(90deg, #004c4c 0%, var(--color-case) 50%, #004c4c 100%); }
        .fs-3 { width: 65%; background: linear-gradient(90deg, #4c2060 0%, var(--color-organ) 50%, #4c2060 100%); }
        .fs-4 { width: 50%; background: linear-gradient(90deg, #004040 0%, var(--color-trans) 50%, #004040 100%); }
        .funnel-arrow { text-align: center; color: rgba(255,255,255,0.8); font-size: 11px; margin: 2px 0; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 4px; }
        .tag-rate { background: rgba(0,0,0,0.4); padding: 1px 8px; border-radius: 10px; border: 1px solid rgba(255,255,255,0.2); }

        /* 趋势图 */
        .chart-legend { display: flex; gap: 15px; font-size: 12px; color: #aaa; }
        .legend-item { display: flex; align-items: center; gap: 5px; }
        .dot { width: 10px; height: 10px; border-radius: 2px; }
        .chart-tag { font-size: 10px; color: #666; background: rgba(255,255,255,0.05); padding: 2px 6px; border-radius: 4px; margin-left: 10px; border: 1px solid rgba(255,255,255,0.1); }
        .chart-wrapper { flex: 1; display: flex; position: relative; padding: 10px 0 0 0; }
        .chart-y-axis { display: flex; flex-direction: column; justify-content: space-between; padding-bottom: 25px; padding-right: 10px; color: #666; font-size: 10px; text-align: right; width: 30px; border-right: 1px solid #333; height: 100%; }
        .chart-grid-area { flex: 1; position: relative; display: flex; align-items: flex-end; justify-content: space-between; border-bottom: 1px solid #333; padding-bottom: 0px; background: repeating-linear-gradient(0deg, #222 0px, transparent 1px, transparent 20%); }
        .chart-col { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; flex: 1; position: relative; }
        .bar-group { display: flex; align-items: flex-end; justify-content: center; gap: 4px; height: 100%; width: 80%; }
        .bar { width: 10px; border-radius: 2px 2px 0 0; position: relative; opacity: 0.9; animation: growUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards; height: 0; }
        .bar:hover { opacity: 1; filter: brightness(1.2); }
        .bar-val-top { position: absolute; top: -16px; left: 50%; transform: translateX(-50%); font-size: 9px; color: #fff; font-family: Arial; opacity: 1; }
        @keyframes growUp { from { height: 0; } to { height: var(--h); } }
        .x-axis-lbl { position: absolute; bottom: -25px; font-size: 10px; color: #888; width: 100%; text-align: center; }

        /* ==================== ROW 3: 底部画像 ==================== */
        .bot-row { display: flex; gap: 20px; flex: 1; min-height: 0; }
        .bot-col { flex: 1; display: flex; flex-direction: column; }
        
        .donut-wrap { display: flex; align-items: center; justify-content: center; height: 100%; gap: 10px; padding: 10px; }
        .donut-chart { width: 170px; height: 170px; border-radius: 50%; background: conic-gradient(var(--color-trans) 0% 35%, var(--color-clue) 35% 60%, var(--color-case) 60% 80%, var(--color-organ) 80% 95%, #ff453a 95% 100%); position: relative; box-shadow: 0 0 20px rgba(0,0,0,0.6); }
        .donut-chart::before { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 110px; height: 110px; background: rgba(16, 36, 68, 1); border-radius: 50%; }
        .donut-center-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #fff; }
        .dc-val { font-size: 24px; font-weight: bold; font-family: Impact; }
        .dc-lbl { font-size: 11px; color: #888; }
        .donut-legend { display: flex; flex-direction: column; gap: 8px; justify-content: center; }
        .dl-item { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #ccc; }
        .dl-color { width: 10px; height: 10px; border-radius: 2px; }

        .age-chart-container { flex: 1; display: flex; position: relative; padding-left: 30px; padding-bottom: 20px; }
        .age-y-axis { position: absolute; left: 0; top: 0; bottom: 20px; width: 30px; display: flex; flex-direction: column; justify-content: space-between; font-size: 9px; color: #666; border-right: 1px solid #333; text-align: right; padding-right: 5px; }
        .age-bars-area { flex: 1; border-bottom: 1px solid #333; display: flex; align-items: flex-end; justify-content: space-around; height: 100%; padding-top: 20px; }
        .age-col { display: flex; flex-direction: column; align-items: center; width: 12%; height: 100%; justify-content: flex-end; position: relative; }
        .age-bar { width: 100%; background: linear-gradient(0deg, rgba(0,240,255,0.2), rgba(0,240,255,0.8)); border-top: 2px solid #fff; border-radius: 2px 2px 0 0; position: relative; }
        .age-val { position: absolute; top: -16px; left: 50%; transform: translateX(-50%); font-size: 10px; color: var(--color-trans); }
        .age-lbl { position: absolute; bottom: -20px; font-size: 10px; color: #888; white-space: nowrap; }

        .profile-container { flex: 1; display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 0.8fr; grid-template-areas: "left center right" "bot-left center bot-right"; gap: 10px 20px; padding: 5px 15px; }
        .area-left { grid-area: left; display: flex; flex-direction: column; justify-content: center; }
        .area-right { grid-area: right; display: flex; flex-direction: column; justify-content: center; }
        .area-center { grid-area: center; display: flex; align-items: center; justify-content: center; position: relative; }
        .area-bot-left { grid-area: bot-left; display: flex; flex-direction: column; justify-content: flex-start; }
        .area-bot-right { grid-area: bot-right; display: flex; flex-direction: column; justify-content: flex-start; }
        .human-silhouette { font-size: 120px; color: rgba(255,255,255,0.05); text-shadow: 0 0 15px var(--color-clue); z-index: 1; }
        .prof-group { display: flex; flex-direction: column; gap: 4px; }
        .prof-title { font-size: 11px; color: var(--color-trans); border-bottom: 1px solid rgba(0,240,255,0.3); padding-bottom: 2px; margin-bottom: 4px; display: flex; align-items: center; gap: 5px; }
        .data-row { display: flex; align-items: center; justify-content: space-between; font-size: 10px; color: #ccc; margin-bottom: 1px; }
        .data-bar-bg { width: 100%; height: 3px; background: rgba(255,255,255,0.1); border-radius: 2px; margin-bottom: 4px; }
        .data-bar-fill { height: 100%; border-radius: 2px; }

    </style>
</head>
<body>

    <div class="bg-layer"></div>

    <div class="analysis-modal">
        <!-- 头部 -->
        <div class="modal-header">
            <div class="mh-title">态势总览分析 <span style="font-size:12px; color:#666; margin-left:10px; border:1px solid #444; padding:2px 6px; border-radius:4px;">V1.9</span></div>
            <div class="mh-close" onclick="alert('返回地图主页')"><i class="fas fa-times"></i></div>
        </div>

        <div class="modal-body">
            
            <!-- 筛选控制栏 (V1.9) -->
            <div class="filter-bar">
                <!-- 区域 -->
                <div class="fb-item">
                    <span class="fb-label">所属区域:</span>
                    <select class="region-select">
                        <option>江苏全省</option>
                        <option>南京市</option>
                        <option>苏州市</option>
                    </select>
                </div>

                <!-- 时间 (E-Charts 风格) -->
                <div class="fb-item">
                    <span class="fb-label">数据时间:</span>
                    <div class="time-picker-container">
                        <!-- 输入显示框 -->
                        <div class="tp-display" onclick="togglePopup()">
                            <i class="far fa-calendar-alt tp-icon"></i>
                            <span id="tp-value">2023</span>
                        </div>
                        
                        <!-- 类型切换 -->
                        <div class="tp-toggles">
                            <button class="tp-btn" onclick="switchTimeType('month')">月度</button>
                            <button class="tp-btn" onclick="switchTimeType('quarter')">季度</button>
                            <button class="tp-btn active" onclick="switchTimeType('year')">年度</button>
                        </div>

                        <!-- 下拉选择面板 -->
                        <div class="tp-popup" id="tp-popup">
                            <!-- 动态渲染内容 -->
                        </div>
                    </div>
                </div>
            </div>

            <!-- Row 1: KPI 指标 -->
            <div class="kpi-row">
                <div class="kpi-card">
                    <i class="fas fa-notes-medical kpi-icon-bg"></i>
                    <div class="kpi-lbl">线索上报</div>
                    <div class="kpi-num c-clue">1,248</div>
                    <div class="kpi-trend"><span style="color:#30d158"><i class="fas fa-arrow-up"></i> 同比增长 12.5%</span></div>
                </div>
                <div class="kpi-card">
                    <i class="fas fa-hands-holding-heart kpi-icon-bg"></i>
                    <div class="kpi-lbl">捐赠案例</div>
                    <div class="kpi-num c-case">356</div>
                    <div class="kpi-trend"><span style="color:#30d158"><i class="fas fa-arrow-up"></i> 同比增长 8.2%</span></div>
                </div>
                <div class="kpi-card">
                    <i class="fas fa-box-open kpi-icon-bg"></i>
                    <div class="kpi-lbl">器官获取</div>
                    <div class="kpi-num c-organ">1,089</div>
                    <div class="kpi-trend"><span style="color:#30d158"><i class="fas fa-arrow-up"></i> 同比增长 5.4%</span></div>
                </div>
                <div class="kpi-card">
                    <i class="fas fa-user-check kpi-icon-bg"></i>
                    <div class="kpi-lbl">成功移植</div>
                    <div class="kpi-num c-trans">1,067</div>
                    <div class="kpi-trend"><span style="color:#30d158"><i class="fas fa-arrow-up"></i> 同比增长 4.9%</span></div>
                </div>
            </div>

            <!-- Row 2: 中部图表 -->
            <div class="mid-row">
                <!-- 左:效能分析 -->
                <div class="panel-box mid-left">
                    <div class="box-title">效能分析</div>
                    <div class="funnel-container">
                        <div class="funnel-block active-block-upper" id="block-upper" onclick="switchChart('case')">
                            <div class="funnel-step fs-1"><div class="fs-content"><span class="fs-name">上报线索</span><span class="fs-val">1,248</span></div></div>
                            <div class="funnel-arrow"><span class="tag-rate"><i class="fas fa-filter"></i> 转化率 45%</span></div>
                            <div class="funnel-step fs-2"><div class="fs-content"><span class="fs-name">案例维护</span><span class="fs-val">561</span></div></div>
                            <div class="funnel-arrow mt-1"><span class="tag-rate text-yellow-300 border-yellow-500/30"><i class="fas fa-exchange-alt"></i> 平均器官获取数 1.94</span></div>
                        </div>
                        <div class="funnel-block" id="block-lower" onclick="switchChart('organ')">
                            <div class="funnel-step fs-3"><div class="fs-content"><span class="fs-name">获取/转运完成</span><span class="fs-val">1,089</span></div></div>
                            <div class="funnel-arrow"><span class="tag-rate"><i class="fas fa-check-circle"></i> 成功率 98%</span></div>
                            <div class="funnel-step fs-4"><div class="fs-content"><span class="fs-name">移植成功</span><span class="fs-val">1,067</span></div></div>
                        </div>
                    </div>
                </div>

                <!-- 右:趋势分析 -->
                <div class="panel-box mid-right">
                    <div class="box-title">
                        <span>趋势分析 <span class="chart-tag">年度全量</span></span>
                        <div class="chart-legend" id="chartLegend"></div>
                    </div>
                    <div class="chart-wrapper">
                        <div class="chart-y-axis"><span>150</span><span>100</span><span>50</span><span>0</span></div>
                        <div class="chart-grid-area" id="trendChartContainer"></div>
                    </div>
                </div>
            </div>

            <!-- Row 3: 底部画像 -->
            <div class="bot-row">
                <!-- 器官分布 -->
                <div class="panel-box bot-col">
                    <div class="box-title">获取器官类型分布</div>
                    <div class="donut-wrap">
                        <div class="donut-chart"><div class="donut-center-text"><div class="dc-val">1089</div><div class="dc-lbl">总量</div></div></div>
                        <div class="donut-legend">
                            <div class="dl-item"><div class="dl-color" style="background:var(--color-trans)"></div> 肝脏 (35%)</div>
                            <div class="dl-item"><div class="dl-color" style="background:var(--color-clue)"></div> 肾脏 (25%)</div>
                            <div class="dl-item"><div class="dl-color" style="background:var(--color-case)"></div> 心脏 (20%)</div>
                            <div class="dl-item"><div class="dl-color" style="background:var(--color-organ)"></div> 肺脏 (15%)</div>
                            <div class="dl-item"><div class="dl-color" style="background:#ff453a"></div> 其他 (5%)</div>
                        </div>
                    </div>
                </div>

                <!-- 年龄分布 -->
                <div class="panel-box bot-col">
                    <div class="box-title">捐献者年龄分布</div>
                    <div class="age-chart-container">
                        <div class="age-y-axis"><span>40%</span><span>20%</span><span>0%</span></div>
                        <div class="age-bars-area">
                            <div class="age-col"><div class="age-val">5%</div><div class="age-bar" style="height:12%"></div><span class="age-lbl">&lt;18</span></div>
                            <div class="age-col"><div class="age-val">25%</div><div class="age-bar" style="height:62%"></div><span class="age-lbl">18-35</span></div>
                            <div class="age-col"><div class="age-val">40%</div><div class="age-bar" style="height:100%"></div><span class="age-lbl">36-50</span></div>
                            <div class="age-col"><div class="age-val">20%</div><div class="age-bar" style="height:50%"></div><span class="age-lbl">51-65</span></div>
                            <div class="age-col"><div class="age-val">10%</div><div class="age-bar" style="height:25%"></div><span class="age-lbl">&gt;65</span></div>
                        </div>
                    </div>
                </div>

                <!-- 供体画像 -->
                <div class="panel-box bot-col">
                    <div class="box-title">供体生物学画像</div>
                    <div class="profile-container">
                        <div class="area-left">
                            <div class="prof-group">
                                <div class="prof-title"><i class="fas fa-tint"></i> 血型分布</div>
                                <div class="data-row"><span>A型</span> <span>32%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-blue-500" style="width:32%"></div></div>
                                <div class="data-row"><span>O型</span> <span>30%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-green-500" style="width:30%"></div></div>
                                <div class="data-row"><span>B型</span> <span>28%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-yellow-500" style="width:28%"></div></div>
                                <div class="data-row"><span>AB型</span> <span>10%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-red-500" style="width:10%"></div></div>
                            </div>
                        </div>
                        <div class="area-center"><i class="fas fa-male human-silhouette"></i></div>
                        <div class="area-right">
                            <div class="prof-group">
                                <div class="prof-title"><i class="fas fa-file-signature"></i> 意愿分布</div>
                                <div class="data-row"><span>全部同意</span> <span>40%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-green-500" style="width:40%"></div></div>
                                <div class="data-row"><span>部分同意</span> <span>20%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-teal-500" style="width:20%"></div></div>
                                <div class="data-row"><span>犹豫</span> <span>15%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-yellow-500" style="width:15%"></div></div>
                                <div class="data-row"><span>不同意</span> <span>25%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-red-500" style="width:25%"></div></div>
                            </div>
                        </div>
                        <div class="area-bot-left">
                            <div class="prof-group">
                                <div class="prof-title"><i class="fas fa-venus-mars"></i> 性别分布</div>
                                <div class="data-row"><span>男</span> <span>62%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-blue-400" style="width:62%"></div></div>
                                <div class="data-row"><span>女</span> <span>38%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-pink-400" style="width:38%"></div></div>
                            </div>
                        </div>
                        <div class="area-bot-right">
                            <div class="prof-group">
                                <div class="prof-title"><i class="fas fa-users"></i> 民族分布</div>
                                <div class="data-row"><span>汉族</span> <span>96%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-indigo-500" style="width:96%"></div></div>
                                <div class="data-row"><span>少数民族</span> <span>4%</span></div><div class="data-bar-bg"><div class="data-bar-fill bg-orange-500" style="width:4%"></div></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

        </div>
    </div>

    <script>
        // --- 1. 时间筛选器逻辑 (E-Charts Style) ---
        let timeMode = 'year';
        let currentTime = '2023';

        function switchTimeType(mode) {
            timeMode = mode;
            
            // Update Buttons
            document.querySelectorAll('.tp-btn').forEach(btn => btn.classList.remove('active'));
            event.target.classList.add('active');
            
            // Update Display Text Placeholder
            const valDisplay = document.getElementById('tp-value');
            if (mode === 'year') valDisplay.innerText = '2023';
            if (mode === 'quarter') valDisplay.innerText = '2023 第一季度';
            if (mode === 'month') valDisplay.innerText = '2023-01';
            
            renderPopupContent();
        }

        function togglePopup() {
            const popup = document.getElementById('tp-popup');
            popup.classList.toggle('show');
            if(popup.classList.contains('show')) renderPopupContent();
        }

        function selectTimeValue(val) {
            document.getElementById('tp-value').innerText = val;
            document.getElementById('tp-popup').classList.remove('show');
        }

        function renderPopupContent() {
            const popup = document.getElementById('tp-popup');
            let header = `
                <div class="tp-pop-header">
                    <span class="tp-pop-arrow"><i class="fas fa-angle-double-left"></i></span>
                    <span>2023年</span>
                    <span class="tp-pop-arrow"><i class="fas fa-angle-double-right"></i></span>
                </div>
            `;
            let grid = '';

            if (timeMode === 'month') {
                let items = ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'];
                grid = `<div class="tp-pop-grid grid-month">` + 
                       items.map(m => `<div class="tp-grid-item" onclick="selectTimeValue('2023-${m}')">${m}</div>`).join('') + 
                       `</div>`;
            } else if (timeMode === 'quarter') {
                let items = ['第一季度','第二季度','第三季度','第四季度'];
                grid = `<div class="tp-pop-grid grid-quarter">` + 
                       items.map(q => `<div class="tp-grid-item" onclick="selectTimeValue('2023 ${q}')">${q}</div>`).join('') + 
                       `</div>`;
            } else { // Year
                // Simple placeholder for year grid
                grid = `<div class="tp-pop-grid grid-quarter">
                    <div class="tp-grid-item active" onclick="selectTimeValue('2023')">2023</div>
                    <div class="tp-grid-item" onclick="selectTimeValue('2022')">2022</div>
                    <div class="tp-grid-item" onclick="selectTimeValue('2021')">2021</div>
                    <div class="tp-grid-item" onclick="selectTimeValue('2020')">2020</div>
                </div>`;
            }

            popup.innerHTML = header + grid;
        }

        // --- 2. 趋势图逻辑 (V1.7 保持不变) ---
        const dataCase = [ { m: '1月', v1: 80, v2: 20 }, { m: '2月', v1: 65, v2: 15 }, { m: '3月', v1: 90, v2: 30 }, { m: '4月', v1: 110, v2: 35 }, { m: '5月', v1: 100, v2: 28 }, { m: '6月', v1: 120, v2: 40 }, { m: '7月', v1: 130, v2: 45 }, { m: '8月', v1: 115, v2: 38 }, { m: '9月', v1: 125, v2: 42 }, { m: '10月', v1: 140, v2: 50 }, { m: '11月', v1: 100, v2: 30 }, { m: '12月', v1: 70, v2: 18 } ];
        const dataOrgan = [ { m: '1月', v1: 55, v2: 53 }, { m: '2月', v1: 40, v2: 38 }, { m: '3月', v1: 85, v2: 82 }, { m: '4月', v1: 95, v2: 95 }, { m: '5月', v1: 75, v2: 70 }, { m: '6月', v1: 110, v2: 108 }, { m: '7月', v1: 125, v2: 120 }, { m: '8月', v1: 100, v2: 98 }, { m: '9月', v1: 115, v2: 112 }, { m: '10月', v1: 135, v2: 135 }, { m: '11月', v1: 80, v2: 80 }, { m: '12月', v1: 50, v2: 48 } ];
        let currentChart = 'case';

        function switchChart(type) {
            currentChart = type;
            renderChart();
            updateBlockStyles();
        }

        function updateBlockStyles() {
            const up = document.getElementById('block-upper');
            const low = document.getElementById('block-lower');
            up.classList.remove('active-block-upper');
            low.classList.remove('active-block-lower');
            if(currentChart === 'case') { up.classList.add('active-block-upper'); } else { low.classList.add('active-block-lower'); }
        }

        function renderChart() {
            const container = document.getElementById('trendChartContainer');
            const legend = document.getElementById('chartLegend');
            const data = currentChart === 'case' ? dataCase : dataOrgan;
            const maxVal = 150; 
            const col1 = currentChart === 'case' ? 'var(--color-clue)' : 'var(--color-organ)';
            const col2 = currentChart === 'case' ? 'var(--color-case)' : 'var(--color-trans)';
            const name1 = currentChart === 'case' ? '线索上报' : '器官获取';
            const name2 = currentChart === 'case' ? '捐赠案例' : '成功移植';

            legend.innerHTML = `<div class="legend-item"><div class="dot" style="background:${col1}"></div>${name1}</div><div class="legend-item"><div class="dot" style="background:${col2}"></div>${name2}</div>`;

            container.innerHTML = data.map(d => {
                const h1 = (d.v1 / maxVal) * 100;
                const h2 = (d.v2 / maxVal) * 100;
                return `<div class="chart-col"><div class="bar-group"><div class="bar" style="--h: ${h1}%; background:${col1}"><span class="bar-val-top">${d.v1}</span></div><div class="bar" style="--h: ${h2}%; background:${col2}"><span class="bar-val-top">${d.v2}</span></div></div><div class="x-axis-lbl">${d.m}</div></div>`;
            }).join('');
        }

        switchChart('case');
        
        // 点击外部关闭下拉
        document.addEventListener('click', function(e) {
            if (!e.target.closest('.time-picker-container')) {
                document.getElementById('tp-popup').classList.remove('show');
            }
        });
    </script>
</body>
</html>
        
编辑器加载中
预览
控制台