From 63154085f7d701af0930621edb868cb4740ab1d4 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Wed, 26 Nov 2025 00:58:43 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=95=B0=E6=8D=AE=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/js/dashboard.js | 116 +++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 23 deletions(-) diff --git a/static/js/dashboard.js b/static/js/dashboard.js index 795d299..c3d1f5d 100644 --- a/static/js/dashboard.js +++ b/static/js/dashboard.js @@ -357,9 +357,9 @@ function updateStatsCards(stats) { return; } - // 添加淡入淡出动画和光晕效果 + // 添加淡入淡出动画和深色光晕效果 // 先移除可能存在的光晕效果类 - element.classList.remove('number-glow'); + element.classList.remove('number-glow', 'number-glow-blue', 'number-glow-red', 'number-glow-green', 'number-glow-yellow'); // 添加淡入淡出动画 element.style.opacity = '0'; @@ -369,28 +369,48 @@ function updateStatsCards(stats) { element.textContent = formattedNewValue; element.style.opacity = '1'; - // 添加光晕效果 + // 添加当前卡片颜色的深色光晕效果 // 根据父级卡片类型确定光晕颜色 const card = element.closest('.stat-card, .bg-blue-50, .bg-red-50, .bg-green-50, .bg-yellow-50'); + let glowColorClass = ''; + + // 使用更精准的卡片颜色检测 if (card) { - // 设置光晕颜色类 - if (card.classList.contains('bg-blue-50') || card.id.includes('total')) { - element.classList.add('number-glow-blue'); + // 根据卡片类名确定深色光晕颜色 + if (card.classList.contains('bg-blue-50') || card.id.includes('total') || card.id.includes('response')) { + // 蓝色卡片 - 深蓝色光晕 + glowColorClass = 'number-glow-dark-blue'; } else if (card.classList.contains('bg-red-50') || card.id.includes('blocked')) { - element.classList.add('number-glow-red'); - } else if (card.classList.contains('bg-green-50') || card.id.includes('allowed')) { - element.classList.add('number-glow-green'); - } else if (card.classList.contains('bg-yellow-50') || card.id.includes('error')) { - element.classList.add('number-glow-yellow'); + // 红色卡片 - 深红色光晕 + glowColorClass = 'number-glow-dark-red'; + } else if (card.classList.contains('bg-green-50') || card.id.includes('allowed') || card.id.includes('active')) { + // 绿色卡片 - 深绿色光晕 + glowColorClass = 'number-glow-dark-green'; + } else if (card.classList.contains('bg-yellow-50') || card.id.includes('error') || card.id.includes('cpu')) { + // 黄色卡片 - 深黄色光晕 + 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'; + } } - } else { - // 默认光晕效果 - element.classList.add('number-glow'); + } + + // 如果确定了光晕颜色类,则添加它 + if (glowColorClass) { + element.classList.add(glowColorClass); } // 2秒后移除光晕效果 setTimeout(() => { - element.classList.remove('number-glow', 'number-glow-blue', 'number-glow-red', 'number-glow-green', 'number-glow-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); }, 200); } @@ -693,6 +713,11 @@ function initCharts() { options: { responsive: true, maintainAspectRatio: false, + // 添加全局动画配置,确保图表创建和更新时都平滑过渡 + animation: { + duration: 500, // 延长动画时间,使过渡更平滑 + easing: 'easeInOutQuart' + }, plugins: { legend: { position: 'bottom', @@ -722,6 +747,11 @@ function initCharts() { options: { responsive: true, maintainAspectRatio: false, + // 添加全局动画配置,确保图表创建和更新时都平滑过渡 + animation: { + duration: 300, + easing: 'easeInOutQuart' + }, plugins: { legend: { position: 'bottom', @@ -800,7 +830,11 @@ function drawDNSRequestsChart() { dnsRequestsChart.data.labels = results[0].labels; // 使用第一个数据集的标签 dnsRequestsChart.data.datasets = datasets; dnsRequestsChart.options.plugins.legend.display = showLegend; - dnsRequestsChart.update(); + // 使用平滑过渡动画更新图表 + dnsRequestsChart.update({ + duration: 800, + easing: 'easeInOutQuart' + }); } else { dnsRequestsChart = new Chart(chartContext, { type: 'line', @@ -811,6 +845,11 @@ function drawDNSRequestsChart() { options: { responsive: true, maintainAspectRatio: false, + // 添加动画配置,确保平滑过渡 + animation: { + duration: 800, + easing: 'easeInOutQuart' + }, plugins: { legend: { display: showLegend, @@ -868,7 +907,11 @@ function drawDNSRequestsChart() { fill: true }]; dnsRequestsChart.options.plugins.legend.display = false; - dnsRequestsChart.update(); + // 使用平滑过渡动画更新图表 + dnsRequestsChart.update({ + duration: 800, + easing: 'easeInOutQuart' + }); } else { dnsRequestsChart = new Chart(chartContext, { type: 'line', @@ -886,6 +929,11 @@ function drawDNSRequestsChart() { options: { responsive: true, maintainAspectRatio: false, + // 添加动画配置,确保平滑过渡 + animation: { + duration: 800, + easing: 'easeInOutQuart' + }, plugins: { legend: { display: false @@ -955,7 +1003,11 @@ function updateCharts(stats, queryTypeStats) { } ratioChart.data.datasets[0].data = [allowed, blocked, error]; - ratioChart.update(); + // 使用自定义动画配置更新图表,确保平滑过渡 + ratioChart.update({ + duration: 500, + easing: 'easeInOutQuart' + }); } // 更新解析类型统计饼图 @@ -984,7 +1036,11 @@ function updateCharts(stats, queryTypeStats) { queryTypeChart.data.datasets[0].backgroundColor = [queryTypeColors[0]]; } - queryTypeChart.update(); + // 使用自定义动画配置更新图表,确保平滑过渡 + queryTypeChart.update({ + duration: 500, + easing: 'easeInOutQuart' + }); } } @@ -1120,7 +1176,16 @@ function updateChartData(chartId, newValue) { // 更新图表数据 chart.data.datasets[0].data = historyData; chart.data.labels = generateTimeLabels(historyData.length); - chart.update(); + + // 使用自定义动画配置更新图表,确保平滑过渡,避免空白区域 + chart.update({ + duration: 300, // 增加动画持续时间 + easing: 'easeInOutQuart', // 使用平滑的缓动函数 + transition: { + duration: 300, + easing: 'easeInOutQuart' + } + }); } // 从统计数据中获取规则数 @@ -1224,9 +1289,14 @@ function initStatCardCharts() { }] }, options: { - responsive: true, - maintainAspectRatio: false, - plugins: { + responsive: true, + maintainAspectRatio: false, + // 添加动画配置,确保平滑过渡 + animation: { + duration: 800, + easing: 'easeInOutQuart' + }, + plugins: { legend: { display: false },