/
eugenesic
/
MetaStream-Flask
Обзор
Документация
Войти
/
eugenesic
/
MetaStream-Flask
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
chart/static/chart.js
148 строк
5 KB
Evgenii Zagorodskikh
refresh
04 дек 2025, 12:34
04 дек 2025, 12:34
e3f1346
Код
Авторство
О чём код?
// chart/static/chart.js document.addEventListener('DOMContentLoaded', function() { const symbolSelect = document.getElementById('symbol-select'); const tfSelect = document.getElementById('tf-select'); const loadBtn = document.getElementById('load-btn'); const chartDiv = document.getElementById('chart'); const loadingDiv = document.getElementById('loading'); const errorDiv = document.getElementById('error'); const statsDiv = document.getElementById('stats'); let currentSymbol = null; let currentTf = null; let autoRefreshInterval = null; // Update timeframes when symbol changes symbolSelect.addEventListener('change', function() { const symbol = this.value; fetch(`/api/timeframes/${symbol}`) .then(r => r.json()) .then(tfs => { tfSelect.innerHTML = ''; tfs.forEach(tf => { const opt = document.createElement('option'); opt.value = tf; opt.textContent = tf; tfSelect.appendChild(opt); }); }); }); // Load chart on button click loadBtn.addEventListener('click', function() { const symbol = symbolSelect.value; const tf = tfSelect.value; loadChart(symbol, tf); }); function loadChart(symbol, tf) { currentSymbol = symbol; currentTf = tf; errorDiv.style.display = 'none'; loadingDiv.style.display = 'block'; statsDiv.innerHTML = ''; fetch(`/api/data/${symbol}/${tf}`) .then(r => { if (!r.ok) throw new Error('Data not found'); return r.json(); }) .then(data => { loadingDiv.style.display = 'none'; renderChart(data, symbol, tf); updateStats(data, symbol, tf); // Start auto-refresh (every 5 seconds) startAutoRefresh(); }) .catch(err => { loadingDiv.style.display = 'none'; errorDiv.style.display = 'block'; errorDiv.textContent = `Error: ${err.message}`; stopAutoRefresh(); }); } function startAutoRefresh() { stopAutoRefresh(); autoRefreshInterval = setInterval(() => { if (currentSymbol && currentTf) { fetch(`/api/data/${currentSymbol}/${currentTf}`) .then(r => r.json()) .then(data => { renderChart(data, currentSymbol, currentTf); updateStats(data, currentSymbol, currentTf); }) .catch(err => { console.log('Auto-refresh error:', err); }); } }, 5000); // Refresh every 5 seconds } function stopAutoRefresh() { if (autoRefreshInterval) { clearInterval(autoRefreshInterval); autoRefreshInterval = null; } } function renderChart(data, symbol, tf) { const trace = { x: data.time, open: data.open, high: data.high, low: data.low, close: data.close, type: 'candlestick' }; const layout = { title: `${symbol} ${tf}`, xaxis: { title: 'Time' }, yaxis: { title: 'Price' }, template: 'plotly_white', hovermode: 'x unified', margin: { l: 60, r: 30, t: 50, b: 50 } }; Plotly.newPlot(chartDiv, [trace], layout, { responsive: true }); } function updateStats(data, symbol, tf) { const n = data.close.length; if (n === 0) return; const close = data.close; const high = data.high; const low = data.low; const vol = data.volume; const latest = close[n - 1]; const open_ = data.open[n - 1]; const change = latest - open_; const changePct = (change / open_ * 100).toFixed(2); const maxHigh = Math.max(...high); const minLow = Math.min(...low); const avgVol = (vol.reduce((a, b) => a + b, 0) / n).toFixed(0); statsDiv.innerHTML = ` <strong>Latest:</strong> ${latest.toFixed(5)}<br> <strong>Change:</strong> ${change > 0 ? '+' : ''}${change.toFixed(5)} (${changePct}%)<br> <strong>High:</strong> ${maxHigh.toFixed(5)}<br> <strong>Low:</strong> ${minLow.toFixed(5)}<br> <strong>Avg Vol:</strong> ${avgVol}<br> <strong>Bars:</strong> ${n}<br> <em style="font-size:11px; color:#999;">Auto-refresh: 5s</em> `; } // Load default chart on page load const defaultSymbol = symbolSelect.value; const defaultTf = tfSelect.value; if (defaultSymbol && defaultTf) { loadChart(defaultSymbol, defaultTf); } });