diff --git a/static/index.html b/static/index.html index affd517c..9e01d814 100644 --- a/static/index.html +++ b/static/index.html @@ -214,7 +214,7 @@ document.addEventListener('DOMContentLoaded', function() { if (he) delete he.dataset.rendered; } if (name === 'health' && !healthRefreshInterval) { - healthRefreshInterval = setInterval(refreshHealth, 10000); + if (!healthRefreshInterval) healthRefreshInterval = setInterval(refreshHealth, 10000); } document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden')); document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('active')); @@ -616,9 +616,12 @@ function renderMarket() { // ── Evaluation Tab ── let evalTimer = null; +let evalBusy = false; function renderEvaluation() { + if (evalBusy) return; + evalBusy = true; const el = document.getElementById('tab-evaluation'); - if (evalTimer) clearInterval(evalTimer); + if (evalTimer) { clearInterval(evalTimer); evalTimer = null; } fetchJSON('/api/tracking').then(data => { const tracks = data.tracks || []; const stats = data.stats || {}; @@ -709,8 +712,9 @@ function renderEvaluation() { }).join('')} `; - evalTimer = setInterval(renderEvaluation, 30000); - }); + if (!evalTimer) evalTimer = setInterval(renderEvaluation, 30000); + evalBusy = false; + }).catch(() => { evalBusy = false; }); } function triggerEval() { const btn = document.querySelector('#tab-evaluation button'); @@ -797,8 +801,9 @@ async function openStock(code) { const chartCanvas = document.getElementById('modalChart'); chartCanvas.innerHTML = ''; const ctx = document.getElementById('stockChart').getContext('2d'); + if (window._stockChart) { try { window._stockChart.destroy(); } catch(e) {} window._stockChart = null; } if (stockData.price_history && stockData.price_history.length > 1) { - new Chart(ctx, { + window._stockChart = new Chart(ctx, { type: 'line', data: { labels: stockData.price_history.map(p => p.date),