From 660e60576d09ccf301b17cf4171466fdade003ef Mon Sep 17 00:00:00 2001 From: wood chen Date: Thu, 5 Dec 2024 01:13:11 +0800 Subject: [PATCH] fix(metrics): enhance metrics chart rendering and data handling - Updated the metrics chart rendering logic to reverse the data order for a more intuitive time progression from left to right. - Introduced chart options to ensure the x-axis is not reversed, improving the clarity of time-based data visualization. - Modified the updateChart function to accept additional options, allowing for more flexible chart configurations. - Added a safeguard in GetRecentMetrics to return a default empty record instead of null when no metrics are available, enhancing data reliability. These changes improve the user experience by providing clearer visualizations and ensuring consistent data handling in the metrics dashboard. --- internal/handler/metrics.go | 70 ++++++++++++++++++++++++------------- internal/models/metrics.go | 14 ++++++++ 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/internal/handler/metrics.go b/internal/handler/metrics.go index 04d97c4..ce8c757 100644 --- a/internal/handler/metrics.go +++ b/internal/handler/metrics.go @@ -644,6 +644,9 @@ var metricsTemplate = ` }) .then(response => response.json()) .then(data => { + // 反转数据顺序,使时间从左到右 + data.reverse(); + const labels = data.map(m => { const date = new Date(m.timestamp); if (hours <= 24) { @@ -655,53 +658,70 @@ var metricsTemplate = ` } }); + // 更新图表配置,添加时间轴方向设置 + const chartOptions = { + scales: { + x: { + reverse: false // 确保时间轴从左到右 + } + } + }; + // 更新或创建图表 updateChart('requestsChart', currentCharts.requests, labels, data, '请求数', - m => m.total_requests, '#007bff'); + m => m.total_requests, '#007bff', chartOptions); updateChart('errorRateChart', currentCharts.errorRate, labels, data, '错误率 (%)', - m => m.error_rate * 100, '#dc3545'); + m => m.error_rate * 100, '#dc3545', chartOptions); updateChart('bytesChart', currentCharts.bytes, labels, data, '流量 (MB)', - m => m.total_bytes / (1024 * 1024), '#28a745'); + m => m.total_bytes / (1024 * 1024), '#28a745', chartOptions); }); } - function updateChart(canvasId, chartInstance, labels, data, label, valueGetter, color) { + function updateChart(canvasId, chartInstance, labels, data, label, valueGetter, color, options = {}) { const ctx = document.getElementById(canvasId).getContext('2d'); - + const chartData = { + labels: labels, + datasets: [{ + label: label, + data: data.map(valueGetter), + borderColor: color, + backgroundColor: color + '20', + fill: true, + tension: 0.4 + }] + }; + if (chartInstance) { - chartInstance.data.labels = labels; - chartInstance.data.datasets[0].data = data.map(valueGetter); + chartInstance.data = chartData; + chartInstance.options = { + ...chartInstance.options, + ...options, + animation: false + }; chartInstance.update(); } else { chartInstance = new Chart(ctx, { type: 'line', - data: { - labels: labels, - datasets: [{ - label: label, - data: data.map(valueGetter), - borderColor: color, - tension: 0.1, - fill: false - }] - }, + data: chartData, options: { + ...options, responsive: true, maintainAspectRatio: false, + plugins: { + legend: { + display: false + } + }, scales: { + y: { + beginAtZero: true + }, x: { - ticks: { - maxRotation: 45, - minRotation: 45 - } + reverse: false } } } }); - - if (canvasId === 'requestsChart') currentCharts.requests = chartInstance; - if (canvasId === 'errorRateChart') currentCharts.errorRate = chartInstance; - if (canvasId === 'bytesChart') currentCharts.bytes = chartInstance; } } diff --git a/internal/models/metrics.go b/internal/models/metrics.go index e56dff1..d18877a 100644 --- a/internal/models/metrics.go +++ b/internal/models/metrics.go @@ -279,5 +279,19 @@ func (db *MetricsDB) GetRecentMetrics(hours int) ([]HistoricalMetrics, error) { } metrics = append(metrics, m) } + + // 如果没有数据,返回一个空的记录而不是 null + if len(metrics) == 0 { + now := time.Now() + metrics = append(metrics, HistoricalMetrics{ + Timestamp: now.Format("2006-01-02 15:04:05"), + TotalRequests: 0, + TotalErrors: 0, + TotalBytes: 0, + ErrorRate: 0, + AvgLatency: 0, + }) + } + return metrics, rows.Err() }