数据更新时,卡片文字滚动翻页显示
This commit is contained in:
59660
dns-server.log
59660
dns-server.log
File diff suppressed because it is too large
Load Diff
@@ -480,18 +480,26 @@ async function loadDashboardData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (document.getElementById('cpu-usage')) {
|
if (document.getElementById('cpu-usage')) {
|
||||||
|
// 从不同可能的数据结构中获取CPU使用率
|
||||||
|
let cpuUsageValue = 0;
|
||||||
|
if (stats.system && typeof stats.system.cpu === 'number') {
|
||||||
|
cpuUsageValue = stats.system.cpu;
|
||||||
|
} else if (typeof stats.cpuUsage === 'number') {
|
||||||
|
cpuUsageValue = stats.cpuUsage;
|
||||||
|
}
|
||||||
|
|
||||||
// 保留两位小数并添加单位
|
// 保留两位小数并添加单位
|
||||||
const cpuUsage = stats.cpuUsage ? stats.cpuUsage.toFixed(2) + '%' : '---';
|
const cpuUsage = cpuUsageValue > 0 ? cpuUsageValue.toFixed(2) + '%' : '---';
|
||||||
document.getElementById('cpu-usage').textContent = cpuUsage;
|
document.getElementById('cpu-usage').textContent = cpuUsage;
|
||||||
|
|
||||||
// 设置CPU状态颜色
|
// 设置CPU状态颜色
|
||||||
const cpuStatusElem = document.getElementById('cpu-status');
|
const cpuStatusElem = document.getElementById('cpu-status');
|
||||||
if (cpuStatusElem) {
|
if (cpuStatusElem) {
|
||||||
if (stats.cpuUsage !== undefined && stats.cpuUsage !== null) {
|
if (cpuUsageValue > 0) {
|
||||||
if (stats.cpuUsage > 80) {
|
if (cpuUsageValue > 80) {
|
||||||
cpuStatusElem.textContent = '警告';
|
cpuStatusElem.textContent = '警告';
|
||||||
cpuStatusElem.className = 'text-danger text-sm flex items-center';
|
cpuStatusElem.className = 'text-danger text-sm flex items-center';
|
||||||
} else if (stats.cpuUsage > 60) {
|
} else if (cpuUsageValue > 60) {
|
||||||
cpuStatusElem.textContent = '较高';
|
cpuStatusElem.textContent = '较高';
|
||||||
cpuStatusElem.className = 'text-warning text-sm flex items-center';
|
cpuStatusElem.className = 'text-warning text-sm flex items-center';
|
||||||
} else {
|
} else {
|
||||||
@@ -593,7 +601,7 @@ function updateStatsCards(stats) {
|
|||||||
activeIPsPercentage = stats[0].activeIPsPercentage || 0;
|
activeIPsPercentage = stats[0].activeIPsPercentage || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为数字元素添加平滑过渡效果和光晕效果的函数
|
// 为数字元素添加翻页滚动特效
|
||||||
function animateValue(elementId, newValue) {
|
function animateValue(elementId, newValue) {
|
||||||
const element = document.getElementById(elementId);
|
const element = document.getElementById(elementId);
|
||||||
if (!element) return;
|
if (!element) return;
|
||||||
@@ -606,17 +614,92 @@ function updateStatsCards(stats) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加淡入淡出动画和深色光晕效果
|
|
||||||
// 先移除可能存在的光晕效果类
|
// 先移除可能存在的光晕效果类
|
||||||
element.classList.remove('number-glow', 'number-glow-blue', 'number-glow-red', 'number-glow-green', 'number-glow-yellow');
|
element.classList.remove('number-glow', 'number-glow-blue', 'number-glow-red', 'number-glow-green', 'number-glow-yellow');
|
||||||
|
|
||||||
// 添加淡入淡出动画
|
// 保存原始样式和内容
|
||||||
element.style.opacity = '0';
|
const originalStyle = element.getAttribute('style') || '';
|
||||||
element.style.transition = 'opacity 200ms ease-out';
|
const originalContent = element.innerHTML;
|
||||||
|
|
||||||
|
// 配置翻页容器样式
|
||||||
|
const containerStyle = `
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
height: ${element.offsetHeight}px;
|
||||||
|
width: ${element.offsetWidth}px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 创建翻页容器
|
||||||
|
const flipContainer = document.createElement('div');
|
||||||
|
flipContainer.style.cssText = containerStyle;
|
||||||
|
flipContainer.className = 'number-flip-container';
|
||||||
|
|
||||||
|
// 创建旧值元素
|
||||||
|
const oldValueElement = document.createElement('div');
|
||||||
|
oldValueElement.textContent = originalContent;
|
||||||
|
oldValueElement.style.cssText = `
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: transform 400ms ease-in-out;
|
||||||
|
transform-origin: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 创建新值元素
|
||||||
|
const newValueElement = document.createElement('div');
|
||||||
|
newValueElement.textContent = formattedNewValue;
|
||||||
|
newValueElement.style.cssText = `
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: transform 400ms ease-in-out;
|
||||||
|
transform-origin: center;
|
||||||
|
transform: translateY(100%);
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 复制原始元素的样式到新元素
|
||||||
|
const computedStyle = getComputedStyle(element);
|
||||||
|
[oldValueElement, newValueElement].forEach(el => {
|
||||||
|
el.style.fontSize = computedStyle.fontSize;
|
||||||
|
el.style.fontWeight = computedStyle.fontWeight;
|
||||||
|
el.style.color = computedStyle.color;
|
||||||
|
el.style.fontFamily = computedStyle.fontFamily;
|
||||||
|
el.style.textAlign = computedStyle.textAlign;
|
||||||
|
el.style.lineHeight = computedStyle.lineHeight;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 替换原始元素的内容
|
||||||
|
element.textContent = '';
|
||||||
|
flipContainer.appendChild(oldValueElement);
|
||||||
|
flipContainer.appendChild(newValueElement);
|
||||||
|
element.appendChild(flipContainer);
|
||||||
|
|
||||||
|
// 启动翻页动画
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
element.textContent = formattedNewValue;
|
oldValueElement.style.transform = 'translateY(-100%)';
|
||||||
element.style.opacity = '1';
|
newValueElement.style.transform = 'translateY(0)';
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
// 动画结束后,恢复原始元素
|
||||||
|
setTimeout(() => {
|
||||||
|
// 清理并设置最终值
|
||||||
|
element.innerHTML = formattedNewValue;
|
||||||
|
if (originalStyle) {
|
||||||
|
element.setAttribute('style', originalStyle);
|
||||||
|
} else {
|
||||||
|
element.removeAttribute('style');
|
||||||
|
}
|
||||||
|
|
||||||
// 添加当前卡片颜色的深色光晕效果
|
// 添加当前卡片颜色的深色光晕效果
|
||||||
// 根据父级卡片类型确定光晕颜色
|
// 根据父级卡片类型确定光晕颜色
|
||||||
@@ -638,30 +721,19 @@ function updateStatsCards(stats) {
|
|||||||
} else if (card.classList.contains('bg-yellow-50') || card.id.includes('error') || card.id.includes('cpu')) {
|
} else if (card.classList.contains('bg-yellow-50') || card.id.includes('error') || card.id.includes('cpu')) {
|
||||||
// 黄色卡片 - 深黄色光晕
|
// 黄色卡片 - 深黄色光晕
|
||||||
glowColorClass = 'number-glow-dark-yellow';
|
glowColorClass = 'number-glow-dark-yellow';
|
||||||
} else {
|
|
||||||
// 其他卡片 - 根据背景色自动确定深色光晕
|
|
||||||
const bgColor = getComputedStyle(card).backgroundColor;
|
|
||||||
// 提取RGB值并转换为深色
|
|
||||||
const rgbMatch = bgColor.match(/\d+/g);
|
|
||||||
if (rgbMatch && rgbMatch.length >= 3) {
|
|
||||||
// 直接添加自定义深色光晕样式
|
|
||||||
element.style.boxShadow = `0 0 15px 3px rgba(${Math.floor(rgbMatch[0] * 0.7)}, ${Math.floor(rgbMatch[1] * 0.7)}, ${Math.floor(rgbMatch[2] * 0.7)}, 0.6)`;
|
|
||||||
element.style.transition = 'box-shadow 300ms ease-in-out, opacity 200ms ease-out';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果确定了光晕颜色类,则添加它
|
// 如果确定了光晕颜色类,则添加它
|
||||||
if (glowColorClass) {
|
if (glowColorClass) {
|
||||||
element.classList.add(glowColorClass);
|
element.classList.add(glowColorClass);
|
||||||
}
|
|
||||||
|
|
||||||
// 2秒后移除光晕效果
|
// 2秒后移除光晕效果
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
element.classList.remove('number-glow-dark-blue', 'number-glow-dark-red', 'number-glow-dark-green', 'number-glow-dark-yellow');
|
element.classList.remove('number-glow-dark-blue', 'number-glow-dark-red', 'number-glow-dark-green', 'number-glow-dark-yellow');
|
||||||
element.style.boxShadow = 'none';
|
}, 2000);
|
||||||
}, 2000);
|
}
|
||||||
}, 200);
|
}, 450);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新百分比元素的函数
|
// 更新百分比元素的函数
|
||||||
@@ -1169,7 +1241,10 @@ function initCharts() {
|
|||||||
datasets: [{
|
datasets: [{
|
||||||
data: ['---', '---', '---'],
|
data: ['---', '---', '---'],
|
||||||
backgroundColor: ['#00B42A', '#F53F3F', '#FF7D00'],
|
backgroundColor: ['#00B42A', '#F53F3F', '#FF7D00'],
|
||||||
borderWidth: 0
|
borderWidth: 2, // 添加边框宽度,增强区块分隔
|
||||||
|
borderColor: '#fff', // 白色边框,使各个扇区更清晰
|
||||||
|
hoverOffset: 10, // 添加悬停偏移效果,增强交互体验
|
||||||
|
hoverBorderWidth: 3 // 悬停时增加边框宽度
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
@@ -1192,6 +1267,15 @@ function initCharts() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
enabled: true,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
padding: 10,
|
||||||
|
titleFont: {
|
||||||
|
size: 12
|
||||||
|
},
|
||||||
|
bodyFont: {
|
||||||
|
size: 11
|
||||||
|
},
|
||||||
callbacks: {
|
callbacks: {
|
||||||
label: function(context) {
|
label: function(context) {
|
||||||
const label = context.label || '';
|
const label = context.label || '';
|
||||||
@@ -1203,7 +1287,15 @@ function initCharts() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cutout: '75%' // 增加中心空白区域比例,使环形更适合小容器
|
cutout: '65%', // 减小中心空白区域比例,增大扇形区域以更好显示线段指示
|
||||||
|
// 添加线段指示相关配置
|
||||||
|
elements: {
|
||||||
|
arc: {
|
||||||
|
// 确保圆弧绘制时有足够的精度
|
||||||
|
borderAlign: 'center',
|
||||||
|
tension: 0.1 // 添加轻微的张力,使圆弧更平滑
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1221,7 +1313,10 @@ function initCharts() {
|
|||||||
datasets: [{
|
datasets: [{
|
||||||
data: [1],
|
data: [1],
|
||||||
backgroundColor: [queryTypeColors[0]],
|
backgroundColor: [queryTypeColors[0]],
|
||||||
borderWidth: 0
|
borderWidth: 2, // 添加边框宽度,增强区块分隔
|
||||||
|
borderColor: '#fff', // 白色边框,使各个扇区更清晰
|
||||||
|
hoverOffset: 10, // 添加悬停偏移效果,增强交互体验
|
||||||
|
hoverBorderWidth: 3 // 悬停时增加边框宽度
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
@@ -1244,6 +1339,15 @@ function initCharts() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
enabled: true,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
padding: 10,
|
||||||
|
titleFont: {
|
||||||
|
size: 12
|
||||||
|
},
|
||||||
|
bodyFont: {
|
||||||
|
size: 11
|
||||||
|
},
|
||||||
callbacks: {
|
callbacks: {
|
||||||
label: function(context) {
|
label: function(context) {
|
||||||
const label = context.label || '';
|
const label = context.label || '';
|
||||||
@@ -1255,7 +1359,15 @@ function initCharts() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cutout: '75%' // 增加中心空白区域比例,使环形更适合小容器
|
cutout: '65%', // 减小中心空白区域比例,增大扇形区域以更好显示线段指示
|
||||||
|
// 添加线段指示相关配置
|
||||||
|
elements: {
|
||||||
|
arc: {
|
||||||
|
// 确保圆弧绘制时有足够的精度
|
||||||
|
borderAlign: 'center',
|
||||||
|
tension: 0.1 // 添加轻微的张力,使圆弧更平滑
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user