@htmlbricks/hb-chartjs
v0.76.5
Published
Embeds Chart.js (line, bar, pie, radar, time scales, etc.) inside the shadow DOM. Pass a JSON `data` object with `type`, `data`, and optional `options`; the chart is recreated on data changes and when the container resizes (ResizeObserver + debounced wind
Readme
hb-chartjs
Category: data · Tags: data, chart
Summary
hb-chartjs is a shadow-DOM web component that renders Chart.js (project dependency ^4.5.1) on a <canvas>. You supply a single JSON data payload shaped like Chart.js’s constructor config (type, data, optional options). The component destroys and recreates the chart when that config changes and when the chart container’s size changes, so sizing stays in sync with the host layout.
What it does
- Registers a fixed set of Chart.js controllers, scales, and plugins inside the component bundle (line, bar, bubble, doughnut, pie, polar area, radar, scatter; category/linear/log/radial linear/time/time-series scales; decimation, filler, legend, title, tooltip, subtitle).
- Builds a
Chartinstance against the shadow-root canvas, merging youroptionswith internal defaults:responsive: true,maintainAspectRatio: true, and anaspectRatioderived from the container’s width/height when both are positive. - Listens for canvas clicks and dispatches a
chartClickcustom event whosedetailis an array of hit points (label/value pairs) from Chart.js’s nearest-element hit test.
Appearance and layout
:host(styles/webcomponent.scss):width: 100%;height: auto.- Chart wrapper (
part="container",#chart-container):position: relative; fills width/height of the host (width: 100%,height: 100%);overflow: hidden; centered withmargin: auto. - Canvas:
display: block;max-width: 100%;max-height: 100%;width: 100%;height: auto; centered.
Give the host a concrete height (or an aspect-ratio) if you need a predictable chart box; the internal layout passes the container box into Chart.js via aspectRatio when it can measure both dimensions.
Logic (Chart.js lifecycle and props)
- Mount: Marks the component as mounted, attaches a
ResizeObserveron#chart-container, adds a debouncedwindowresizelistener (100 ms), then callsupdateChart(). updateChart(): If mounted,datais set, and the canvas exists in the shadow root, any existingChartis destroyed, then a newChartis created with{ type: data.type, data: data.data, options: { ...data.options, ...defaultOptions } }.- Reactive
data: Whendatais a string, it isJSON.parsed andupdateChart()runs. Treat HTML usage as always passing a JSON string on thedataattribute (see types). - Resize: ResizeObserver callbacks and debounced window resize both call
updateChart(), which recreates the chart (not an in-placeupdate()). - Unmount: Removes listeners, disconnects the observer, and destroys the chart instance.
Click path: The canvas uses a debounced handler that calls chart.getElementsAtEventForMode(event, 'nearest', { intersect: true }, true). For each element, detail gets { label, value } from chart.data.labels[index] and chart.data.datasets[datasetIndex].data[index]. If nothing is hit, detail is an empty array.
Custom element
hb-chartjs
Attributes (snake_case; string values in HTML)
| Attribute | Required | Description |
|-----------|----------|-------------|
| data | no (recommended) | JSON string or object: Chart.js config with type, data, and optional options. When omitted initially, the chart updates once data is set. |
| id | no | Passed through as the component’s optional id (string). |
Authoritative prop names for integrators: src/wc/chartjs/types/webcomponent.type.d.ts (Component).
Events
Listen with addEventListener (or framework equivalents).
| Event | event.detail (TypeScript) |
|-------|-----------------------------|
| chartClick | Array<{ label?: string; value?: any }> — one entry per hit element; empty array if no point was hit. |
Defined alongside Component in src/wc/chartjs/types/webcomponent.type.d.ts (Events).
CSS custom properties, parts, and slots
Variables (theme on :host via forwarded Bulma host theme; see extra/docs.ts / styles/bulma.scss):
| Variable | Role |
|----------|------|
| --bulma-text | Text token on :host (e.g. captions around the chart). |
| --bulma-background | Surface / background token on :host. |
Chart colors normally come from the Chart.js JSON (datasets, options), not from these variables.
Parts:
| Part | Role |
|------|------|
| container | Wrapper around the <canvas> — size the chart from the light DOM with ::part(container) (width, height, margins, aspect-ratio, etc.). |
Slots: none (htmlSlots is empty in extra/docs.ts).
Typings path
- Consumer-oriented
Component/Events:src/wc/chartjs/types/webcomponent.type.d.ts - Metadata, CSS tokens, and Storybook-style examples:
src/wc/chartjs/extra/docs.ts
Minimal HTML and JavaScript example
<hb-chartjs
id="sales-chart"
data='{"type":"bar","data":{"labels":["Q1","Q2"],"datasets":[{"label":"Revenue","data":[12,19]}]},"options":{}}'
></hb-chartjs>
<script>
const chart = document.getElementById("sales-chart");
chart.addEventListener("chartClick", (event) => {
/** @type {{ label?: string; value?: any }[]} */
const points = event.detail;
console.log(points);
});
chart.setAttribute(
"data",
JSON.stringify({
type: "line",
data: {
labels: ["Jan", "Feb"],
datasets: [{ label: "Series A", data: [1, 2] }],
},
options: {},
})
);
</script>Use setAttribute("data", …) with JSON.stringify when updating from vanilla JS so the internal string handling and chart rebuild stay aligned with attribute-based usage.
