1import type { RenderResponse } from '../worker/renderWorker';
3export default function DiagnosticsPanel({ result }: { result: RenderResponse }) {
4 const d = result.diag;
5 const modes = Array.from(result.modeF);
6 const shown = modes.slice(0, 8);
7 return (
8 <div className="diag">
9 <table>
10 <tbody>
11 <tr>
12 <th>Strokes</th>
13 <td>
14 {d.strikeCount === 1
15 ? `single, ${d.meanV.toFixed(2)} m/s`
16 : `${d.strikeCount} · mean ${d.meanV.toFixed(2)} m/s, max ${d.maxV.toFixed(2)} m/s`}
17 </td>
18 </tr>
19 <tr>
20 <th>Contact</th>
21 <td>
22 r = {(d.strikeRadiusM * 100).toFixed(1)} cm ({(d.strikeRimM * 100).toFixed(1)} cm in
23 from the rim{d.strikeCount > 1
24 ? `, alternating with ${(d.roll2RadiusM * 100).toFixed(1)} cm`
25 : ''})
26 </td>
27 </tr>
28 <tr>
29 <th>Impact</th>
30 <td>
31 {d.meanTauUs.toFixed(0)} µs mean (Hertz) · peak force {d.peakForceN.toFixed(0)} N
32 </td>
33 </tr>
34 <tr>
35 <th>Plate modes</th>
36 <td className="partials">
37 {d.modesKept} up to n = {d.maxN} nodal diameters · {d.plateMassKg.toFixed(2)} kg
38 </td>
39 </tr>
40 <tr>
41 <th>Lowest</th>
42 <td className="partials">{shown.map((f) => f.toFixed(0)).join(', ')} … Hz</td>
43 </tr>
44 <tr>
45 <th>Nonlinearity</th>
46 <td>
47 peak w<sub>rms</sub> {d.peakWrmsUm.toFixed(0)} µm ={' '}
48 {Math.sqrt(d.peakStrength).toFixed(2)} thicknesses ·{' '}
49 {(100 * d.cascadeLostFrac).toFixed(1)}% left the top of the band
50 </td>
51 </tr>
52 <tr>
53 <th>Listener</th>
54 <td>{(d.listenerDistM * 100).toFixed(0)} cm from the plate</td>
55 </tr>
56 <tr>
57 <th>Peak pressure</th>
58 <td>
59 {d.peakPa.toFixed(3)} Pa ({d.peakSplDb.toFixed(1)} dB SPL) · click{' '}
60 {d.directPeakPa.toFixed(2)} Pa
61 </td>
62 </tr>
63 <tr>
64 <th>Length</th>
65 <td>
66 {d.durationS.toFixed(2)} s · {result.quality} · oversample {d.oversample}
67 </td>
68 </tr>
69 </tbody>
70 </table>
71 <div className="cachenote">
72 eigensolves: {d.solveCached ? 'cached' : `${(d.solveMs / 1000).toFixed(2)} s`} · cascade +
73 radiation: {d.radiateCached ? 'cached' : `${(d.radiateMs / 1000).toFixed(2)} s`}
74 </div>
75 {d.warnings.map((w, i) => (
76 <div key={i} className="warning">⚠ {w}</div>
77 ))}
78 </div>
79 );
80}