<!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>
index.html
style.css
index.js
index.html