import { useState, useEffect, useMemo } from 'react'; import Plot from 'react-plotly.js'; interface SeismicSectionProps { nodes: any[]; currentTime: number; channel: string; visible: boolean; onClose: () => void; } const API_BASE = '/seismic/api'; function SeismicSection({ nodes, currentTime, channel, visible, onClose }: SeismicSectionProps) { const [data, setData] = useState(null); const [viewMode, setViewMode] = useState<'day' | 'global'>('day'); const [loading, setLoading] = useState(false); useEffect(() => { if (!visible) return; setLoading(true); const url = viewMode === 'global' ? `${API_BASE}/global-history?channel=${channel}` : `${API_BASE}/rms-timeline?date=${new Date(currentTime * 1000).toISOString().split('T')[0]}&channel=${channel}`; fetch(url) .then(r => r.json()) .then(d => { setData(d.nodes); setLoading(false); }) .catch(() => setLoading(false)); }, [visible, viewMode, channel, currentTime]); useEffect(() => { if (!visible) return; const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', handleEscape); return () => document.removeEventListener('keydown', handleEscape); }, [visible, onClose]); const plotData = useMemo(() => { if (!data) return []; const traces: any[] = []; const nodeIds = Object.keys(data).sort(); nodeIds.forEach((id, index) => { const points = data[id]; if (!points || points.length === 0) return; const maxRms = Math.max(...points.map((p: any) => p.rms)) || 1; traces.push({ x: points.map((p: any) => new Date(p.ts * 1000)), y: points.map((p: any) => (p.rms / maxRms) * 0.9 + index), type: 'scatter', mode: 'lines', name: `Node ${id}`, line: { color: '#4ade80', width: 1 }, fill: 'tonexty', showlegend: false }); }); return traces; }, [data]); if (!visible) return null; return (

Vue Sismique Globale

{loading ?
Fusion des données…
: ( i), ticktext: Object.keys(data || {}).sort().map(id => `b${id}`) } }} config={{ responsive: true }} style={{ width: '100%', height: '100%' }} /> )}
); } export default SeismicSection;