/
spaceswimmer
/
perf-source
Обзор
Документация
Войти
/
spaceswimmer
/
perf-source
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
PerfSource/webboard/scripts.js
254 строки
8 KB
spaceswimmer
master Is this finished?
10 мар 2026, 17:45
10 мар 2026, 17:45
a420a94
Код
Авторство
О чём код?
const fMin_exact_fixed = 24.66; const fMax_exact_fixed = 48.8; const CONFIG_ENDPOINT = '/config'; async function loadConfig() { try { const response = await fetch(CONFIG_ENDPOINT); if (!response.ok) throw new Error('Failed to load config'); const config = await response.json(); // Populate form fields document.getElementById('fmin').value = config.fmin; document.getElementById('fmax').value = config.fmax; document.getElementById('tmax').value = config.tmax; document.getElementById('law').value = config.law; console.log('Config loaded:', config); updateChart(); // Redraw chart with loaded values } catch (e) { console.error('Error loading config:', e); document.getElementById('status').innerHTML = '⚠️ Using default values'; } } function frequencyToPot(frequency) { let value = 1 + (frequency - fMin_exact_fixed) * 234 / (fMax_exact_fixed - fMin_exact_fixed); return Math.max(1, Math.min(235, Math.round(value))); } function potToFrequency(potValue) { return fMin_exact_fixed + (potValue - 1) * (fMax_exact_fixed - fMin_exact_fixed) / 234; } function drawSimpleChart(labels, data, minY, maxY) { const canvas = document.getElementById('chart'); const ctx = canvas.getContext('2d'); const width = canvas.width; const height = canvas.height; const padding = 40; ctx.clearRect(0, 0, width, height); const chartWidth = width - 2 * padding; const chartHeight = height - 2 * padding; ctx.strokeStyle = '#eee'; ctx.lineWidth = 1; for (let i = 0; i <= 5; i++) { const y = padding + (i * chartHeight / 5); ctx.beginPath(); ctx.moveTo(padding, y); ctx.lineTo(width - padding, y); ctx.stroke(); ctx.fillStyle = '#666'; ctx.font = '12px Arial'; ctx.textAlign = 'right'; const value = maxY - (maxY - minY) * i / 5; ctx.fillText(value.toFixed(0), padding - 10, y + 4); } for (let i = 0; i <= 5; i++) { const x = padding + (i * chartWidth / 5); ctx.beginPath(); ctx.moveTo(x, padding); ctx.lineTo(x, height - padding); ctx.stroke(); ctx.fillStyle = '#666'; ctx.font = '12px Arial'; ctx.textAlign = 'center'; const timeValue = (labels[labels.length - 1] * i / 5).toFixed(1); ctx.fillText(timeValue, x, height - padding + 20); } ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(padding, padding); ctx.lineTo(padding, height - padding); ctx.lineTo(width - padding, height - padding); ctx.stroke(); ctx.fillStyle = '#000'; ctx.font = '14px Arial'; ctx.textAlign = 'center'; ctx.fillText('Time (seconds)', width / 2, height - 5); ctx.save(); ctx.translate(15, height / 2); ctx.rotate(-Math.PI / 2); ctx.fillText('Frequency (Hz)', 0, 0); ctx.restore(); if (data.length < 2) return; ctx.strokeStyle = '#3498db'; ctx.lineWidth = 3; ctx.beginPath(); const xScale = chartWidth / (labels.length - 1); const yScale = chartHeight / (maxY - minY); for (let i = 0; i < data.length; i++) { const x = padding + i * xScale; const y = height - padding - (data[i] - minY) * yScale; if (i === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.stroke(); ctx.fillStyle = 'rgba(52, 152, 219, 0.1)'; ctx.lineTo(padding + (data.length - 1) * xScale, height - padding); ctx.lineTo(padding, height - padding); ctx.closePath(); ctx.fill(); } function updateChart() { const fmin_display = parseInt(document.getElementById('fmin').value) || 25; const fmax_display = parseInt(document.getElementById('fmax').value) || 49; const tmax = parseFloat(document.getElementById('tmax').value) || 10; const law = document.getElementById('law').value; const pot_min = frequencyToPot(fmin_display); const pot_max = frequencyToPot(fmax_display); const steps = 50; const labels = []; const data = []; for (let i = 0; i <= steps; i++) { const t = (i / steps) * tmax; labels.push(t); let potValue; const normalizedTime = i / steps; if (law === 'linear') { potValue = pot_min + normalizedTime * (pot_max - pot_min); } else if (law === 'exponential') { const I = pot_min + (pot_max - pot_min) * (Math.exp(normalizedTime * Math.log(236)) - 1) / 235; potValue = Math.max(pot_min, Math.min(pot_max, I)); } else if (law === 'chirp') { const invF2 = (1 - normalizedTime) * (1 / (fmin_display * fmin_display)) + normalizedTime * (1 / (fmax_display * fmax_display)); const f = 1 / Math.sqrt(invF2); potValue = frequencyToPot(f); } const freq = potToFrequency(potValue); data.push(freq); } drawSimpleChart(labels, data, 25, 49); document.getElementById('status').innerHTML = 'Graph updated | Display: ' + fmin_display + '-' + fmax_display + ' Hz | ' + 'Potentiometer: ' + pot_min + '-' + pot_max + ' | ' + 'Actual frequency: ' + potToFrequency(pot_min).toFixed(1) + '-' + potToFrequency(pot_max).toFixed(1) + ' Hz'; } async function sendToESP() { const params = { fmin: document.getElementById('fmin').value, fmax: document.getElementById('fmax').value, tmax: document.getElementById('tmax').value, law: document.getElementById('law').value }; try { const form = new FormData(); form.append('fmin', params.fmin); form.append('fmax', params.fmax); form.append('tmax', params.tmax); form.append('law', params.law); const response = await fetch('/set_params', { method: 'POST', body: form }); const text = await response.text(); document.getElementById('status').innerHTML = '✅ ' + text; } catch (e) { document.getElementById('status').innerHTML = '❌ Error: ' + e; } } async function startSweep() { const response = await fetch('/start', { method: 'POST' }); if (response.ok) { document.getElementById('startBtn').disabled = true; document.getElementById('stopBtn').disabled = false; document.getElementById('status').innerHTML = '▶️ Sweep started!'; checkStatus(); } } async function stopSweep() { const response = await fetch('/stop', { method: 'POST' }); if (response.ok) { document.getElementById('startBtn').disabled = false; document.getElementById('stopBtn').disabled = true; document.getElementById('status').innerHTML = '⏹️ Sweep stopped!'; } } async function checkStatus() { try { const response = await fetch('/status'); const text = await response.text(); if (text.includes("Running")) { setTimeout(checkStatus, 1000); } else { document.getElementById('startBtn').disabled = false; document.getElementById('stopBtn').disabled = true; document.getElementById('status').innerHTML = '✅ Sweep completed!'; } } catch (e) { setTimeout(checkStatus, 2000); } } window.onload = function () { loadConfig(); ['fmin', 'fmax', 'tmax', 'law'].forEach(id => { document.getElementById(id).addEventListener('change', updateChart); }); const canvas = document.getElementById('chart'); canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; updateChart(); }; window.addEventListener('resize', function () { const canvas = document.getElementById('chart'); canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; updateChart(); });