Create HTML Embed
Create self-contained D3.js chart embeds for the research article template.
Before you start
Read the full directives file for all conventions, patterns, and checklists:
- directives.md — single source of truth for embed authoring rules
This covers: colors & palettes, layout, SVG scope, mounting, theming, controls, tooltips, data loading, responsiveness, legends, accessibility, performance, error handling, printing, and the full agent checklist.
Workflow
Step 1: Understand the request
Clarify with the user:
- What type of chart? (line, bar, scatter, sankey, waffle, heatmap, custom)
- What data source? (CSV path, JSON, inline data)
- Interactive controls needed? (metric selector, filters)
- Any specific design requirements?
Step 2: Create the HTML file
- Location:
app/src/content/embeds/
- Naming:
d3-<descriptive-name>.html (e.g., d3-training-loss.html)
- Root class:
.d3-<descriptive-name> (must match filename)
Step 3: Follow the mandatory structure
Every embed must have this structure:
<div class="d3-yourname"></div>
<style>
.d3-yourname { /* scoped styles */ }
</style>
<script>
(() => {
const ensureD3 = (cb) => { /* D3 CDN loader */ };
const bootstrap = () => {
/* mount guard + container selection */
/* tooltip setup */
/* SVG scaffolding */
/* data loading */
/* render function with ResizeObserver */
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => ensureD3(bootstrap), { once: true });
} else { ensureD3(bootstrap); }
})();
</script>
Step 4: Integrate in MDX
Import and use the HtmlEmbed component:
import HtmlEmbed from '../../components/HtmlEmbed.astro';
<HtmlEmbed src="d3-yourname.html" title="Chart Title" desc="Description text" />
HtmlEmbed props
| Prop |
Type |
Description |
src |
string |
Path to HTML file in embeds/ (required) |
title |
string |
Title above the card |
desc |
string |
Description below (supports HTML) |
frameless |
boolean |
Removes card background/border |
wide |
boolean |
Wide layout (~1100px) |
data |
string or string[] |
Path(s) to data files |
config |
object |
JSON config passed via data-config attribute |
Usage examples
<!-- Simple embed -->
<HtmlEmbed src="d3-training-loss.html" title="Training Loss" />
<!-- With external data -->
<HtmlEmbed src="d3-line-simple.html" title="Attention" data="attention_loss.csv" />
<!-- With config -->
<HtmlEmbed
src="d3-line-simple.html"
title="Learning Rate"
data="lr_loss.csv"
config={{ defaultMetric: 'loss', xDomain: [0, 45e9] }}
/>
<!-- Multiple data files -->
<HtmlEmbed
src="d3-comparison.html"
title="A vs B"
data={['formatting_filters.csv', 'relevance_filters.csv']}
/>
<!-- Frameless -->
<HtmlEmbed frameless src="d3-banner.html" />
Key conventions (quick reference)
Full details in the directives file. The critical ones:
- Colors: Use
window.ColorPalettes.getColors('categorical', n) — never hardcode palettes
- CSS variables:
--text-color, --surface-bg, --border-color, --axis-color, --tick-color, --grid-color
- Dark mode: Check
document.documentElement.getAttribute('data-theme') === 'dark'
- Mount guard: Always set
container.dataset.mounted = 'true'
- Data loading: Try
/data/<file> first, then ./assets/data/<file> — use fetchFirstAvailable()
- Responsiveness:
ResizeObserver on container, recompute on resize
- Legend: HTML-based, title "Legend", swatch 14x14px
- Controls: HTML only (no SVG UI), selects labeled "Metric" when applicable
- Tooltip: Single
.d3-tooltip absolutely positioned inside container
- No globals: Everything in IIFE, nothing on
window
Data files
- Store data in:
app/src/content/assets/data/
- Served from:
/data/ (public) at build time
- Formats: CSV (preferred for tabular), JSON (for nested/hierarchical)
Post-creation checklist
After creating the embed, verify against the Agent Checklist (section 14.1) and Definition of Done (section 14.2) in directives.md.
1---2name: create-html-embed3description: Create self-contained D3 HTML embed charts for the research article template. Use when the user asks to create a chart, visualization, embed, D3 chart, line chart, bar chart, scatter plot, sankey diagram, or any data visualization as an HTML embed file.4---56# Create HTML Embed78Create self-contained D3.js chart embeds for the research article template.910## Before you start1112**Read the full directives file** for all conventions, patterns, and checklists:1314- [directives.md](directives.md) — single source of truth for embed authoring rules1516This covers: colors & palettes, layout, SVG scope, mounting, theming, controls, tooltips, data loading, responsiveness, legends, accessibility, performance, error handling, printing, and the full agent checklist.1718## Workflow1920### Step 1: Understand the request2122Clarify with the user:23- What type of chart? (line, bar, scatter, sankey, waffle, heatmap, custom)24- What data source? (CSV path, JSON, inline data)25- Interactive controls needed? (metric selector, filters)26- Any specific design requirements?2728### Step 2: Create the HTML file2930- Location: `app/src/content/embeds/`31- Naming: `d3-<descriptive-name>.html` (e.g., `d3-training-loss.html`)32- Root class: `.d3-<descriptive-name>` (must match filename)3334### Step 3: Follow the mandatory structure3536Every embed must have this structure:3738```html39<div class="d3-yourname"></div>40<style>41 .d3-yourname { /* scoped styles */ }42</style>43<script>44 (() => {45 const ensureD3 = (cb) => { /* D3 CDN loader */ };46 const bootstrap = () => {47 /* mount guard + container selection */48 /* tooltip setup */49 /* SVG scaffolding */50 /* data loading */51 /* render function with ResizeObserver */52 };53 if (document.readyState === 'loading') {54 document.addEventListener('DOMContentLoaded', () => ensureD3(bootstrap), { once: true });55 } else { ensureD3(bootstrap); }56 })();57</script>58```5960### Step 4: Integrate in MDX6162Import and use the `HtmlEmbed` component:6364```mdx65import HtmlEmbed from '../../components/HtmlEmbed.astro';6667<HtmlEmbed src="d3-yourname.html" title="Chart Title" desc="Description text" />68```6970#### HtmlEmbed props7172| Prop | Type | Description |73|------|------|-------------|74| `src` | string | Path to HTML file in `embeds/` (required) |75| `title` | string | Title above the card |76| `desc` | string | Description below (supports HTML) |77| `frameless` | boolean | Removes card background/border |78| `wide` | boolean | Wide layout (~1100px) |79| `data` | string or string[] | Path(s) to data files |80| `config` | object | JSON config passed via `data-config` attribute |8182#### Usage examples8384```mdx85<!-- Simple embed -->86<HtmlEmbed src="d3-training-loss.html" title="Training Loss" />8788<!-- With external data -->89<HtmlEmbed src="d3-line-simple.html" title="Attention" data="attention_loss.csv" />9091<!-- With config -->92<HtmlEmbed93 src="d3-line-simple.html"94 title="Learning Rate"95 data="lr_loss.csv"96 config={{ defaultMetric: 'loss', xDomain: [0, 45e9] }}97/>9899<!-- Multiple data files -->100<HtmlEmbed101 src="d3-comparison.html"102 title="A vs B"103 data={['formatting_filters.csv', 'relevance_filters.csv']}104/>105106<!-- Frameless -->107<HtmlEmbed frameless src="d3-banner.html" />108```109110## Key conventions (quick reference)111112Full details in the directives file. The critical ones:1131141. **Colors**: Use `window.ColorPalettes.getColors('categorical', n)` — never hardcode palettes1152. **CSS variables**: `--text-color`, `--surface-bg`, `--border-color`, `--axis-color`, `--tick-color`, `--grid-color`1163. **Dark mode**: Check `document.documentElement.getAttribute('data-theme') === 'dark'`1174. **Mount guard**: Always set `container.dataset.mounted = 'true'`1185. **Data loading**: Try `/data/<file>` first, then `./assets/data/<file>` — use `fetchFirstAvailable()`1196. **Responsiveness**: `ResizeObserver` on container, recompute on resize1207. **Legend**: HTML-based, title "Legend", swatch 14x14px1218. **Controls**: HTML only (no SVG UI), selects labeled "Metric" when applicable1229. **Tooltip**: Single `.d3-tooltip` absolutely positioned inside container12310. **No globals**: Everything in IIFE, nothing on `window`124125## Data files126127- Store data in: `app/src/content/assets/data/`128- Served from: `/data/` (public) at build time129- Formats: CSV (preferred for tabular), JSON (for nested/hierarchical)130131## Post-creation checklist132133After creating the embed, verify against the **Agent Checklist** (section 14.1) and **Definition of Done** (section 14.2) in [directives.md](directives.md).