Last updated: 2026-03-26
This guide explains how to embed GramFrame spectrogram viewers in HTML pages. GramFrame auto-discovers configuration tables and replaces them with interactive SVG overlays.
<script src="gramframe.js"></script>For standalone use (no build tool), use the IIFE bundle:
<script src="gramframe.bundle.js"></script>The standalone bundle includes CSS inlined automatically — no separate stylesheet needed.
<table class="gram-config">
<tr><td colspan="2"><img src="spectrogram.png" /></td></tr>
<tr><td>time-start</td><td>0</td></tr>
<tr><td>time-end</td><td>10</td></tr>
<tr><td>freq-start</td><td>0</td></tr>
<tr><td>freq-end</td><td>2000</td></tr>
</table>On DOMContentLoaded, GramFrame scans the page for all <table class="gram-config"> elements and replaces each one with an interactive spectrogram viewer.
The configuration table uses a 2-column format: parameter | value.
| Parameter | Type | Required | Description |
|---|---|---|---|
time-start |
number | Yes | Start time value (bottom of Y-axis) |
time-end |
number | Yes | End time value (top of Y-axis). Must be > time-start |
freq-start |
number | Yes | Start frequency value (left of X-axis) |
freq-end |
number | Yes | End frequency value (right of X-axis). Must be > freq-start |
The first row must contain an <img> element with the spectrogram image (using colspan="2").
- All four parameters (
time-start,time-end,freq-start,freq-end) are required - Values must be valid numbers (parsed with
parseFloat) - Start values must be strictly less than end values
- The
<img>element must have asrcattribute - If validation fails, the original table is preserved and an error indicator is shown
You can have multiple independent GramFrame instances on a single page. Each config table becomes its own instance with independent state.
<!-- First spectrogram -->
<table class="gram-config">
<tr><td colspan="2"><img src="spectrogram-1.png" /></td></tr>
<tr><td>time-start</td><td>0</td></tr>
<tr><td>time-end</td><td>30</td></tr>
<tr><td>freq-start</td><td>0</td></tr>
<tr><td>freq-end</td><td>5000</td></tr>
</table>
<!-- Second spectrogram (different image and ranges) -->
<table class="gram-config">
<tr><td colspan="2"><img src="spectrogram-2.png" /></td></tr>
<tr><td>time-start</td><td>0</td></tr>
<tr><td>time-end</td><td>60</td></tr>
<tr><td>freq-start</td><td>100</td></tr>
<tr><td>freq-end</td><td>20000</td></tr>
</table>Each instance:
- Has its own state (cursor position, mode, markers, etc.)
- Responds independently to mouse interactions
- Can be in different modes simultaneously
- Gets a unique
instanceIdfor programmatic access
If you need to initialize GramFrame after page load (e.g., for dynamically added content):
// Initialize all config tables in a specific container
const container = document.getElementById('my-container')
const instances = GramFrame.detectAndReplaceConfigTables(container)Listen for state changes across all instances:
// Add a listener
const listener = GramFrame.addStateListener(state => {
console.log('Mode:', state.mode)
console.log('Cursor:', state.cursorPosition)
})
// Remove a listener
GramFrame.removeStateListener(listener)State is deep-copied before being passed to listeners, so you cannot accidentally mutate internal state.
GramFrame supports file:// protocol for offline use. The standalone IIFE build (gramframe.bundle.js) bundles all CSS inline, avoiding cross-origin restrictions. See ADR-013.
Build the standalone bundle with:
yarn build:standalone- Verify the table has
class="gram-config"(exact class name) - Ensure the script is loaded before
DOMContentLoadedfires - Check the browser console for error messages
If a red error box appears below the table:
- "No image element found" — First row must contain an
<img>tag - "Image element has no src" — The
<img>needs a validsrcattribute - "Missing required time/frequency configuration" — All four parameters must be present
- "Invalid time/frequency range" — Start value must be less than end value
- "Invalid numeric value" — Parameter values must be numbers
- Verify the image path is correct relative to the HTML file
- For
file://protocol, ensure the image is in an accessible directory - Check browser console for 404 errors
Each instance is fully independent. If instances seem to interfere:
- Verify each table has its own
<img>element (not shared) - Check that state listeners are filtering by
instanceIdif needed
- ADR-005: HTML Table Configuration — Design rationale for the table-based config approach
- ADR-013: File Protocol Compatibility — Offline/file:// support decisions
- Tech-Architecture.md — Full system architecture