能碳平台大屏改版edit 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>2024年度能碳数据核算与ESG评价全景</title>
    <!-- 引入 ECharts -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <!-- 引入图标库 -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        /* --- 全局变量与重置 --- */
        :root {
            --bg-color: #0B1A2F;
            --panel-bg: rgba(13, 25, 45, 0.85);
            --border-color: rgba(64, 169, 255, 0.2);
            --text-main: #ffffff;
            --text-sub: #8c9bb3;
            
            --color-gold: #D4AF37;       /* 碳资产/VIP */
            --color-blue: #00BFFF;       /* 能耗/科技 */
            --color-green: #00E396;      /* ESG/环保 */
            --color-silver: #E0E0E0;     /* 强度/辅助 */
            
            --font-family: 'Inter', 'Microsoft YaHei', sans-serif;
        }

        * { margin: 0; padding: 0; box-sizing: border-box; }
        
        body {
            background-color: var(--bg-color);
            background-image: 
                radial-gradient(circle at 50% 50%, rgba(0, 191, 255, 0.05) 0%, transparent 60%),
                linear-gradient(0deg, rgba(0,0,0,0.2) 1px, transparent 1px),
                linear-gradient(90deg, rgba(0,0,0,0.2) 1px, transparent 1px);
            background-size: 100% 100%, 40px 40px, 40px 40px;
            color: var(--text-main);
            font-family: var(--font-family);
            overflow: hidden; /* 大屏通常不滚动 */
            width: 100vw;
            height: 100vh;
        }

        /* --- 布局结构 --- */
        .container {
            display: grid;
            grid-template-rows: 80px 1fr;
            height: 100%;
            padding: 0 20px 20px;
            gap: 15px;
        }

        /* --- 头部 --- */
        header {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            background: url('https://assets.codepen.io/13471/sparkle.png') no-repeat center;
            background-size: contain;
            border-bottom: 1px solid var(--border-color);
            position: relative;
        }
        header h1 {
            font-size: 32px;
            letter-spacing: 2px;
            text-shadow: 0 0 10px rgba(0, 191, 255, 0.5);
            background: linear-gradient(to bottom, #fff, #8ec5fc);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        header .subtitle {
            font-size: 12px;
            color: var(--text-sub);
            text-transform: uppercase;
            letter-spacing: 1px;
            margin-top: 5px;
        }

        /* --- 主体内容区 --- */
        main {
            display: grid;
            grid-template-columns: 25% 45% 30%;
            gap: 20px;
            height: 100%;
        }

        /* --- 通用面板样式 --- */
        .panel {
            background: var(--panel-bg);
            border: 1px solid var(--border-color);
            border-radius: 8px;
            padding: 15px;
            display: flex;
            flex-direction: column;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
            backdrop-filter: blur(10px);
            position: relative;
        }
        .panel::before {
            content: '';
            position: absolute;
            top: 0; left: 0; width: 10px; height: 10px;
            border-top: 2px solid var(--color-blue);
            border-left: 2px solid var(--color-blue);
        }
        .panel::after {
            content: '';
            position: absolute;
            bottom: 0; right: 0; width: 10px; height: 10px;
            border-bottom: 2px solid var(--color-blue);
            border-right: 2px solid var(--color-blue);
        }

        .panel-title {
            font-size: 16px;
            font-weight: bold;
            padding-left: 10px;
            border-left: 4px solid var(--color-blue);
            margin-bottom: 10px;
            display: flex;
            justify-content: space-between;
            align-items: baseline;
        }
        .panel-title span.en {
            font-size: 10px;
            color: var(--text-sub);
            font-weight: normal;
            margin-left: 8px;
        }

        /* --- 左侧列 --- */
        .left-col { display: grid; grid-template-rows: 30% 35% 35%; gap: 15px; }
        
        #chart-energy, #chart-carbon { width: 100%; height: 100%; }

        /* ESG 部分 */
        .esg-container {
            display: flex;
            flex-direction: column;
            gap: 15px;
            height: 100%;
        }
        .esg-stat {
            display: flex;
            justify-content: space-between;
            margin-bottom: 5px;
            font-size: 14px;
        }
        .progress-bg {
            background: rgba(255,255,255,0.1);
            height: 8px;
            border-radius: 4px;
            overflow: hidden;
        }
        .progress-bar {
            height: 100%;
            background: var(--color-green);
            width: 0;
            transition: width 1.5s ease-out;
        }
        
        .esg-report-box {
            display: flex;
            align-items: center;
            background: rgba(255,255,255,0.05);
            padding: 15px;
            border-radius: 8px;
            margin-top: auto;
        }
        .report-cover {
            width: 50px;
            height: 70px;
            background: linear-gradient(135deg, #1e3c72, #2a5298);
            border: 1px solid #fff;
            margin-right: 15px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 8px;
            text-align: center;
            box-shadow: 2px 2px 5px rgba(0,0,0,0.5);
            transform: perspective(500px) rotateY(-15deg);
            transition: transform 0.3s;
        }
        .esg-report-box:hover .report-cover {
            transform: perspective(500px) rotateY(0deg) scale(1.1);
        }
        .report-info h4 { color: var(--color-green); margin-bottom: 4px; }
        .report-info p { font-size: 12px; color: var(--text-sub); }

        /* --- 中间列 (核心) --- */
        .center-col {
            display: flex;
            flex-direction: column;
            gap: 20px;
        }

        /* 顶部 KPI 卡片 */
        .kpi-wrapper {
            display: flex;
            justify-content: space-between;
            gap: 15px;
        }
        .kpi-card {
            flex: 1;
            background: rgba(0, 191, 255, 0.05);
            border: 1px solid rgba(0, 191, 255, 0.1);
            padding: 15px 10px;
            text-align: center;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s;
            position: relative;
        }
        .kpi-card:hover { transform: translateY(-2px); background: rgba(0, 191, 255, 0.1); }
        .kpi-card.active {
            border-color: var(--color-gold);
            background: linear-gradient(to bottom, rgba(212, 175, 55, 0.1), transparent);
            box-shadow: 0 0 15px rgba(212, 175, 55, 0.2);
        }
        .kpi-card .label { font-size: 14px; color: var(--text-sub); display: block; margin-bottom: 5px; }
        .kpi-card .value { font-size: 28px; font-weight: bold; font-family: 'Arial'; }
        .kpi-card .unit { font-size: 12px; margin-left: 2px; }
        
        .val-carbon { color: var(--color-gold); }
        .val-energy { color: var(--color-blue); }
        .val-intensity { color: var(--text-main); }

        /* 拓扑图区域 */
        .topology-container {
            flex: 1;
            position: relative;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding-top: 10px;
        }
        
        /* Level 1: 集团 */
        .node-root {
            background: linear-gradient(90deg, #0b3d66, #16588f);
            padding: 10px 30px;
            border-radius: 20px;
            border: 1px solid var(--color-blue);
            box-shadow: 0 0 15px var(--color-blue);
            margin-bottom: 30px;
            z-index: 2;
        }

        /* Level 2: 边界 (A-F) */
        .boundary-row {
            display: flex;
            justify-content: space-between;
            width: 100%;
            margin-bottom: 40px;
            position: relative;
        }
        /* 连接线 */
        .boundary-row::before {
            content: ''; position: absolute; top: -20px; left: 10%; right: 10%; height: 20px;
            border-top: 1px dashed rgba(255,255,255,0.2);
            border-left: 1px dashed rgba(255,255,255,0.2);
            border-right: 1px dashed rgba(255,255,255,0.2);
            z-index: 0;
        }
        .boundary-card {
            background: rgba(255,255,255,0.05);
            font-size: 10px;
            padding: 5px 8px;
            border-radius: 4px;
            color: var(--text-sub);
            text-align: center;
            width: 14%;
            border: 1px solid transparent;
        }

        /* Level 3: 排放源图标 */
        .source-row {
            display: flex;
            justify-content: space-around;
            width: 100%;
            flex-wrap: wrap;
            gap: 10px;
            z-index: 2;
        }
        .source-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            cursor: pointer;
            transition: all 0.3s;
            padding: 10px;
            border-radius: 8px;
        }
        .source-item:hover, .source-item.active {
            background: rgba(255,255,255,0.05);
            box-shadow: 0 0 10px rgba(0,191,255,0.3);
        }
        .source-item.active i { color: var(--color-gold); text-shadow: 0 0 10px var(--color-gold); }
        
        .icon-box {
            width: 40px; height: 40px;
            border-radius: 50%;
            background: rgba(0,0,0,0.3);
            border: 1px solid var(--color-blue);
            display: flex; justify-content: center; align-items: center;
            font-size: 18px;
            color: var(--color-blue);
            margin-bottom: 5px;
            position: relative;
        }
        .source-name { font-size: 12px; color: var(--text-sub); }
        .source-val { font-size: 10px; color: var(--text-main); margin-top: 2px; }

        /* Level 4: 汇聚动画 */
        .flow-lines {
            flex: 1;
            width: 100%;
            position: relative;
            overflow: hidden;
            mask-image: linear-gradient(to bottom, black, transparent);
            -webkit-mask-image: linear-gradient(to bottom, black, transparent);
        }
        .flow-lines svg { width: 100%; height: 100%; }
        .flow-path {
            fill: none;
            stroke: var(--color-gold);
            stroke-width: 2;
            stroke-opacity: 0.3;
            stroke-dasharray: 10;
            animation: dash 1s linear infinite;
        }
        @keyframes dash { to { stroke-dashoffset: -20; } }

        /* --- 右侧列 --- */
        .right-col { display: grid; grid-template-rows: 40% 60%; gap: 15px; }

        /* 列表通用 */
        .rank-list {
            list-style: none;
            overflow-y: auto;
            height: 100%;
            padding-right: 5px;
        }
        .rank-list::-webkit-scrollbar { width: 4px; background: transparent; }
        .rank-list::-webkit-scrollbar-thumb { background: var(--color-blue); border-radius: 2px; }

        .rank-item {
            display: flex;
            align-items: center;
            padding: 8px 0;
            border-bottom: 1px solid rgba(255,255,255,0.05);
            animation: fadeIn 0.5s ease-in;
        }
        @keyframes fadeIn { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: translateX(0); } }

        .rank-num {
            width: 24px; height: 24px;
            text-align: center; line-height: 24px;
            font-size: 12px;
            background: rgba(255,255,255,0.1);
            border-radius: 4px;
            margin-right: 10px;
            color: var(--text-sub);
        }
        .rank-name { flex: 1; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .rank-val { font-weight: bold; font-family: 'Arial'; text-align: right; }

        /* 金银铜奖牌样式 (仅Top榜使用) */
        .medal-mode .rank-item:nth-child(1) .rank-num { background: linear-gradient(135deg, #FFD700, #B8860B); color: #000; font-weight: bold; box-shadow: 0 0 10px #FFD700; }
        .medal-mode .rank-item:nth-child(2) .rank-num { background: linear-gradient(135deg, #C0C0C0, #808080); color: #000; font-weight: bold; }
        .medal-mode .rank-item:nth-child(3) .rank-num { background: linear-gradient(135deg, #CD7F32, #8B4513); color: #fff; font-weight: bold; }

        /* 底部双数据榜单 */
        .double-bar-item {
            display: flex;
            flex-direction: column;
            margin-bottom: 12px;
            border-bottom: none;
        }
        .db-header { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 4px; }
        .db-header .co-name { color: var(--text-main); }
        .db-bars { display: flex; gap: 5px; height: 6px; width: 100%; }
        .bar-wrapper { flex: 1; background: rgba(255,255,255,0.1); border-radius: 3px; position: relative; }
        .bar-fill { height: 100%; border-radius: 3px; width: 0; transition: width 1s; }
        .bar-blue { background: var(--color-blue); }
        .bar-gold { background: var(--color-gold); }
        .db-vals { display: flex; justify-content: space-between; font-size: 10px; margin-top: 2px; }
        .val-blue { color: var(--color-blue); }
        .val-gold { color: var(--color-gold); }

    </style>
</head>
<body>

<div class="container">
    <!-- 1. 头部 -->
    <header>
        <h1>2024年度能碳数据核算与ESG评价全景</h1>
        <div class="subtitle">2024 Energy-Carbon Accounting & ESG Evaluation Panorama</div>
    </header>

    <main>
        <!-- 2. 左侧列:构成与管理 -->
        <aside class="left-col">
            <!-- 模块1:能源结构 -->
            <div class="panel">
                <div class="panel-title">能源消费结构分析 <span class="en">Energy Structure</span></div>
                <div id="chart-energy"></div>
            </div>

            <!-- 模块2:碳排构成 -->
            <div class="panel">
                <div class="panel-title">碳排放源构成分析 <span class="en">Emission Sources</span></div>
                <div id="chart-carbon"></div>
            </div>

            <!-- 模块3:ESG -->
            <div class="panel">
                <div class="panel-title">ESG评价体系与成果 <span class="en">ESG Evaluation</span></div>
                <div class="esg-container">
                    <div>
                        <div class="esg-stat"><span>任务完成率 Task Rate</span> <span style="color:var(--color-green)">100%</span></div>
                        <div class="progress-bg"><div class="progress-bar" style="width: 100%"></div></div>
                    </div>
                    <div>
                        <div class="esg-stat"><span>数据校验通过率 Pass Rate</span> <span style="color:var(--color-green)">98.5%</span></div>
                        <div class="progress-bg"><div class="progress-bar" style="width: 98.5%"></div></div>
                    </div>
                    <div class="esg-report-box">
                        <div class="report-cover">
                            <div>2024<br>ESG<br>Report</div>
                        </div>
                        <div class="report-info">
                            <h4>2024 集团ESG报告</h4>
                            <p>状态: 已发布 / Released</p>
                            <p style="color: var(--color-blue); margin-top:5px; font-size:10px; cursor:not-allowed"><i class="fa fa-download"></i> 点击预览</p>
                        </div>
                    </div>
                </div>
            </div>
        </aside>

        <!-- 3. 中间列:核心逻辑 -->
        <section class="center-col">
            <!-- KPI 看板 -->
            <div class="kpi-wrapper">
                <div class="kpi-card active" onclick="switchKPI('carbon', this)">
                    <span class="label">年度碳排放总量 <br><small>Total Emissions</small></span>
                    <span class="value val-carbon" id="kpi-carbon">125,400</span> <span class="unit">tCO₂e</span>
                </div>
                <div class="kpi-card" onclick="switchKPI('energy', this)">
                    <span class="label">年度综合能耗量 <br><small>Total Energy</small></span>
                    <span class="value val-energy" id="kpi-energy">78,900</span> <span class="unit">tce</span>
                </div>
                <div class="kpi-card" onclick="switchKPI('intensity', this)">
                    <span class="label">单位能耗碳排放 <br><small>Intensity</small></span>
                    <span class="value val-intensity" id="kpi-intensity">1.58</span> <span class="unit">t/t</span>
                </div>
            </div>

            <!-- 拓扑图 -->
            <div class="topology-container">
                <!-- Level 1 -->
                <div class="node-root">XX集团总部 (Group HQ) - 2024</div>
                
                <!-- Level 2 -->
                <div class="boundary-row">
                    <div class="boundary-card">A:直接排放</div>
                    <div class="boundary-card">B:能源间接</div>
                    <div class="boundary-card">C:交通运输</div>
                    <div class="boundary-card">D:产品服务</div>
                    <div class="boundary-card">E:关联产品</div>
                    <div class="boundary-card">F:其他来源</div>
                </div>

                <!-- Level 3 (Interactive) -->
                <div class="source-row">
                    <div class="source-item" onclick="switchSource('coal', this)">
                        <div class="icon-box"><i class="fa fa-fire"></i></div>
                        <div class="source-name">煤炭 Coal</div>
                        <div class="source-val">1.2万 t</div>
                    </div>
                    <div class="source-item active" onclick="switchSource('elec', this)">
                        <div class="icon-box"><i class="fa fa-bolt"></i></div>
                        <div class="source-name">外购电力 Elec</div>
                        <div class="source-val">5000万 kWh</div>
                    </div>
                    <div class="source-item" onclick="switchSource('gas', this)">
                        <div class="icon-box"><i class="fa fa-burn"></i></div>
                        <div class="source-name">天然气 Gas</div>
                        <div class="source-val">800万 m³</div>
                    </div>
                    <div class="source-item" onclick="switchSource('steam', this)">
                        <div class="icon-box"><i class="fa fa-cloud"></i></div>
                        <div class="source-name">蒸汽 Steam</div>
                        <div class="source-val">4000 GJ</div>
                    </div>
                    <div class="source-item" onclick="switchSource('transport', this)">
                        <div class="icon-box"><i class="fa fa-truck"></i></div>
                        <div class="source-name">交通 Transport</div>
                        <div class="source-val">200 t</div>
                    </div>
                </div>

                <!-- Level 4 Flow Animation (SVG) -->
                <div class="flow-lines">
                    <svg viewBox="0 0 400 100" preserveAspectRatio="none">
                        <!-- Simple converging lines simulation -->
                        <path class="flow-path" d="M50,0 Q50,50 200,100" />
                        <path class="flow-path" d="M120,0 Q120,50 200,100" />
                        <path class="flow-path" d="M200,0 L200,100" />
                        <path class="flow-path" d="M280,0 Q280,50 200,100" />
                        <path class="flow-path" d="M350,0 Q350,50 200,100" />
                    </svg>
                </div>
            </div>
        </section>

        <!-- 4. 右侧列:排行与明细 -->
        <aside class="right-col">
            <!-- 模块1:KPI 排行 -->
            <div class="panel" style="overflow:hidden">
                <div class="panel-title" id="rank-title">综合碳绩效排行 <span class="en">Ranking</span></div>
                <ul class="rank-list medal-mode" id="top-rank-list">
                    <!-- JS填充 -->
                </ul>
            </div>

            <!-- 模块2:明细排行 -->
            <div class="panel" style="overflow:hidden">
                <div class="panel-title" id="detail-title">重点排放源分项明细 <span class="en">Breakdown</span></div>
                <ul class="rank-list" id="bottom-rank-list">
                    <!-- JS填充 -->
                </ul>
            </div>
        </aside>
    </main>
</div>

<script>
    // --- Mock Data ---
    const companies = [
        { name: '第一机械加工厂', carbon: 15000, energy: 8200, intensity: 1.8 },
        { name: '高新科技产业园', carbon: 12000, energy: 9000, intensity: 1.3 },
        { name: '集团物流中心', carbon: 9500, energy: 4000, intensity: 2.3 },
        { name: '生物医药实验室', carbon: 8000, energy: 5000, intensity: 1.6 },
        { name: '总部行政大楼', carbon: 3000, energy: 2500, intensity: 1.2 },
        { name: '新材料研发基地', carbon: 11000, energy: 6800, intensity: 1.6 },
        { name: '滨海分厂', carbon: 14500, energy: 8500, intensity: 1.7 },
    ];

    const sourceDetails = {
        'elec': { unit: 'kWh', data: [
            { name: '高新科技产业园', act: 25000, emit: 14000 },
            { name: '第一机械加工厂', act: 18000, emit: 10080 },
            { name: '滨海分厂', act: 16000, emit: 8960 },
            { name: '新材料研发基地', act: 12000, emit: 6720 },
            { name: '生物医药实验室', act: 8000, emit: 4480 },
        ]},
        'coal': { unit: 't', data: [
            { name: '第一机械加工厂', act: 5000, emit: 9200 },
            { name: '滨海分厂', act: 4200, emit: 7700 },
            { name: '新材料研发基地', act: 1000, emit: 1800 },
        ]},
        'gas': { unit: 'm³', data: [
            { name: '生物医药实验室', act: 50000, emit: 1200 },
            { name: '总部行政大楼', act: 20000, emit: 480 },
        ]},
        'steam': { unit: 'GJ', data: [
            { name: '第一机械加工厂', act: 8000, emit: 880 },
            { name: '高新科技产业园', act: 6000, emit: 660 },
        ]},
        'transport': { unit: 't', data: [
            { name: '集团物流中心', act: 1500, emit: 4500 },
            { name: '总部行政大楼', act: 200, emit: 600 },
        ]}
    };

    // --- State ---
    let currentKPIMode = 'carbon';

    // --- ECharts Initialization ---
    function initCharts() {
        // Chart 1: Energy Structure (Donut)
        const chartEnergy = echarts.init(document.getElementById('chart-energy'));
        chartEnergy.setOption({
            color: ['#00BFFF', '#00E396', '#FEB019', '#FF4560', '#775DD0'],
            tooltip: { trigger: 'item' },
            legend: { bottom: '0%', textStyle: { color: '#fff', fontSize: 10 }, itemWidth: 10, itemHeight: 10 },
            series: [{
                type: 'pie',
                radius: ['40%', '65%'],
                center: ['50%', '45%'],
                avoidLabelOverlap: false,
                itemStyle: { borderRadius: 5, borderColor: '#0B1A2F', borderWidth: 2 },
                label: { show: false, position: 'center' },
                emphasis: { label: { show: true, fontSize: '14', fontWeight: 'bold', color: '#fff', formatter: '{b}\n{d}%' } },
                labelLine: { show: false },
                data: [
                    { value: 1048, name: '电力 Elec' },
                    { value: 735, name: '天然气 Gas' },
                    { value: 580, name: '蒸汽 Steam' },
                    { value: 484, name: '煤炭 Coal' },
                    { value: 300, name: '燃油 Oil' }
                ]
            }]
        });

        // Chart 2: Carbon Source (Stacked Bar)
        const chartCarbon = echarts.init(document.getElementById('chart-carbon'));
        chartCarbon.setOption({
            tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
            grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
            xAxis: { type: 'value', splitLine: { show: false }, axisLabel: { color: '#8c9bb3' } },
            yAxis: { type: 'category', data: ['排放量 (tCO₂e)'], axisLabel: { show: false }, axisTick: {show: false}, axisLine: {show: false} },
            series: [
                { name: 'Scope 1 (直接)', type: 'bar', stack: 'total', color: '#FEB019', data: [32000], barWidth: 30 },
                { name: 'Scope 2 (间接)', type: 'bar', stack: 'total', color: '#00BFFF', data: [85000], barWidth: 30 },
                { name: 'Scope 3 (其他)', type: 'bar', stack: 'total', color: '#00E396', data: [8400], barWidth: 30 }
            ]
        });

        // Resize listener
        window.addEventListener('resize', () => {
            chartEnergy.resize();
            chartCarbon.resize();
        });
    }

    // --- Logic: Top Rank Render ---
    function renderTopRank(mode) {
        const list = document.getElementById('top-rank-list');
        list.innerHTML = '';
        
        // Toggle medal style
        if (mode === 'carbon') {
            list.classList.add('medal-mode');
            document.getElementById('rank-title').innerHTML = '综合碳绩效排行 <span class="en">Carbon Ranking</span>';
        } else {
            list.classList.remove('medal-mode');
            let title = mode === 'energy' ? '综合能耗排行 <span class="en">Energy Ranking</span>' : '单位能耗碳排量排行 <span class="en">Intensity Ranking</span>';
            document.getElementById('rank-title').innerHTML = title;
        }

        // Sort Data
        let sortedData = [...companies].sort((a, b) => b[mode] - a[mode]);

        sortedData.forEach((item, index) => {
            let val = item[mode];
            if (mode === 'carbon') val = val.toLocaleString() + ' <small>t</small>';
            if (mode === 'energy') val = val.toLocaleString() + ' <small>tce</small>';
            
            let colorClass = mode === 'carbon' ? 'val-carbon' : (mode === 'energy' ? 'val-blue' : 'val-intensity');

            const li = document.createElement('li');
            li.className = 'rank-item';
            li.innerHTML = `
                <div class="rank-num">${index + 1}</div>
                <div class="rank-name" title="${item.name}">${item.name}</div>
                <div class="rank-val ${colorClass}">${val}</div>
            `;
            list.appendChild(li);
        });
    }

    // --- Logic: Bottom Detail Render ---
    function renderDetailRank(sourceKey) {
        const list = document.getElementById('bottom-rank-list');
        list.innerHTML = '';
        
        const source = sourceDetails[sourceKey] || sourceDetails['elec'];
        // Sort by Activity Data for visualization
        const sortedData = [...source.data].sort((a, b) => b.act - a.act);
        const maxAct = sortedData[0].act;
        const maxEmit = Math.max(...sortedData.map(d => d.emit));

        document.getElementById('detail-title').innerHTML = `排放源分析排行 - ${getLabel(sourceKey)} <span class="en">Breakdown</span>`;

        sortedData.forEach(item => {
            const actPct = (item.act / maxAct) * 100;
            const emitPct = (item.emit / maxEmit) * 100;

            const li = document.createElement('li');
            li.className = 'rank-item double-bar-item';
            li.innerHTML = `
                <div class="db-header">
                    <span class="co-name">${item.name}</span>
                </div>
                <div class="db-bars">
                    <div class="bar-wrapper"><div class="bar-fill bar-blue" style="width: ${actPct}%"></div></div>
                    <div class="bar-wrapper"><div class="bar-fill bar-gold" style="width: ${emitPct}%"></div></div>
                </div>
                <div class="db-vals">
                    <span class="val-blue">${item.act.toLocaleString()} ${source.unit}</span>
                    <span class="val-gold">${item.emit.toLocaleString()} tCO₂e</span>
                </div>
            `;
            list.appendChild(li);
        });
    }

    function getLabel(key) {
        const map = { 'elec': '外购电力', 'coal': '煤炭', 'gas': '天然气', 'steam': '蒸汽', 'transport': '交通' };
        return map[key] || key;
    }

    // --- Interaction Handlers ---
    window.switchKPI = function(mode, el) {
        // Remove active class from all cards
        document.querySelectorAll('.kpi-card').forEach(c => c.classList.remove('active'));
        // Add to clicked
        el.classList.add('active');
        
        currentKPIMode = mode;
        renderTopRank(mode);
    }

    window.switchSource = function(key, el) {
        document.querySelectorAll('.source-item').forEach(c => c.classList.remove('active'));
        el.classList.add('active');
        renderDetailRank(key);
    }

    // --- Initialization ---
    document.addEventListener('DOMContentLoaded', () => {
        initCharts();
        renderTopRank('carbon'); // Default Mode
        renderDetailRank('elec'); // Default Source
    });

</script>
</body>
</html>
        
编辑器加载中
预览
控制台