https://github.com/c-cube/hx-plot
htmx extensions for plotting with vega-lite
https://github.com/c-cube/hx-plot
extension html plot vega-lite
Last synced: 18 days ago
JSON representation
htmx extensions for plotting with vega-lite
- Host: GitHub
- URL: https://github.com/c-cube/hx-plot
- Owner: c-cube
- Created: 2026-03-26T20:00:36.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-05T00:39:52.000Z (3 months ago)
- Last Synced: 2026-05-01T04:25:13.615Z (about 2 months ago)
- Topics: extension, html, plot, vega-lite
- Language: JavaScript
- Homepage: https://c-cube.github.io/hx-plot/
- Size: 424 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# hx-plot
**hx-plot** is an [htmx](https://htmx.org) extension that renders [Vega-Lite](https://vega.github.io/vega-lite/) charts directly from JSON — inline on the page or fetched from a server endpoint. Add `hx-ext="plot"` to any element and point it at a JSON spec; htmx handles the rest.
> **[Live playground →](https://c-cube.github.io/hx-plot/)** · [GitHub](https://github.com/c-cube/hx-plot)
Two builds are available:
| File | Size | How it loads Vega |
|------|------|-------------------|
| `hx-plot.min.js` | ~2.5 KiB | Lazy CDN import on first use |
| `hx-plot.full.min.js` | ~750 kiB | Fully self-contained |
## Usage
```html
```
### Inline JSON
Read a Vega-Lite spec from a `` element. Renders once on load.
```html
<script id="cfg" type="application/json">
{
"mark": "point",
"data": {"values": [{"x": 1, "y": 2}, {"x": 2, "y": 4}]},
"encoding": {
"x": {"field": "x", "type": "quantitative"},
"y": {"field": "y", "type": "quantitative"}
}
}
```
### Fetch from URL
Fetch a Vega-Lite spec as JSON from a server endpoint. Supports all htmx trigger and swap options.
```html
```
### Error handling
Upon error, a `ht-plot:error` event is emitted, and a message is printed
on the console.
### Live updates with view transitions
```html
```
## JSON format
The JSON must be a valid [Vega-Lite spec](https://vega.github.io/vega-lite/docs/). It is passed directly to `vegaLite.compile()` then rendered with Vega.
```json
{
"mark": "line",
"data": {"values": [{"x": 0, "y": 0}, {"x": 1, "y": 1}]},
"encoding": {
"x": {"field": "x", "type": "quantitative"},
"y": {"field": "y", "type": "quantitative"}
}
}
```
Layered charts, facets, and all other Vega-Lite features work as-is.
## Attributes
| Attribute | Description |
|-----------|-------------|
| `hx-ext="plot"` | Activates the extension on an element |
| `hx-plot="#selector"` | Render from inline JSON element (renders on page load) |
| `hx-get="/url"` | Fetch JSON from URL (respects `hx-trigger`) |
| `hx-target="#id"` | Where to render the chart (defaults to the element itself) |
| `hx-trigger="..."` | Standard htmx trigger — `load`, `every 2s`, `click`, etc. |
| `hx-swap="innerHTML transition:true"` | Enable View Transitions API on swap |
| `hx-swap-on-error` | On error, replace the chart container with a `
` |
## Events
| Event | Fired on | Detail |
|-------|----------|--------|
| `hx-plot:render-start` | container | `{ spec }` |
| `hx-plot:render-done` | container | `{ spec }` |
| `hx-plot:error` | container (or `document`) | `{ error, spec? }` |
All events bubble. Listen on a parent element to catch errors from multiple charts.
## Full examples
### Inline JSON
```html
{
"mark": "point",
"data": {"values": [{"x": 1, "y": 2}, {"x": 2, "y": 4}, {"x": 3, "y": 1}]},
"encoding": {
"x": {"field": "x", "type": "quantitative"},
"y": {"field": "y", "type": "quantitative"}
}
}
```
### Fetch from URL (e.g. on page load)
```html
```
### Live updates every 2 seconds with view transitions
```html
#chart { view-transition-name: my-chart; }
::view-transition-old(my-chart),
::view-transition-new(my-chart) { animation-duration: 0.3s; }
```
### Error handling
```html
document.getElementById('charts').addEventListener('hx-plot:error', e => {
console.error('chart failed:', e.detail.error);
});
```
## Building
```sh
make install # pnpm install
make # build dist/hx-plot.min.js and dist/hx-plot.full.min.js
make serve # start dev server at http://localhost:8000/demo/demo.html
make update # upgrade vega + vega-lite and rebuild
make lint # biome lint
```