Skip to content

feat(d3): implement spectrogram-mel#8420

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/spectrogram-mel/d3
Jun 3, 2026
Merged

feat(d3): implement spectrogram-mel#8420
MarkusNeusinger merged 6 commits into
mainfrom
implementation/spectrogram-mel/d3

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Jun 3, 2026

Implementation: spectrogram-mel - javascript/d3

Implements the javascript/d3 version of spectrogram-mel.

File: plots/spectrogram-mel/implementations/javascript/d3.js

Parent Issue: #4672


🤖 impl-generate workflow

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Jun 3, 2026

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): The mel-spectrogram is displayed on a warm off-white (#FAF8F1) background. The heatmap fills the plot area with a green-to-blue imprint_seq colormap — the noise floor (-80 dB) renders in bright brand-green (#009E73) and the harmonic peaks (near 0 dB) render in medium-dark blue (#4467A3). A C-major scale ascending then descending is clearly visible as blue harmonic patches forming an arc shape across the plot. The Y-axis uses custom mel-scale tick marks at 100Hz, 250Hz, 500Hz, 1kHz, 2kHz, 4kHz, 8kHz in dark secondary text. The X-axis shows time in seconds (0.0s–4.0s). A colorbar on the right side shows the dB scale from -80 (bottom, green) to 0 (top, blue) with a "Power (dB)" rotated label. Title "spectrogram-mel · javascript · d3 · anyplot.ai" is bold and clearly readable. All text is readable against the light background.

Dark render (plot-dark.png): The same plot on a warm near-black (#1A1A17) background. All data colors are identical to the light render — the green noise floor and blue harmonic patches appear unchanged. Chrome elements (title, axis labels, tick labels, colorbar labels) switch to light text colors. All text is clearly readable against the dark background with no dark-on-dark failures detected. The brand green (#009E73) remains visually prominent on the dark surface. Both renders pass legibility checks.

Score: 83/100

Category Score Max
Visual Quality 27 30
Design Excellence 10 20
Spec Compliance 15 15
Data Quality 14 15
Code Quality 10 10
Library Mastery 7 10
Total 83 100

Visual Quality (27/30)

  • VQ-01: Text Legibility (7/8) — all font sizes explicitly set (22px title, 18px axis labels, 15px axis ticks, 14px colorbar); all text readable in both themes; minor: colorbar label at 14px is small but readable
  • VQ-02: No Overlap (6/6) — no text or element overlap in either render
  • VQ-03: Element Visibility (4/6) — heatmap cells are visible; however the color mapping places the noise floor in bright brand-green (visually dominant) and the signal in darker blue (visually recessive), inverting conventional spectrogram contrast
  • VQ-04: Color Accessibility (2/2) — imprint_seq used correctly, CVD-safe
  • VQ-05: Layout & Canvas (4/4) — canvas gate passed, good margins, colorbar properly spaced
  • VQ-06: Axis Labels & Title (2/2) — "Frequency (Hz)", "Time (s)", "Power (dB)" all descriptive with units
  • VQ-07: Palette Compliance (2/2) — imprint_seq via t.seq[0]→t.seq[1], correct light (#FAF8F1) and dark (#1A1A17) backgrounds, t.ink for title, t.inkSoft for chrome

Design Excellence (10/20)

  • DE-01: Aesthetic Sophistication (4/8) — well-implemented with custom mel scale computation and harmonic synthesis, but the dominant bright-green noise floor and inverted contrast reduce overall aesthetic impact; reads as a well-configured implementation rather than publication-ready
  • DE-02: Visual Refinement (3/6) — custom mel-scale Y-axis with manually drawn ticks is a nice refinement; no grid (appropriate for heatmap); clean margins; but the block-resolution heatmap (80×150 cells) shows visible cell artifacts
  • DE-03: Data Storytelling (3/6) — the C-major arc pattern is visible in the blue patches, but the inverted perceptual convention (noise = bright, signal = dark) forces the viewer to mentally reverse expectations; the musical story is present but not immediately obvious

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — correct mel-spectrogram with mel-scale frequency axis
  • SC-02: Required Features (4/4) — dB scale conversion, sequential colormap, time X-axis, mel-scaled Y-axis with Hz labels, colorbar labeled in dB all present
  • SC-03: Data Mapping (3/3) — time on X, mel-scaled frequency on Y, power on color
  • SC-04: Title & Legend (3/3) — "spectrogram-mel · javascript · d3 · anyplot.ai" correct

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) — comprehensive mel-spectrogram features; uses 80 mel bins vs spec-recommended 128, slightly reducing resolution
  • DQ-02: Realistic Context (5/5) — C major scale ascending/descending is a recognizable, neutral musical audio signal
  • DQ-03: Appropriate Scale (4/4) — 0–4s, 40–8000 Hz range, -80 to 0 dB are all realistic audio ML parameters

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — flat script, no functions or classes
  • CQ-02: Reproducibility (2/2) — fully deterministic data generation (no RNG)
  • CQ-03: Clean Imports (2/2) — no imports needed; d3 is a global as required
  • CQ-04: Code Elegance (2/2) — well-structured, appropriate complexity for a mel spectrogram
  • CQ-05: Output & API (1/1) — follows D3 harness contract; SVG sized from window.ANYPLOT_SIZE

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — good D3 patterns: data joins (.data().join()), d3.scaleLinear/axisBottom/axisRight, SVG defs/linearGradient for colorbar
  • LM-02: Distinctive Features (3/5) — custom SVG linearGradient colorbar built with d3 defs; custom manual Y-axis (drawing tick lines and text directly without d3.axisLeft, because the mel scale doesn't map to a standard D3 axis scale)

Score Caps Applied

  • None

Strengths

  • Correct mel-scale frequency axis with custom Hz tick marks at perceptually meaningful breakpoints (100Hz, 250Hz, 500Hz, 1kHz, 2kHz, 4kHz, 8kHz)
  • Deterministic harmonic synthesis producing a recognizable musical arc pattern (C major ascending/descending)
  • Custom SVG linearGradient colorbar — a D3-idiomatic approach to the colorbar requirement
  • Perfect spec compliance: all required features present and correctly implemented
  • Clean D3 code with proper data binding patterns and theme token usage

Weaknesses

  • Color scale visual inversion: imprint_seq maps the noise floor (-80 dB) to bright brand-green (#009E73), making it the visually dominant element, while harmonics (near 0 dB) appear as darker blue — the opposite of conventional spectrogram readability where silence should recede and signal should stand out. Apply a non-linear (power/gamma) domain compression to widen the perceptual gap: e.g., map the dB domain through a power function before interpolating colors, so the transition from noise floor to signal is visually sharp rather than smooth.
  • Cell resolution is visibly blocky: 80 mel bins (vs spec-recommended 128) × 150 frames produces large rectangular cells at this canvas size. Increase to n_mels=128 and n_frames=200 for a smoother appearance.
  • Design lacks visual hierarchy: no annotation indicating the musical arc, no horizontal reference lines at key frequency bands (fundamental frequency range ~260–520Hz), and the block-grid appearance at 80 mel bins reduces the perceptual smoothness expected of a spectrogram visualization.

Issues Found

  1. VQ-03 LOW: Inverted color salience — noise floor (bright green) visually outcompetes signal (darker blue). Fix: apply a non-linear gamma/power compression to the dB-to-color mapping so low-power regions visually recede and harmonic peaks visually pop.
  2. DQ-01 MINOR: n_mels=80 vs spec-recommended 128 produces blocky cells. Fix: use n_mels=128 and increase n_frames to 200.
  3. DE-01/DE-03 LOW: No visual hierarchy or story emphasis. Fix: increase mel bin and frame resolution, add optional horizontal dashed reference lines at key frequency octave bands, and consider a subtle alpha overlay to dim the noise floor below -60 dB.

AI Feedback for Next Attempt

Primary fix: The imprint_seq colormap applied linearly over -80 to 0 dB makes the noise floor (majority of the image) the brightest/most saturated element. Apply a gamma/power compression — e.g., map dB values through before interpolating colors — so quiet regions read as dark-ish and loud harmonic peaks read as vivid. This single change will transform readability. Secondary: increase n_mels to 128 and n_frames to 200 for smoother cell appearance. Optionally add subtle dashed horizontal reference lines at key octave bands (500Hz, 1kHz, 2kHz, 4kHz) using t.grid color at low opacity.

Verdict: REJECTED

@github-actions github-actions Bot added quality:83 Quality score 83/100 ai-rejected Quality not OK, triggers update labels Jun 3, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jun 3, 2026
Attempt 1/3 - fixes based on AI review
@github-actions
Copy link
Copy Markdown
Contributor Author

github-actions Bot commented Jun 3, 2026

🔧 Repair Attempt 1/4

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Jun 3, 2026

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): The canvas margins (title area, axis areas, and colorbar region) display the warm off-white #FAF8F1 background. The heatmap fills the plot area with 200×128 mel-spectrogram cells: a blue-slate noise floor (Imprint seq token at 0 dB) supporting bright Imprint-green (#009E73) harmonic bands. The C major scale ascending then descending is clearly visible as a horizontal arc of bright energy across the midrange frequencies (260–500 Hz for the fundamentals, with visible overtones up to ~4 kHz). Seven dashed reference lines at 100/250/500/1 k/2 k/4 k/8 kHz break the heatmap into interpretable frequency bands. The colorbar on the right transitions smoothly from blue-slate (−80 dB, bottom) to brand green (0 dB, top), labeled "Power (dB)". Title "spectrogram-mel · javascript · d3 · anyplot.ai" is dark text at 22 px, fully readable. X-axis tick labels (0.0 s–4.0 s) and Y-axis tick labels (100 Hz–8 kHz) are clearly readable at 15 px. Legibility verdict: PASS.

Dark render (plot-dark.png): Canvas margins flip to near-black (#1A1A17). The heatmap data colors are identical to the light render — the same blue-slate noise floor and the same brand-green harmonics. The C major arc pattern reads with the same clarity. Title and all axis text render in the light inkSoft token, clearly visible against the dark background. Colorbar tick labels are light-colored and readable. No "dark-on-dark" failures detected — all chrome elements have correctly adapted via ANYPLOT_TOKENS. Legibility verdict: PASS.

Both paragraphs confirm: data colors are identical across themes; only chrome flips.

Score: 88/100

Category Score Max
Visual Quality 29 30
Design Excellence 12 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 7 10
Total 88 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (7/8) — all font sizes explicitly set (22px title, 18px axis labels, 15px tick labels, 14px colorbar ticks); readable in both themes. Minor deduction: colorbar "Power (dB)" tick labels at 14px CSS are at the minimum of the recommended range for a 1600px CSS mount.
  • VQ-02: No Overlap (6/6) — no overlapping text detected in either render
  • VQ-03: Element Visibility (6/6) — mel-spectrogram cells fill the heatmap clearly; harmonic bands are prominent; reference lines subtle but visible
  • VQ-04: Color Accessibility (2/2) — Imprint sequential blue→green is CVD-safe; luminance contrast between noise floor and harmonics is strong
  • VQ-05: Layout & Canvas (4/4) — canvas gate passed (landscape 3200×1800); proportions well-balanced; colorbar correctly positioned in right margin
  • VQ-06: Axis Labels & Title (2/2) — "Time (s)", "Frequency (Hz)", "Power (dB)" all present with units
  • VQ-07: Palette Compliance (2/2) — continuous data uses Imprint t.seq tokens (t.seq[0] green = peak signal, t.seq[1] blue = noise floor); direction reversed from imprint_seq canonical but still uses the correct Imprint seq stops — valid for spectrograms where high intensity should map to bright color; plot background #FAF8F1 light / #1A1A17 dark; both renders theme-correct

Design Excellence (12/20)

  • DE-01: Aesthetic Sophistication (5/8) — above "well-configured default" (4): the gamma-compression (dbGamma = 2.2) is a genuinely sophisticated technique that pushes the noise floor to the dark end and makes the harmonics pop; synthesized C major scale creates a structured, recognizable visual; not yet at "strong design" (6) due to minimal typographic polish and no additional layout finesse
  • DE-02: Visual Refinement (3/6) — above library defaults: dashed reference lines at key frequency bands are a subtle, useful addition; clean margins; however, axis domain lines remain as thick strokes (inkSoft) rather than refined or removed, and the colorbar frame has no extra visual care
  • DE-03: Data Storytelling (4/6) — good: the C major ascending-descending melody creates an immediately recognizable arc; harmonic overtones are visible; reference lines help the viewer map frequency bands; clear focal point at the peak of the melody around t=2s at the 2–4 kHz range

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — correct mel-spectrogram as a 2D intensity heatmap with mel-scaled Y axis
  • SC-02: Required Features (4/4) — mel filter banks (128), dB conversion (10·log₁₀), colorbar labeled in dB, time X-axis, Hz tick labels at key mel band edges, synthesized audio data
  • SC-03: Data Mapping (3/3) — time on X, mel-scaled frequency on Y, power (dB) encoded as color
  • SC-04: Title & Legend (3/3) — title "spectrogram-mel · javascript · d3 · anyplot.ai" matches the required format exactly

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — shows full mel-spectrogram with 128 mel bins, 200 time frames, harmonic structure (10 harmonics per note), amplitude envelope (attack/sustain/decay), ascending and descending melody pattern
  • DQ-02: Realistic Context (5/5) — C major scale with physically accurate note frequencies (C4=261.6 Hz, etc.) is a realistic, neutral, and musically meaningful scenario for demonstrating mel-spectrogram behavior
  • DQ-03: Appropriate Scale (4/4) — 4 seconds duration, 40–8000 Hz frequency range, n_mels=128 (exactly as spec recommends), power range −80 to 0 dB (standard audio dynamic range)

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — linear structure: tokens → parameters → data synthesis → SVG mount → scales → heatmap → axes → colorbar → title; helper arrow functions (hzToMel, melToHz, colorScale, hzToY) are minimal and necessary
  • CQ-02: Reproducibility (2/2) — fully deterministic: note frequencies and mel bin centers are fixed; no RNG
  • CQ-03: Clean Imports (2/2) — uses only the global d3 and window.ANYPLOT_TOKENS/SIZE; no unnecessary dependencies
  • CQ-04: Code Elegance (2/2) — well-organized, appropriate complexity for a mel-spectrogram; no fake interactivity
  • CQ-05: Output & API (1/1) — D3 harness handles plot-{theme}.png + plot-{theme}.html output correctly

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — uses modern D3 .join() pattern, d3.scaleLinear, d3.axisBottom/Right, d3.interpolateRgb, SVG linearGradient via defs; above the default-3 level
  • LM-02: Distinctive Features (3/5) — SVG linearGradient for the colorbar is a distinctive D3 SVG capability; custom mel-scale Y-axis drawn by hand (manually appending tick marks and text) rather than using a D3 axis generator; d3.interpolateRgb for gamma-compressed color mapping; above the default-1 level

Score Caps Applied

  • None — DE-01=5 > 2 and DE-02=3 > 2, no 75-cap; all other caps not triggered

Strengths

  • Gamma-compressed colorscale (dbGamma=2.2) is a sophisticated, real-world technique that improves visual dynamic range by pushing noise floor to the dark end while keeping harmonic signal peaks vivid and bright
  • Synthesized C major scale with physically accurate note frequencies, 10 harmonics per note, and realistic attack/sustain/decay envelopes produces a genuinely instructive and visually compelling mel-spectrogram
  • All spec requirements satisfied: mel scale, decibel conversion, colorbar labeled in dB, time axis, Hz labels at key mel band edges
  • Correct Imprint sequential tokens (t.seq) used for continuous color mapping; theme-adaptive chrome correctly adapts across light and dark renders
  • SVG linearGradient + d3.axisRight colorbar is idiomatic and elegant D3 implementation

Weaknesses

  • Colorbar "Power (dB)" rotated label at 14px CSS is at the lower end of the recommended range — increasing to 15–16px would improve readability when the plot is scaled down
  • DE-02: Axis domain lines rendered as thick strokes (inkSoft color) rather than refined or de-emphasized; the colorbar border/frame has no visual polish beyond the gradient rect
  • LM-02: Color scale uses d3.interpolateRgb(t.seq[1], t.seq[0]) rather than the more D3-idiomatic d3.scaleSequential(d3.interpolateRgbBasis(t.seq)) — a minor API refinement opportunity

Issues Found

  1. DE-02 MODERATE: Axis domain lines are solid strokes with the inkSoft color rather than styled to complement the heatmap; the colorbar has no visual frame refinement
    • Fix: Set axis .domain stroke-opacity lower, or remove domain line for a cleaner look; add a subtle border to the colorbar rect
  2. VQ-01 MINOR: Colorbar "Power (dB)" tick label size at 14px CSS is at the minimum; could improve legibility at small print sizes
    • Fix: Increase colorbar tick labels from 14px to 15px and the "Power (dB)" rotated label from 14px to 16px

AI Feedback for Next Attempt

The implementation is technically excellent and scores 88/100. Primary improvement opportunities are in Design Excellence: (1) reduce axis domain line opacity or remove it for a cleaner heatmap look; (2) bump colorbar label sizes from 14px to 15–16px for better legibility at small sizes; (3) consider adding a thin border-radius or subtle stroke to the colorbar rect for visual polish. The gamma compression, musical pattern, and Imprint sequential colormap are all excellent choices — keep them.

Verdict: APPROVED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-approved Quality OK, ready for merge and removed quality:83 Quality score 83/100 labels Jun 3, 2026
@MarkusNeusinger MarkusNeusinger merged commit 3c1e305 into main Jun 3, 2026
@MarkusNeusinger MarkusNeusinger deleted the implementation/spectrogram-mel/d3 branch June 3, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Quality OK, ready for merge ai-attempt-1 First repair attempt quality:88 Quality score: 88/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant