103 lines
2.5 KiB
JavaScript
103 lines
2.5 KiB
JavaScript
/**
|
|
* Utility Functions
|
|
*/
|
|
|
|
/**
|
|
* Format bytes to human-readable string
|
|
*/
|
|
function formatBytes(bytes, decimals = 2) {
|
|
if (!bytes || bytes === 0) return '0 B';
|
|
const k = 1024;
|
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
|
const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(k));
|
|
const value = bytes / Math.pow(k, i);
|
|
return value.toFixed(decimals) + ' ' + sizes[i];
|
|
}
|
|
|
|
/**
|
|
* Format bytes per second to human-readable bandwidth
|
|
*/
|
|
function formatBandwidth(bytesPerSec, decimals = 2) {
|
|
if (!bytesPerSec || bytesPerSec === 0) return '0 B/s';
|
|
const k = 1024;
|
|
const sizes = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s'];
|
|
const i = Math.floor(Math.log(Math.abs(bytesPerSec)) / Math.log(k));
|
|
const value = bytesPerSec / Math.pow(k, i);
|
|
return value.toFixed(decimals) + ' ' + sizes[i];
|
|
}
|
|
|
|
/**
|
|
* Format percentage
|
|
*/
|
|
function formatPercent(value, decimals = 1) {
|
|
if (!value || isNaN(value)) return '0%';
|
|
return value.toFixed(decimals) + '%';
|
|
}
|
|
|
|
/**
|
|
* Format a timestamp to HH:MM
|
|
*/
|
|
function formatTime(timestamp) {
|
|
const d = new Date(timestamp);
|
|
return d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
|
|
}
|
|
|
|
/**
|
|
* Format full clock
|
|
*/
|
|
function formatClock() {
|
|
const now = new Date();
|
|
const date = now.toLocaleDateString('zh-CN', {
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit'
|
|
});
|
|
const time = now.toLocaleTimeString('zh-CN', {
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
second: '2-digit'
|
|
});
|
|
return `${date} ${time}`;
|
|
}
|
|
|
|
/**
|
|
* Get color based on usage percentage
|
|
*/
|
|
function getUsageColor(percent) {
|
|
if (percent < 50) return '#10b981';
|
|
if (percent < 75) return '#f59e0b';
|
|
return '#f43f5e';
|
|
}
|
|
|
|
/**
|
|
* Smooth number animation
|
|
*/
|
|
function animateValue(element, start, end, duration = 600) {
|
|
const startTime = performance.now();
|
|
const diff = end - start;
|
|
|
|
function update(currentTime) {
|
|
const elapsed = currentTime - startTime;
|
|
const progress = Math.min(elapsed / duration, 1);
|
|
// Ease out cubic
|
|
const eased = 1 - Math.pow(1 - progress, 3);
|
|
const current = start + diff * eased;
|
|
|
|
if (element.dataset.format === 'percent') {
|
|
element.textContent = formatPercent(current);
|
|
} else if (element.dataset.format === 'bytes') {
|
|
element.textContent = formatBytes(current);
|
|
} else if (element.dataset.format === 'bandwidth') {
|
|
element.textContent = formatBandwidth(current);
|
|
} else {
|
|
element.textContent = Math.round(current);
|
|
}
|
|
|
|
if (progress < 1) {
|
|
requestAnimationFrame(update);
|
|
}
|
|
}
|
|
|
|
requestAnimationFrame(update);
|
|
}
|