|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
|
|
const lazyImages = document.querySelectorAll('img[data-src]'); |
|
|
|
|
|
const imageObserver = new IntersectionObserver((entries, observer) => { |
|
|
entries.forEach(entry => { |
|
|
if (entry.isIntersecting) { |
|
|
const img = entry.target; |
|
|
img.src = img.dataset.src; |
|
|
img.classList.add('loaded'); |
|
|
observer.unobserve(img); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
lazyImages.forEach(img => imageObserver.observe(img)); |
|
|
|
|
|
|
|
|
const lazyElements = document.querySelectorAll('.lazy-load'); |
|
|
|
|
|
const elementObserver = new IntersectionObserver((entries, observer) => { |
|
|
entries.forEach(entry => { |
|
|
if (entry.isIntersecting) { |
|
|
entry.target.classList.add('loaded'); |
|
|
observer.unobserve(entry.target); |
|
|
} |
|
|
}); |
|
|
}, { threshold: 0.1 }); |
|
|
|
|
|
lazyElements.forEach(el => elementObserver.observe(el)); |
|
|
}); |
|
|
|
|
|
|
|
|
function initChart(ctx, config) { |
|
|
return new Chart(ctx, config); |
|
|
} |
|
|
|
|
|
|
|
|
function formatNumber(num, decimals = 0) { |
|
|
if (num >= 100000000) { |
|
|
return (num / 100000000).toFixed(decimals) + '亿'; |
|
|
} else if (num >= 10000) { |
|
|
return (num / 10000).toFixed(decimals) + '万'; |
|
|
} |
|
|
return num.toLocaleString('zh-CN', { maximumFractionDigits: decimals }); |
|
|
} |
|
|
|
|
|
|
|
|
function formatPercent(value, decimals = 1) { |
|
|
return (value * 100).toFixed(decimals) + '%'; |
|
|
} |
|
|
|
|
|
|
|
|
function createTrendIndicator(value) { |
|
|
const isPositive = value >= 0; |
|
|
const icon = isPositive ? '↑' : '↓'; |
|
|
const className = isPositive ? 'stat-change positive' : 'stat-change negative'; |
|
|
return `<span class="${className}">${icon} ${Math.abs(value).toFixed(1)}%</span>`; |
|
|
} |
|
|
|
|
|
|
|
|
function getResponsiveConfig(baseConfig) { |
|
|
return { |
|
|
...baseConfig, |
|
|
options: { |
|
|
...baseConfig.options, |
|
|
responsive: true, |
|
|
maintainAspectRatio: false, |
|
|
plugins: { |
|
|
...baseConfig.options?.plugins, |
|
|
legend: { |
|
|
...baseConfig.options?.plugins?.legend, |
|
|
display: window.innerWidth > 768 |
|
|
} |
|
|
} |
|
|
} |
|
|
}; |
|
|
} |