@vielzeug/codex 26.10.4 → 26.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/catalog.json +45 -48
- package/data/llms-full.txt +929 -1272
- package/data/llms.txt +2 -2
- package/data/manifest.json +1 -1
- package/data/packages/prism.json +4 -4
- package/data/refine.json +299 -280
- package/data/search.json +7 -7
- package/package.json +2 -2
package/data/llms-full.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vielzeug: Full Documentation
|
|
2
2
|
|
|
3
|
-
> Complete documentation for 41 packages. Version: 26.10.
|
|
3
|
+
> Complete documentation for 41 packages. Version: 26.10.4
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -16403,64 +16403,60 @@ The IndexedDB adapter is built on Vault. Use Vault directly for unrelated storag
|
|
|
16403
16403
|
|
|
16404
16404
|
## Why Prism?
|
|
16405
16405
|
|
|
16406
|
-
|
|
16406
|
+
Prism renders charts as SVG in a host element and keeps application state outside the chart. You can replace chart data explicitly, respond to container resizing, and style the output with CSS custom properties.
|
|
16407
16407
|
|
|
16408
16408
|
```ts
|
|
16409
|
-
// Before: Chart.js, imperative setup with a canvas you can't CSS-theme
|
|
16410
|
-
import Chart from 'chart.js/auto';
|
|
16411
|
-
const ctx = document.getElementById('myChart') as HTMLCanvasElement;
|
|
16412
|
-
new Chart(ctx, {
|
|
16413
|
-
type: 'line',
|
|
16414
|
-
data: { labels, datasets: [{ data: values }] },
|
|
16415
|
-
// re-create or mutate the Chart.js instance when data changes
|
|
16416
|
-
});
|
|
16417
|
-
|
|
16418
|
-
// After: Prism, responsive SVG with an explicit update boundary
|
|
16419
16409
|
import { createLineChart } from '@vielzeug/prism';
|
|
16420
16410
|
|
|
16421
|
-
const
|
|
16422
|
-
|
|
16423
|
-
|
|
16424
|
-
|
|
16425
|
-
|
|
16426
|
-
|
|
16427
|
-
|
|
16428
|
-
|
|
16429
|
-
|
|
16430
|
-
|
|
16431
|
-
|
|
16432
|
-
|
|
16433
|
-
|
|
16411
|
+
const host = document.createElement('div');
|
|
16412
|
+
host.style.cssText = 'width:640px;height:320px';
|
|
16413
|
+
document.body.append(host);
|
|
16414
|
+
|
|
16415
|
+
// Before: replace a hand-drawn SVG each time values change.
|
|
16416
|
+
function drawLine(values: number[]) {
|
|
16417
|
+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
16418
|
+
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
16419
|
+
const low = Math.min(...values);
|
|
16420
|
+
const span = Math.max(...values) - low || 1;
|
|
16421
|
+
const points = values.map((value, index) => {
|
|
16422
|
+
const x = (index / Math.max(1, values.length - 1)) * 640;
|
|
16423
|
+
const y = 320 - ((value - low) / span) * 320;
|
|
16424
|
+
return `${index === 0 ? 'M' : 'L'}${x},${y}`;
|
|
16425
|
+
});
|
|
16426
|
+
svg.setAttribute('viewBox', '0 0 640 320');
|
|
16427
|
+
path.setAttribute('d', points.join(' '));
|
|
16428
|
+
path.setAttribute('fill', 'none');
|
|
16429
|
+
path.setAttribute('stroke', 'currentColor');
|
|
16430
|
+
svg.append(path);
|
|
16431
|
+
host.replaceChildren(svg);
|
|
16432
|
+
}
|
|
16433
|
+
drawLine([10, 25, 18]);
|
|
16434
|
+
drawLine([10, 25, 18, 32]);
|
|
16435
|
+
|
|
16436
|
+
// After: keep the chart instance and replace its series data.
|
|
16437
|
+
const chart = createLineChart(host, {
|
|
16438
|
+
a11y: { ariaLabel: 'Revenue by month' },
|
|
16439
|
+
series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }], name: 'Revenue' }],
|
|
16434
16440
|
});
|
|
16435
|
-
|
|
16436
|
-
|
|
16437
|
-
|
|
16438
|
-
|
|
16439
|
-
|
|
16440
|
-
{ key: 2, value: 40 },
|
|
16441
|
-
{ key: 3, value: 28 },
|
|
16442
|
-
{ key: 4, value: 65 },
|
|
16443
|
-
],
|
|
16444
|
-
name: 'Users',
|
|
16445
|
-
},
|
|
16446
|
-
]);
|
|
16441
|
+
chart.update([{
|
|
16442
|
+
data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }, { key: 4, value: 32 }],
|
|
16443
|
+
name: 'Revenue',
|
|
16444
|
+
}]);
|
|
16445
|
+
chart.dispose();
|
|
16447
16446
|
```
|
|
16448
16447
|
|
|
16449
|
-
| Feature
|
|
16450
|
-
|
|
|
16451
|
-
| Bundle size
|
|
16452
|
-
| Zero dependencies
|
|
16453
|
-
|
|
|
16454
|
-
|
|
|
16455
|
-
|
|
|
16456
|
-
|
|
|
16457
|
-
| Accessible SVG | | | | Manual |
|
|
16458
|
-
| Keyboard navigation | | | | Manual |
|
|
16459
|
-
| TypeScript-first | | Partial | | Types available |
|
|
16448
|
+
| Feature | Prism | Hand-written SVG |
|
|
16449
|
+
| --- | --- | --- |
|
|
16450
|
+
| Bundle size | | No chart package |
|
|
16451
|
+
| Zero dependencies | (uses Orbit) | |
|
|
16452
|
+
| Data updates | `ChartHandle.update()` replaces chart data | You implement the update path |
|
|
16453
|
+
| Responsive sizing | `ResizeObserver` recalculates the chart layout | You implement the resize behavior |
|
|
16454
|
+
| Chart interactions | Built-in pointer and keyboard interactions on supported charts | You implement them |
|
|
16455
|
+
| SVG accessibility | Informative charts support an accessible name and keyboard focus | You implement the accessible behavior |
|
|
16460
16456
|
|
|
16461
|
-
**Use Prism when** you need
|
|
16457
|
+
**Use Prism when** you need chart factories, responsive SVG output, and an explicit data-update boundary without adopting a charting framework.
|
|
16462
16458
|
|
|
16463
|
-
**Consider
|
|
16459
|
+
**Consider hand-written SVG when** you need a single specialized graphic and prefer to own its scales, resizing, labels, and interactions directly.
|
|
16464
16460
|
|
|
16465
16461
|
## Installation
|
|
16466
16462
|
|
|
@@ -16478,63 +16474,48 @@ yarn add @vielzeug/prism
|
|
|
16478
16474
|
|
|
16479
16475
|
## Quick Start
|
|
16480
16476
|
|
|
16477
|
+
Create and size a host element before creating the chart. Import `theme.css` once to load Prism's default styles and CSS custom properties.
|
|
16478
|
+
|
|
16481
16479
|
```ts
|
|
16482
16480
|
import { createLineChart } from '@vielzeug/prism';
|
|
16483
16481
|
import '@vielzeug/prism/theme.css';
|
|
16484
16482
|
|
|
16485
|
-
const
|
|
16483
|
+
const host = document.createElement('div');
|
|
16484
|
+
host.style.cssText = 'width:640px;height:320px';
|
|
16485
|
+
document.body.append(host);
|
|
16486
|
+
|
|
16487
|
+
const chart = createLineChart(host, {
|
|
16486
16488
|
a11y: { ariaLabel: 'Revenue by month' },
|
|
16487
|
-
series: [
|
|
16488
|
-
{
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
{ key: 1, value: 10 },
|
|
16492
|
-
{ key: 2, value: 25 },
|
|
16493
|
-
{ key: 3, value: 18 },
|
|
16494
|
-
{ key: 4, value: 32 },
|
|
16495
|
-
],
|
|
16496
|
-
name: 'Revenue',
|
|
16497
|
-
},
|
|
16498
|
-
],
|
|
16499
|
-
xAxis: { position: 'bottom' },
|
|
16500
|
-
yAxis: { position: 'left', grid: true },
|
|
16489
|
+
series: [{
|
|
16490
|
+
data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }],
|
|
16491
|
+
name: 'Revenue',
|
|
16492
|
+
}],
|
|
16501
16493
|
tooltip: true,
|
|
16502
|
-
crosshair: true,
|
|
16503
|
-
onHover: (event) => console.log(event?.datum),
|
|
16504
16494
|
});
|
|
16505
16495
|
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }, { key: 4, value: 32 }, { key: 5, value: 28 }],
|
|
16511
|
-
name: 'Revenue',
|
|
16512
|
-
},
|
|
16513
|
-
]);
|
|
16496
|
+
chart.update([{
|
|
16497
|
+
data: [{ key: 1, value: 10 }, { key: 2, value: 25 }, { key: 3, value: 18 }, { key: 4, value: 32 }],
|
|
16498
|
+
name: 'Revenue',
|
|
16499
|
+
}]);
|
|
16514
16500
|
|
|
16515
|
-
// Cleanup when done
|
|
16516
16501
|
chart.dispose();
|
|
16517
16502
|
```
|
|
16518
16503
|
|
|
16519
16504
|
## Features
|
|
16520
16505
|
|
|
16521
|
-
- **`createLineChart(
|
|
16522
|
-
- **`createBarChart(
|
|
16523
|
-
- **`
|
|
16524
|
-
- **`createPieChart(
|
|
16525
|
-
- **`createRadarChart(
|
|
16526
|
-
- **`createSparkline(
|
|
16527
|
-
- **`
|
|
16528
|
-
- **`ChartHandle.
|
|
16529
|
-
- **`
|
|
16530
|
-
-
|
|
16531
|
-
- **
|
|
16532
|
-
- **
|
|
16533
|
-
- **
|
|
16534
|
-
- **CSS custom properties**: full theme control via `--prism-*` tokens, with dark mode built in
|
|
16535
|
-
- **Responsive**: auto-resizes via `ResizeObserver`
|
|
16536
|
-
- **`ChartHandle.tap()`**: observe resize and dispose events outside the render path, with zero cost when untapped
|
|
16537
|
-
- **`Symbol.dispose`**: explicit resource management following the TC39 proposal
|
|
16506
|
+
- **`createLineChart()` / `createAreaChart()`**: plot continuous numeric or date-keyed series
|
|
16507
|
+
- **`createBarChart()`**: compare categories with grouped, stacked, or horizontal bars
|
|
16508
|
+
- **`createScatterChart()`**: plot independent numeric `(x, y)` points
|
|
16509
|
+
- **`createPieChart()`**: render pie, donut, or semi-circle slices
|
|
16510
|
+
- **`createRadarChart()`**: compare series across fixed, labelled axes
|
|
16511
|
+
- **`createSparkline()`**: render compact line, area, bar, or stacked values without axes
|
|
16512
|
+
- **`ChartHandle.update(data)`**: replace chart data without handing state ownership to Prism
|
|
16513
|
+
- **`ChartHandle.dispose()` / `Symbol.dispose`**: release the SVG, observer, overlays, and chart-owned animation
|
|
16514
|
+
- **`ChartHandle.tap()`**: observe resize and disposal events
|
|
16515
|
+
- **`setTheme()` / `resetTheme()`**: set supported palette, typography, axis, grid, and tooltip tokens globally or on one element
|
|
16516
|
+
- **CSS custom properties**: style the chart palette, marks, axes, labels, tooltip, legend, and motion
|
|
16517
|
+
- **Resize observation**: recalculate SVG layout when the host element changes size
|
|
16518
|
+
- **Accessible interaction**: labelled interactive charts expose keyboard navigation and polite value announcements; sparklines are pointer-only without value announcements
|
|
16538
16519
|
|
|
16539
16520
|
## Documentation
|
|
16540
16521
|
|
|
@@ -16545,37 +16526,44 @@ chart.dispose();
|
|
|
16545
16526
|
|
|
16546
16527
|
## See Also
|
|
16547
16528
|
|
|
16548
|
-
- [Refine](/refine/):
|
|
16549
|
-
- [Orbit](/orbit/): floating
|
|
16529
|
+
- [Refine](/refine/): web components and theme tokens for building controls and layouts around chart hosts
|
|
16530
|
+
- [Orbit](/orbit/): floating-element positioning used internally by Prism's built-in tooltip
|
|
16550
16531
|
|
|
16551
16532
|
### API Reference
|
|
16552
16533
|
|
|
16553
16534
|
## API Overview
|
|
16554
16535
|
|
|
16536
|
+
All chart factories, scale utilities, theme helpers, and error classes are synchronous. Charts render into an HTML element and return a `ChartHandle`; they do not return a promise.
|
|
16537
|
+
|
|
16555
16538
|
| Symbol | Purpose | Execution mode | Common gotcha |
|
|
16556
16539
|
| --- | --- | --- | --- |
|
|
16557
|
-
| `createLineChart()` | Render
|
|
16558
|
-
| `createAreaChart()` | Render
|
|
16559
|
-
| `
|
|
16560
|
-
| `
|
|
16561
|
-
| `
|
|
16562
|
-
| `
|
|
16563
|
-
| `
|
|
16564
|
-
| `
|
|
16565
|
-
| `
|
|
16566
|
-
| `
|
|
16567
|
-
| `
|
|
16568
|
-
| `
|
|
16540
|
+
| `createLineChart()` | Render one or more continuous line series | Sync | `key` values must be numbers or dates |
|
|
16541
|
+
| `createAreaChart()` | Render continuous series with filled areas | Sync | Fills use a gradient by default |
|
|
16542
|
+
| `createScatterChart()` | Plot independent `(x, y)` points | Sync | `key` is the x-value; the y-domain is fitted to data |
|
|
16543
|
+
| `createBarChart()` | Render categorical bars | Sync | Negative values in stacked variants are clamped to zero |
|
|
16544
|
+
| `createPieChart()` | Render pie, donut, or semi-circle slices | Sync | `variant` is fixed at creation; `update()` replaces slices |
|
|
16545
|
+
| `createRadarChart()` | Compare series across fixed axes | Sync | Requires at least three axes to draw |
|
|
16546
|
+
| `createSparkline()` | Render a compact line, area, bar, or stack | Sync | Has no axes, legend, or keyboard navigation |
|
|
16547
|
+
| `linearScale()` | Create a numeric scale | Sync | `nice` defaults to `true`; set `nice: false` to preserve the domain |
|
|
16548
|
+
| `timeScale()` | Create a date scale | Sync | `nice` defaults to `true` |
|
|
16549
|
+
| `bandScale()` | Create an ordered categorical scale | Sync | Unknown categories map to `0` and warn in development |
|
|
16550
|
+
| `setTheme()` | Set Prism CSS custom properties | Sync | Writes inline styles to `document.documentElement` by default |
|
|
16551
|
+
| `resetTheme()` | Remove theme overrides set by `setTheme()` | Sync | Only clears the selected target |
|
|
16552
|
+
| `seriesColor()` | Resolve a palette CSS value | Sync | Palette positions wrap after eight |
|
|
16553
|
+
| `PrismError` | Base class for Prism errors | Sync | Use `instanceof` to catch any Prism error |
|
|
16554
|
+
| `PrismRenderError` | Report an invalid chart container or failed chart operation | Sync | Also thrown by `update()` after disposal |
|
|
16569
16555
|
|
|
16570
16556
|
## Package Entry Point
|
|
16571
16557
|
|
|
16572
16558
|
| Import | Purpose |
|
|
16573
16559
|
| --- | --- |
|
|
16574
|
-
| `@vielzeug/prism` | Chart factories,
|
|
16575
|
-
| `@vielzeug/prism/theme.css` | Default CSS custom properties
|
|
16560
|
+
| `@vielzeug/prism` | Chart factories, scale and theme functions, error classes, and public types |
|
|
16561
|
+
| `@vielzeug/prism/theme.css` | Default chart styles, CSS custom properties, dark-mode values, and reduced-motion rules |
|
|
16576
16562
|
|
|
16577
16563
|
## Chart Factories
|
|
16578
16564
|
|
|
16565
|
+
Each factory appends an SVG to `container`. A chart with no measurable container size uses a temporary `600 × 300` SVG size and emits a development warning; `ResizeObserver` applies later size changes. Unless `a11y` is informative, the SVG is hidden from the accessibility tree.
|
|
16566
|
+
|
|
16579
16567
|
### `createLineChart()`
|
|
16580
16568
|
|
|
16581
16569
|
```ts
|
|
@@ -16585,28 +16573,32 @@ function createLineChart(
|
|
|
16585
16573
|
): ChartHandle;
|
|
16586
16574
|
```
|
|
16587
16575
|
|
|
16588
|
-
Renders
|
|
16576
|
+
Renders line series and returns a handle whose `update()` argument replaces the complete series array. Axes render by default; the value axis has grid lines by default. Pass `false` to `xAxis` or `yAxis` to suppress that axis.
|
|
16577
|
+
|
|
16578
|
+
Series use linear interpolation by default, omit point markers by default, and use a point radius of 3 when markers are enabled. `yAxis` defaults to `'left'`; crosshair, tooltip, and legend are disabled unless configured.
|
|
16589
16579
|
|
|
16590
16580
|
| Parameter | Type | Description |
|
|
16591
16581
|
| --- | --- | --- |
|
|
16592
|
-
| `container` | `HTMLElement` | Host that receives the SVG and optional overlays |
|
|
16593
|
-
| `config` | `LineChartConfig` |
|
|
16582
|
+
| `container` | `HTMLElement` | Host that receives the chart SVG and optional overlays |
|
|
16583
|
+
| `config` | `LineChartConfig` | Series, axes, interaction, accessibility, and motion settings |
|
|
16594
16584
|
|
|
16595
16585
|
**Returns:** `ChartHandle`.
|
|
16596
16586
|
|
|
16597
16587
|
```ts
|
|
16598
16588
|
import { createLineChart } from '@vielzeug/prism';
|
|
16599
16589
|
|
|
16600
|
-
const
|
|
16590
|
+
const host = document.createElement('div');
|
|
16591
|
+
host.style.cssText = 'width:640px;height:320px';
|
|
16592
|
+
document.body.append(host);
|
|
16593
|
+
|
|
16594
|
+
const chart = createLineChart(host, {
|
|
16601
16595
|
a11y: { ariaLabel: 'Revenue by month' },
|
|
16602
|
-
series: [{ data: [{ key: 1, value: 10 }], name: 'Revenue' }],
|
|
16596
|
+
series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }], name: 'Revenue' }],
|
|
16603
16597
|
});
|
|
16604
|
-
|
|
16605
|
-
chart.
|
|
16598
|
+
chart.update([{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }, { key: 3, value: 18 }], name: 'Revenue' }]);
|
|
16599
|
+
chart.dispose();
|
|
16606
16600
|
```
|
|
16607
16601
|
|
|
16608
|
-
---
|
|
16609
|
-
|
|
16610
16602
|
### `createAreaChart()`
|
|
16611
16603
|
|
|
16612
16604
|
```ts
|
|
@@ -16616,24 +16608,67 @@ function createAreaChart(
|
|
|
16616
16608
|
): ChartHandle;
|
|
16617
16609
|
```
|
|
16618
16610
|
|
|
16619
|
-
Renders
|
|
16611
|
+
Renders continuous area series with a gradient fill by default. `update()` replaces the complete series array.
|
|
16612
|
+
|
|
16613
|
+
Area series use linear interpolation by default and show their top line unless `showLine: false` is set. Axes render by default, with grid lines on the value axis.
|
|
16620
16614
|
|
|
16621
16615
|
| Parameter | Type | Description |
|
|
16622
16616
|
| --- | --- | --- |
|
|
16623
|
-
| `container` | `HTMLElement` | Host that receives the SVG and optional overlays |
|
|
16624
|
-
| `config` | `AreaChartConfig` |
|
|
16617
|
+
| `container` | `HTMLElement` | Host that receives the chart SVG and optional overlays |
|
|
16618
|
+
| `config` | `AreaChartConfig` | Series, axes, interaction, accessibility, and motion settings |
|
|
16625
16619
|
|
|
16626
16620
|
**Returns:** `ChartHandle`.
|
|
16627
16621
|
|
|
16628
16622
|
```ts
|
|
16629
16623
|
import { createAreaChart } from '@vielzeug/prism';
|
|
16630
16624
|
|
|
16631
|
-
const
|
|
16632
|
-
|
|
16625
|
+
const host = document.createElement('div');
|
|
16626
|
+
host.style.cssText = 'width:640px;height:320px';
|
|
16627
|
+
document.body.append(host);
|
|
16628
|
+
|
|
16629
|
+
const chart = createAreaChart(host, {
|
|
16630
|
+
a11y: { ariaLabel: 'Visitors over time' },
|
|
16631
|
+
series: [{ data: [{ key: 1, value: 10 }, { key: 2, value: 18 }], name: 'Visitors' }],
|
|
16633
16632
|
});
|
|
16633
|
+
chart.dispose();
|
|
16634
16634
|
```
|
|
16635
16635
|
|
|
16636
|
-
|
|
16636
|
+
### `createScatterChart()`
|
|
16637
|
+
|
|
16638
|
+
```ts
|
|
16639
|
+
function createScatterChart(
|
|
16640
|
+
container: HTMLElement,
|
|
16641
|
+
config: ScatterChartConfig,
|
|
16642
|
+
): ChartHandle;
|
|
16643
|
+
```
|
|
16644
|
+
|
|
16645
|
+
Plots each datum independently: `key` is the numeric or date x-value and `value` is the y-value. Points are not joined. `update()` replaces the complete series array.
|
|
16646
|
+
|
|
16647
|
+
Axes render by default, with grid lines on the value axis. The value scale is fitted to the observed data rather than forced to include zero. Tooltip, crosshair, and legend are disabled unless configured.
|
|
16648
|
+
|
|
16649
|
+
| Parameter | Type | Description |
|
|
16650
|
+
| --- | --- | --- |
|
|
16651
|
+
| `container` | `HTMLElement` | Host that receives the chart SVG and optional overlays |
|
|
16652
|
+
| `config` | `ScatterChartConfig` | Independent points, axes, interaction, accessibility, and motion settings |
|
|
16653
|
+
|
|
16654
|
+
**Returns:** `ChartHandle`.
|
|
16655
|
+
|
|
16656
|
+
```ts
|
|
16657
|
+
import { createScatterChart } from '@vielzeug/prism';
|
|
16658
|
+
|
|
16659
|
+
const host = document.createElement('div');
|
|
16660
|
+
host.style.cssText = 'width:640px;height:320px';
|
|
16661
|
+
document.body.append(host);
|
|
16662
|
+
|
|
16663
|
+
const chart = createScatterChart(host, {
|
|
16664
|
+
a11y: { ariaLabel: 'Height against weight' },
|
|
16665
|
+
series: [{ data: [{ key: 160, value: 55 }, { key: 175, value: 70 }], name: 'Cohort A' }],
|
|
16666
|
+
tooltip: true,
|
|
16667
|
+
});
|
|
16668
|
+
chart.dispose();
|
|
16669
|
+
```
|
|
16670
|
+
|
|
16671
|
+
Scatter interaction reports one datum and series rather than a `values` array. Keyboard navigation visits points across series in x order.
|
|
16637
16672
|
|
|
16638
16673
|
### `createBarChart()`
|
|
16639
16674
|
|
|
@@ -16644,25 +16679,32 @@ function createBarChart(
|
|
|
16644
16679
|
): ChartHandle;
|
|
16645
16680
|
```
|
|
16646
16681
|
|
|
16647
|
-
Renders grouped, stacked, grouped-horizontal, or stacked-horizontal
|
|
16682
|
+
Renders grouped, stacked, grouped-horizontal, or stacked-horizontal categories. `update()` replaces the complete series array; the variant is fixed at creation. Axes render by default, with grid lines on the value axis.
|
|
16683
|
+
|
|
16684
|
+
The default variant is `grouped`; tooltip and legend are disabled unless configured.
|
|
16648
16685
|
|
|
16649
16686
|
| Parameter | Type | Description |
|
|
16650
16687
|
| --- | --- | --- |
|
|
16651
|
-
| `container` | `HTMLElement` | Host that receives the SVG and optional overlays |
|
|
16652
|
-
| `config` | `BarChartConfig` |
|
|
16688
|
+
| `container` | `HTMLElement` | Host that receives the chart SVG and optional overlays |
|
|
16689
|
+
| `config` | `BarChartConfig` | Series, layout variant, axes, interaction, accessibility, and motion settings |
|
|
16653
16690
|
|
|
16654
16691
|
**Returns:** `ChartHandle`.
|
|
16655
16692
|
|
|
16656
16693
|
```ts
|
|
16657
16694
|
import { createBarChart } from '@vielzeug/prism';
|
|
16658
16695
|
|
|
16659
|
-
const
|
|
16660
|
-
|
|
16661
|
-
|
|
16696
|
+
const host = document.createElement('div');
|
|
16697
|
+
host.style.cssText = 'width:640px;height:320px';
|
|
16698
|
+
document.body.append(host);
|
|
16699
|
+
|
|
16700
|
+
const chart = createBarChart(host, {
|
|
16701
|
+
a11y: { ariaLabel: 'Tasks by status' },
|
|
16702
|
+
series: [{ data: [{ key: 'Open', value: 12 }, { key: 'Done', value: 8 }], name: 'Tasks' }],
|
|
16662
16703
|
});
|
|
16704
|
+
chart.dispose();
|
|
16663
16705
|
```
|
|
16664
16706
|
|
|
16665
|
-
|
|
16707
|
+
For stacked variants, negative values are treated as zero and produce a development warning.
|
|
16666
16708
|
|
|
16667
16709
|
### `createPieChart()`
|
|
16668
16710
|
|
|
@@ -16673,26 +16715,30 @@ function createPieChart(
|
|
|
16673
16715
|
): ChartHandle;
|
|
16674
16716
|
```
|
|
16675
16717
|
|
|
16676
|
-
Renders pie, donut, or semi-circle slices.
|
|
16718
|
+
Renders pie, donut, or semi-circle slices. The default variant is `pie`; `update()` replaces the slice array. The default inner radius is zero for pies and 55% of the outer radius for donut and semi variants. Pie slices default to no padding or rounded corners; donut and semi slices default to 8px padding and corner radius.
|
|
16677
16719
|
|
|
16678
16720
|
| Parameter | Type | Description |
|
|
16679
16721
|
| --- | --- | --- |
|
|
16680
|
-
| `container` | `HTMLElement` | Host that receives the SVG and optional overlays |
|
|
16681
|
-
| `config` | `PieChartConfig` |
|
|
16722
|
+
| `container` | `HTMLElement` | Host that receives the chart SVG and optional overlays |
|
|
16723
|
+
| `config` | `PieChartConfig` | Slices, shape, geometry, legend, tooltip, and interaction settings |
|
|
16682
16724
|
|
|
16683
16725
|
**Returns:** `ChartHandle`.
|
|
16684
16726
|
|
|
16685
16727
|
```ts
|
|
16686
16728
|
import { createPieChart } from '@vielzeug/prism';
|
|
16687
16729
|
|
|
16688
|
-
const
|
|
16689
|
-
|
|
16730
|
+
const host = document.createElement('div');
|
|
16731
|
+
host.style.cssText = 'width:320px;height:240px';
|
|
16732
|
+
document.body.append(host);
|
|
16733
|
+
|
|
16734
|
+
const chart = createPieChart(host, {
|
|
16735
|
+
a11y: { ariaLabel: 'Orders by channel' },
|
|
16736
|
+
data: [{ label: 'Direct', value: 72 }, { label: 'Referral', value: 28 }],
|
|
16690
16737
|
variant: 'donut',
|
|
16691
16738
|
});
|
|
16739
|
+
chart.dispose();
|
|
16692
16740
|
```
|
|
16693
16741
|
|
|
16694
|
-
---
|
|
16695
|
-
|
|
16696
16742
|
### `createRadarChart()`
|
|
16697
16743
|
|
|
16698
16744
|
```ts
|
|
@@ -16702,47 +16748,32 @@ function createRadarChart(
|
|
|
16702
16748
|
): ChartHandle;
|
|
16703
16749
|
```
|
|
16704
16750
|
|
|
16705
|
-
Renders one
|
|
16751
|
+
Renders one shape per series across the configured axes. `update()` replaces series data but not axes or other configuration. Fewer than three axes warn in development and draw no chart. Tooltip and legend are disabled unless configured.
|
|
16706
16752
|
|
|
16707
16753
|
| Parameter | Type | Description |
|
|
16708
16754
|
| --- | --- | --- |
|
|
16709
|
-
| `container` | `HTMLElement` | Host that receives the SVG and optional overlays |
|
|
16710
|
-
| `config` | `RadarChartConfig` |
|
|
16711
|
-
|
|
16712
|
-
| Field | Type | Default | Description |
|
|
16713
|
-
| --- | --- | --- | --- |
|
|
16714
|
-
| `axes` | `RadarAxisConfig[]` | N/A | Ordered axes, drawn clockwise; needs at least 3 |
|
|
16715
|
-
| `series` | `RadarSeriesConfig[]` | N/A | Values keyed by `axis.key` |
|
|
16716
|
-
| `domain` | `[number, number]` | `[0, nice max]` | Shared value range; `axis.min`/`axis.max` override it per axis |
|
|
16717
|
-
| `grid` | `boolean \| RadarGridConfig` | `true` | Rings, bands, and level labels; `false` hides the grid |
|
|
16718
|
-
| `fill` | `'gradient' \| 'none' \| 'solid'` | `'solid'` | Shape fill; `gradient` deepens toward the rim |
|
|
16719
|
-
| `curve` | `'linear' \| 'rounded'` | `'linear'` | Straight edges or a smooth closed curve |
|
|
16720
|
-
| `showPoints` | `boolean` | `true` | Vertex dots; a missing value shows a hollow dot at the centre |
|
|
16721
|
-
| `showValues` | `boolean` | `false` | Print each value beside its vertex |
|
|
16722
|
-
| `startAngle` | `number` | `0` | Degrees clockwise from 12 o'clock for the first axis |
|
|
16723
|
-
| `onHover` | `(event: RadarEvent \| null) => void` | N/A | Nearest axis under the pointer or keyboard focus |
|
|
16724
|
-
| `onClick` | `(event: RadarEvent) => void` | N/A | Axis clicked, or activated with Enter/Space |
|
|
16755
|
+
| `container` | `HTMLElement` | Host that receives the chart SVG and optional overlays |
|
|
16756
|
+
| `config` | `RadarChartConfig` | Fixed axes, series, scale, grid, appearance, and interaction settings |
|
|
16725
16757
|
|
|
16726
16758
|
**Returns:** `ChartHandle`.
|
|
16727
16759
|
|
|
16728
16760
|
```ts
|
|
16729
16761
|
import { createRadarChart } from '@vielzeug/prism';
|
|
16730
16762
|
|
|
16731
|
-
const
|
|
16763
|
+
const host = document.createElement('div');
|
|
16764
|
+
host.style.cssText = 'width:400px;height:320px';
|
|
16765
|
+
document.body.append(host);
|
|
16766
|
+
|
|
16767
|
+
const chart = createRadarChart(host, {
|
|
16732
16768
|
a11y: { ariaLabel: 'Hero stats' },
|
|
16733
|
-
axes: [
|
|
16734
|
-
{ key: 'str', label: 'Strength' },
|
|
16735
|
-
{ key: 'agi', label: 'Agility' },
|
|
16736
|
-
{ key: 'end', label: 'Endurance' },
|
|
16737
|
-
],
|
|
16769
|
+
axes: [{ key: 'str', label: 'Strength' }, { key: 'agi', label: 'Agility' }, { key: 'end', label: 'Endurance' }],
|
|
16738
16770
|
domain: [0, 10],
|
|
16739
16771
|
series: [{ data: [{ key: 'str', value: 8 }, { key: 'agi', value: 6 }, { key: 'end', value: 9 }], name: 'Adam' }],
|
|
16740
16772
|
});
|
|
16773
|
+
chart.dispose();
|
|
16741
16774
|
```
|
|
16742
16775
|
|
|
16743
|
-
|
|
16744
|
-
|
|
16745
|
-
---
|
|
16776
|
+
Radar defaults are a solid fill, linear curves, visible points, a four-level polygon grid with bands, no grid labels, and a first-axis angle of zero degrees. Grid labels render only when all axes share a domain.
|
|
16746
16777
|
|
|
16747
16778
|
### `createSparkline()`
|
|
16748
16779
|
|
|
@@ -16753,22 +16784,29 @@ function createSparkline(
|
|
|
16753
16784
|
): ChartHandle;
|
|
16754
16785
|
```
|
|
16755
16786
|
|
|
16756
|
-
Renders
|
|
16787
|
+
Renders compact data without axes, chart margins, or a legend. `update()` replaces the number or stack-segment array. The default variant is `line`; only line and area variants draw the endpoint marker by default.
|
|
16757
16788
|
|
|
16758
16789
|
| Parameter | Type | Description |
|
|
16759
16790
|
| --- | --- | --- |
|
|
16760
|
-
| `container` | `HTMLElement` | Host that receives the SVG |
|
|
16761
|
-
| `config` | `SparklineConfig` |
|
|
16791
|
+
| `container` | `HTMLElement` | Host that receives the chart SVG |
|
|
16792
|
+
| `config` | `SparklineConfig` | Values, variant, appearance, accessibility, and pointer callbacks |
|
|
16762
16793
|
|
|
16763
16794
|
**Returns:** `ChartHandle`.
|
|
16764
16795
|
|
|
16765
16796
|
```ts
|
|
16766
16797
|
import { createSparkline } from '@vielzeug/prism';
|
|
16767
16798
|
|
|
16768
|
-
const
|
|
16799
|
+
const host = document.createElement('div');
|
|
16800
|
+
host.style.cssText = 'width:240px;height:48px';
|
|
16801
|
+
document.body.append(host);
|
|
16802
|
+
|
|
16803
|
+
const chart = createSparkline(host, { data: [2, 5, 3, 8], variant: 'area' });
|
|
16769
16804
|
chart.update([2, 5, 3, 8, 13]);
|
|
16805
|
+
chart.dispose();
|
|
16770
16806
|
```
|
|
16771
16807
|
|
|
16808
|
+
`StackSegment[]` is for `variant: 'stack'`. Pointer callbacks are available for numeric line, area, and bar sparklines; sparklines do not support keyboard navigation.
|
|
16809
|
+
|
|
16772
16810
|
## Scale Factories
|
|
16773
16811
|
|
|
16774
16812
|
### `linearScale()`
|
|
@@ -16777,14 +16815,16 @@ chart.update([2, 5, 3, 8, 13]);
|
|
|
16777
16815
|
function linearScale(config: LinearScaleConfig): Scale;
|
|
16778
16816
|
```
|
|
16779
16817
|
|
|
16780
|
-
|
|
16818
|
+
Maps a numeric domain to a numeric range. `nice` defaults to `true`; `clamp` defaults to `false` and applies to `map()`, not `invert()`.
|
|
16819
|
+
|
|
16820
|
+
| Parameter | Type | Default | Description |
|
|
16781
16821
|
| --- | --- | --- | --- |
|
|
16782
|
-
| `domain` | `[number, number]` |
|
|
16783
|
-
| `range` | `[number, number]` |
|
|
16784
|
-
| `clamp` | `boolean` | `false` | Clamp mapped
|
|
16785
|
-
| `nice` | `boolean` | `true` | Expand the domain to rounded boundaries |
|
|
16822
|
+
| `config.domain` | `[number, number]` | Required | Input extent |
|
|
16823
|
+
| `config.range` | `[number, number]` | Required | Output extent |
|
|
16824
|
+
| `config.clamp` | `boolean` | `false` | Clamp mapped values to the range |
|
|
16825
|
+
| `config.nice` | `boolean` | `true` | Expand the domain to rounded boundaries |
|
|
16786
16826
|
|
|
16787
|
-
**Returns:** `Scale`.
|
|
16827
|
+
**Returns:** `Scale`, with `map`, `invert`, `ticks`, `domain`, and `range`.
|
|
16788
16828
|
|
|
16789
16829
|
```ts
|
|
16790
16830
|
import { linearScale } from '@vielzeug/prism';
|
|
@@ -16793,21 +16833,21 @@ const scale = linearScale({ domain: [0, 100], range: [0, 500] });
|
|
|
16793
16833
|
scale.map(50); // 250
|
|
16794
16834
|
```
|
|
16795
16835
|
|
|
16796
|
-
---
|
|
16797
|
-
|
|
16798
16836
|
### `timeScale()`
|
|
16799
16837
|
|
|
16800
16838
|
```ts
|
|
16801
16839
|
function timeScale(config: TimeScaleConfig): Scale;
|
|
16802
16840
|
```
|
|
16803
16841
|
|
|
16804
|
-
|
|
16842
|
+
Maps date values to a numeric range. `nice` defaults to `true` and rounds the domain to a time interval.
|
|
16843
|
+
|
|
16844
|
+
| Parameter | Type | Default | Description |
|
|
16805
16845
|
| --- | --- | --- | --- |
|
|
16806
|
-
| `domain` | `[Date, Date]` |
|
|
16807
|
-
| `range` | `[number, number]` |
|
|
16808
|
-
| `nice` | `boolean` | `true` | Expand the domain to
|
|
16846
|
+
| `config.domain` | `[Date, Date]` | Required | Input date extent |
|
|
16847
|
+
| `config.range` | `[number, number]` | Required | Output extent |
|
|
16848
|
+
| `config.nice` | `boolean` | `true` | Expand the domain to time-interval boundaries |
|
|
16809
16849
|
|
|
16810
|
-
**Returns:** `Scale`.
|
|
16850
|
+
**Returns:** `Scale`, with `map`, `invert`, `ticks`, `domain`, and `range`.
|
|
16811
16851
|
|
|
16812
16852
|
```ts
|
|
16813
16853
|
import { timeScale } from '@vielzeug/prism';
|
|
@@ -16816,45 +16856,59 @@ const scale = timeScale({
|
|
|
16816
16856
|
domain: [new Date('2026-01-01'), new Date('2026-12-31')],
|
|
16817
16857
|
range: [0, 500],
|
|
16818
16858
|
});
|
|
16859
|
+
scale.map(new Date('2026-07-02'));
|
|
16819
16860
|
```
|
|
16820
16861
|
|
|
16821
|
-
---
|
|
16822
|
-
|
|
16823
16862
|
### `bandScale()`
|
|
16824
16863
|
|
|
16825
16864
|
```ts
|
|
16826
16865
|
function bandScale(config: BandScaleConfig): BandScale;
|
|
16827
16866
|
```
|
|
16828
16867
|
|
|
16829
|
-
|
|
16868
|
+
Maps ordered string categories to the start of each band. `padding` defaults to `0.1`; `paddingOuter` defaults to the same value. Mapping an unknown category returns `0` and warns in development.
|
|
16869
|
+
|
|
16870
|
+
| Parameter | Type | Default | Description |
|
|
16830
16871
|
| --- | --- | --- | --- |
|
|
16831
|
-
| `domain` | `string[]` |
|
|
16832
|
-
| `range` | `[number, number]` |
|
|
16833
|
-
| `padding` | `number` | `0.1` | Inner gap ratio |
|
|
16834
|
-
| `paddingOuter` | `number` | `padding` | Outer gap ratio |
|
|
16872
|
+
| `config.domain` | `string[]` | Required | Ordered categories |
|
|
16873
|
+
| `config.range` | `[number, number]` | Required | Output extent |
|
|
16874
|
+
| `config.padding` | `number` | `0.1` | Inner gap as a ratio of bandwidth |
|
|
16875
|
+
| `config.paddingOuter` | `number` | `padding` | Outer gap as a ratio of bandwidth |
|
|
16835
16876
|
|
|
16836
|
-
**Returns:** `BandScale`.
|
|
16877
|
+
**Returns:** `BandScale`, with `map`, `ticks`, `bandwidth`, `gap`, `domain`, and `range`.
|
|
16837
16878
|
|
|
16838
16879
|
```ts
|
|
16839
16880
|
import { bandScale } from '@vielzeug/prism';
|
|
16840
16881
|
|
|
16841
16882
|
const scale = bandScale({ domain: ['A', 'B'], range: [0, 200] });
|
|
16883
|
+
scale.bandwidth();
|
|
16842
16884
|
```
|
|
16843
16885
|
|
|
16844
16886
|
## Theme Utilities
|
|
16845
16887
|
|
|
16888
|
+
`theme.css` supplies the base CSS values and styles. `setTheme()` writes inline custom properties, which take precedence over stylesheet declarations. For other visual controls, set CSS custom properties directly.
|
|
16889
|
+
|
|
16846
16890
|
### `setTheme()`
|
|
16847
16891
|
|
|
16848
16892
|
```ts
|
|
16849
16893
|
function setTheme(theme: PrismTheme, options?: ThemeScope): void;
|
|
16850
16894
|
```
|
|
16851
16895
|
|
|
16852
|
-
Sets
|
|
16896
|
+
Sets the provided theme values on `options.scope`, or on `document.documentElement` when omitted. Omitted scalar keys remain unchanged. Providing `colors` replaces all eight palette slots, removing unused slots.
|
|
16853
16897
|
|
|
16854
16898
|
| Parameter | Type | Description |
|
|
16855
16899
|
| --- | --- | --- |
|
|
16856
|
-
| `theme` | `PrismTheme` |
|
|
16857
|
-
| `options.scope` | `HTMLElement` |
|
|
16900
|
+
| `theme` | `PrismTheme` | Palette and supported axis, grid, text, font, and tooltip properties |
|
|
16901
|
+
| `options.scope` | `HTMLElement` | Element that scopes the inline custom properties |
|
|
16902
|
+
|
|
16903
|
+
**Returns:** `void`.
|
|
16904
|
+
|
|
16905
|
+
```ts
|
|
16906
|
+
import { setTheme } from '@vielzeug/prism';
|
|
16907
|
+
|
|
16908
|
+
const host = document.createElement('div');
|
|
16909
|
+
document.body.append(host);
|
|
16910
|
+
setTheme({ colors: ['#2563eb', '#16a34a'], textColor: '#111827' }, { scope: host });
|
|
16911
|
+
```
|
|
16858
16912
|
|
|
16859
16913
|
### `resetTheme()`
|
|
16860
16914
|
|
|
@@ -16862,7 +16916,21 @@ Sets Prism theme custom properties as inline styles on `options.scope` when give
|
|
|
16862
16916
|
function resetTheme(options?: ThemeScope): void;
|
|
16863
16917
|
```
|
|
16864
16918
|
|
|
16865
|
-
Removes every custom property `setTheme()`
|
|
16919
|
+
Removes every custom property managed by `setTheme()` from the given scope or the document root. It does not remove CSS rules or change any other custom properties.
|
|
16920
|
+
|
|
16921
|
+
| Parameter | Type | Description |
|
|
16922
|
+
| --- | --- | --- |
|
|
16923
|
+
| `options` | `ThemeScope` | Optional target; defaults to `document.documentElement` |
|
|
16924
|
+
|
|
16925
|
+
**Returns:** `void`.
|
|
16926
|
+
|
|
16927
|
+
```ts
|
|
16928
|
+
import { resetTheme, setTheme } from '@vielzeug/prism';
|
|
16929
|
+
|
|
16930
|
+
const scope = document.createElement('div');
|
|
16931
|
+
setTheme({ textColor: '#111827' }, { scope });
|
|
16932
|
+
resetTheme({ scope });
|
|
16933
|
+
```
|
|
16866
16934
|
|
|
16867
16935
|
### `seriesColor()`
|
|
16868
16936
|
|
|
@@ -16870,1383 +16938,972 @@ Removes every custom property `setTheme()` can set from `options.scope` (default
|
|
|
16870
16938
|
function seriesColor(index: number, override?: string): string;
|
|
16871
16939
|
```
|
|
16872
16940
|
|
|
16873
|
-
Returns `override` when provided; otherwise returns `var(--prism-color-N)`
|
|
16941
|
+
Returns `override` when it is provided; otherwise returns a `var(--prism-color-N)` reference. The palette has eight positions and the index wraps around after the eighth.
|
|
16942
|
+
|
|
16943
|
+
| Parameter | Type | Description |
|
|
16944
|
+
| --- | --- | --- |
|
|
16945
|
+
| `index` | `number` | Zero-based palette position |
|
|
16946
|
+
| `override` | `string` | Optional color returned instead of a CSS variable |
|
|
16947
|
+
|
|
16948
|
+
**Returns:** `string`.
|
|
16949
|
+
|
|
16950
|
+
```ts
|
|
16951
|
+
import { seriesColor } from '@vielzeug/prism';
|
|
16952
|
+
|
|
16953
|
+
seriesColor(0); // 'var(--prism-color-1)'
|
|
16954
|
+
seriesColor(1, '#2563eb'); // '#2563eb'
|
|
16955
|
+
```
|
|
16956
|
+
|
|
16957
|
+
## Chart Handle
|
|
16958
|
+
|
|
16959
|
+
`ChartHandle` is returned by every chart factory. `update()` synchronously rebuilds the chart from its new data; enabled motion may animate the resulting SVG. `dispose()` is idempotent, removes the chart SVG, observers, tooltip and legend, cancels chart-owned animation, aborts `disposalSignal`, and emits one `dispose` tap event. `update()` after disposal throws `PrismRenderError`.
|
|
16960
|
+
|
|
16961
|
+
`tap()` observes `resize` and `dispose` events outside the render path. It returns an unsubscribe function; an optional abort signal removes the subscription. Observer-handler exceptions are swallowed so they cannot affect chart behavior. A tap added after disposal returns a no-op unsubscribe function.
|
|
16962
|
+
|
|
16963
|
+
`[Symbol.dispose]()` delegates to `dispose()`, allowing explicit resource management where supported.
|
|
16964
|
+
|
|
16965
|
+
All chart handles expose the same lifecycle members; interactive cartesian and pie/radar charts use a `.prism-live` status region when no tooltip is enabled. A tooltip is itself a polite status region. Sparklines have neither a tooltip nor a live value announcer.
|
|
16966
|
+
|
|
16967
|
+
| Method or property | Contract |
|
|
16968
|
+
| --- | --- |
|
|
16969
|
+
| `el` | The chart's root `SVGSVGElement` |
|
|
16970
|
+
| `update(data)` | Replace chart data and render; throws `PrismRenderError` after disposal |
|
|
16971
|
+
| `dispose()` | Idempotently release chart-owned DOM, observation, and motion |
|
|
16972
|
+
| `disposed` | Whether the handle has been disposed |
|
|
16973
|
+
| `disposalSignal` | `AbortSignal` aborted during disposal |
|
|
16974
|
+
| `tap(handler, options?)` | Observe resize/dispose events; returns an unsubscribe function |
|
|
16975
|
+
| `[Symbol.dispose]()` | Calls `dispose()` |
|
|
16976
|
+
|
|
16977
|
+
`PrismEvent` reports a changed SVG content size as `{ type: 'resize', width, height }`; the `dispose` event is emitted once before teardown completes.
|
|
16874
16978
|
|
|
16875
16979
|
## Types
|
|
16876
16980
|
|
|
16877
|
-
|
|
16981
|
+
The following are all types and interfaces exported from `@vielzeug/prism`. Definitions mirror the package entry-point contracts.
|
|
16982
|
+
|
|
16983
|
+
### Animation Types
|
|
16878
16984
|
|
|
16879
16985
|
```ts
|
|
16880
|
-
|
|
16881
|
-
|
|
16882
|
-
|
|
16883
|
-
|
|
16884
|
-
|
|
16885
|
-
|
|
16886
|
-
|
|
16887
|
-
|
|
16986
|
+
export type EasingFn = (t: number) => number;
|
|
16987
|
+
export type EasingName = 'back-out' | 'ease-in' | 'ease-in-out' | 'ease-out' | 'expo-out' | 'linear';
|
|
16988
|
+
|
|
16989
|
+
export interface TransitionConfig {
|
|
16990
|
+
/** Milliseconds per animated lane. Defaults to 300 (420 for a line entrance, 400 for radar). */
|
|
16991
|
+
duration?: number;
|
|
16992
|
+
easing?: EasingName | ((t: number) => number);
|
|
16993
|
+
/** `system` skips animation when reduced motion is preferred. */
|
|
16994
|
+
preference?: 'always' | 'never' | 'system';
|
|
16995
|
+
/** Per-bar delay on bar charts or per-series delay on radar charts. */
|
|
16996
|
+
stagger?: number;
|
|
16888
16997
|
}
|
|
16889
16998
|
|
|
16890
|
-
type
|
|
16891
|
-
|
|
16892
|
-
| { readonly type: 'dispose' };
|
|
16999
|
+
export type TransitionOption = TransitionConfig | boolean;
|
|
17000
|
+
```
|
|
16893
17001
|
|
|
16894
|
-
|
|
16895
|
-
|
|
16896
|
-
|
|
17002
|
+
### Theme Types
|
|
17003
|
+
|
|
17004
|
+
```ts
|
|
17005
|
+
export interface PrismTheme {
|
|
17006
|
+
axisColor?: string;
|
|
17007
|
+
colors?: string[];
|
|
17008
|
+
fontFamily?: string;
|
|
17009
|
+
gridColor?: string;
|
|
17010
|
+
gridOpacity?: number;
|
|
17011
|
+
textColor?: string;
|
|
17012
|
+
textColorSecondary?: string;
|
|
17013
|
+
tooltipBg?: string;
|
|
17014
|
+
tooltipBorder?: string;
|
|
17015
|
+
tooltipColor?: string;
|
|
17016
|
+
}
|
|
17017
|
+
|
|
17018
|
+
export interface ThemeScope {
|
|
17019
|
+
readonly scope?: HTMLElement;
|
|
17020
|
+
}
|
|
17021
|
+
```
|
|
17022
|
+
|
|
17023
|
+
`PrismTheme.colors` writes up to eight palette slots. The scalar fields map as follows:
|
|
17024
|
+
|
|
17025
|
+
| Field | CSS custom property |
|
|
17026
|
+
| --- | --- |
|
|
17027
|
+
| `axisColor` | `--prism-axis-color` |
|
|
17028
|
+
| `fontFamily` | `--prism-font-family` |
|
|
17029
|
+
| `gridColor` | `--prism-grid-color` |
|
|
17030
|
+
| `gridOpacity` | `--prism-grid-opacity` |
|
|
17031
|
+
| `textColor` | `--prism-text-color` |
|
|
17032
|
+
| `textColorSecondary` | `--prism-text-color-secondary` |
|
|
17033
|
+
| `tooltipBg` | `--prism-tooltip-bg` |
|
|
17034
|
+
| `tooltipBorder` | `--prism-tooltip-border` |
|
|
17035
|
+
| `tooltipColor` | `--prism-tooltip-color` |
|
|
17036
|
+
|
|
17037
|
+
### Core and Data Types
|
|
17038
|
+
|
|
17039
|
+
```ts
|
|
17040
|
+
export interface ChartMargin {
|
|
16897
17041
|
bottom: number;
|
|
16898
17042
|
left: number;
|
|
17043
|
+
right: number;
|
|
17044
|
+
top: number;
|
|
16899
17045
|
}
|
|
16900
17046
|
|
|
16901
|
-
interface ChartDimensions {
|
|
16902
|
-
width: number;
|
|
17047
|
+
export interface ChartDimensions {
|
|
16903
17048
|
height: number;
|
|
16904
17049
|
margin: ChartMargin;
|
|
17050
|
+
width: number;
|
|
16905
17051
|
}
|
|
16906
17052
|
|
|
16907
|
-
type
|
|
16908
|
-
| { readonly
|
|
16909
|
-
| { readonly
|
|
16910
|
-
```
|
|
16911
|
-
|
|
16912
|
-
`update()` renders synchronously and throws `PrismRenderError` after disposal. Omitting `a11y` makes the SVG decorative with `aria-hidden="true"`.
|
|
16913
|
-
|
|
16914
|
-
`tap()` observes runtime behavior outside the render path: it receives `resize` and `dispose` events (see `PrismEvent`). It returns an unsubscribe function; pass `options.signal` to detach automatically. Handler errors are swallowed, and tapping a disposed handle returns a no-op unsubscribe.
|
|
17053
|
+
export type PrismEvent =
|
|
17054
|
+
| { readonly height: number; readonly type: 'resize'; readonly width: number }
|
|
17055
|
+
| { readonly type: 'dispose' };
|
|
16915
17056
|
|
|
16916
|
-
|
|
17057
|
+
export interface ChartHandle {
|
|
17058
|
+
readonly disposalSignal: AbortSignal;
|
|
17059
|
+
dispose(): void;
|
|
17060
|
+
readonly disposed: boolean;
|
|
17061
|
+
readonly el: SVGSVGElement;
|
|
17062
|
+
tap(handler: (event: PrismEvent) => void, options?: { readonly signal?: AbortSignal }): () => void;
|
|
17063
|
+
update(data: TData): void;
|
|
17064
|
+
[Symbol.dispose](): void;
|
|
17065
|
+
}
|
|
16917
17066
|
|
|
16918
|
-
|
|
17067
|
+
export type ChartA11y =
|
|
17068
|
+
| { readonly decorative: true }
|
|
17069
|
+
| { readonly ariaLabel: string; readonly decorative?: false };
|
|
16919
17070
|
|
|
16920
|
-
|
|
16921
|
-
|
|
17071
|
+
export interface Datum {
|
|
17072
|
+
dash?: string;
|
|
16922
17073
|
key: TKey;
|
|
16923
|
-
value: number;
|
|
16924
17074
|
meta?: Record;
|
|
16925
|
-
|
|
16926
|
-
|
|
17075
|
+
opacity?: number;
|
|
17076
|
+
value: number;
|
|
16927
17077
|
}
|
|
16928
17078
|
|
|
16929
|
-
type ContinuousDatum = Datum;
|
|
17079
|
+
export type ContinuousDatum = Datum;
|
|
16930
17080
|
|
|
16931
|
-
interface Series {
|
|
16932
|
-
name: string;
|
|
16933
|
-
data: TDatum[];
|
|
17081
|
+
export interface Series {
|
|
16934
17082
|
color?: string;
|
|
16935
|
-
|
|
17083
|
+
data: TDatum[];
|
|
17084
|
+
id?: string;
|
|
17085
|
+
name: string;
|
|
16936
17086
|
}
|
|
16937
17087
|
|
|
16938
|
-
interface ChartEvent {
|
|
17088
|
+
export interface ChartEvent {
|
|
16939
17089
|
datum: Datum;
|
|
16940
|
-
series: Series;
|
|
16941
17090
|
originalEvent: Event;
|
|
16942
|
-
|
|
17091
|
+
series: Series;
|
|
17092
|
+
values?: SeriesValue[];
|
|
16943
17093
|
}
|
|
16944
17094
|
|
|
16945
|
-
interface SeriesValue {
|
|
17095
|
+
export interface SeriesValue {
|
|
16946
17096
|
datum: Datum | undefined;
|
|
16947
17097
|
series: Series;
|
|
16948
17098
|
}
|
|
16949
17099
|
```
|
|
16950
17100
|
|
|
16951
|
-
|
|
16952
|
-
|
|
16953
|
-
#### Per-datum presentation
|
|
16954
|
-
|
|
16955
|
-
`dash` and `opacity` style an individual datum's marks without splitting the series — the usual case is a forecast tail where points past "today" are faded or dashed. They are styling-only: interaction, tooltip, and accessibility behavior never change. Support is per chart type:
|
|
17101
|
+
`Datum.dash` and `Datum.opacity` affect rendered marks only on the chart types that support them. On bars, `dash` adds a 1px series-color stroke so the dash is visible against the fill. `Series.id` becomes a `data-series-id` attribute on a series group; characters outside `[A-Za-z0-9_-]` are replaced with `-`. When omitted, the id is based on the series index.
|
|
16956
17102
|
|
|
16957
17103
|
| Chart | `dash` | `opacity` |
|
|
16958
17104
|
| --- | --- | --- |
|
|
16959
|
-
| Bar |
|
|
16960
|
-
| Line |
|
|
16961
|
-
| Area |
|
|
16962
|
-
|
|
|
16963
|
-
|
|
16964
|
-
Consecutive datums that share one `dash`/`opacity` render as a single path run. Absent fields keep the series/theme default, and a series with no presentation fields renders byte-identically to a chart that never used them. See [Forecast / emphasis styling](./usage.md#forecast--emphasis-styling).
|
|
17105
|
+
| Bar | Strokes that datum's bar | Applies to that bar |
|
|
17106
|
+
| Line | Applies to the segment from this datum to the next | Applies to that segment and its point marker |
|
|
17107
|
+
| Area | Applies to the top-line segment from this datum to the next | Applies to that segment |
|
|
17108
|
+
| Scatter | Ignored | Applies to that point |
|
|
17109
|
+
| Pie, radar, sparkline | Ignored | Ignored |
|
|
16965
17110
|
|
|
16966
|
-
|
|
17111
|
+
For line and area charts, the last datum has no following segment, so its `dash` value is ignored. The chart factories group adjacent segments with the same presentation values into path runs.
|
|
16967
17112
|
|
|
16968
|
-
`
|
|
17113
|
+
For line, area, and bar charts, `ChartEvent.values` lists each series at the active key in series order. Its `datum` is `undefined` when that series has no matching key. `originalEvent` is a pointer event or a keyboard event for keyboard activation. Scatter events identify only the nearest independent point and omit `values`.
|
|
16969
17114
|
|
|
16970
|
-
|
|
16971
|
-
|
|
16972
|
-
### Chart configurations
|
|
17115
|
+
### Scale Types
|
|
16973
17116
|
|
|
16974
17117
|
```ts
|
|
16975
|
-
interface
|
|
16976
|
-
|
|
16977
|
-
|
|
16978
|
-
|
|
16979
|
-
|
|
16980
|
-
|
|
16981
|
-
tooltip?: boolean | TooltipConfig;
|
|
16982
|
-
transition?: TransitionOption; // motion is on by default; false renders synchronously
|
|
16983
|
-
// Omitted renders the axis with defaults (value axis with gridlines); false suppresses it.
|
|
16984
|
-
xAxis?: XAxisConfig | false;
|
|
16985
|
-
yAxis?: YAxisConfig | false;
|
|
17118
|
+
export interface Scale {
|
|
17119
|
+
readonly domain: readonly [T, T];
|
|
17120
|
+
invert(pixel: number): T;
|
|
17121
|
+
map(value: T): number;
|
|
17122
|
+
readonly range: readonly [number, number];
|
|
17123
|
+
ticks(count?: number): T[];
|
|
16986
17124
|
}
|
|
16987
17125
|
|
|
16988
|
-
interface
|
|
16989
|
-
|
|
16990
|
-
|
|
16991
|
-
|
|
17126
|
+
export interface BandScale {
|
|
17127
|
+
bandwidth(): number;
|
|
17128
|
+
readonly domain: readonly string[];
|
|
17129
|
+
gap(): number;
|
|
17130
|
+
map(value: string): number;
|
|
17131
|
+
readonly range: readonly [number, number];
|
|
17132
|
+
ticks(count?: number): string[];
|
|
16992
17133
|
}
|
|
16993
17134
|
|
|
16994
|
-
interface
|
|
16995
|
-
|
|
16996
|
-
|
|
17135
|
+
export interface LinearScaleConfig {
|
|
17136
|
+
clamp?: boolean;
|
|
17137
|
+
domain: [number, number];
|
|
17138
|
+
nice?: boolean;
|
|
17139
|
+
range: [number, number];
|
|
16997
17140
|
}
|
|
16998
17141
|
|
|
16999
|
-
interface
|
|
17000
|
-
|
|
17001
|
-
|
|
17142
|
+
export interface TimeScaleConfig {
|
|
17143
|
+
domain: [Date, Date];
|
|
17144
|
+
nice?: boolean;
|
|
17145
|
+
range: [number, number];
|
|
17002
17146
|
}
|
|
17003
17147
|
|
|
17004
|
-
interface
|
|
17005
|
-
|
|
17006
|
-
|
|
17007
|
-
|
|
17008
|
-
|
|
17009
|
-
cornerRadius?: number;
|
|
17010
|
-
padPixels?: number;
|
|
17011
|
-
onClick?: (event: PieEvent) => void;
|
|
17012
|
-
onHover?: (event: PieEvent | null) => void;
|
|
17148
|
+
export interface BandScaleConfig {
|
|
17149
|
+
domain: string[];
|
|
17150
|
+
padding?: number;
|
|
17151
|
+
paddingOuter?: number;
|
|
17152
|
+
range: [number, number];
|
|
17013
17153
|
}
|
|
17154
|
+
```
|
|
17014
17155
|
|
|
17015
|
-
|
|
17016
|
-
extends Omit {
|
|
17017
|
-
axes: RadarAxisConfig[];
|
|
17018
|
-
series: RadarSeriesConfig[];
|
|
17019
|
-
curve?: 'linear' | 'rounded';
|
|
17020
|
-
domain?: [number, number];
|
|
17021
|
-
fill?: 'gradient' | 'none' | 'solid';
|
|
17022
|
-
grid?: boolean | RadarGridConfig;
|
|
17023
|
-
showPoints?: boolean;
|
|
17024
|
-
showValues?: boolean;
|
|
17025
|
-
startAngle?: number;
|
|
17026
|
-
onClick?: (event: RadarEvent) => void;
|
|
17027
|
-
onHover?: (event: RadarEvent | null) => void;
|
|
17028
|
-
}
|
|
17029
|
-
|
|
17030
|
-
interface SparklineConfig {
|
|
17031
|
-
data: number[] | StackSegment[];
|
|
17032
|
-
variant?: SparklineVariant;
|
|
17033
|
-
a11y?: ChartA11y;
|
|
17034
|
-
color?: string;
|
|
17035
|
-
cornerRadius?: number;
|
|
17036
|
-
curve?: 'linear' | 'monotone' | 'step';
|
|
17037
|
-
fillOpacity?: number; // overrides --prism-spark-fill-opacity (area variant)
|
|
17038
|
-
onClick?: (event: SparklineEvent) => void;
|
|
17039
|
-
onHover?: (event: SparklineEvent | null) => void;
|
|
17040
|
-
padPixels?: number;
|
|
17041
|
-
showEndPoint?: boolean; // default true: dot on the latest value (line, area)
|
|
17042
|
-
strokeWidth?: number;
|
|
17043
|
-
transition?: TransitionOption; // motion is on by default; false renders synchronously
|
|
17044
|
-
}
|
|
17045
|
-
```
|
|
17046
|
-
|
|
17047
|
-
---
|
|
17048
|
-
|
|
17049
|
-
### Series and slice configurations
|
|
17156
|
+
### Axis and Interaction Types
|
|
17050
17157
|
|
|
17051
17158
|
```ts
|
|
17052
|
-
|
|
17053
|
-
|
|
17054
|
-
|
|
17055
|
-
pointRadius?: number;
|
|
17056
|
-
showPoints?: boolean;
|
|
17057
|
-
strokeWidth?: number; // overrides --prism-line-width
|
|
17058
|
-
}
|
|
17059
|
-
|
|
17060
|
-
interface AreaSeriesConfig extends Series {
|
|
17061
|
-
curve?: 'linear' | 'monotone' | 'step';
|
|
17062
|
-
fill?: 'gradient' | 'solid'; // default 'gradient', fading toward the baseline
|
|
17063
|
-
fillOpacity?: number; // overrides --prism-area-opacity
|
|
17064
|
-
showLine?: boolean;
|
|
17065
|
-
}
|
|
17066
|
-
|
|
17067
|
-
interface BarSeriesConfig extends Series {
|
|
17068
|
-
borderRadius?: number; // overrides --prism-bar-radius; stacked bars stay square
|
|
17069
|
-
}
|
|
17070
|
-
|
|
17071
|
-
interface PieSliceConfig {
|
|
17072
|
-
value: number;
|
|
17073
|
-
color?: string;
|
|
17074
|
-
label?: string;
|
|
17075
|
-
}
|
|
17076
|
-
|
|
17077
|
-
interface PieEvent {
|
|
17078
|
-
index: number;
|
|
17079
|
-
originalEvent: Event;
|
|
17080
|
-
slice: PieSliceConfig;
|
|
17081
|
-
}
|
|
17082
|
-
|
|
17083
|
-
interface RadarAxisConfig {
|
|
17084
|
-
key: string;
|
|
17085
|
-
label: string;
|
|
17086
|
-
min?: number;
|
|
17087
|
-
max?: number;
|
|
17088
|
-
format?: (value: number) => string;
|
|
17089
|
-
}
|
|
17090
|
-
|
|
17091
|
-
type RadarSeriesConfig = Series>;
|
|
17092
|
-
|
|
17093
|
-
interface RadarGridConfig {
|
|
17094
|
-
bands?: boolean; // default true
|
|
17095
|
-
labels?: boolean; // default false; drawn only when every axis shares one domain
|
|
17096
|
-
levels?: number; // default 4
|
|
17097
|
-
shape?: 'circle' | 'polygon'; // default 'polygon'
|
|
17098
|
-
}
|
|
17099
|
-
|
|
17100
|
-
interface RadarEvent {
|
|
17101
|
-
axis: RadarAxisConfig;
|
|
17102
|
-
index: number;
|
|
17103
|
-
values: RadarAxisValue[];
|
|
17104
|
-
originalEvent: Event;
|
|
17105
|
-
}
|
|
17106
|
-
|
|
17107
|
-
interface RadarAxisValue {
|
|
17108
|
-
datum: Datum | undefined;
|
|
17109
|
-
series: RadarSeriesConfig;
|
|
17110
|
-
}
|
|
17159
|
+
export type HorizontalAxisPosition = 'bottom' | 'top';
|
|
17160
|
+
export type VerticalAxisPosition = 'left' | 'right';
|
|
17161
|
+
export type AxisPosition = HorizontalAxisPosition | VerticalAxisPosition;
|
|
17111
17162
|
|
|
17112
|
-
interface
|
|
17113
|
-
value: number;
|
|
17163
|
+
export interface GridConfig {
|
|
17114
17164
|
color?: string;
|
|
17115
|
-
|
|
17116
|
-
}
|
|
17117
|
-
|
|
17118
|
-
interface SparklineEvent {
|
|
17119
|
-
index: number;
|
|
17120
|
-
originalEvent: Event;
|
|
17121
|
-
value: number;
|
|
17165
|
+
dash?: string;
|
|
17122
17166
|
}
|
|
17123
|
-
```
|
|
17124
|
-
|
|
17125
|
-
A custom radar `tooltip.render` receives `datum.meta` with `axis`, `values`, and the default `text`.
|
|
17126
|
-
|
|
17127
|
-
---
|
|
17128
|
-
|
|
17129
|
-
### Axis, interaction, and transition configurations
|
|
17130
17167
|
|
|
17131
|
-
|
|
17132
|
-
|
|
17133
|
-
type VerticalAxisPosition = 'left' | 'right';
|
|
17134
|
-
type AxisPosition = HorizontalAxisPosition | VerticalAxisPosition;
|
|
17135
|
-
|
|
17136
|
-
interface AxisConfig {
|
|
17137
|
-
grid?: boolean | GridConfig;
|
|
17168
|
+
export interface AxisConfig {
|
|
17169
|
+
grid?: GridConfig | boolean;
|
|
17138
17170
|
label?: string;
|
|
17139
17171
|
position?: TPosition;
|
|
17140
17172
|
tickCount?: number;
|
|
17141
17173
|
tickFormat?: (value: Date | number | string) => string;
|
|
17142
17174
|
}
|
|
17143
17175
|
|
|
17144
|
-
type XAxisConfig = AxisConfig;
|
|
17145
|
-
type YAxisConfig = AxisConfig;
|
|
17176
|
+
export type XAxisConfig = AxisConfig;
|
|
17177
|
+
export type YAxisConfig = AxisConfig;
|
|
17146
17178
|
|
|
17147
|
-
interface
|
|
17148
|
-
color?: string;
|
|
17149
|
-
dash?: string;
|
|
17150
|
-
}
|
|
17151
|
-
|
|
17152
|
-
interface TooltipConfig {
|
|
17179
|
+
export interface TooltipConfig {
|
|
17153
17180
|
offset?: number;
|
|
17154
17181
|
render?: (datum: Datum, series: Series) => Node | string;
|
|
17155
17182
|
}
|
|
17156
17183
|
|
|
17157
|
-
interface CrosshairConfig {
|
|
17184
|
+
export interface CrosshairConfig {
|
|
17158
17185
|
horizontal?: boolean;
|
|
17159
17186
|
snap?: boolean;
|
|
17160
17187
|
vertical?: boolean;
|
|
17161
17188
|
}
|
|
17162
17189
|
|
|
17163
|
-
|
|
17164
|
-
position?: LegendPosition;
|
|
17165
|
-
}
|
|
17166
|
-
|
|
17167
|
-
type LegendPosition = 'bottom' | 'left' | 'right' | 'top';
|
|
17190
|
+
export type LegendPosition = 'bottom' | 'left' | 'right' | 'top';
|
|
17168
17191
|
|
|
17169
|
-
interface
|
|
17170
|
-
|
|
17171
|
-
easing?: EasingName | EasingFn;
|
|
17172
|
-
preference?: 'always' | 'never' | 'system'; // 'system' (default) skips reduced-motion
|
|
17173
|
-
stagger?: number; // ms per bar (bar) or series (radar); ignored elsewhere
|
|
17192
|
+
export interface LegendConfig {
|
|
17193
|
+
position?: LegendPosition;
|
|
17174
17194
|
}
|
|
17175
|
-
|
|
17176
|
-
// Motion is on by default. `false` renders every update synchronously,
|
|
17177
|
-
// `true` uses the chart defaults, or pass a config to tune them.
|
|
17178
|
-
type TransitionOption = TransitionConfig | boolean;
|
|
17179
|
-
|
|
17180
|
-
type EasingName = 'ease-in' | 'ease-in-out' | 'ease-out' | 'back-out' | 'expo-out' | 'linear';
|
|
17181
|
-
|
|
17182
|
-
type EasingFn = (t: number) => number;
|
|
17183
17195
|
```
|
|
17184
17196
|
|
|
17185
|
-
|
|
17197
|
+
The crosshair defaults to a vertical line that snaps to the nearest datum; the horizontal line is hidden by default. With `snap: false`, only the guide follows the pointer—tooltip and callback data still refer to the nearest datum.
|
|
17186
17198
|
|
|
17187
|
-
|
|
17199
|
+
Tooltip strings are assigned as text, not parsed as HTML. For a radar chart, `tooltip.render` receives a datum whose `meta` contains the active axis, all series values, and the default announcement text.
|
|
17188
17200
|
|
|
17189
|
-
###
|
|
17201
|
+
### Chart Configuration Types
|
|
17190
17202
|
|
|
17191
17203
|
```ts
|
|
17192
|
-
interface
|
|
17193
|
-
|
|
17194
|
-
|
|
17195
|
-
|
|
17196
|
-
|
|
17197
|
-
|
|
17204
|
+
export interface BaseChartConfig {
|
|
17205
|
+
a11y?: ChartA11y;
|
|
17206
|
+
legend?: LegendConfig | boolean;
|
|
17207
|
+
margin?: Partial;
|
|
17208
|
+
onClick?: (event: ChartEvent) => void;
|
|
17209
|
+
onHover?: (event: ChartEvent | null) => void;
|
|
17210
|
+
tooltip?: TooltipConfig | boolean;
|
|
17211
|
+
transition?: TransitionOption;
|
|
17212
|
+
xAxis?: XAxisConfig | false;
|
|
17213
|
+
yAxis?: YAxisConfig | false;
|
|
17198
17214
|
}
|
|
17199
17215
|
|
|
17200
|
-
interface
|
|
17201
|
-
|
|
17202
|
-
|
|
17203
|
-
|
|
17204
|
-
|
|
17205
|
-
|
|
17206
|
-
gap(): number;
|
|
17216
|
+
export interface LineSeriesConfig extends Series {
|
|
17217
|
+
curve?: 'linear' | 'monotone' | 'step';
|
|
17218
|
+
pointRadius?: number;
|
|
17219
|
+
showPoints?: boolean;
|
|
17220
|
+
strokeWidth?: number;
|
|
17221
|
+
yAxis?: 'left' | 'right';
|
|
17207
17222
|
}
|
|
17208
17223
|
|
|
17209
|
-
interface
|
|
17210
|
-
|
|
17211
|
-
|
|
17212
|
-
|
|
17213
|
-
nice?: boolean;
|
|
17224
|
+
export interface LineChartConfig extends BaseChartConfig {
|
|
17225
|
+
crosshair?: CrosshairConfig | boolean;
|
|
17226
|
+
rightYAxis?: Omit;
|
|
17227
|
+
series: LineSeriesConfig[];
|
|
17214
17228
|
}
|
|
17215
17229
|
|
|
17216
|
-
interface
|
|
17217
|
-
|
|
17218
|
-
|
|
17219
|
-
|
|
17230
|
+
export interface AreaSeriesConfig extends Series {
|
|
17231
|
+
curve?: 'linear' | 'monotone' | 'step';
|
|
17232
|
+
fill?: 'gradient' | 'solid';
|
|
17233
|
+
fillOpacity?: number;
|
|
17234
|
+
showLine?: boolean;
|
|
17220
17235
|
}
|
|
17221
17236
|
|
|
17222
|
-
interface
|
|
17223
|
-
|
|
17224
|
-
|
|
17225
|
-
padding?: number;
|
|
17226
|
-
paddingOuter?: number;
|
|
17237
|
+
export interface AreaChartConfig extends BaseChartConfig {
|
|
17238
|
+
crosshair?: CrosshairConfig | boolean;
|
|
17239
|
+
series: AreaSeriesConfig[];
|
|
17227
17240
|
}
|
|
17228
|
-
```
|
|
17229
17241
|
|
|
17230
|
-
|
|
17231
|
-
|
|
17232
|
-
### Remaining unions and theme type
|
|
17233
|
-
|
|
17234
|
-
```ts
|
|
17235
|
-
type BarVariant = 'grouped' | 'grouped-horizontal' | 'stacked' | 'stacked-horizontal';
|
|
17236
|
-
type PieVariant = 'donut' | 'pie' | 'semi';
|
|
17237
|
-
type SparklineVariant = 'area' | 'bar' | 'line' | 'stack';
|
|
17238
|
-
|
|
17239
|
-
interface PrismTheme {
|
|
17240
|
-
axisColor?: string; // --prism-axis-color
|
|
17241
|
-
colors?: string[];
|
|
17242
|
-
fontFamily?: string;
|
|
17243
|
-
gridColor?: string;
|
|
17244
|
-
gridOpacity?: number;
|
|
17245
|
-
textColor?: string; // --prism-text-color
|
|
17246
|
-
textColorSecondary?: string; // --prism-text-color-secondary
|
|
17247
|
-
tooltipBg?: string; // --prism-tooltip-bg
|
|
17248
|
-
tooltipBorder?: string; // --prism-tooltip-border
|
|
17249
|
-
tooltipColor?: string; // --prism-tooltip-color
|
|
17242
|
+
export interface ScatterSeriesConfig extends Series {
|
|
17243
|
+
pointRadius?: number;
|
|
17250
17244
|
}
|
|
17251
17245
|
|
|
17252
|
-
interface
|
|
17253
|
-
|
|
17246
|
+
export interface ScatterChartConfig extends BaseChartConfig {
|
|
17247
|
+
crosshair?: CrosshairConfig | boolean;
|
|
17248
|
+
series: ScatterSeriesConfig[];
|
|
17254
17249
|
}
|
|
17255
|
-
```
|
|
17256
|
-
|
|
17257
|
-
## Errors
|
|
17258
|
-
|
|
17259
|
-
### `PrismError`
|
|
17260
|
-
|
|
17261
|
-
Base class for every Prism-originated error. It supports standard `ErrorOptions` cause chaining.
|
|
17262
|
-
|
|
17263
|
-
### `PrismRenderError`
|
|
17264
|
-
|
|
17265
|
-
Extends `PrismError`. Thrown for invalid containers, failed initial renders, and attempts to update disposed charts.
|
|
17266
|
-
|
|
17267
|
-
### Usage Guide
|
|
17268
|
-
|
|
17269
|
-
## Basic Usage
|
|
17270
|
-
|
|
17271
|
-
Every chart needs a container element with defined dimensions and the theme CSS:
|
|
17272
|
-
|
|
17273
|
-
```ts
|
|
17274
|
-
import { createLineChart } from '@vielzeug/prism';
|
|
17275
|
-
import '@vielzeug/prism/theme.css';
|
|
17276
|
-
|
|
17277
|
-
const container = document.querySelector('#chart')!;
|
|
17278
|
-
const chart = createLineChart(container, {
|
|
17279
|
-
series: [
|
|
17280
|
-
{
|
|
17281
|
-
name: 'Revenue',
|
|
17282
|
-
data: [
|
|
17283
|
-
{ key: 1, value: 10 },
|
|
17284
|
-
{ key: 2, value: 16 },
|
|
17285
|
-
],
|
|
17286
|
-
},
|
|
17287
|
-
],
|
|
17288
|
-
});
|
|
17289
|
-
|
|
17290
|
-
chart.dispose();
|
|
17291
|
-
```
|
|
17292
|
-
|
|
17293
|
-
```html
|
|
17294
|
-
|
|
17295
|
-
```
|
|
17296
|
-
|
|
17297
|
-
Prism observes the container size via `ResizeObserver` and re-renders automatically on resize. If the container has zero dimensions at mount time, a `warn` is emitted in development: ensure the container has layout before calling the chart factory.
|
|
17298
|
-
|
|
17299
|
-
## Updating Data
|
|
17300
|
-
|
|
17301
|
-
Chart factories render synchronously and return a typed handle. Call `update()` with the same data shape used by the factory when application state changes.
|
|
17302
|
-
|
|
17303
|
-
```ts
|
|
17304
|
-
import { createLineChart } from '@vielzeug/prism';
|
|
17305
|
-
|
|
17306
|
-
const chart = createLineChart(container, {
|
|
17307
|
-
series: [{ data: [{ key: 1, value: 10 }], name: 'Live' }],
|
|
17308
|
-
});
|
|
17309
|
-
|
|
17310
|
-
chart.update([
|
|
17311
|
-
{
|
|
17312
|
-
data: [
|
|
17313
|
-
{ key: 1, value: 10 },
|
|
17314
|
-
{ key: 2, value: 20 },
|
|
17315
|
-
],
|
|
17316
|
-
name: 'Live',
|
|
17317
|
-
},
|
|
17318
|
-
]);
|
|
17319
|
-
```
|
|
17320
|
-
|
|
17321
|
-
`update()` is state-library neutral. Call it from a framework effect, store subscription, event handler, or request callback. It throws after the chart is disposed instead of silently retaining detached state.
|
|
17322
|
-
|
|
17323
|
-
## Line Charts
|
|
17324
|
-
|
|
17325
|
-
```ts
|
|
17326
|
-
import { createLineChart } from '@vielzeug/prism';
|
|
17327
|
-
|
|
17328
|
-
const chart = createLineChart(container, {
|
|
17329
|
-
series: [
|
|
17330
|
-
{
|
|
17331
|
-
name: 'Revenue',
|
|
17332
|
-
data: [
|
|
17333
|
-
{ key: 1, value: 100 },
|
|
17334
|
-
{ key: 2, value: 150 },
|
|
17335
|
-
{ key: 3, value: 130 },
|
|
17336
|
-
],
|
|
17337
|
-
color: '#3b82f6',
|
|
17338
|
-
curve: 'monotone', // 'linear' | 'monotone' | 'step'
|
|
17339
|
-
strokeWidth: 2,
|
|
17340
|
-
showPoints: true,
|
|
17341
|
-
pointRadius: 4,
|
|
17342
|
-
},
|
|
17343
|
-
],
|
|
17344
|
-
xAxis: { position: 'bottom' },
|
|
17345
|
-
yAxis: { position: 'left', grid: true },
|
|
17346
|
-
tooltip: true,
|
|
17347
|
-
crosshair: true,
|
|
17348
|
-
});
|
|
17349
|
-
```
|
|
17350
|
-
|
|
17351
|
-
### Multiple Series
|
|
17352
|
-
|
|
17353
|
-
```ts
|
|
17354
|
-
const chart = createLineChart(container, {
|
|
17355
|
-
series: [
|
|
17356
|
-
{ name: 'Revenue', data: revenueData, color: '#3b82f6' },
|
|
17357
|
-
{ name: 'Expenses', data: expenseData, color: '#ef4444' },
|
|
17358
|
-
],
|
|
17359
|
-
xAxis: { position: 'bottom' },
|
|
17360
|
-
yAxis: { position: 'left', grid: true },
|
|
17361
|
-
});
|
|
17362
|
-
```
|
|
17363
|
-
|
|
17364
|
-
### Independent Value Axes
|
|
17365
|
-
|
|
17366
|
-
Assign a line series to `yAxis: 'right'` when its values need a different range. Both axes share the same X scale, while tooltips retain the original values.
|
|
17367
|
-
|
|
17368
|
-
```ts
|
|
17369
|
-
const chart = createLineChart(container, {
|
|
17370
|
-
series: [
|
|
17371
|
-
{ name: 'Health', data: [{ key: 0, value: 30 }, { key: 1, value: 20 }] },
|
|
17372
|
-
{ name: 'Damage', yAxis: 'right', data: [{ key: 0, value: 0 }, { key: 1, value: 300 }] },
|
|
17373
|
-
],
|
|
17374
|
-
yAxis: { label: 'Health' },
|
|
17375
|
-
rightYAxis: { label: 'Damage' },
|
|
17376
|
-
tooltip: true,
|
|
17377
|
-
});
|
|
17378
|
-
```
|
|
17379
|
-
|
|
17380
|
-
The primary axis is on the left when right-axis series are present. Grid configuration belongs to the primary axis. Dual-axis curve crossings do not imply equal numeric values. Preserve each marker's axis assignment when calling `update()`.
|
|
17381
|
-
|
|
17382
|
-
### Time-based X Axis
|
|
17383
|
-
|
|
17384
|
-
When data points use `Date` objects for `key`, Prism automatically applies a time scale. The domain spans exactly the first to the last date, so the series fills the plot width:
|
|
17385
|
-
|
|
17386
|
-
```ts
|
|
17387
|
-
const chart = createLineChart(container, {
|
|
17388
|
-
series: [
|
|
17389
|
-
{
|
|
17390
|
-
name: 'Signups',
|
|
17391
|
-
data: [
|
|
17392
|
-
{ key: new Date('2024-01-01'), value: 50 },
|
|
17393
|
-
{ key: new Date('2024-02-01'), value: 80 },
|
|
17394
|
-
{ key: new Date('2024-03-01'), value: 120 },
|
|
17395
|
-
],
|
|
17396
|
-
},
|
|
17397
|
-
],
|
|
17398
|
-
xAxis: { position: 'bottom', tickFormat: (d) => (d as Date).toLocaleDateString() },
|
|
17399
|
-
yAxis: { position: 'left' },
|
|
17400
|
-
});
|
|
17401
|
-
```
|
|
17402
|
-
|
|
17403
|
-
## Bar Charts
|
|
17404
|
-
|
|
17405
|
-
```ts
|
|
17406
|
-
import { createBarChart } from '@vielzeug/prism';
|
|
17407
|
-
|
|
17408
|
-
const chart = createBarChart(container, {
|
|
17409
|
-
series: [
|
|
17410
|
-
{
|
|
17411
|
-
name: 'Sales',
|
|
17412
|
-
data: [
|
|
17413
|
-
{ key: 'Q1', value: 200 },
|
|
17414
|
-
{ key: 'Q2', value: 350 },
|
|
17415
|
-
{ key: 'Q3', value: 280 },
|
|
17416
|
-
{ key: 'Q4', value: 400 },
|
|
17417
|
-
],
|
|
17418
|
-
borderRadius: 4,
|
|
17419
|
-
},
|
|
17420
|
-
],
|
|
17421
|
-
xAxis: { position: 'bottom' },
|
|
17422
|
-
yAxis: { position: 'left', grid: true },
|
|
17423
|
-
tooltip: true,
|
|
17424
|
-
});
|
|
17425
|
-
```
|
|
17426
|
-
|
|
17427
|
-
### Variants
|
|
17428
|
-
|
|
17429
|
-
Select the bar layout with `variant`:
|
|
17430
|
-
|
|
17431
|
-
| Value | Layout |
|
|
17432
|
-
| ---------------------- | -------------------------- |
|
|
17433
|
-
| `'grouped'` | Vertical grouped (default) |
|
|
17434
|
-
| `'stacked'` | Vertical stacked |
|
|
17435
|
-
| `'grouped-horizontal'` | Horizontal grouped |
|
|
17436
|
-
| `'stacked-horizontal'` | Horizontal stacked |
|
|
17437
|
-
|
|
17438
|
-
```ts
|
|
17439
|
-
const chart = createBarChart(container, {
|
|
17440
|
-
variant: 'stacked',
|
|
17441
|
-
series: [
|
|
17442
|
-
{ name: 'Mobile', data: mobileData, color: '#3b82f6', borderRadius: 0 },
|
|
17443
|
-
{ name: 'Desktop', data: desktopData, color: '#10b981', borderRadius: 0 },
|
|
17444
|
-
],
|
|
17445
|
-
xAxis: { position: 'bottom' },
|
|
17446
|
-
yAxis: { position: 'left', grid: true },
|
|
17447
|
-
tooltip: true,
|
|
17448
|
-
legend: true,
|
|
17449
|
-
});
|
|
17450
|
-
```
|
|
17451
|
-
|
|
17452
|
-
For horizontal layouts, categories appear on the Y axis and values on the X axis:
|
|
17453
|
-
|
|
17454
|
-
```ts
|
|
17455
|
-
const chart = createBarChart(container, {
|
|
17456
|
-
variant: 'grouped-horizontal',
|
|
17457
|
-
series: [{ name: 'Revenue', data, color: '#3b82f6' }],
|
|
17458
|
-
xAxis: { position: 'bottom', grid: true },
|
|
17459
|
-
yAxis: { position: 'left' },
|
|
17460
|
-
});
|
|
17461
|
-
```
|
|
17462
|
-
|
|
17463
|
-
### Grouped Bars
|
|
17464
17250
|
|
|
17465
|
-
|
|
17466
|
-
|
|
17467
|
-
|
|
17468
|
-
const chart = createBarChart(container, {
|
|
17469
|
-
series: [
|
|
17470
|
-
{ name: '2023', data: lastYearData, color: '#94a3b8' },
|
|
17471
|
-
{ name: '2024', data: thisYearData, color: '#3b82f6' },
|
|
17472
|
-
],
|
|
17473
|
-
});
|
|
17474
|
-
```
|
|
17475
|
-
|
|
17476
|
-
## Area Charts
|
|
17477
|
-
|
|
17478
|
-
Area fills use a vertical gradient that fades toward the baseline. Set `fill: 'solid'` for a flat fill:
|
|
17479
|
-
|
|
17480
|
-
```ts
|
|
17481
|
-
import { createAreaChart } from '@vielzeug/prism';
|
|
17482
|
-
|
|
17483
|
-
const chart = createAreaChart(container, {
|
|
17484
|
-
series: [
|
|
17485
|
-
{
|
|
17486
|
-
name: 'Users',
|
|
17487
|
-
data: userData,
|
|
17488
|
-
curve: 'monotone',
|
|
17489
|
-
fill: 'gradient', // 'gradient' (default) | 'solid'
|
|
17490
|
-
showLine: true,
|
|
17491
|
-
},
|
|
17492
|
-
],
|
|
17493
|
-
xAxis: { position: 'bottom' },
|
|
17494
|
-
yAxis: { position: 'left', grid: true },
|
|
17495
|
-
crosshair: true,
|
|
17496
|
-
});
|
|
17497
|
-
```
|
|
17498
|
-
|
|
17499
|
-
`fillOpacity` overrides the theme opacity for one series.
|
|
17500
|
-
|
|
17501
|
-
## Forecast / emphasis styling
|
|
17502
|
-
|
|
17503
|
-
A single series often mixes points that should look different — actuals plus a
|
|
17504
|
-
forecast tail, or a run that crossed a budget. Rather than split the series,
|
|
17505
|
-
carry `dash` and `opacity` on the individual datums. They are styling-only:
|
|
17506
|
-
tooltips, hover, keyboard, and screen-reader behavior never change.
|
|
17507
|
-
|
|
17508
|
-
For a forecast tail, map a parallel `types` array onto the datums:
|
|
17509
|
-
|
|
17510
|
-
```ts
|
|
17511
|
-
import { createLineChart } from '@vielzeug/prism';
|
|
17251
|
+
export interface BarSeriesConfig extends Series {
|
|
17252
|
+
borderRadius?: number;
|
|
17253
|
+
}
|
|
17512
17254
|
|
|
17513
|
-
|
|
17255
|
+
export type BarVariant = 'grouped' | 'grouped-horizontal' | 'stacked' | 'stacked-horizontal';
|
|
17514
17256
|
|
|
17515
|
-
|
|
17516
|
-
series: [
|
|
17517
|
-
|
|
17518
|
-
|
|
17519
|
-
data: values.map((value, i) => ({
|
|
17520
|
-
key: months[i],
|
|
17521
|
-
value,
|
|
17522
|
-
...(types[i] === 'FORECAST' ? { dash: '5 5', opacity: 0.4 } : {}),
|
|
17523
|
-
})),
|
|
17524
|
-
},
|
|
17525
|
-
],
|
|
17526
|
-
});
|
|
17527
|
-
```
|
|
17257
|
+
export interface BarChartConfig extends BaseChartConfig {
|
|
17258
|
+
series: BarSeriesConfig[];
|
|
17259
|
+
variant?: BarVariant;
|
|
17260
|
+
}
|
|
17528
17261
|
|
|
17529
|
-
|
|
17530
|
-
next, so the forecast run renders dashed while the actuals stay solid; its
|
|
17531
|
-
`opacity` fades that segment and the point marker. The last datum's `dash` has
|
|
17532
|
-
no segment to paint and is ignored. On a bar chart, both fields apply to that
|
|
17533
|
-
datum's own bar — a `dash` adds a 1px series-color stroke so the dash reads on
|
|
17534
|
-
the filled rect. On an area chart they style the top line only; the fill keeps
|
|
17535
|
-
its series-level treatment.
|
|
17262
|
+
export type PieVariant = 'donut' | 'pie' | 'semi';
|
|
17536
17263
|
|
|
17537
|
-
|
|
17264
|
+
export interface PieSliceConfig {
|
|
17265
|
+
color?: string;
|
|
17266
|
+
label?: string;
|
|
17267
|
+
value: number;
|
|
17268
|
+
}
|
|
17538
17269
|
|
|
17539
|
-
|
|
17540
|
-
|
|
17270
|
+
export interface PieEvent {
|
|
17271
|
+
index: number;
|
|
17272
|
+
originalEvent: Event;
|
|
17273
|
+
slice: PieSliceConfig;
|
|
17274
|
+
}
|
|
17541
17275
|
|
|
17542
|
-
|
|
17543
|
-
|
|
17544
|
-
|
|
17545
|
-
|
|
17546
|
-
|
|
17547
|
-
|
|
17548
|
-
|
|
17549
|
-
|
|
17550
|
-
|
|
17551
|
-
},
|
|
17552
|
-
],
|
|
17553
|
-
});
|
|
17554
|
-
```
|
|
17276
|
+
export interface PieChartConfig extends Omit {
|
|
17277
|
+
cornerRadius?: number;
|
|
17278
|
+
data: PieSliceConfig[];
|
|
17279
|
+
innerRadius?: number;
|
|
17280
|
+
onClick?: (event: PieEvent) => void;
|
|
17281
|
+
onHover?: (event: PieEvent | null) => void;
|
|
17282
|
+
padPixels?: number;
|
|
17283
|
+
variant?: PieVariant;
|
|
17284
|
+
}
|
|
17555
17285
|
|
|
17556
|
-
|
|
17557
|
-
|
|
17558
|
-
|
|
17559
|
-
|
|
17286
|
+
export interface RadarAxisConfig {
|
|
17287
|
+
format?: (value: number) => string;
|
|
17288
|
+
key: string;
|
|
17289
|
+
label: string;
|
|
17290
|
+
max?: number;
|
|
17291
|
+
min?: number;
|
|
17292
|
+
}
|
|
17560
17293
|
|
|
17561
|
-
|
|
17294
|
+
export type RadarSeriesConfig = Series>;
|
|
17562
17295
|
|
|
17563
|
-
|
|
17296
|
+
export interface RadarGridConfig {
|
|
17297
|
+
bands?: boolean;
|
|
17298
|
+
labels?: boolean;
|
|
17299
|
+
levels?: number;
|
|
17300
|
+
shape?: 'circle' | 'polygon';
|
|
17301
|
+
}
|
|
17564
17302
|
|
|
17565
|
-
|
|
17566
|
-
|
|
17303
|
+
export interface RadarAxisValue {
|
|
17304
|
+
datum: Datum | undefined;
|
|
17305
|
+
series: RadarSeriesConfig;
|
|
17306
|
+
}
|
|
17567
17307
|
|
|
17568
|
-
|
|
17569
|
-
|
|
17570
|
-
|
|
17571
|
-
|
|
17572
|
-
|
|
17573
|
-
|
|
17574
|
-
],
|
|
17575
|
-
variant: 'donut', // 'pie' | 'donut' | 'semi'
|
|
17576
|
-
tooltip: true,
|
|
17577
|
-
transition: { duration: 400, easing: 'ease-out' },
|
|
17578
|
-
});
|
|
17579
|
-
```
|
|
17308
|
+
export interface RadarEvent {
|
|
17309
|
+
axis: RadarAxisConfig;
|
|
17310
|
+
index: number;
|
|
17311
|
+
originalEvent: Event;
|
|
17312
|
+
values: RadarAxisValue[];
|
|
17313
|
+
}
|
|
17580
17314
|
|
|
17581
|
-
|
|
17315
|
+
export interface RadarChartConfig extends Omit {
|
|
17316
|
+
axes: RadarAxisConfig[];
|
|
17317
|
+
curve?: 'linear' | 'rounded';
|
|
17318
|
+
domain?: [number, number];
|
|
17319
|
+
fill?: 'gradient' | 'none' | 'solid';
|
|
17320
|
+
grid?: RadarGridConfig | boolean;
|
|
17321
|
+
onClick?: (event: RadarEvent) => void;
|
|
17322
|
+
onHover?: (event: RadarEvent | null) => void;
|
|
17323
|
+
series: RadarSeriesConfig[];
|
|
17324
|
+
showPoints?: boolean;
|
|
17325
|
+
showValues?: boolean;
|
|
17326
|
+
startAngle?: number;
|
|
17327
|
+
}
|
|
17582
17328
|
|
|
17583
|
-
|
|
|
17584
|
-
| --------- | ------------------------------------------------------- |
|
|
17585
|
-
| `'pie'` | Full circle, no hole |
|
|
17586
|
-
| `'donut'` | Full circle with inner hole (~55% of outer by default) |
|
|
17587
|
-
| `'semi'` | Top-half semicircle with inner hole: useful for gauges |
|
|
17329
|
+
export type SparklineVariant = 'area' | 'bar' | 'line' | 'stack';
|
|
17588
17330
|
|
|
17589
|
-
|
|
17331
|
+
export interface StackSegment {
|
|
17332
|
+
color?: string;
|
|
17333
|
+
label?: string;
|
|
17334
|
+
value: number;
|
|
17335
|
+
}
|
|
17590
17336
|
|
|
17591
|
-
|
|
17337
|
+
export interface SparklineEvent {
|
|
17338
|
+
index: number;
|
|
17339
|
+
originalEvent: Event;
|
|
17340
|
+
value: number;
|
|
17341
|
+
}
|
|
17592
17342
|
|
|
17593
|
-
|
|
17594
|
-
|
|
17595
|
-
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
|
|
17343
|
+
export interface SparklineConfig {
|
|
17344
|
+
a11y?: ChartA11y;
|
|
17345
|
+
color?: string;
|
|
17346
|
+
cornerRadius?: number;
|
|
17347
|
+
curve?: 'linear' | 'monotone' | 'step';
|
|
17348
|
+
data: number[] | StackSegment[];
|
|
17349
|
+
fillOpacity?: number;
|
|
17350
|
+
onClick?: (event: SparklineEvent) => void;
|
|
17351
|
+
onHover?: (event: SparklineEvent | null) => void;
|
|
17352
|
+
padPixels?: number;
|
|
17353
|
+
showEndPoint?: boolean;
|
|
17354
|
+
strokeWidth?: number;
|
|
17355
|
+
transition?: TransitionOption;
|
|
17356
|
+
variant?: SparklineVariant;
|
|
17357
|
+
}
|
|
17599
17358
|
```
|
|
17600
17359
|
|
|
17601
|
-
|
|
17360
|
+
## Errors
|
|
17602
17361
|
|
|
17603
|
-
|
|
17362
|
+
### `PrismError`
|
|
17604
17363
|
|
|
17605
17364
|
```ts
|
|
17606
|
-
|
|
17607
|
-
|
|
17608
|
-
|
|
17609
|
-
Style labels via CSS:
|
|
17610
|
-
|
|
17611
|
-
```css
|
|
17612
|
-
:root {
|
|
17613
|
-
--prism-pie-label-color: #fff;
|
|
17614
|
-
--prism-pie-label-size: 11px;
|
|
17365
|
+
class PrismError extends Error {
|
|
17366
|
+
constructor(message: string, opts?: ErrorOptions);
|
|
17615
17367
|
}
|
|
17616
17368
|
```
|
|
17617
17369
|
|
|
17618
|
-
|
|
17619
|
-
|
|
17620
|
-
```ts
|
|
17621
|
-
const chart = createPieChart(container, {
|
|
17622
|
-
data: [
|
|
17623
|
-
{ label: 'A', value: 40 },
|
|
17624
|
-
{ label: 'B', value: 60 },
|
|
17625
|
-
],
|
|
17626
|
-
variant: 'donut',
|
|
17627
|
-
});
|
|
17628
|
-
|
|
17629
|
-
chart.update([
|
|
17630
|
-
{ label: 'A', value: 55 },
|
|
17631
|
-
{ label: 'B', value: 45 },
|
|
17632
|
-
]);
|
|
17633
|
-
```
|
|
17370
|
+
Base class for Prism-originated errors. Its `name` is set to the concrete error class name, and it supports the standard `ErrorOptions` including `cause`.
|
|
17634
17371
|
|
|
17635
|
-
###
|
|
17372
|
+
### `PrismRenderError`
|
|
17636
17373
|
|
|
17637
17374
|
```ts
|
|
17638
|
-
|
|
17639
|
-
data,
|
|
17640
|
-
onHover: (event) => {
|
|
17641
|
-
// event is PieEvent | null (null on mouseleave)
|
|
17642
|
-
if (event) console.log(event.index, event.slice.label, event.slice.value);
|
|
17643
|
-
},
|
|
17644
|
-
onClick: (event) => {
|
|
17645
|
-
console.log('clicked', event.index, event.slice.label);
|
|
17646
|
-
},
|
|
17647
|
-
});
|
|
17375
|
+
class PrismRenderError extends PrismError {}
|
|
17648
17376
|
```
|
|
17649
17377
|
|
|
17650
|
-
|
|
17378
|
+
Thrown when a chart cannot be rendered because its container is not a DOM element, when initial rendering fails (the original error is available as `cause`), or when `update()` is called after disposal. Empty or malformed chart data may instead produce a development warning or an empty rendering, depending on the chart.
|
|
17651
17379
|
|
|
17652
|
-
|
|
17380
|
+
### Usage Guide
|
|
17381
|
+
|
|
17382
|
+
## Basic Usage
|
|
17653
17383
|
|
|
17654
|
-
|
|
17384
|
+
Create a host element with non-zero dimensions, then pass it to a chart factory. This example creates the host in JavaScript so the snippet can run as written.
|
|
17655
17385
|
|
|
17656
17386
|
```ts
|
|
17657
|
-
import {
|
|
17387
|
+
import { createLineChart } from '@vielzeug/prism';
|
|
17388
|
+
import '@vielzeug/prism/theme.css';
|
|
17658
17389
|
|
|
17659
|
-
const
|
|
17660
|
-
|
|
17661
|
-
|
|
17662
|
-
{ key: 'int', label: 'Intellect' },
|
|
17663
|
-
{ key: 'end', label: 'Endurance' },
|
|
17664
|
-
{ key: 'spd', label: 'Speed', max: 5 },
|
|
17665
|
-
];
|
|
17390
|
+
const container = document.createElement('div');
|
|
17391
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17392
|
+
document.body.append(container);
|
|
17666
17393
|
|
|
17667
|
-
const chart =
|
|
17668
|
-
a11y: { ariaLabel: '
|
|
17669
|
-
axes,
|
|
17670
|
-
domain: [0, 10],
|
|
17671
|
-
fill: 'gradient',
|
|
17672
|
-
showValues: true,
|
|
17394
|
+
const chart = createLineChart(container, {
|
|
17395
|
+
a11y: { ariaLabel: 'Revenue by month' },
|
|
17673
17396
|
series: [
|
|
17674
17397
|
{
|
|
17675
|
-
name: '
|
|
17398
|
+
name: 'Revenue',
|
|
17676
17399
|
data: [
|
|
17677
|
-
{ key:
|
|
17678
|
-
{ key:
|
|
17679
|
-
{ key: 'int', value: 4 },
|
|
17680
|
-
{ key: 'end', value: 9 },
|
|
17681
|
-
{ key: 'spd', value: 3 },
|
|
17400
|
+
{ key: 1, value: 10 },
|
|
17401
|
+
{ key: 2, value: 16 },
|
|
17682
17402
|
],
|
|
17683
17403
|
},
|
|
17684
17404
|
],
|
|
17405
|
+
tooltip: true,
|
|
17685
17406
|
});
|
|
17407
|
+
|
|
17408
|
+
chart.dispose();
|
|
17686
17409
|
```
|
|
17687
17410
|
|
|
17688
|
-
|
|
17411
|
+
Each factory appends an SVG to its container and returns a `ChartHandle`. Prism observes the container with `ResizeObserver`; if it has zero dimensions on creation, Prism uses a temporary `600 × 300` size and warns in development. Give the host its layout before creating the chart.
|
|
17689
17412
|
|
|
17690
|
-
|
|
17413
|
+
## Updating Data
|
|
17691
17414
|
|
|
17692
|
-
|
|
17415
|
+
Keep application state outside Prism and pass the next complete data value to `update()`. The update method replaces chart data synchronously; the default transition may animate the resulting SVG.
|
|
17693
17416
|
|
|
17694
|
-
|
|
17695
|
-
|
|
17696
|
-
| `fill` | `'solid'`, `'gradient'`, `'none'` | `gradient` for a single hero; `solid` or `none` when overlaying several |
|
|
17697
|
-
| `curve` | `'linear'`, `'rounded'` | Rounded reads softer; linear keeps exact vertices |
|
|
17698
|
-
| `grid.shape` | `'polygon'`, `'circle'` | Polygon matches the axes; circle suits many axes |
|
|
17699
|
-
| `grid.levels` / `grid.bands` | number / boolean | Ring count and alternate shading |
|
|
17700
|
-
| `grid.labels` | boolean | Level values; drawn only when every axis shares one domain |
|
|
17701
|
-
| `showValues` | boolean | Value beside each vertex, formatted by `axis.format` |
|
|
17417
|
+
```ts
|
|
17418
|
+
import { createLineChart } from '@vielzeug/prism';
|
|
17702
17419
|
|
|
17703
|
-
|
|
17420
|
+
const container = document.createElement('div');
|
|
17421
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17422
|
+
document.body.append(container);
|
|
17704
17423
|
|
|
17705
|
-
|
|
17424
|
+
let series = [{ data: [{ key: 1, value: 10 }], name: 'Live' }];
|
|
17425
|
+
const chart = createLineChart(container, { series });
|
|
17706
17426
|
|
|
17707
|
-
|
|
17708
|
-
|
|
17709
|
-
|
|
17710
|
-
legend: true,
|
|
17711
|
-
series: [adam, eve],
|
|
17712
|
-
tooltip: true, // "Agility: Adam 6, Eve 9"
|
|
17713
|
-
onHover: (event) => event && console.log(event.axis.label, event.values),
|
|
17714
|
-
});
|
|
17427
|
+
series = [{ data: [{ key: 1, value: 10 }, { key: 2, value: 20 }], name: 'Live' }];
|
|
17428
|
+
chart.update(series);
|
|
17429
|
+
chart.dispose();
|
|
17715
17430
|
```
|
|
17716
17431
|
|
|
17717
|
-
|
|
17432
|
+
`update()` accepts the type shown by that factory's handle: a complete series array for line, area, scatter, bar, and radar charts; a slice array for pie charts; and a number or stack-segment array for sparklines. Chart options such as axes, variant, callbacks, and accessibility are set at creation. For example, radar axes and a pie chart's variant do not change through `update()`.
|
|
17433
|
+
|
|
17434
|
+
## Line Charts
|
|
17718
17435
|
|
|
17719
|
-
|
|
17436
|
+
Line and area series use number or `Date` keys. All series in one chart must use the same key kind. Use `curve` to choose interpolation, and enable markers with `showPoints`.
|
|
17720
17437
|
|
|
17721
17438
|
```ts
|
|
17722
|
-
import {
|
|
17439
|
+
import { createLineChart } from '@vielzeug/prism';
|
|
17440
|
+
|
|
17441
|
+
const container = document.createElement('div');
|
|
17442
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17443
|
+
document.body.append(container);
|
|
17723
17444
|
|
|
17724
|
-
const
|
|
17725
|
-
|
|
17726
|
-
|
|
17727
|
-
|
|
17728
|
-
|
|
17729
|
-
|
|
17445
|
+
const chart = createLineChart(container, {
|
|
17446
|
+
a11y: { ariaLabel: 'Revenue and expenses' },
|
|
17447
|
+
series: [
|
|
17448
|
+
{
|
|
17449
|
+
curve: 'monotone',
|
|
17450
|
+
data: [{ key: 1, value: 100 }, { key: 2, value: 150 }, { key: 3, value: 130 }],
|
|
17451
|
+
name: 'Revenue',
|
|
17452
|
+
showPoints: true,
|
|
17453
|
+
},
|
|
17454
|
+
{
|
|
17455
|
+
color: '#c2410c',
|
|
17456
|
+
data: [{ key: 1, value: 70 }, { key: 2, value: 95 }, { key: 3, value: 110 }],
|
|
17457
|
+
name: 'Expenses',
|
|
17458
|
+
},
|
|
17459
|
+
],
|
|
17460
|
+
tooltip: true,
|
|
17461
|
+
xAxis: { label: 'Month' },
|
|
17462
|
+
yAxis: { grid: true, label: 'Dollars' },
|
|
17730
17463
|
});
|
|
17731
17464
|
|
|
17732
|
-
|
|
17465
|
+
chart.dispose();
|
|
17733
17466
|
```
|
|
17734
17467
|
|
|
17735
|
-
###
|
|
17468
|
+
### Independent Value Axes
|
|
17736
17469
|
|
|
17737
|
-
|
|
17738
|
-
- **`area`**: gradient-filled area + line overlay
|
|
17739
|
-
- **`bar`**: vertical bar for each data point
|
|
17740
|
-
- **`stack`**: horizontal proportional segments; use `StackSegment[]` for `data` with per-segment colors
|
|
17470
|
+
Assign a line series to the right axis when it uses a different value range. Both axes share the x-scale; `rightYAxis` configures the second axis and cannot configure its position or grid.
|
|
17741
17471
|
|
|
17742
|
-
|
|
17472
|
+
```ts
|
|
17473
|
+
import { createLineChart } from '@vielzeug/prism';
|
|
17743
17474
|
|
|
17744
|
-
|
|
17475
|
+
const container = document.createElement('div');
|
|
17476
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17477
|
+
document.body.append(container);
|
|
17745
17478
|
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
|
|
17479
|
+
const chart = createLineChart(container, {
|
|
17480
|
+
a11y: { ariaLabel: 'Health and damage by level' },
|
|
17481
|
+
rightYAxis: { label: 'Damage' },
|
|
17482
|
+
series: [
|
|
17483
|
+
{ data: [{ key: 1, value: 30 }, { key: 2, value: 20 }], name: 'Health' },
|
|
17484
|
+
{ data: [{ key: 1, value: 100 }, { key: 2, value: 300 }], name: 'Damage', yAxis: 'right' },
|
|
17485
|
+
],
|
|
17486
|
+
yAxis: { grid: true, label: 'Health' },
|
|
17750
17487
|
});
|
|
17751
17488
|
|
|
17752
|
-
|
|
17489
|
+
chart.dispose();
|
|
17753
17490
|
```
|
|
17754
17491
|
|
|
17755
|
-
|
|
17492
|
+
When any series uses the right axis, the primary value axis is placed on the left. Grid lines belong to the primary `yAxis`. The independent numeric scales mean that curve crossings do not imply equal values.
|
|
17756
17493
|
|
|
17757
|
-
|
|
17494
|
+
### Time-Based X Axis
|
|
17495
|
+
|
|
17496
|
+
Use `Date` values for every key when plotting time. Line and area charts use a time scale whose domain fits the data instead of rounding outward to tick boundaries.
|
|
17758
17497
|
|
|
17759
17498
|
```ts
|
|
17760
|
-
|
|
17761
|
-
|
|
17762
|
-
|
|
17763
|
-
|
|
17764
|
-
|
|
17765
|
-
|
|
17766
|
-
|
|
17767
|
-
|
|
17768
|
-
},
|
|
17499
|
+
import { createLineChart } from '@vielzeug/prism';
|
|
17500
|
+
|
|
17501
|
+
const container = document.createElement('div');
|
|
17502
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17503
|
+
document.body.append(container);
|
|
17504
|
+
|
|
17505
|
+
const formatter = new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric' });
|
|
17506
|
+
const chart = createLineChart(container, {
|
|
17507
|
+
a11y: { ariaLabel: 'Signups over time' },
|
|
17508
|
+
series: [{
|
|
17509
|
+
data: [
|
|
17510
|
+
{ key: new Date('2026-09-01'), value: 50 },
|
|
17511
|
+
{ key: new Date('2026-09-08'), value: 80 },
|
|
17512
|
+
{ key: new Date('2026-09-15'), value: 120 },
|
|
17513
|
+
],
|
|
17514
|
+
name: 'Signups',
|
|
17515
|
+
}],
|
|
17516
|
+
xAxis: { tickFormat: (value) => value instanceof Date ? formatter.format(value) : String(value) },
|
|
17769
17517
|
});
|
|
17770
|
-
```
|
|
17771
17518
|
|
|
17772
|
-
|
|
17519
|
+
chart.dispose();
|
|
17520
|
+
```
|
|
17773
17521
|
|
|
17774
|
-
|
|
17522
|
+
`tickFormat` formats axis labels only. Tooltip content and accessibility announcements use the underlying keys and values.
|
|
17775
17523
|
|
|
17776
|
-
##
|
|
17524
|
+
## Bar Charts
|
|
17777
17525
|
|
|
17778
|
-
|
|
17526
|
+
Bar chart keys are string categories. The default `grouped` variant puts series side by side; the horizontal variants put categories on the y-axis and values on the x-axis.
|
|
17779
17527
|
|
|
17780
17528
|
```ts
|
|
17781
|
-
{
|
|
17782
|
-
xAxis: {
|
|
17783
|
-
position: 'bottom', // 'top' | 'bottom'
|
|
17784
|
-
tickCount: 5,
|
|
17785
|
-
tickFormat: (v) => `$${v}`,
|
|
17786
|
-
label: 'Month',
|
|
17787
|
-
grid: true, // or { color: '#ddd', dash: '4 2' }
|
|
17788
|
-
},
|
|
17789
|
-
yAxis: {
|
|
17790
|
-
position: 'left', // 'left' | 'right'
|
|
17791
|
-
grid: { color: '#f0f0f0' },
|
|
17792
|
-
label: 'Revenue ($)',
|
|
17793
|
-
},
|
|
17794
|
-
}
|
|
17795
|
-
```
|
|
17796
|
-
|
|
17797
|
-
Category axes show every label when the labels fit and thin them out only when they would overlap. Set `tickCount` to choose the density yourself.
|
|
17529
|
+
import { createBarChart } from '@vielzeug/prism';
|
|
17798
17530
|
|
|
17799
|
-
|
|
17531
|
+
const container = document.createElement('div');
|
|
17532
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17533
|
+
document.body.append(container);
|
|
17800
17534
|
|
|
17801
|
-
|
|
17535
|
+
const chart = createBarChart(container, {
|
|
17536
|
+
a11y: { ariaLabel: 'Sales by quarter' },
|
|
17537
|
+
series: [{
|
|
17538
|
+
data: [{ key: 'Q1', value: 200 }, { key: 'Q2', value: 350 }, { key: 'Q3', value: 280 }],
|
|
17539
|
+
name: 'Sales',
|
|
17540
|
+
}],
|
|
17541
|
+
tooltip: true,
|
|
17542
|
+
});
|
|
17802
17543
|
|
|
17803
|
-
|
|
17804
|
-
{
|
|
17805
|
-
tooltip: {
|
|
17806
|
-
offset: 12,
|
|
17807
|
-
render: (datum, series) => {
|
|
17808
|
-
const content = document.createElement('strong');
|
|
17809
|
-
content.textContent = `${series.name}: ${datum.value.toLocaleString()}`;
|
|
17810
|
-
return content;
|
|
17811
|
-
},
|
|
17812
|
-
},
|
|
17813
|
-
}
|
|
17544
|
+
chart.dispose();
|
|
17814
17545
|
```
|
|
17815
17546
|
|
|
17816
|
-
|
|
17547
|
+
Choose `grouped`, `stacked`, `grouped-horizontal`, or `stacked-horizontal` in `variant`. Negative values in a stacked chart are clamped to zero and produce a development warning. Bars in stacked variants remain square; `borderRadius` applies to grouped bars.
|
|
17817
17548
|
|
|
17818
|
-
|
|
17549
|
+
Axes render by default, with grid lines on the value axis. For horizontal variants, `xAxis` is the value axis and `yAxis` is the category axis. Configure `grid` on the value axis.
|
|
17819
17550
|
|
|
17820
|
-
##
|
|
17551
|
+
## Area Charts
|
|
17821
17552
|
|
|
17822
|
-
|
|
17553
|
+
Area series use a gradient fill by default. Set `fill: 'solid'` for a flat fill, or set `fillOpacity` to override the theme opacity for that series.
|
|
17823
17554
|
|
|
17824
17555
|
```ts
|
|
17825
|
-
{
|
|
17826
|
-
crosshair: true,
|
|
17827
|
-
// or configure:
|
|
17828
|
-
crosshair: { vertical: true, horizontal: true, snap: true },
|
|
17829
|
-
}
|
|
17830
|
-
```
|
|
17556
|
+
import { createAreaChart } from '@vielzeug/prism';
|
|
17831
17557
|
|
|
17832
|
-
|
|
17558
|
+
const container = document.createElement('div');
|
|
17559
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17560
|
+
document.body.append(container);
|
|
17833
17561
|
|
|
17834
|
-
|
|
17562
|
+
const chart = createAreaChart(container, {
|
|
17563
|
+
a11y: { ariaLabel: 'Visitors over time' },
|
|
17564
|
+
crosshair: true,
|
|
17565
|
+
series: [{
|
|
17566
|
+
curve: 'monotone',
|
|
17567
|
+
data: [{ key: 1, value: 12 }, { key: 2, value: 18 }, { key: 3, value: 15 }],
|
|
17568
|
+
fill: 'solid',
|
|
17569
|
+
fillOpacity: 0.2,
|
|
17570
|
+
name: 'Visitors',
|
|
17571
|
+
showLine: true,
|
|
17572
|
+
}],
|
|
17573
|
+
});
|
|
17835
17574
|
|
|
17836
|
-
|
|
17837
|
-
{
|
|
17838
|
-
legend: true,
|
|
17839
|
-
// or:
|
|
17840
|
-
legend: { position: 'top' }, // 'top' | 'bottom' | 'left' | 'right'
|
|
17841
|
-
}
|
|
17575
|
+
chart.dispose();
|
|
17842
17576
|
```
|
|
17843
17577
|
|
|
17844
|
-
|
|
17578
|
+
## Scatter Charts
|
|
17845
17579
|
|
|
17846
|
-
|
|
17847
|
-
:root {
|
|
17848
|
-
--prism-legend-gap: 1rem;
|
|
17849
|
-
--prism-legend-dot-size: 0.5rem;
|
|
17850
|
-
--prism-legend-font-size: 0.75rem;
|
|
17851
|
-
}
|
|
17852
|
-
```
|
|
17580
|
+
Scatter charts treat every datum as an independent point: `key` is the numeric x-value and `value` is the y-value. The scales fit the observed values rather than forcing the y-domain to include zero. Set `pointRadius` on a series to change its marker size.
|
|
17853
17581
|
|
|
17854
|
-
|
|
17582
|
+
```ts
|
|
17583
|
+
import { createScatterChart } from '@vielzeug/prism';
|
|
17855
17584
|
|
|
17856
|
-
|
|
17585
|
+
const container = document.createElement('div');
|
|
17586
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17587
|
+
document.body.append(container);
|
|
17857
17588
|
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
series: [{
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
|
|
17864
|
-
},
|
|
17865
|
-
|
|
17866
|
-
console.log('clicked', event.datum);
|
|
17867
|
-
},
|
|
17589
|
+
const chart = createScatterChart(container, {
|
|
17590
|
+
a11y: { ariaLabel: 'Height against weight' },
|
|
17591
|
+
series: [{
|
|
17592
|
+
data: [{ key: 160, value: 55 }, { key: 175, value: 70 }, { key: 190, value: 88 }],
|
|
17593
|
+
name: 'Cohort A',
|
|
17594
|
+
pointRadius: 5,
|
|
17595
|
+
}],
|
|
17596
|
+
tooltip: true,
|
|
17868
17597
|
});
|
|
17869
|
-
```
|
|
17870
17598
|
|
|
17871
|
-
|
|
17599
|
+
chart.dispose();
|
|
17600
|
+
```
|
|
17872
17601
|
|
|
17873
|
-
- `
|
|
17874
|
-
- `series`: the corresponding `Series` config
|
|
17875
|
-
- `values`: every series at the same key (line, area, and bar charts)
|
|
17876
|
-
- `originalEvent`: the raw `MouseEvent` or, for keyboard navigation, `KeyboardEvent`
|
|
17602
|
+
Scatter callbacks identify one nearest point and do not provide cross-series `values`, because points do not share a category key.
|
|
17877
17603
|
|
|
17878
|
-
|
|
17604
|
+
## Forecast and Emphasis Styling
|
|
17879
17605
|
|
|
17880
|
-
|
|
17606
|
+
Add `dash` or `opacity` to individual `Datum` objects when one part of a series needs distinct styling. These fields do not change interaction, tooltip, or accessibility behavior.
|
|
17881
17607
|
|
|
17882
|
-
|
|
17883
|
-
|
|
17884
|
-
radar polygons reshape, and sparklines tween. Motion runs through one
|
|
17885
|
-
`requestAnimationFrame` loop and is skipped when the user prefers reduced motion
|
|
17886
|
-
(`preference: 'system'`, the default).
|
|
17608
|
+
```ts
|
|
17609
|
+
import { createLineChart } from '@vielzeug/prism';
|
|
17887
17610
|
|
|
17888
|
-
|
|
17611
|
+
const container = document.createElement('div');
|
|
17612
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17613
|
+
document.body.append(container);
|
|
17889
17614
|
|
|
17890
|
-
|
|
17891
|
-
{
|
|
17892
|
-
|
|
17893
|
-
|
|
17894
|
-
|
|
17895
|
-
|
|
17896
|
-
|
|
17897
|
-
}
|
|
17898
|
-
|
|
17615
|
+
const values = [10, 13, 15, 18];
|
|
17616
|
+
const chart = createLineChart(container, {
|
|
17617
|
+
series: [{
|
|
17618
|
+
data: values.map((value, index) => ({
|
|
17619
|
+
key: index + 1,
|
|
17620
|
+
value,
|
|
17621
|
+
...(index >= 2 ? { dash: '5 5', opacity: 0.4 } : {}),
|
|
17622
|
+
})),
|
|
17623
|
+
name: 'Forecast',
|
|
17624
|
+
showPoints: true,
|
|
17625
|
+
}],
|
|
17626
|
+
});
|
|
17899
17627
|
|
|
17900
|
-
|
|
17901
|
-
{ transition: false } // every update renders synchronously
|
|
17902
|
-
{ transition: true } // the defaults, stated explicitly
|
|
17628
|
+
chart.dispose();
|
|
17903
17629
|
```
|
|
17904
17630
|
|
|
17905
|
-
|
|
17906
|
-
`'expo-out'` (a hard decelerate), and `'back-out'` (a small overshoot); pass a
|
|
17907
|
-
`(t: number) => number` for anything else. `stagger` applies to bar-chart bars
|
|
17908
|
-
and radar-chart series and is ignored elsewhere — bar charts cap the total
|
|
17909
|
-
staggered delay near 400 ms so a long category axis still finishes promptly.
|
|
17631
|
+
For line and area charts, each datum's `dash` styles the segment from that datum to the next; the final datum has no outgoing segment. Line opacity also fades the datum's marker. Area styling affects the top line, not the fill. Bar opacity and dashes apply to the individual bar; scatter opacity applies to its point and scatter dashes are ignored. Pie, radar, and sparkline ignore these two fields.
|
|
17910
17632
|
|
|
17911
|
-
##
|
|
17633
|
+
## Pie, Donut, and Semi Charts
|
|
17912
17634
|
|
|
17913
|
-
|
|
17635
|
+
Use `createPieChart()` for all three shapes. `variant` is fixed when the chart is created; `update()` replaces the slice data.
|
|
17914
17636
|
|
|
17915
17637
|
```ts
|
|
17916
|
-
import '@vielzeug/prism
|
|
17917
|
-
```
|
|
17918
|
-
|
|
17919
|
-
### Programmatic Theme with `setTheme`
|
|
17920
|
-
|
|
17921
|
-
Call `setTheme` once at app startup to apply custom tokens programmatically:
|
|
17638
|
+
import { createPieChart } from '@vielzeug/prism';
|
|
17922
17639
|
|
|
17923
|
-
|
|
17924
|
-
|
|
17640
|
+
const container = document.createElement('div');
|
|
17641
|
+
container.style.cssText = 'width:320px;height:240px';
|
|
17642
|
+
document.body.append(container);
|
|
17925
17643
|
|
|
17926
|
-
|
|
17927
|
-
|
|
17928
|
-
|
|
17929
|
-
|
|
17930
|
-
|
|
17931
|
-
|
|
17932
|
-
|
|
17933
|
-
|
|
17644
|
+
const chart = createPieChart(container, {
|
|
17645
|
+
a11y: { ariaLabel: 'Orders by channel' },
|
|
17646
|
+
data: [
|
|
17647
|
+
{ label: 'Direct', value: 42 },
|
|
17648
|
+
{ label: 'Organic', value: 28 },
|
|
17649
|
+
{ label: 'Referral', value: 18 },
|
|
17650
|
+
{ label: 'Social', value: 12 },
|
|
17651
|
+
],
|
|
17652
|
+
legend: true,
|
|
17653
|
+
tooltip: true,
|
|
17654
|
+
variant: 'donut',
|
|
17934
17655
|
});
|
|
17656
|
+
|
|
17657
|
+
chart.dispose();
|
|
17935
17658
|
```
|
|
17936
17659
|
|
|
17937
|
-
`
|
|
17660
|
+
The `pie` default has no inner radius. `donut` and `semi` default to an inner radius of 55% of the outer radius. `innerRadius` overrides that size in pixels. Slice labels are omitted when they do not fit; keep a tooltip or legend when small slices need identifying.
|
|
17938
17661
|
|
|
17939
|
-
|
|
17940
|
-
import { resetTheme } from '@vielzeug/prism';
|
|
17662
|
+
## Radar Charts
|
|
17941
17663
|
|
|
17942
|
-
|
|
17943
|
-
```
|
|
17664
|
+
Define at least three axes when creating a radar chart. Series data uses string keys that match `RadarAxisConfig.key`; `update()` replaces series but keeps axes and other configuration fixed.
|
|
17944
17665
|
|
|
17945
|
-
|
|
17666
|
+
```ts
|
|
17667
|
+
import { createRadarChart } from '@vielzeug/prism';
|
|
17946
17668
|
|
|
17947
|
-
|
|
17669
|
+
const container = document.createElement('div');
|
|
17670
|
+
container.style.cssText = 'width:400px;height:320px';
|
|
17671
|
+
document.body.append(container);
|
|
17948
17672
|
|
|
17949
|
-
|
|
17950
|
-
|
|
17951
|
-
|
|
17952
|
-
|
|
17953
|
-
|
|
17673
|
+
const axes = [
|
|
17674
|
+
{ key: 'strength', label: 'Strength' },
|
|
17675
|
+
{ key: 'agility', label: 'Agility' },
|
|
17676
|
+
{ key: 'endurance', label: 'Endurance' },
|
|
17677
|
+
];
|
|
17678
|
+
const chart = createRadarChart(container, {
|
|
17679
|
+
a11y: { ariaLabel: 'Hero stats' },
|
|
17680
|
+
axes,
|
|
17681
|
+
domain: [0, 10],
|
|
17682
|
+
series: [{
|
|
17683
|
+
data: [{ key: 'strength', value: 8 }, { key: 'agility', value: 6 }, { key: 'endurance', value: 9 }],
|
|
17684
|
+
name: 'Adam',
|
|
17685
|
+
}],
|
|
17686
|
+
tooltip: true,
|
|
17687
|
+
});
|
|
17954
17688
|
|
|
17955
|
-
|
|
17956
|
-
|
|
17957
|
-
const containerRef = useRef(null);
|
|
17689
|
+
chart.dispose();
|
|
17690
|
+
```
|
|
17958
17691
|
|
|
17959
|
-
|
|
17960
|
-
const scope = containerRef.current;
|
|
17692
|
+
The default shared domain starts at zero and uses a nice maximum; set `domain` to compare series on a fixed range. Per-axis `min` and `max` override the chart domain for that axis. Grid rings, bands, curves, fills, vertex dots, and values are configurable; see `RadarChartConfig` and `RadarGridConfig` in the API reference.
|
|
17961
17693
|
|
|
17962
|
-
|
|
17694
|
+
## Sparklines
|
|
17963
17695
|
|
|
17964
|
-
|
|
17965
|
-
setTheme(
|
|
17966
|
-
{ axisColor: theme.palette.divider, textColor: theme.palette.text.primary },
|
|
17967
|
-
{ scope },
|
|
17968
|
-
);
|
|
17696
|
+
Sparklines omit axes, margins, and legends. Choose `line`, `area`, or `bar` for numeric arrays, and `stack` for an array of `StackSegment` objects.
|
|
17969
17697
|
|
|
17970
|
-
|
|
17698
|
+
```ts
|
|
17699
|
+
import { createSparkline } from '@vielzeug/prism';
|
|
17971
17700
|
|
|
17972
|
-
|
|
17973
|
-
|
|
17974
|
-
|
|
17975
|
-
};
|
|
17976
|
-
}, [series, theme]);
|
|
17701
|
+
const container = document.createElement('div');
|
|
17702
|
+
container.style.cssText = 'width:240px;height:48px';
|
|
17703
|
+
document.body.append(container);
|
|
17977
17704
|
|
|
17978
|
-
|
|
17979
|
-
}
|
|
17705
|
+
const chart = createSparkline(container, {
|
|
17706
|
+
a11y: { ariaLabel: 'Weekly orders' },
|
|
17707
|
+
data: [10, 14, 12, 18, 22],
|
|
17708
|
+
variant: 'area',
|
|
17709
|
+
});
|
|
17710
|
+
|
|
17711
|
+
chart.update([10, 14, 12, 18, 22, 25]);
|
|
17712
|
+
chart.dispose();
|
|
17980
17713
|
```
|
|
17981
17714
|
|
|
17982
|
-
|
|
17715
|
+
For a stacked sparkline, each segment can set `value`, `color`, and `label`. Sparklines do not offer keyboard navigation, a tooltip, or a live value announcer. Add a visible value or summary when the trend conveys important information.
|
|
17983
17716
|
|
|
17984
|
-
|
|
17717
|
+
## Interaction
|
|
17985
17718
|
|
|
17986
|
-
|
|
17987
|
-
:root {
|
|
17988
|
-
--prism-color-1: #6366f1;
|
|
17989
|
-
--prism-color-2: #22c55e;
|
|
17990
|
-
--prism-axis-color: #71717a;
|
|
17991
|
-
--prism-grid-color: #f4f4f5;
|
|
17992
|
-
--prism-text-color: #18181b;
|
|
17993
|
-
--prism-tooltip-bg: #27272a;
|
|
17994
|
-
--prism-font-family: 'Inter', system-ui, sans-serif;
|
|
17995
|
-
}
|
|
17996
|
-
```
|
|
17719
|
+
Set `tooltip: true` to show Prism's default tooltip, or pass a `TooltipConfig` to format its content. A `render` callback receives the active `Datum` and `Series`. Returned strings are inserted as text; return a DOM `Node` for structured content.
|
|
17997
17720
|
|
|
17998
|
-
|
|
17721
|
+
```ts
|
|
17722
|
+
import { createLineChart } from '@vielzeug/prism';
|
|
17999
17723
|
|
|
18000
|
-
|
|
17724
|
+
const container = document.createElement('div');
|
|
17725
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17726
|
+
document.body.append(container);
|
|
18001
17727
|
|
|
18002
|
-
|
|
18003
|
-
|
|
18004
|
-
|
|
18005
|
-
|
|
18006
|
-
|
|
18007
|
-
}
|
|
18008
|
-
```
|
|
17728
|
+
const chart = createLineChart(container, {
|
|
17729
|
+
series: [{ data: [{ key: 1, value: 4200 }, { key: 2, value: 5100 }], name: 'Revenue' }],
|
|
17730
|
+
tooltip: {
|
|
17731
|
+
render: (datum, series) => `${series.name}: ${new Intl.NumberFormat().format(datum.value)}`,
|
|
17732
|
+
},
|
|
17733
|
+
});
|
|
18009
17734
|
|
|
18010
|
-
|
|
17735
|
+
chart.dispose();
|
|
17736
|
+
```
|
|
18011
17737
|
|
|
18012
|
-
|
|
18013
|
-
| ------------------------- | -------------------------- | ---------------------- |
|
|
18014
|
-
| `--prism-color-{1-8}` | Colorblind-safe palette | Series color palette |
|
|
18015
|
-
| `--prism-bg` | `transparent` | Chart background |
|
|
18016
|
-
| `--prism-axis-color` | `hsl(215deg 16% 47%)` | Axis lines and ticks |
|
|
18017
|
-
| `--prism-grid-color` | `hsl(220deg 10% 75%)` | Grid lines |
|
|
18018
|
-
| `--prism-text-color` | `hsl(215deg 25% 27%)` | Axis labels and text |
|
|
18019
|
-
| `--prism-font-family` | `system-ui` | Chart font |
|
|
18020
|
-
| `--prism-font-size` | `0.75rem` | Label font size |
|
|
18021
|
-
| `--prism-tooltip-bg` | `hsl(222deg 47% 11%)` | Tooltip background |
|
|
18022
|
-
| `--prism-tooltip-color` | `hsl(210deg 40% 98%)` | Tooltip text |
|
|
18023
|
-
| `--prism-tooltip-radius` | `0.375rem` | Tooltip border radius |
|
|
18024
|
-
| `--prism-crosshair-color` | `hsl(215deg 16% 47%)` | Crosshair line |
|
|
18025
|
-
| `--prism-crosshair-dash` | `4 2` | Crosshair dash pattern |
|
|
18026
|
-
|
|
18027
|
-
The palette follows Wong (2011) so adjacent series stay distinguishable under common color-vision deficiencies. Dark mode applies through `prefers-color-scheme`, an `html.dark` class, or `data-prism-theme="dark"` on the chart container or any ancestor — the last is the hook for apps that switch theme in JS without owning ``.
|
|
18028
|
-
|
|
18029
|
-
Radar charts add their own tokens, each defaulting to a shared one:
|
|
18030
|
-
|
|
18031
|
-
| Token | Default | Description |
|
|
18032
|
-
| --- | --- | --- |
|
|
18033
|
-
| `--prism-radar-grid-color` | `--prism-grid-color` | Rings |
|
|
18034
|
-
| `--prism-radar-grid-opacity` | `0.7` | Ring and spoke opacity |
|
|
18035
|
-
| `--prism-radar-band-fill` | `--prism-grid-color` | Alternate ring shading |
|
|
18036
|
-
| `--prism-radar-band-opacity` | `0.14` | Shading opacity |
|
|
18037
|
-
| `--prism-radar-spoke-color` | `--prism-radar-grid-color` | Spokes |
|
|
18038
|
-
| `--prism-radar-fill-opacity` | `--prism-area-opacity` | Solid shape fill |
|
|
18039
|
-
| `--prism-radar-stroke-width` | `--prism-line-width` | Shape outline |
|
|
18040
|
-
| `--prism-radar-point-radius` | `--prism-point-radius` | Vertex dots |
|
|
18041
|
-
| `--prism-radar-point-radius-active` | `--prism-point-radius-hover` | Dots on the active axis |
|
|
18042
|
-
| `--prism-radar-label-color` / `-size` | Secondary text tokens | Axis labels |
|
|
18043
|
-
| `--prism-radar-value-color` / `-size` | Text tokens | Vertex values |
|
|
18044
|
-
| `--prism-radar-dim-opacity` | `--prism-dim-opacity` | Other shapes while one is hovered |
|
|
18045
|
-
|
|
18046
|
-
Shared interaction and chart tokens:
|
|
18047
|
-
|
|
18048
|
-
| Token | Default | Description |
|
|
18049
|
-
| --- | --- | --- |
|
|
18050
|
-
| `--prism-dim-opacity` | `0.35` | Series or slices outside the active one |
|
|
18051
|
-
| `--prism-active-point-radius` | `--prism-point-radius-hover` | Points marked at the active key |
|
|
18052
|
-
| `--prism-point-ring` | `Canvas` | Ring separating active and end points from the line |
|
|
18053
|
-
| `--prism-focus-color` | `--prism-color-1` | Focus outline of a keyboard-focused chart |
|
|
18054
|
-
| `--prism-bar-radius` | `4px` | Bar corner radius (stacked bars stay square) |
|
|
18055
|
-
| `--prism-bar-band-fill` / `-opacity` | Grid colour / `0.18` | Shaded active category |
|
|
18056
|
-
| `--prism-bar-dim-opacity` | `0.55` | Bars outside the active category |
|
|
18057
|
-
| `--prism-area-gradient-start` / `-end` | `0.45` / `0.02` | Gradient fill opacity at the line and the baseline |
|
|
18058
|
-
| `--prism-spark-gradient-start` / `-end` | `0.35` / `0` | Sparkline gradient fill |
|
|
17738
|
+
`onHover` receives an event while a point, category, slice, or radar axis is active, then `null` when the interaction clears. `onClick` receives the selected event. For line, area, and bar charts, `ChartEvent.values` contains each series' datum at that shared key; a missing datum is `undefined`. Scatter, pie, radar, and sparkline use their chart-specific event types.
|
|
18059
17739
|
|
|
18060
|
-
|
|
17740
|
+
`crosshair` is available on line, area, and scatter charts. By default it shows a vertical guide and snaps the line to the nearest datum. Set `horizontal: true` to add a horizontal guide or `vertical: false` to hide the vertical one. Set `snap: false` to make the guide follow the pointer; tooltip and callback data still come from the nearest datum.
|
|
18061
17741
|
|
|
18062
|
-
|
|
17742
|
+
### Keyboard and Announcements
|
|
18063
17743
|
|
|
18064
|
-
|
|
17744
|
+
Set `a11y: { ariaLabel }` on an informative chart. Prism gives the SVG `role="img"`, an accessible name, and keyboard focus. Arrow keys move among chart data; `Home` and `End` move to the first and last item where supported; `Enter` or `Space` activates an item when an `onClick` callback is configured; `Escape` clears the active selection. Sparklines do not support keyboard navigation.
|
|
18065
17745
|
|
|
18066
|
-
|
|
18067
|
-
import { linearScale, timeScale, bandScale } from '@vielzeug/prism';
|
|
17746
|
+
When `a11y` is omitted, or set to `{ decorative: true }`, the SVG is marked `aria-hidden="true"` and does not enter the keyboard tab order. Only mark charts decorative when their information is available elsewhere. Interactive cartesian and pie/radar charts use the tooltip as a polite live region when enabled; otherwise they announce active values in `.prism-live`. Sparklines have no live value announcements, so provide an equivalent visible value or summary.
|
|
18068
17747
|
|
|
18069
|
-
|
|
18070
|
-
y.map(50); // → 150
|
|
18071
|
-
y.invert(150); // → 50
|
|
18072
|
-
y.ticks(5); // → [0, 20, 40, 60, 80, 100]
|
|
17748
|
+
## Animation
|
|
18073
17749
|
|
|
18074
|
-
|
|
18075
|
-
x.map('B'); // → pixel left edge of band B
|
|
18076
|
-
x.bandwidth(); // → width of each band
|
|
18077
|
-
```
|
|
17750
|
+
Chart motion is enabled by default, with a 300 ms duration per animated lane (radar uses 400 ms). Pass `transition: false` to render updates synchronously, or pass `true` to state the default explicitly.
|
|
18078
17751
|
|
|
18079
|
-
|
|
17752
|
+
```ts
|
|
17753
|
+
import { createBarChart } from '@vielzeug/prism';
|
|
18080
17754
|
|
|
18081
|
-
|
|
17755
|
+
const container = document.createElement('div');
|
|
17756
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17757
|
+
document.body.append(container);
|
|
18082
17758
|
|
|
18083
|
-
|
|
18084
|
-
|
|
17759
|
+
const chart = createBarChart(container, {
|
|
17760
|
+
series: [{ data: [{ key: 'A', value: 4 }, { key: 'B', value: 7 }], name: 'Count' }],
|
|
17761
|
+
transition: { duration: 500, easing: 'ease-out', preference: 'system' },
|
|
17762
|
+
});
|
|
18085
17763
|
|
|
18086
|
-
// When done:
|
|
18087
17764
|
chart.dispose();
|
|
18088
|
-
|
|
18089
|
-
// Or with TC39 explicit resource management:
|
|
18090
|
-
{
|
|
18091
|
-
using chart = createLineChart(container, config);
|
|
18092
|
-
// auto-disposed at block end
|
|
18093
|
-
}
|
|
18094
17765
|
```
|
|
18095
17766
|
|
|
18096
|
-
|
|
18097
|
-
|
|
18098
|
-
- Cancels in-flight transitions
|
|
18099
|
-
- Disconnects the `ResizeObserver`
|
|
18100
|
-
- Removes the SVG element, tooltip, and legend from the DOM
|
|
18101
|
-
- Restores container styles changed for tooltip positioning
|
|
18102
|
-
- Is idempotent: safe to call multiple times
|
|
17767
|
+
Columns grow together from their baseline by default over 300 ms. Lines trace their final curve over 420 ms, uncovering point markers along the way without fading or shifting the series. Line data updates retain the default 300 ms geometry transition; an explicit `duration` overrides both timings.
|
|
18103
17768
|
|
|
18104
|
-
|
|
17769
|
+
`preference: 'system'` (the default) disables JavaScript motion when the user prefers reduced motion. Use `'always'` to ignore that preference or `'never'` to disable motion. `stagger` sets an optional delay between bars or radar series; bar charts cap the effective delay so long category axes do not add unbounded time. Named easing values are `ease-in`, `ease-in-out`, `ease-out`, `back-out`, `expo-out`, and `linear`; you can also provide an easing function.
|
|
18105
17770
|
|
|
18106
|
-
## Responsive
|
|
17771
|
+
## Responsive Layout and Lifecycle
|
|
18107
17772
|
|
|
18108
|
-
|
|
17773
|
+
Size the host with CSS. Prism observes its content box and updates the SVG dimensions and chart layout when it changes. Bar and line resize redraws apply immediately rather than animating between layout sizes; entrance animations and explicit data-update transitions remain enabled. The legend is rendered as container chrome outside the SVG and included in resize calculations.
|
|
18109
17774
|
|
|
18110
|
-
|
|
17775
|
+
Call `dispose()` when the view no longer owns the chart. Disposal is idempotent: it removes the SVG, tooltip, legend, and resize observation, stops in-flight chart motion, and aborts `disposalSignal`. `chart[Symbol.dispose]()` calls the same cleanup method.
|
|
18111
17776
|
|
|
18112
|
-
|
|
17777
|
+
Use `tap()` when external code needs resize or dispose notifications rather than observing the chart DOM itself:
|
|
18113
17778
|
|
|
18114
17779
|
```ts
|
|
18115
17780
|
import { createLineChart } from '@vielzeug/prism';
|
|
18116
17781
|
|
|
17782
|
+
const container = document.createElement('div');
|
|
17783
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17784
|
+
document.body.append(container);
|
|
17785
|
+
|
|
18117
17786
|
const chart = createLineChart(container, {
|
|
18118
17787
|
series: [{ data: [{ key: 1, value: 10 }], name: 'Revenue' }],
|
|
18119
17788
|
});
|
|
18120
|
-
const
|
|
18121
|
-
|
|
18122
|
-
(event)
|
|
18123
|
-
|
|
18124
|
-
|
|
18125
|
-
|
|
18126
|
-
|
|
18127
|
-
);
|
|
17789
|
+
const stopObserving = chart.tap((event) => {
|
|
17790
|
+
if (event.type === 'resize') console.log(event.width, event.height);
|
|
17791
|
+
if (event.type === 'dispose') console.log('chart disposed');
|
|
17792
|
+
});
|
|
17793
|
+
|
|
17794
|
+
stopObserving();
|
|
17795
|
+
chart.dispose();
|
|
18128
17796
|
```
|
|
18129
17797
|
|
|
18130
|
-
`tap()` returns an unsubscribe function
|
|
17798
|
+
`tap()` returns an unsubscribe function and accepts `{ signal }` for automatic unsubscription. A listener exception is swallowed by the observer so it cannot interrupt chart rendering.
|
|
18131
17799
|
|
|
18132
|
-
##
|
|
17800
|
+
## Theming
|
|
18133
17801
|
|
|
18134
|
-
|
|
17802
|
+
Import the stylesheet once to load Prism's structural styles, default tokens, dark-mode rules, and reduced-motion CSS. You can override any CSS custom property on an ancestor of the chart.
|
|
18135
17803
|
|
|
18136
|
-
```
|
|
18137
|
-
|
|
18138
|
-
|
|
18139
|
-
|
|
18140
|
-
|
|
17804
|
+
```css
|
|
17805
|
+
.dashboard-chart {
|
|
17806
|
+
--prism-color-1: #2563eb;
|
|
17807
|
+
--prism-color-2: #16a34a;
|
|
17808
|
+
--prism-grid-color: #94a3b8;
|
|
17809
|
+
--prism-line-width: 3;
|
|
17810
|
+
--prism-text-color: #172033;
|
|
17811
|
+
--prism-tooltip-bg: #111827;
|
|
17812
|
+
}
|
|
18141
17813
|
```
|
|
18142
17814
|
|
|
18143
|
-
|
|
17815
|
+
`setTheme()` provides a typed subset of theme properties. A scoped call writes inline values on the provided element; omit `scope` to write them to `document.documentElement`. Inline values override stylesheet tokens until reset.
|
|
18144
17816
|
|
|
18145
17817
|
```ts
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
17818
|
+
import { resetTheme, setTheme } from '@vielzeug/prism';
|
|
17819
|
+
|
|
17820
|
+
const container = document.createElement('div');
|
|
17821
|
+
container.style.cssText = 'width:640px;height:320px';
|
|
17822
|
+
document.body.append(container);
|
|
17823
|
+
|
|
17824
|
+
setTheme({ colors: ['#2563eb', '#16a34a'], fontFamily: 'Inter, sans-serif' }, { scope: container });
|
|
17825
|
+
// Call resetTheme({ scope: container }) when this scoped theme is no longer needed.
|
|
17826
|
+
resetTheme({ scope: container });
|
|
18150
17827
|
```
|
|
18151
17828
|
|
|
18152
|
-
###
|
|
17829
|
+
### Available Tokens
|
|
18153
17830
|
|
|
18154
|
-
|
|
17831
|
+
The stylesheet defines defaults for the following token groups. Pie-label color and size are read with fallback values by the renderer but are not declared in the base token block. Set a token on the chart container or an ancestor to scope an override.
|
|
18155
17832
|
|
|
18156
|
-
|
|
|
18157
|
-
| --- | --- |
|
|
18158
|
-
|
|
|
18159
|
-
|
|
|
18160
|
-
|
|
|
18161
|
-
|
|
|
17833
|
+
| Group | CSS custom properties |
|
|
17834
|
+
| --- | --- |
|
|
17835
|
+
| Palette and surfaces | `--prism-color-1` through `--prism-color-8`, `--prism-bg`, `--prism-border-radius` |
|
|
17836
|
+
| Axes and grid | `--prism-axis-color`, `--prism-axis-width`, `--prism-grid-color`, `--prism-grid-width`, `--prism-grid-dash`, `--prism-grid-opacity` |
|
|
17837
|
+
| Text | `--prism-font-family`, `--prism-font-size`, `--prism-font-size-label`, `--prism-font-size-title`, `--prism-font-weight`, `--prism-font-weight-title`, `--prism-text-color`, `--prism-text-color-secondary` |
|
|
17838
|
+
| Tooltip | `--prism-tooltip-bg`, `--prism-tooltip-color`, `--prism-tooltip-border`, `--prism-tooltip-radius`, `--prism-tooltip-padding`, `--prism-tooltip-shadow`, `--prism-tooltip-font-size` |
|
|
17839
|
+
| Crosshair | `--prism-crosshair-color`, `--prism-crosshair-width`, `--prism-crosshair-dash`, `--prism-crosshair-opacity` |
|
|
17840
|
+
| Points | `--prism-point-radius`, `--prism-point-radius-hover`, `--prism-point-stroke-width`, `--prism-point-stroke` |
|
|
17841
|
+
| Bars | `--prism-bar-radius`, `--prism-bar-hover-opacity`, `--prism-bar-gap`, `--prism-bar-band-fill`, `--prism-bar-band-opacity`, `--prism-bar-dim-opacity` |
|
|
17842
|
+
| Areas and lines | `--prism-area-opacity`, `--prism-area-stroke-width`, `--prism-area-gradient-start`, `--prism-area-gradient-end`, `--prism-line-width`, `--prism-line-width-hover` |
|
|
17843
|
+
| Interaction | `--prism-dim-opacity`, `--prism-active-point-radius`, `--prism-point-ring`, `--prism-focus-color` |
|
|
17844
|
+
| Sparklines | `--prism-spark-fill-opacity`, `--prism-spark-gradient-start`, `--prism-spark-gradient-end` |
|
|
17845
|
+
| Radar | `--prism-radar-grid-color`, `--prism-radar-grid-opacity`, `--prism-radar-band-fill`, `--prism-radar-band-opacity`, `--prism-radar-spoke-color`, `--prism-radar-fill-opacity`, `--prism-radar-stroke-width`, `--prism-radar-point-radius`, `--prism-radar-point-radius-active`, `--prism-radar-label-color`, `--prism-radar-label-size`, `--prism-radar-value-color`, `--prism-radar-value-size`, `--prism-radar-dim-opacity` |
|
|
17846
|
+
| Motion | `--prism-duration-fast`, `--prism-duration`, `--prism-duration-slow`, `--prism-ease`, `--prism-ease-spring`, `--prism-transition`, `--prism-transition-fast` |
|
|
17847
|
+
| Legend and pie labels | `--prism-legend-gap`, `--prism-legend-dot-size`, `--prism-legend-font-size`, `--prism-pie-label-color`, `--prism-pie-label-size` |
|
|
17848
|
+
|
|
17849
|
+
The default palette and structural colors adapt to `prefers-color-scheme: dark`, `html.dark`, or `[data-prism-theme='dark']` on an ancestor. Scoped inline values set with `setTheme()` take precedence in either mode. The stylesheet also provides `prefers-reduced-motion` overrides for CSS transitions.
|
|
18162
17850
|
|
|
18163
|
-
|
|
17851
|
+
## Errors and Diagnostics
|
|
18164
17852
|
|
|
18165
|
-
|
|
17853
|
+
Prism throws `PrismRenderError` when the container is not a DOM element, when initial rendering fails, or when `update()` is called on a disposed chart. A wrapped initial-render error exposes its cause. Use `PrismError` to catch all Prism-originated errors.
|
|
18166
17854
|
|
|
18167
|
-
|
|
17855
|
+
Empty or malformed data is not always an exception. Depending on the chart, Prism may draw nothing or emit a development-only `console.warn`; examples include an unknown `bandScale` category, negative values in stacked bars, and radar axes with fewer than three entries or duplicate keys. Correct the input rather than relying on a warning for validation.
|
|
18168
17856
|
|
|
18169
17857
|
## Framework Integration
|
|
18170
17858
|
|
|
18171
|
-
Prism has no
|
|
17859
|
+
Prism has no React, Vue, or Svelte adapter. In any framework, give Prism a host element after it is mounted, call `update()` when data changes, and call `dispose()` before the host is removed. This plain DOM pattern shows the ownership boundary without depending on a framework-specific lifecycle API:
|
|
18172
17860
|
|
|
18173
17861
|
```ts
|
|
18174
|
-
import { createLineChart, type
|
|
18175
|
-
|
|
18176
|
-
let chart: ChartHandle | undefined;
|
|
18177
|
-
|
|
18178
|
-
export function mountChart(container: HTMLElement, data: ContinuousDatum[]): void {
|
|
18179
|
-
chart = createLineChart(container, { series: [{ data, name: 'Series' }] });
|
|
18180
|
-
}
|
|
17862
|
+
import { createLineChart, type LineSeriesConfig } from '@vielzeug/prism';
|
|
18181
17863
|
|
|
18182
|
-
|
|
18183
|
-
chart
|
|
18184
|
-
}
|
|
17864
|
+
function mountChart(host: HTMLElement, series: LineSeriesConfig[]) {
|
|
17865
|
+
const chart = createLineChart(host, { a11y: { ariaLabel: 'Revenue' }, series });
|
|
18185
17866
|
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
|
|
17867
|
+
return {
|
|
17868
|
+
update(next: LineSeriesConfig[]) {
|
|
17869
|
+
chart.update(next);
|
|
17870
|
+
},
|
|
17871
|
+
dispose() {
|
|
17872
|
+
chart.dispose();
|
|
17873
|
+
},
|
|
17874
|
+
};
|
|
18189
17875
|
}
|
|
18190
|
-
```
|
|
18191
|
-
|
|
18192
|
-
## Working with Other Vielzeug Libraries
|
|
18193
|
-
|
|
18194
|
-
### With Ripple
|
|
18195
17876
|
|
|
18196
|
-
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
const data = signal([{ key: 1, value: 10 }]);
|
|
18203
|
-
const toSeries = () => [{ data: data.value, name: 'Series' }];
|
|
18204
|
-
const chart = createLineChart(container, { series: toSeries() });
|
|
18205
|
-
const unsubscribe = data.subscribe(() => chart.update(toSeries()));
|
|
18206
|
-
|
|
18207
|
-
// Cleanup both owners together.
|
|
18208
|
-
unsubscribe();
|
|
18209
|
-
chart.dispose();
|
|
17877
|
+
const host = document.createElement('div');
|
|
17878
|
+
host.style.cssText = 'width:640px;height:320px';
|
|
17879
|
+
document.body.append(host);
|
|
17880
|
+
const view = mountChart(host, [{ data: [{ key: 1, value: 10 }], name: 'Revenue' }]);
|
|
17881
|
+
view.update([{ data: [{ key: 1, value: 10 }, { key: 2, value: 15 }], name: 'Revenue' }]);
|
|
17882
|
+
view.dispose();
|
|
18210
17883
|
```
|
|
18211
17884
|
|
|
18212
|
-
|
|
18213
|
-
|
|
18214
|
-
Bind chart data to a Sourcerer remote source so charts update whenever the list refreshes.
|
|
17885
|
+
The application owns its state and host; Prism owns only the SVG, observer, and optional overlay elements it creates.
|
|
18215
17886
|
|
|
18216
|
-
|
|
18217
|
-
import { createBarChart } from '@vielzeug/prism';
|
|
18218
|
-
import { createPageSource } from '@vielzeug/sourcerer';
|
|
17887
|
+
## Working with Other Vielzeug Libraries
|
|
18219
17888
|
|
|
18220
|
-
|
|
18221
|
-
load: async ({ page, pageSize, signal }) => {
|
|
18222
|
-
const result = await api.stats.list({ page, pageSize }, { signal });
|
|
18223
|
-
return { items: result.data, totalItems: result.total };
|
|
18224
|
-
},
|
|
18225
|
-
});
|
|
18226
|
-
const toSeries = (state) => [
|
|
18227
|
-
{
|
|
18228
|
-
data: state.items.map((item) => ({ key: item.label, value: item.count })),
|
|
18229
|
-
name: 'Series',
|
|
18230
|
-
},
|
|
18231
|
-
];
|
|
18232
|
-
const chart = createBarChart(container, { series: toSeries(source.state) });
|
|
18233
|
-
const unsubscribe = source.subscribe((state) => chart.update(toSeries(state)));
|
|
18234
|
-
void source.reload().catch(() => undefined);
|
|
18235
|
-
```
|
|
17889
|
+
Use Refine components for dashboard controls and keep Prism in a sized host element. Map Refine theme tokens to Prism CSS custom properties or call `setTheme()` with a scoped element; Prism does not require a Refine adapter. Prism uses Orbit internally to place tooltips, so chart users do not need to create Orbit floating elements for the built-in tooltip.
|
|
18236
17890
|
|
|
18237
17891
|
## Best Practices
|
|
18238
17892
|
|
|
18239
|
-
-
|
|
18240
|
-
-
|
|
18241
|
-
-
|
|
18242
|
-
-
|
|
18243
|
-
-
|
|
18244
|
-
-
|
|
17893
|
+
- Give the host a non-zero size before creating a chart.
|
|
17894
|
+
- Set `a11y.ariaLabel` when a chart communicates information.
|
|
17895
|
+
- Use `Date` or number keys consistently across each line or area chart.
|
|
17896
|
+
- Pass the complete new data value to `update()`.
|
|
17897
|
+
- Keep chart options fixed after creation; recreate the chart to change them.
|
|
17898
|
+
- Dispose the handle when its host leaves the owning view.
|
|
17899
|
+
- Use `transition: false` for deterministic synchronous rendering.
|
|
17900
|
+
- Prefer CSS custom properties for reusable theme overrides.
|
|
18245
17901
|
|
|
18246
17902
|
### Examples
|
|
18247
17903
|
|
|
18248
17904
|
- [Create a line chart](./examples/line-chart.md)
|
|
18249
17905
|
- [Plot a time series](./examples/time-series.md)
|
|
17906
|
+
- [Plot a scatter chart](./examples/scatter-chart.md)
|
|
18250
17907
|
- [Compare categories with a bar chart](./examples/bar-chart.md)
|
|
18251
17908
|
- [Render compact charts](./examples/compact-charts.md)
|
|
18252
17909
|
- [Compare hero stats with a radar chart](./examples/radar-chart.md)
|