diff --git a/internal/handler/metrics.go b/internal/handler/metrics.go index a3e024e..6b02cad 100644 --- a/internal/handler/metrics.go +++ b/internal/handler/metrics.go @@ -629,7 +629,7 @@ var metricsTemplate = ` // 每5秒自动刷新 setInterval(refreshMetrics, 5000); - // 修改图表加载相关代码 + // 修改图表相关代码 let currentCharts = { requests: null, errorRate: null, @@ -644,6 +644,11 @@ var metricsTemplate = ` }) .then(response => response.json()) .then(data => { + if (!Array.isArray(data)) { + console.error('Invalid data format'); + return; + } + // 反转数据顺序,使时间从左到右 data.reverse(); @@ -658,27 +663,64 @@ var metricsTemplate = ` } }); - // 更新图表配置,添加时间轴方向设置 - const chartOptions = { + const commonOptions = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + display: false + } + }, scales: { x: { - reverse: false // 确保时间轴从左到右 + display: true, + grid: { + display: false + } + }, + y: { + beginAtZero: true, + grid: { + drawBorder: false + } + } + }, + elements: { + line: { + tension: 0.4 + }, + point: { + radius: 2 } } }; // 更新或创建图表 - updateChart('requestsChart', currentCharts.requests, labels, data, '请求数', - m => m.total_requests, '#007bff', chartOptions); - updateChart('errorRateChart', currentCharts.errorRate, labels, data, '错误率 (%)', - m => m.error_rate * 100, '#dc3545', chartOptions); - updateChart('bytesChart', currentCharts.bytes, labels, data, '流量 (MB)', - m => m.total_bytes / (1024 * 1024), '#28a745', chartOptions); - }); + updateChart('requestsChart', 'requests', labels, data, '请求数', + m => m.total_requests, '#007bff', commonOptions); + updateChart('errorRateChart', 'errorRate', labels, data, '错误率 (%)', + m => m.error_rate * 100, '#dc3545', commonOptions); + updateChart('bytesChart', 'bytes', labels, data, '流量 (MB)', + m => m.total_bytes / (1024 * 1024), '#28a745', commonOptions); + }) + .catch(error => console.error('Error:', error)); } - function updateChart(canvasId, chartInstance, labels, data, label, valueGetter, color, options = {}) { - const ctx = document.getElementById(canvasId).getContext('2d'); + function updateChart(canvasId, chartKey, labels, data, label, valueGetter, color, options) { + // 确保 canvas 元素存在 + const canvas = document.getElementById(canvasId); + if (!canvas) { + console.error('Canvas element ' + canvasId + ' not found'); + return; + } + + // 如果存在旧图表,销毁它 + if (currentCharts[chartKey]) { + currentCharts[chartKey].destroy(); + currentCharts[chartKey] = null; + } + + const ctx = canvas.getContext('2d'); const chartData = { labels: labels, datasets: [{ @@ -686,52 +728,16 @@ var metricsTemplate = ` data: data.map(valueGetter), borderColor: color, backgroundColor: color + '20', - fill: true, - tension: 0.4 + fill: true }] }; - if (chartInstance) { - chartInstance.data = chartData; - chartInstance.options = { - ...chartInstance.options, - ...options, - animation: false - }; - chartInstance.update(); - } else { - // 创建新图表前先销毁旧的 - if (currentCharts[canvasId.replace('Chart', '')]) { - currentCharts[canvasId.replace('Chart', '')].destroy(); - } - - // 创建新图表 - const newChart = new Chart(ctx, { - type: 'line', - data: chartData, - options: { - ...options, - responsive: true, - maintainAspectRatio: false, - plugins: { - legend: { - display: false - } - }, - scales: { - y: { - beginAtZero: true - }, - x: { - reverse: false - } - } - } - }); - - // 更新 currentCharts 对象 - currentCharts[canvasId.replace('Chart', '')] = newChart; - } + // 创建新图表 + currentCharts[chartKey] = new Chart(ctx, { + type: 'line', + data: chartData, + options: options + }); } // 时间范围按钮处理 @@ -739,16 +745,19 @@ var metricsTemplate = ` btn.addEventListener('click', function() { document.querySelectorAll('.time-btn').forEach(b => b.classList.remove('active')); this.classList.add('active'); - loadHistoryData(this.dataset.hours); + loadHistoryData(parseInt(this.dataset.hours)); }); }); // 初始加载历史数据 - loadHistoryData(24); + document.addEventListener('DOMContentLoaded', function() { + loadHistoryData(24); + }); - + + `