Docs · Embed
Embed a chart that stays alive
One hosted script, one custom element, no build step. The chart draws itself in, morphs when its spec changes, and carries its own accessibility — this page is the full contract. For the two-minute version, start at get started.
1 · Load the element
The bundle is self-contained — engine included, about 16 KB gzipped — and served from this domain with CORS open, so the same tag works on any origin. An npm package ships at launch.
<script type="module" src="https://meikucharts.com/v1/live-chart.js"></script>
2 · Drop a chart with its spec as a JSON child
The way most embedders start: the spec travels inside the element, so the snippet is one self-sufficient block of HTML.
<live-chart>
<script type="application/json">
{
"type": "column",
"theme": "editorial",
"title": "Weekly Signups",
"source": "Product analytics",
"data": {
"labels": [
"Mon",
"Tue",
"Wed",
"Thu",
"Fri"
],
"series": [
{
"name": "Signups",
"values": [
12,
19,
14,
27,
22
]
}
]
}
}
</script>
</live-chart> 3 · Or pass the spec another way
Three inputs, same result — pick whichever fits the page. A spec attribute
carrying JSON suits server-rendered templates:
<live-chart spec='{"type":"line","theme":"mint","data":{"labels":["Q1","Q2","Q3"],"series":[{"values":[12,19,27]}]}}'></live-chart>
And the spec property suits scripts — assign a plain object, no serialization.
Setting it on a mounted chart is also how you morph:
const chart = document.querySelector("live-chart");
chart.spec = {
"type": "line",
"theme": "mint",
"title": "Weekly Signups",
"source": "Product analytics",
"data": {
"labels": [
"Mon",
"Tue",
"Wed",
"Thu",
"Fri"
],
"series": [
{
"name": "Signups",
"values": [
18,
24,
20,
33,
29
]
}
]
}
}; The element re-parses on every change and the engine animates from the old shape to the new one — including across chart types. There is no separate update API to learn.
Sizing
The host renders as a block, full width, 300px tall by default. Size it like any element — the canvas follows its box, crisp on high-DPI screens:
live-chart {
height: 420px; /* default is 300px */
max-width: 720px;
} States you can style and script against
The host mirrors the engine's state as an attribute: "animating" while drawing or morphing,
"idle" once settled. Tests in this repository wait for state="idle"; a host page
can do the same, or hook CSS on it:
live-chart[state="animating"] { /* drawing or morphing */ }
live-chart[state="idle"] { /* settled */ }
A spec that fails to parse never throws: the chart shows a short structured message, and the
element's error property returns the same {path, message, hint}
list the spec reference documents.
Accessibility, built in
Every chart ships a hidden data table with its raw values (screen readers get the truth, not
a description of pixels), an aria-label naming the chart, and keyboard
navigation — Tab to the canvas, arrows between marks, Escape out — with a visible focus
ring. Hover tooltips have keyboard parity. None of this needs configuration.
Theming the embed
Charts follow their theme's light or dark variant. Pass options.variant as
"auto" to follow the visitor's OS preference (omitting it shows the theme's own
canonical side instead), or pin "light"/"dark" — which is what a
page with its own theme toggle should do, since the engine can see the OS but never a host
page's toggle. Details and the format/target options live in the
spec reference.
What the embed never does
No network requests beyond loading the script itself, no cookies, no tracking, nothing uploaded — the spec renders entirely in the visitor's browser. The e2e suite proves the exported snippet renders on a blank page with only that one script fetch.