Most chart libraries tax every page: 40–150 KB of JS, hydration delay, and markup crawlers never see. ProvChart takes another path—data becomes HTML and CSS (custom properties + clip-path). ProvChart Runtime is an optional script that adds tooltips, motion, and legend focus without changing how charts are generated.
This post walks through a minimal setup: generate an area chart from the API, inject it, and let the runtime enhance it.
What you get
| Layer | Role |
|---|---|
| ProvChart API |
POST /api/v1/generate → { html, css } — zero chart-library runtime on the page |
| ProvChart Runtime | Scans [data-provchart], adds hover tooltips, scroll reveal, legend dimming |
| SVG API (optional) |
POST /api/v1/generate-svg for README/docs — runtime skips pure SVG by design |
Repo / install:
- github.com/fscss-ttr/provchart-runtime
-
npm i provchart-runtime - CDN: jsDelivr or unpkg
Product: chart.devtem.org
1. Get an API key
- Sign in at chart.devtem.org
- Open Dashboard → Developer API
- Create a key
Signed-up free accounts get a monthly test quota. HTML and SVG generations share the same pool.
2. Minimal page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ProvChart + Runtime</title>
<style>
body {
margin: 0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #0c0a16;
font-family: system-ui, sans-serif;
}
#chart { width: min(640px, 92vw); }
.err { color: #ff5e7d; font-size: 14px; padding: 16px; }
</style>
<script>
window.ProvChartRuntimeConfig = {
animation: true,
revealOnScroll: true,
tooltips: true,
perPointTooltips: true,
observe: true,
selector: '[data-provchart]',
excludeSvg: true,
};
</script>
<script src="https://cdn.jsdelivr.net/npm/provchart-runtime@1.0.0/dist/provchart-runtime.min.js"></script>
</head>
<body>
<div id="chart"></div>
<script type="module">
const API = 'https://provchart-api.devtem.org/api/v1/generate';
const API_KEY = 'YOUR_API_KEY';
const payload = {
type: 'area',
series: [
{ name: 'Traffic', color: '#4fd8c4', points: [30, 45, 40, 60, 55, 70, 65] },
{ name: 'Signups', color: '#f0a860', points: [8, 12, 11, 18, 16, 22, 20] },
],
axisX: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
};
const mount = document.getElementById('chart');
try {
const res = await fetch(API, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY,
},
body: JSON.stringify(payload),
});
const data = await res.json();
if (!data.success) throw new Error(data.error || 'Generate failed');
let style = document.getElementById('provchart-style');
if (!style) {
style = document.createElement('style');
style.id = 'provchart-style';
document.head.appendChild(style);
}
style.textContent = data.css || '';
mount.innerHTML = data.html || '';
// Optional: only if your build exposes it
// window.ProvChartRuntime?.scan?.();
} catch (err) {
mount.innerHTML = `<p class="err">${err.message}</p>`;
}
</script>
</body>
</html>
Replace YOUR_API_KEY. After load you should see a two-series area chart; hover legend/points if the runtime attached correctly.
3. How the runtime finds charts
Generated roots look like:
<div class="pc-chart-…" data-provchart="area">…</div>
The runtime:
- Queries
[data-provchart] - Skips pure SVG embeds when
excludeSvg: true - Uses a
MutationObserverso charts injected viafetchstill get enhanced - Reads series points from CSS variables like
--pc-{id}-s1-p1for per-point tooltips
You don’t call into ProvChart’s core from the client for paint—the browser already painted CSS.
4. Config worth knowing
window.ProvChartRuntimeConfig = {
animation: true,
revealOnScroll: true,
tooltips: true,
perPointTooltips: true,
countUp: true, // gauge / stat numbers
observe: true, // watch DOM for new charts
excludeSvg: true, // leave README SVGs alone
};
Define this before the runtime script tag.
5. HTML/CSS vs SVG
| Use case | Endpoint | Runtime |
|---|---|---|
| App UI, dashboard, marketing page | /api/v1/generate |
Yes |
| GitHub README, static docs asset | /api/v1/generate-svg |
No (commit .svg or data URI) |
Same payload shape (type, series, axisX); different output.
6. Why this split matters
- Performance: no Chart.js-sized dependency to parse before first paint
- SEO: chart structure is in HTML/CSS on first response
- Progressive enhancement: runtime is optional; charts work without it
- Docs vs apps: SVG for Markdown hosts; HTML/CSS + runtime for product UI
Links
generate charts as HTML and CSS, ship them with almost no client chart code, and add interactivity only when you want it—with a single script tag
Top comments (0)