Dashboard web FastAPI + Chart.js
- 4 vues : spectre temps reel, historique detections, background, timeline CPS - API REST : /api/status, /api/spectrum/current, /api/spectrum/difference, /api/background, /api/background/spectrum, /api/history, /api/cps/timeline - Frontend vanilla JS + Chart.js (pas de Node.js, leger pour Pi 4) - Moniteur modifie pour exporter son etat dans /data/monitor_state.json et le CPS dans /data/cps_log.jsonl chaque cycle - Nouveau conteneur Docker 'web' sur port 8080 - Theme sombre, calibration energie (E = 0.33 + 2.97 * canal) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
83
web/static/js/cps.js
Normal file
83
web/static/js/cps.js
Normal file
@ -0,0 +1,83 @@
|
||||
let cpsChart = null;
|
||||
|
||||
async function loadCps(hours = 24) {
|
||||
// Highlight active button
|
||||
document.querySelectorAll('.controls button').forEach(b => b.style.opacity = '0.6');
|
||||
const activeBtn = [...document.querySelectorAll('.controls button')].find(
|
||||
b => b.textContent.includes(hours <= 24 ? `${hours}h` : `${hours/24}j`) || (hours === 168 && b.textContent === '7j')
|
||||
);
|
||||
if (activeBtn) activeBtn.style.opacity = '1';
|
||||
|
||||
try {
|
||||
const resp = await fetch(`${API_BASE}/api/cps/timeline?hours=${hours}`);
|
||||
if (!resp.ok) return;
|
||||
const data = await resp.json();
|
||||
|
||||
if (!data.data_points || data.data_points.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const labels = data.data_points.map(d => d.ts);
|
||||
const cpsValues = data.data_points.map(d => d.cps);
|
||||
|
||||
updateCpsChart(labels, cpsValues);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
function updateCpsChart(labels, values) {
|
||||
const ctx = document.getElementById('cps-chart').getContext('2d');
|
||||
|
||||
const chartData = {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
label: 'CPS',
|
||||
data: values,
|
||||
borderColor: '#4caf50',
|
||||
backgroundColor: 'rgba(76, 175, 80, 0.1)',
|
||||
borderWidth: 1.5,
|
||||
pointRadius: 0,
|
||||
fill: true,
|
||||
tension: 0.3,
|
||||
}]
|
||||
};
|
||||
|
||||
const options = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: { labels: { color: '#e0e0e0' } },
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
time: {
|
||||
tooltipFormat: 'dd/MM HH:mm',
|
||||
displayFormats: { minute: 'HH:mm', hour: 'HH:mm', day: 'dd/MM' }
|
||||
},
|
||||
title: { display: true, text: 'Temps', color: '#888' },
|
||||
ticks: { color: '#888', maxTicksLimit: 12 },
|
||||
grid: { color: '#333' },
|
||||
},
|
||||
y: {
|
||||
title: { display: true, text: 'CPS', color: '#888' },
|
||||
ticks: { color: '#888' },
|
||||
grid: { color: '#333' },
|
||||
beginAtZero: true,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (cpsChart) {
|
||||
cpsChart.data = chartData;
|
||||
cpsChart.options = options;
|
||||
cpsChart.update();
|
||||
} else {
|
||||
// Chart.js needs the date adapter for time axis
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js';
|
||||
script.onload = () => {
|
||||
cpsChart = new Chart(ctx, { type: 'line', data: chartData, options });
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user