@hemicycle/vanilla
v0.1.5
Published
Hemicycle svg component for vanilla JS
Downloads
598
Maintainers
Readme
@hemicycle/vanilla
Framework-free SVG renderer for parliament-style hemicycle seat charts.
@hemicycle/vanilla wraps @hemicycle/core with a lightweight rendering layer that writes directly into an <svg> element — no framework, no bundler magic required. Pass it a config, call render(), and get a fully drawn hemicycle.
Features
- Direct SVG rendering — writes
<path>elements into anySVGSVGElementyou provide - Three seat shapes —
arc(default),rect, andcircle - Per-seat styling — override color, shape, and border radius on individual seats via
seatConfig - Hide empty seats — optionally omit unoccupied seats for sparse layouts
- All
@hemicycle/coreoptions — full access to rows, radii, aisles, mirroring, and ordering - TypeScript-first — fully typed with ESM and CJS dual output
Installation
npm install @hemicycle/vanilla@hemicycle/core is a peer dependency and is included automatically.
Requires Node.js ≥ 18 and a DOM environment (browser or jsdom).
Quick Start
<svg id="hemicycle"></svg>import { Hemicycle } from "@hemicycle/vanilla";
const hemicycle = new Hemicycle({
rows: 7,
totalSeats: 577,
innerRadius: 40,
outerRadius: 95,
width: 800,
height: 420,
});
const svg = document.getElementById("hemicycle") as SVGSVGElement;
hemicycle.render(svg);API
new Hemicycle(config)
Creates a new renderer. Accepts all @hemicycle/core config options plus the following:
| Option | Type | Default | Description |
| ---------------- | ------------ | --------- | -------------------------------------------- |
| width | number | 800 | SVG width attribute value |
| height | number | 400 | SVG height attribute value |
| seatConfig | SeatConfig | see below | Default visual style applied to all seats |
| hideEmptySeats | boolean | false | Skip rendering seats with no associated data |
SeatConfig
| Option | Type | Default | Description |
| -------------- | ----------------------------- | -------- | ------------------------------------------------------------ |
| shape | "arc" \| "rect" \| "circle" | "arc" | Seat shape |
| color | string | "#ccc" | Fill color |
| borderRadius | number | 1.5 | Corner rounding for arc and rect shapes |
| radius | number | 2 | Radius for circle shape; radial thickness for arc/rect |
hemicycle.render(svg)
Clears the target <svg> element and renders all seats into it. Also sets viewBox, width, and height attributes automatically.
hemicycle.render(document.querySelector("svg")!);hemicycle.updateData(data)
Attaches seat data and computes per-seat paths. Each item must identify a seat by idx or by { rowIndex, seatIndex }, and may include a seatConfig to override the default style for that seat.
hemicycle.updateData([
{ idx: 0, party: "Left", seatConfig: { color: "#e63946" } },
{ idx: 1, party: "Center", seatConfig: { color: "#457b9d" } },
]);
hemicycle.render(svg);Data items without a seatConfig inherit the global config. The seatConfig field is optional — omit it to use the global default.
hemicycle.updateConfig(config)
Applies a partial config update. Call render() again afterward to redraw.
Other accessors
| Method | Returns |
| --------------- | -------------------------------------------------------------- |
| getSeatData() | ComputedSeatData<T>[] — seat layouts with computed SVG paths |
| getViewBox() | string — the computed SVG viewBox value |
| getEngine() | The underlying @hemicycle/core Hemicycle instance |
| getConfig() | HemicycleConfig |
Examples
Coloring seats by party
const hemicycle = new Hemicycle({
rows: 7,
totalSeats: 577,
seatConfig: { color: "#ddd", shape: "arc" },
});
hemicycle.updateData(
members.map((m) => ({
idx: m.seatNumber,
seatConfig: { color: m.partyColor },
})),
);
hemicycle.render(document.querySelector("#parliament")!);Hiding unoccupied seats
const hemicycle = new Hemicycle({
rows: 5,
totalSeats: 100,
hideEmptySeats: true,
});
hemicycle.updateData(occupiedSeats); // Only these will be drawn
hemicycle.render(svg);Circular seats with custom radius
const hemicycle = new Hemicycle({
rows: 6,
totalSeats: 200,
seatConfig: {
shape: "circle",
radius: 2.5,
color: "#adb5bd",
},
});Reactive updates
const hemicycle = new Hemicycle({ rows: 5, totalSeats: 50 });
hemicycle.render(svg);
// On user interaction, update data and re-render:
button.addEventListener("click", () => {
hemicycle.updateData(newData);
hemicycle.render(svg); // cleanUp() is called automatically
});Seat Shapes
| Shape | Description |
| -------- | ---------------------------------------------------------------- |
| arc | Curved wedge following the concentric arc of the row (default) |
| rect | Rectangular seat aligned to the arc midpoint |
| circle | Circle centered at the seat's midpoint |
Related
@hemicycle/core— layout engine (no rendering)
Contributing
Bug reports and pull requests are welcome on GitHub.
Support
- Issues: GitHub Issues
- Source: github.com/GabrielVidal1/hemicycle
Maintainer
Gabriel Vidal — [email protected]
