<!DOCTYPE html>

<html lang="zh-CN">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>居民幸福感导向建成环境智能优化系统</title>

    <!-- Leaflet & ECharts -->

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />

    <script src="https://cdn.tailwindcss.com"></script>

    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>

    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>

    <style>

        :root {

            --panel-bg: rgba(6, 26, 50, 0.3);

            --accent-blue: #00f2ff;

            --border-color: rgba(0, 242, 255, 0.15);

            --text-main: #cbd5e1;

        }

        

        body, html { 

            margin: 0; padding: 0; width: 100vw; height: 100vh; 

            background: #020b1a; 

            font-family: "PingFang SC", "Microsoft YaHei", sans-serif; 

            overflow: hidden; 

            color: var(--text-main); 

        }

        

        #map { 

            height: 100%; width: 100%; z-index: 1; 

            background: #050d18 !important;

        }

        

        .leaflet-tile-pane { 

            filter: invert(100%) hue-rotate(180deg) brightness(0.7) contrast(1.2) grayscale(0.5); 

        }


        .grid-overlay {

            position: fixed;

            top: 0; left: 0; width: 100%; height: 100%;

            background-image: radial-gradient(rgba(0, 242, 255, 0.05) 0.5px, transparent 0.5px);

            background-size: 60px 60px;

            pointer-events: none;

            z-index: 5;

            opacity: 0.1;

        }


        .glass-panel {

            background: var(--panel-bg);

            border: 1px solid var(--border-color);

            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);

            backdrop-filter: blur(8px);

            -webkit-backdrop-filter: blur(8px);

            display: flex;

            flex-direction: column;

            padding: 10px;

            overflow: hidden;

            border-radius: 6px;

        }

        

        .panel-title {

            color: #fff; font-size: 11px; font-weight: bold;

            display: flex; align-items: center; margin-bottom: 8px;

            flex-shrink: 0; letter-spacing: 0.5px;

            text-shadow: 0 0 10px rgba(0, 242, 255, 0.5);

        }

        .panel-title::before {

            content: ""; width: 3px; height: 11px; background: var(--accent-blue);

            margin-right: 6px; box-shadow: 0 0 8px var(--accent-blue);

        }


        .header {

            position: absolute; top: 0; left: 0; width: 100%; height: 50px;

            background: linear-gradient(180deg, rgba(2,11,26,0.6) 0%, rgba(2,11,26,0.1) 100%);

            backdrop-filter: blur(4px);

            z-index: 100; display: flex; justify-content: space-between; align-items: center;

            padding: 0 25px; border-bottom: 1px solid rgba(0, 242, 255, 0.1);

        }


        .side-container {

            position: absolute; top: 65px; bottom: 15px;

            display: flex; flex-direction: column; gap: 12px;

            z-index: 20; transition: all 0.4s ease;

        }

        

        .home-width { width: 230px; }

        .detail-width { width: 32vw; min-width: 480px; } 

        .left-side { left: 15px; }

        .right-side { right: 15px; }

        

        .chart-wrapper { flex: 1; width: 100%; min-height: 0; position: relative; }

        .horizontal-scroll-box { flex: 1; width: 100%; overflow-x: auto; overflow-y: hidden; cursor: grab; }

        .scroll-content { height: 100%; min-width: 450px; }

        .scroll-content-wide { height: 100%; min-width: 800px; }


        .data-table { width: 100%; font-size: 10px; border-collapse: collapse; }

        .data-table th { 

            color: var(--accent-blue); text-align: left; padding: 6px 4px; 

            border-bottom: 1px solid rgba(0, 242, 255, 0.2); 

            position: sticky; top: 0; background: rgba(8, 29, 58, 0.4); z-index: 1; 

        }

        .data-table td { padding: 6px 4px; border-bottom: 1px solid rgba(255, 255, 255, 0.05); }


        .scroll-custom::-webkit-scrollbar { height: 3px; width: 3px; }

        .scroll-custom::-webkit-scrollbar-thumb { background: rgba(0, 242, 255, 0.3); border-radius: 10px; }


        .nav-item { cursor: pointer; transition: all 0.3s; padding: 4px 0; position: relative; color: rgba(255,255,255,0.7); }

        .nav-item:hover { color: #fff; }

        .nav-item.active { color: var(--accent-blue); font-weight: bold; }

        .nav-item.active::after { content: ""; position: absolute; bottom: 0; left: 0; width: 100%; height: 2px; background: var(--accent-blue); box-shadow: 0 0 10px var(--accent-blue); }


        .hidden-panel { display: none !important; }


        .custom-select {

            background: rgba(8, 29, 58, 0.3); border: 1px solid rgba(0, 242, 255, 0.3);

            color: #fff; font-size: 10px; padding: 2px 4px; border-radius: 2px;

            outline: none; width: 100%; cursor: pointer;

        }


        .analysis-text-container { font-size: 10px; line-height: 1.6; color: #cbd5e1; padding-right: 8px; }

        .keyword-highlight { color: var(--accent-blue); font-weight: bold; text-shadow: 0 0 5px rgba(0, 242, 255, 0.3); }

        .important-term { color: #facc15; font-weight: bold; }

        .text-section-title { color: #fff; font-weight: bold; margin-top: 8px; margin-bottom: 4px; display: block; border-bottom: 1px solid rgba(0, 242, 255, 0.1); padding-bottom: 2px; }


        /* Leaflet Popup 样式优化 */

        .leaflet-popup-content-wrapper { 

            background: rgba(255, 255, 255, 0.95) !important; 

            color: #1a1a1a !important; 

            border-radius: 6px !important; 

            box-shadow: 0 4px 15px rgba(0,0,0,0.3) !important;

            border: 1px solid rgba(0, 242, 255, 0.5);

        }

        .leaflet-popup-tip { background: rgba(255, 255, 255, 0.95) !important; }


        .embedded-analysis-img { 

            width: 100%; height: 100%;

            object-fit: contain; 

            border: none;

            background: rgba(0, 0, 0, 0.2);

        }

    </style>

</head>

<body>


    <div class="grid-overlay"></div>

    <div id="map"></div>


    <header class="header">

        <div>

            <h1 class="text-base font-bold italic text-white tracking-tight">居民幸福感导向建成环境智能优化系统</h1>

            <p class="text-[7px] tracking-[0.2em] text-cyan-400 uppercase">Intelligent Built Environment Optimization System</p>

        </div>

        <nav class="flex space-x-8 text-[11px]">

            <span id="nav-home" class="nav-item active" onclick="switchTab('home')">首页</span>

            <span id="nav-detail" class="nav-item" onclick="switchTab('detail')">指标详情</span>

        </nav>

    </header>


    <!-- [首页视图] -->

    <div id="home-left" class="side-container left-side home-width">

        <div class="glass-panel flex-[1.1]">

            <div class="panel-title">主导情绪数目统计</div>

            <div id="pieChart" class="chart-wrapper"></div>

        </div>

        <div class="glass-panel flex-[1.1]">

            <div class="panel-title">主导情绪波动统计</div>

            <div class="horizontal-scroll-box scroll-custom">

                <div class="scroll-content">

                    <div id="lineChart" class="w-full h-full"></div>

                </div>

            </div>

        </div>

        <div class="glass-panel flex-[1]">

            <div class="panel-title">各街道幸福感指数</div>

            <div class="horizontal-scroll-box scroll-custom">

                <div class="scroll-content-wide">

                    <div id="barChart" class="w-full h-full"></div>

                </div>

            </div>

        </div>

    </div>


    <div id="home-right" class="side-container right-side home-width">

        <div class="glass-panel" style="height: 150px; flex-shrink: 0;">

            <div class="panel-title">幸福感总体评价</div>

            <div class="flex justify-around items-center h-full">

                <div class="text-center">

                    <div id="gauge1" style="width:90px; height:90px;"></div>

                    <div class="text-[8px] -mt-2 text-cyan-400 font-bold">综合指数</div>

                </div>

                <div class="text-center">

                    <div id="gauge2" style="width:90px; height:90px;"></div>

                    <div class="text-[8px] -mt-2 text-cyan-400 font-bold">环境匹配</div>

                </div>

            </div>

        </div>

        <div class="glass-panel flex-1">

            <div class="panel-title">各街道幸福感排名</div>

            <div class="flex-1 overflow-y-auto scroll-custom">

                <table class="data-table">

                    <thead>

                        <tr><th>街道</th><th>数值</th><th>趋势</th></tr>

                    </thead>

                    <tbody id="rankTable"></tbody>

                </table>

            </div>

        </div>

    </div>


    <!-- [指标详情页] -->

    <div id="detail-left" class="side-container left-side home-width hidden-panel">

        <div class="glass-panel" style="padding: 10px;">

            <div class="panel-title">关键建成环境指标探索</div>

            <div class="flex flex-col gap-3 mt-1">

                <div>

                    <label class="text-[9px] text-cyan-400/80 mb-1 block">一级指标</label>

                    <select id="mainCategory" class="custom-select" onchange="updateSubCategory()">

                        <option value="1">1.道路交通指标</option>

                        <option value="2" selected>2.建筑宜居指标</option>

                        <option value="3">3.社会经济指标</option>

                        <option value="4">4.功能复合指标</option>

                    </select>

                </div>

                <div>

                    <label class="text-[9px] text-cyan-400/80 mb-1 block">二级指标</label>

                    <select id="subCategory" class="custom-select" onchange="checkVisibility()">

                    </select>

                </div>

            </div>

        </div>

    </div>


    <div id="detail-right" class="side-container right-side detail-width hidden-panel">

        <div id="detailContentContainer" class="flex flex-col gap-3 h-full hidden-panel">

            <div class="flex gap-3 h-[38%]">

                <div class="glass-panel flex-1">

                    <div class="panel-title">容积率指标汇总表</div>

                    <div id="detailRadar" class="chart-wrapper"></div>

                </div>

                <div class="glass-panel flex-[1.6]">

                    <div class="panel-title">智能规划建议</div>

                    <div class="chart-wrapper overflow-y-auto scroll-custom analysis-text-container pr-1">

                        <div class="mb-2">

                            <span class="text-section-title">关键词——<span class="keyword-highlight">最优容积率区间:0.8 - 1.5</span></span>

                        </div>

                        <div class="text-justify">

                            <span class="text-section-title">分析过程——</span>

                            <p class="mb-2">观察散点图,高幸福感(紫色点)主要分布在幸福感评分 <span class="important-term">65-80</span> 的区域,对应的容积率集中在 <span class="important-term">0.5-1.5</span> 之间,其中 <span class="keyword-highlight">0.8-1.5</span> 最为密集。</p>

                            <p class="mb-2">当容积率低于0.5时,虽然也有高幸福感点,但这些样本在南京建成区中极其稀少(多位于远郊),不具备普遍性。当容积率超过1.5时,高幸福感点开始明显减少,超过2.0后几乎消失。</p>

                            <p class="mb-2">南京主城区现状容积率普遍在1.2-2.5之间。容积率低于0.8意味着别墅、低密度洋房,这类产品仅占市场供应量的5%以下,且单价极高,不具备普遍参考价值。</p>

                            <p class="mb-2">因此,具有建设指导意义的区间应该是 <span class="important-term">0.8-1.5</span> ——这个区间对应的是 <span class="important-term">6-11 层的小高层住宅</span>,既能保证居住舒适度(一梯两户、南北通透、楼间距充裕),又具备现实可操作性。</p>

                            <p>超过1.5则进入高层住宅范畴,人口密度上升、电梯等待时间增加、公共空间被压缩,幸福感开始下降。所以,数据与现实的交集告诉我们:在南京建成区,容积率控制在 <span class="keyword-highlight">1.0-1.5</span> 之间的小高层社区,是幸福感与可操作性的最佳平衡点。</p>

                        </div>

                    </div>

                </div>

            </div>

            <div class="glass-panel flex-[2] p-0 overflow-hidden">

                <div class="panel-title px-3 pt-3">幸福感与容积率关系分析</div>

                <div class="chart-wrapper flex items-center justify-center overflow-hidden">

                    <img id="analysisImg" src="https://i.imgs.ovh/2026/04/08/ZHuRKh.jpeg" class="embedded-analysis-img" alt="分析图">

                </div>

            </div>

        </div>

        <div id="detailPlaceholder" class="glass-panel flex-1">

            <div class="empty-state flex flex-col items-center justify-center h-full text-cyan-400/30 text-xs">

                <span>请在左侧选择具体指标以查看详细分析</span>

            </div>

        </div>

    </div>


    <script>

        const geojsonData = {

            "type": "FeatureCollection",

            "name": "南京幸福感大样本数据",

            "features": [

                { "type": "Feature", "properties": { "幸福感": 92.16, "街道": "宁海路街道" }, "geometry": { "type": "Point", "coordinates": [ 118.905248, 32.109082 ] } },

                { "type": "Feature", "properties": { "幸福感": 92.56, "街道": "华侨路街道" }, "geometry": { "type": "Point", "coordinates": [ 118.790343, 32.156244 ] } },

                { "type": "Feature", "properties": { "幸福感": 87.21, "街道": "湖南路街道" }, "geometry": { "type": "Point", "coordinates": [ 118.835926, 32.168242 ] } },

                { "type": "Feature", "properties": { "幸福感": 92.16, "街道": "中央门街道" }, "geometry": { "type": "Point", "coordinates": [ 118.750558, 32.017352 ] } },

                { "type": "Feature", "properties": { "幸福感": 94.19, "街道": "挹江门街道" }, "geometry": { "type": "Point", "coordinates": [ 118.70892, 31.977134 ] } },

                { "type": "Feature", "properties": { "幸福感": 98.14, "街道": "江东街道" }, "geometry": { "type": "Point", "coordinates": [ 118.719673, 32.011841 ] } },

                { "type": "Feature", "properties": { "幸福感": 77.67, "街道": "莫愁湖街道" }, "geometry": { "type": "Point", "coordinates": [ 118.737599, 32.037651 ] } },

                { "type": "Feature", "properties": { "幸福感": 85.58, "街道": "建邺街道" }, "geometry": { "type": "Point", "coordinates": [ 118.653587, 31.97263 ] } },

                { "type": "Feature", "properties": { "幸福感": 65.42, "街道": "栖霞街道" }, "geometry": { "type": "Point", "coordinates": [ 118.8982, 32.1321 ] } },

                { "type": "Feature", "properties": { "幸福感": 82.11, "街道": "新街口街道" }, "geometry": { "type": "Point", "coordinates": [ 118.7831, 32.0425 ] } },

                { "type": "Feature", "properties": { "幸福感": 74.88, "街道": "迈皋桥街道" }, "geometry": { "type": "Point", "coordinates": [ 118.8122, 32.1054 ] } },

                { "type": "Feature", "properties": { "幸福感": 91.32, "街道": "燕子矶街道" }, "geometry": { "type": "Point", "coordinates": [ 118.8251, 32.1481 ] } },

                { "type": "Feature", "properties": { "幸福感": 79.25, "街道": "后宰门街道" }, "geometry": { "type": "Point", "coordinates": [ 118.8093, 32.0461 ] } },

                { "type": "Feature", "properties": { "幸福感": 88.64, "街道": "朝天宫街道" }, "geometry": { "type": "Point", "coordinates": [ 118.7752, 32.0354 ] } },

                { "type": "Feature", "properties": { "幸福感": 71.55, "街道": "红山街道" }, "geometry": { "type": "Point", "coordinates": [ 118.8105, 32.0894 ] } },

                { "type": "Feature", "properties": { "幸福感": 83.47, "街道": "夫子庙街道" }, "geometry": { "type": "Point", "coordinates": [ 118.7901, 32.0182 ] } },

                { "type": "Feature", "properties": { "幸福感": 95.80, "街道": "双闸街道" }, "geometry": { "type": "Point", "coordinates": [ 118.6952, 31.9785 ] } },

                { "type": "Feature", "properties": { "幸福感": 68.91, "街道": "玄武门街道" }, "geometry": { "type": "Point", "coordinates": [ 118.7952, 32.0652 ] } },

                { "type": "Feature", "properties": { "幸福感": 76.33, "街道": "五老村街道" }, "geometry": { "type": "Point", "coordinates": [ 118.7981, 32.0381 ] } },

                { "type": "Feature", "properties": { "幸福感": 84.19, "街道": "龙江街道" }, "geometry": { "type": "Point", "coordinates": [ 118.7352, 32.0582 ] } },

                { "type": "Feature", "properties": { "幸福感": 90.15, "街道": "仙林街道" }, "geometry": { "type": "Point", "coordinates": [ 118.917, 32.102 ] } },

                { "type": "Feature", "properties": { "幸福感": 62.45, "街道": "西善桥街道" }, "geometry": { "type": "Point", "coordinates": [ 118.718, 31.954 ] } },

                { "type": "Feature", "properties": { "幸福感": 78.90, "街道": "赛虹桥街道" }, "geometry": { "type": "Point", "coordinates": [ 118.761, 32.002 ] } },

                { "type": "Feature", "properties": { "幸福感": 85.32, "街道": "梅山街道" }, "geometry": { "type": "Point", "coordinates": [ 118.635, 31.902 ] } },

                { "type": "Feature", "properties": { "幸福感": 94.67, "街道": "顶山街道" }, "geometry": { "type": "Point", "coordinates": [ 118.692, 32.084 ] } },

                { "type": "Feature", "properties": { "幸福感": 88.12, "街道": "泰山街道" }, "geometry": { "type": "Point", "coordinates": [ 118.721, 32.135 ] } },

                { "type": "Feature", "properties": { "幸福感": 71.44, "街道": "雨花街道" }, "geometry": { "type": "Point", "coordinates": [ 118.775, 31.985 ] } },

                { "type": "Feature", "properties": { "幸福感": 69.21, "街道": "铁心桥街道" }, "geometry": { "type": "Point", "coordinates": [ 118.785, 31.962 ] } },

                { "type": "Feature", "properties": { "幸福感": 96.45, "街道": "兴隆街道" }, "geometry": { "type": "Point", "coordinates": [ 118.725, 32.001 ] } },

                { "type": "Feature", "properties": { "幸福感": 82.56, "街道": "沙洲街道" }, "geometry": { "type": "Point", "coordinates": [ 118.712, 31.975 ] } },

                { "type": "Feature", "properties": { "幸福感": 89.92, "街道": "南苑街道" }, "geometry": { "type": "Point", "coordinates": [ 118.742, 32.022 ] } },

                { "type": "Feature", "properties": { "幸福感": 76.81, "街道": "莫愁湖街道" }, "geometry": { "type": "Point", "coordinates": [ 118.735, 32.038 ] } },

                { "type": "Feature", "properties": { "幸福感": 91.21, "街道": "江东路" }, "geometry": { "type": "Point", "coordinates": [ 118.724, 32.031 ] } },

                { "type": "Feature", "properties": { "幸福感": 84.55, "街道": "汉中门" }, "geometry": { "type": "Point", "coordinates": [ 118.765, 32.042 ] } },

                { "type": "Feature", "properties": { "幸福感": 68.32, "街道": "瑞金路" }, "geometry": { "type": "Point", "coordinates": [ 118.812, 32.032 ] } },

                { "type": "Feature", "properties": { "幸福感": 72.89, "街道": "光华路" }, "geometry": { "type": "Point", "coordinates": [ 118.834, 32.018 ] } },

                { "type": "Feature", "properties": { "幸福感": 93.11, "街道": "大行宫" }, "geometry": { "type": "Point", "coordinates": [ 118.795, 32.042 ] } },

                { "type": "Feature", "properties": { "幸福感": 79.45, "街道": "月牙湖" }, "geometry": { "type": "Point", "coordinates": [ 118.831, 32.035 ] } },

                { "type": "Feature", "properties": { "幸福感": 86.72, "街道": "紫金山" }, "geometry": { "type": "Point", "coordinates": [ 118.855, 32.062 ] } },

                { "type": "Feature", "properties": { "幸福感": 90.54, "街道": "锁金村" }, "geometry": { "type": "Point", "coordinates": [ 118.815, 32.078 ] } }

            ]

        };


        let map;

        const charts = [];

        let pointLayer;

        let currentTab = 'home'; 


        function getColor(v) {

            return v > 90 ? '#d946ef' : v > 80 ? '#3b82f6' : v > 70 ? '#06b6d4' : v > 60 ? '#22c55e' : '#eab308';

        }


        function initMap() {

            map = L.map('map', { 

                center: [32.05, 118.78], 

                zoom: 12, zoomControl: false, attributionControl: false,

                renderer: L.canvas({ tolerance: 5 }) 

            });

            

            L.tileLayer('https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {

                subdomains: ['1', '2', '3', '4']

            }).addTo(map);


            pointLayer = L.geoJSON(geojsonData, {

                pointToLayer: function (feature, latlng) {

                    const val = feature.properties.幸福感;

                    return L.circleMarker(latlng, {

                        radius: 6, fillColor: getColor(val), color: "#ffffff",

                        weight: 1.5, opacity: 0.8, fillOpacity: 0.9, interactive: true

                    });

                },

                onEachFeature: function (feature, layer) {

                    layer.on('mouseover', function(e) {

                        if (currentTab !== 'home') return;

                        const val = feature.properties.幸福感;

                        const street = feature.properties.街道;

                        const color = getColor(val);

                        const content = `

                            <div style="min-width:140px; padding: 5px;">

                                <div style="font-size: 13px; font-weight: bold; color: #1a1a1a; margin-bottom: 4px; border-bottom: 1px solid #eee; padding-bottom: 2px;">${street}</div>

                                <div style="font-size: 10px; color: #666; margin-bottom: 4px;">居民幸福感指数</div>

                                <div style="font-size: 26px; font-weight: 900; color: ${color}; line-height: 1;">${val}<span style="font-size: 14px; margin-left: 2px;">%</span></div>

                            </div>

                        `;

                        L.popup({ closeButton: false, autoPan: false, offset: [0, -8] })

                        .setLatLng(e.latlng).setContent(content).openOn(map);

                        this.setStyle({ radius: 9, weight: 3, opacity: 1 });

                    });

                    layer.on('mouseout', function() {

                        map.closePopup();

                        this.setStyle({ radius: 6, weight: 1.5, opacity: 0.8 });

                    });

                }

            }).addTo(map);


            if (geojsonData.features.length > 0) {

                map.fitBounds(pointLayer.getBounds(), { padding: [80, 80] });

            }

        }


        function initHomeCharts() {

            const commonAxis = { 

                axisLine:{lineStyle:{color:'rgba(0,242,255,0.1)'}}, 

                axisLabel:{color:'#94a3b8', fontSize:7}, 

                splitLine:{show:false}

            };

            

            // 模块一:主导情绪数目统计 - 修复点击显示不完整问题

            const pie = echarts.init(document.getElementById('pieChart'));

            pie.setOption({

                tooltip: { 

                    trigger: 'item', 

                    backgroundColor: 'rgba(8, 29, 58, 0.95)', 

                    borderColor: 'rgba(0, 242, 255, 0.4)', 

                    borderWidth: 1, 

                    textStyle: { color: '#fff', fontSize: 10 },

                    // 自定义显示格式,确保包含:主导情绪、数量、占比

                    formatter: function(params) {

                        return `<div style="padding:4px">

                                    <b style="color:${params.color}; font-size:11px">${params.name}</b><br/>

                                    数量:${params.value}<br/>

                                    占比:${params.percent}%

                                </div>`;

                    }

                },

                legend: { 

                    orient: 'vertical', right: '2%', top: 'center', 

                    itemWidth: 8, itemHeight: 8, 

                    textStyle: { color: '#cbd5e1', fontSize: 9 } 

                },

                color: ['#00f2ff', '#0095ff', '#32c5ff', '#1e40af', '#fbbf24', '#475569'],

                series: [{ 

                    type: 'pie', radius: ['45%', '70%'], center: ['35%', '50%'], 

                    avoidLabelOverlap: true,

                    label: { show: false }, 

                    data: [

                        { value: 160983, name: '快乐' }, 

                        { value: 25793, name: '伤心' }, 

                        { value: 19499, name: '惊讶' }, 

                        { value: 13021, name: '厌恶' }, 

                        { value: 9380, name: '愤怒' }, 

                        { value: 2424, name: '恐惧' }

                    ] 

                }]

            });

            charts.push(pie);


            // 模块二:主导情绪波动统计

            const line = echarts.init(document.getElementById('lineChart'));

            const pseudoNames = Array.from({length: 15}, (_, i) => `${i+1}街道`);

            line.setOption({

                grid: { top: 10, bottom: 20, left: 25, right: 5 },

                xAxis: { ...commonAxis, type: 'category', data: pseudoNames },

                yAxis: commonAxis,

                series: [{ type: 'line', smooth: true, data: pseudoNames.map(() => Math.floor(Math.random()*50 + 100)), color: '#00f2ff', areaStyle: { color: 'rgba(0,242,255,0.04)' } }]

            });

            charts.push(line);


            // 模块三:各街道幸福感指数 - 左右滑动折线图保持同步

            const bar = echarts.init(document.getElementById('barChart'));

            const streetDataForLine = geojsonData.features.map(f => ({

                name: f.properties.街道,

                val: f.properties.幸福感

            }));


            bar.setOption({

                grid: { top: 15, bottom: 25, left: 30, right: 15 },

                tooltip: { 

                    trigger: 'axis', 

                    backgroundColor: 'rgba(8, 29, 58, 0.9)', 

                    textStyle: {color: '#fff', fontSize: 10} 

                },

                xAxis: { 

                    ...commonAxis, 

                    type: 'category', 

                    data: streetDataForLine.map(d => d.name),

                    axisLabel: { ...commonAxis.axisLabel, interval: 0, rotate: 35 }

                },

                yAxis: { ...commonAxis, min: 50 },

                series: [{ 

                    type: 'line', 

                    data: streetDataForLine.map(d => d.val), 

                    smooth: true, 

                    symbol: 'circle',

                    symbolSize: 4,

                    itemStyle: { color: '#00f2ff' },

                    lineStyle: { width: 2, shadowBlur: 10, shadowColor: 'rgba(0,242,255,0.5)' },

                    areaStyle: {

                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [

                            { offset: 0, color: 'rgba(0,242,255,0.3)' },

                            { offset: 1, color: 'rgba(0,242,255,0)' }

                        ])

                    }

                }]

            });

            charts.push(bar);


            const createGauge = (id, val, color) => {

                const chart = echarts.init(document.getElementById(id));

                chart.setOption({

                    series: [{

                        type: 'gauge', radius: '100%', startAngle: 210, endAngle: -30,

                        progress: { show: true, width: 3, itemStyle: { color: color } },

                        detail: { formatter: '{value}%', color: '#fff', fontSize: 10, offsetCenter: [0, '30%'] },

                        data: [{ value: val }],

                        axisLine: { lineStyle: { width: 2, color: [[1, 'rgba(255,255,255,0.05)']] } },

                        axisTick: { show: false }, splitLine: { show: false }, axisLabel: { show: false }, pointer: { show: false }

                    }]

                });

                charts.push(chart);

            };

            createGauge('gauge1', 84, '#00f2ff');

            createGauge('gauge2', 68, '#3b82f6');

        }


        const subData = {

            "1": ["1.1 公交站点密度", "1.2 主干路网密度", "1.3 次干路网密度", "1.4 支路网密度", "1.5 交叉口密度", "1.6 地铁交通可达性"],

            "2": ["2.1 生活圈容积率", "2.2 生活圈建筑密度"],

            "3": ["3.1 人口密度", "3.2 平均房价", "3.3 人均GDP", "3.4 失业率"],

            "4": ["4.1 混合度指数", "4.2 POI多样性", "4.3 产城融合度"]

        };


        function updateSubCategory() {

            const mainVal = document.getElementById('mainCategory').value;

            const subSelect = document.getElementById('subCategory');

            subSelect.innerHTML = "";

            (subData[mainVal] || []).forEach((item, index) => {

                const opt = document.createElement('option');

                opt.value = mainVal + "." + (index + 1);

                opt.textContent = item;

                subSelect.appendChild(opt);

            });

            checkVisibility();

        }


        function checkVisibility() {

            const mainVal = document.getElementById('mainCategory').value;

            const subVal = document.getElementById('subCategory').value;

            const content = document.getElementById('detailContentContainer');

            const placeholder = document.getElementById('detailPlaceholder');

            if (mainVal === "2" && subVal === "2.1") {

                content.classList.remove('hidden-panel');

                placeholder.classList.add('hidden-panel');

                setTimeout(() => charts.forEach(c => c.resize()), 50);

            } else {

                content.classList.add('hidden-panel');

                placeholder.classList.remove('hidden-panel');

            }

        }


        function initDetailCharts() {

            const radar = echarts.init(document.getElementById('detailRadar'));

            radar.setOption({

                radar: {

                    indicator: [{name:'容积率',max:100},{name:'绿化',max:100},{name:'公服',max:100},{name:'交通',max:100},{name:'建筑',max:100}],

                    name: { textStyle: { color: '#94a3b8', fontSize: 8 } },

                    splitArea: { show: false }, splitLine: { lineStyle: { color: 'rgba(0,242,255,0.05)' } }

                },

                series: [{ type:'radar', data:[{value:[85,70,80,65,75]}], itemStyle:{color:'#00f2ff'}, areaStyle:{color:'rgba(0,242,255,0.05)'}}]

            });

            charts.push(radar);

        }


        function populateData() {

            const rankTable = document.getElementById('rankTable');

            const streetsFromGeo = geojsonData.features.map(f => ({

                name: f.properties.街道 || "未名街道",

                val: f.properties.幸福感 || 0

            }));

            const sortedStreets = streetsFromGeo.sort((a, b) => b.val - a.val);

            rankTable.innerHTML = ""; 

            sortedStreets.forEach((s) => {

                rankTable.innerHTML += `

                    <tr>

                        <td class="text-white/60 py-2">${s.name}</td>

                        <td class="text-cyan-400 font-mono">${s.val.toFixed(2)}</td>

                        <td class="${s.val > 80 ? 'text-green-400' : 'text-yellow-400'} text-[8px]">${s.val > 85 ? '▲' : '▬'}</td>

                    </tr>

                `;

            });

        }


        function switchTab(tab) {

            currentTab = tab; 

            document.querySelectorAll('.nav-item').forEach(el => el.classList.remove('active'));

            document.getElementById(`nav-${tab}`).classList.add('active');

            map.closePopup();


            const isHome = (tab === 'home');

            document.getElementById('home-left').classList.toggle('hidden-panel', !isHome);

            document.getElementById('home-right').classList.toggle('hidden-panel', !isHome);

            document.getElementById('detail-left').classList.toggle('hidden-panel', isHome);

            document.getElementById('detail-right').classList.toggle('hidden-panel', isHome);

            

            if (isHome) {

                if (!map.hasLayer(pointLayer)) map.addLayer(pointLayer);

            } else {

                if (map.hasLayer(pointLayer)) map.removeLayer(pointLayer);

                checkVisibility();

            }

            setTimeout(() => charts.forEach(c => c.resize()), 200);

        }


        window.onload = function() {

            initMap();

            initHomeCharts();

            initDetailCharts();

            populateData();

            updateSubCategory();

        };


        window.onresize = () => charts.forEach(c => c.resize());

    </script>

</body>

</html>