Explorer: caption the ground-truth and detection bands so their roles are explicit
2 changed files+20−9
src/main.tsmodified+1−0View file
@@ -740,6 +740,7 @@ function updateExplorer(): void {
740740 names: bench.names,
741741 colors: bench.colors,
742742 events: result.score.events,
743+ algoName: bench.algos.find((a) => a.id === algoId)?.name,
743744 });
744745 updatePlayButton();
745746 }
src/ui/explorer.tsmodified+19−9View file
@@ -17,11 +17,14 @@ export interface ExplorerData {
1717 names: string[];
1818 colors: string[];
1919 events: ScoredEvent[];
20+ /** Shown in the detections band caption. */
21+ algoName?: string;
2022 }
2123
2224 const BG = '#16181d';
2325 const WAVE = '#5b8dbf';
2426 const LANE_H = 18;
27+const BAND_HEAD = 15;
2528 const WAVE_H = 110;
2629 const AXIS_H = 22;
2730 const LABEL_W = 64;
@@ -71,7 +74,7 @@ export class Explorer {
7174
7275 private height(): number {
7376 const n = this.data ? this.data.names.length : 0;
74- return n * LANE_H * 2 + WAVE_H + AXIS_H + 8;
77+ return 2 * BAND_HEAD + n * LANE_H * 2 + WAVE_H + AXIS_H + 8;
7578 }
7679
7780 private duration(): number {
@@ -218,11 +221,23 @@ export class Explorer {
218221 }
219222 const d = this.data;
220223 const nTypes = d.names.length;
221- const truthTop = 0;
222- const waveTop = nTypes * LANE_H;
223- const detTop = waveTop + WAVE_H;
224+ const truthTop = BAND_HEAD;
225+ const waveTop = truthTop + nTypes * LANE_H;
226+ const detTop = waveTop + WAVE_H + BAND_HEAD;
224227 const axisTop = detTop + nTypes * LANE_H;
225228
229+ // band captions: what is above the waveform and what is below it
230+ g.fillStyle = 'rgba(255,255,255,0.08)';
231+ g.fillRect(0, 0, w, BAND_HEAD);
232+ g.fillRect(0, waveTop + WAVE_H, w, BAND_HEAD);
233+ g.fillStyle = 'rgba(255,255,255,0.65)';
234+ g.font = 'bold 10px system-ui';
235+ g.fillText('GROUND TRUTH: events placed by the synthesizer', 4, 11);
236+ g.fillText(
237+ `DETECTED${d.algoName ? ` BY ${d.algoName}` : ''}: events the algorithm reported`,
238+ 4, waveTop + WAVE_H + 11,
239+ );
240+
226241 // lane labels and separators
227242 g.font = '10px system-ui';
228243 for (let k = 0; k < nTypes; k++) {
@@ -235,11 +250,6 @@ export class Explorer {
235250 g.fillText(d.names[k].slice(0, 9), 4, truthTop + k * LANE_H + 12);
236251 g.fillText(d.names[k].slice(0, 9), 4, detTop + k * LANE_H + 12);
237252 }
238- g.fillStyle = 'rgba(255,255,255,0.35)';
239- g.textAlign = 'right';
240- g.fillText('ground truth', w - 6, truthTop + 12);
241- g.fillText('detections', w - 6, detTop + 12);
242- g.textAlign = 'left';
243253
244254 // waveform over the visible window
245255 const s0 = Math.max(0, Math.floor(this.t0 * d.fs));