@zakkster/lite-charts 1.0.0 → 1.1.0
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/CHANGELOG.md +96 -0
- package/Charts.d.ts +249 -21
- package/Charts.js +1653 -482
- package/README.md +156 -102
- package/llms.txt +276 -126
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -15,21 +15,29 @@
|
|
|
15
15
|
> points at 60fps with sub-frame budget. Built on `@zakkster/lite-scene`
|
|
16
16
|
> (Canvas2D scene graph), `@zakkster/lite-signal` (reactive core), and
|
|
17
17
|
> `@zakkster/lite-axis` (tick generation). Three peer deps. ESM-only.
|
|
18
|
-
>
|
|
19
|
-
|
|
20
|
-
**Status
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
> ~1100 lines single file. MIT.
|
|
19
|
+
|
|
20
|
+
**Status: v1.1.0** — nine chart types across four independent kernels.
|
|
21
|
+
The headline addition is bar-chart layout polish (stacked bars, rounded
|
|
22
|
+
corners, per-bar hover tint, all opt-in). This release also lands several
|
|
23
|
+
features originally scoped for the v1.2.0 alpha train that proved stable
|
|
24
|
+
enough to ship together:
|
|
25
|
+
|
|
26
|
+
- **`createScatterChart`** — bubble's simpler sibling on the same axis
|
|
27
|
+
kernel; constant marker, no third dimension.
|
|
28
|
+
- **`createHeatmap`** on a new `createBaseGridChart` kernel (10.5 KB
|
|
29
|
+
minified, the smallest of the nine bundles). Two band scales, flat
|
|
30
|
+
`Float32Array` cell storage, `Uint8Array` presentMask for sparse data,
|
|
31
|
+
per-cell color strings precomputed at extract for zero-allocation
|
|
32
|
+
draws. Default linear-RGB ramp; `colorFn` for custom mappings.
|
|
33
|
+
- **Multi-series bubble** with per-point color via `colorKey` and a
|
|
34
|
+
global size domain across visible series.
|
|
35
|
+
- **Pluggable spatial-index** (`SpatialIndex` / `SpatialIndexFactory`)
|
|
36
|
+
for O(log n) hit-test on dense point clouds.
|
|
37
|
+
`@zakkster/lite-delaunay` is the intended default but optional.
|
|
38
|
+
|
|
39
|
+
**231/231 tests pass.** See [CHANGELOG.md](./CHANGELOG.md) for the full
|
|
40
|
+
release contract and [ROADMAP.md](./ROADMAP.md) for the forward plan.
|
|
33
41
|
|
|
34
42
|
## Install
|
|
35
43
|
|
|
@@ -78,7 +86,7 @@ explicit re-render needed.
|
|
|
78
86
|
| **Reactive data binding** | First-class signals | Imperative `.update()` | Imperative `.setData()` | Manual selection re-bind |
|
|
79
87
|
| **100k points** | 1.4 ms / 4.7 ms p95 (CPU) | Drops frames | OK | Hand-rolled |
|
|
80
88
|
| **Zero-GC steady state** | Yes (slab-based) | No | Mostly | No |
|
|
81
|
-
| **Bundle (min
|
|
89
|
+
| **Bundle (min+gz)** | ~6 KB (alpha est.) | 78 KB | 40 KB | 70+ KB |
|
|
82
90
|
| **Render substrate** | Canvas2D via lite-scene | Canvas2D | Canvas2D | SVG / Canvas |
|
|
83
91
|
| **API style** | Vega-Lite middle ground | Imperative config | Hand-tuned | Composable primitives |
|
|
84
92
|
| **Twitch Extension fit** | Yes (1MB / 3s budget) | No | Yes | No |
|
|
@@ -93,30 +101,30 @@ in a 1MB bundle without GC pauses.
|
|
|
93
101
|
|
|
94
102
|
```mermaid
|
|
95
103
|
graph TD
|
|
96
|
-
User[
|
|
104
|
+
User[User config + data signal] --> Constructor[createLineChart]
|
|
97
105
|
Constructor --> Normalize["Normalize: data shorthand -> series[]"]
|
|
98
|
-
Normalize --> Accessors[
|
|
99
|
-
Accessors --> InferType[
|
|
100
|
-
InferType --> StateAlloc[
|
|
101
|
-
|
|
102
|
-
StateAlloc --> Mount[
|
|
103
|
-
Mount --> Scene[
|
|
104
|
-
Scene --> Effect1[
|
|
105
|
-
Scene --> Effect2[
|
|
106
|
-
Scene --> Axes[
|
|
107
|
-
Scene --> SeriesNodes[
|
|
108
|
-
SeriesNodes --> DrawFn[
|
|
106
|
+
Normalize --> Accessors[Build accessors x/y]
|
|
107
|
+
Accessors --> InferType[Infer x-scale type]
|
|
108
|
+
InferType --> StateAlloc[Allocate SeriesState slabs]
|
|
109
|
+
|
|
110
|
+
StateAlloc --> Mount[mount(container)]
|
|
111
|
+
Mount --> Scene[createScene from lite-scene]
|
|
112
|
+
Scene --> Effect1[Effect: width/height -> plotBounds]
|
|
113
|
+
Scene --> Effect2[Effect: data -> SoA extract -> scale -> pixels]
|
|
114
|
+
Scene --> Axes[buildAxis x2 / lite-axis ticks]
|
|
115
|
+
Scene --> SeriesNodes[path nodes / one per series]
|
|
116
|
+
SeriesNodes --> DrawFn[makeLineDrawFn closure]
|
|
109
117
|
|
|
110
118
|
DrawFn --> PathSelect{"n > 2*cols?"}
|
|
111
119
|
PathSelect -->|yes| Decimate["decimateMinMax kernel<br/>lifted from lite-canvas-graph"]
|
|
112
|
-
PathSelect -->|no| Polyline[
|
|
113
|
-
Decimate --> Stroke[
|
|
120
|
+
PathSelect -->|no| Polyline[Direct polyline / NaN-aware]
|
|
121
|
+
Decimate --> Stroke[ctx.stroke]
|
|
114
122
|
Polyline --> Stroke
|
|
115
123
|
|
|
116
|
-
Signal[
|
|
117
|
-
LiteSignal --> EffectsRun[
|
|
118
|
-
EffectsRun --> DirtyBridge[
|
|
119
|
-
DirtyBridge --> SceneDraw[
|
|
124
|
+
Signal[Any signal write] --> LiteSignal[lite-signal sync flush]
|
|
125
|
+
LiteSignal --> EffectsRun[Effects re-run]
|
|
126
|
+
EffectsRun --> DirtyBridge[scaleVersion bump -> scene.markDirty]
|
|
127
|
+
DirtyBridge --> SceneDraw[lite-scene drawAll / coalesced via _queued]
|
|
120
128
|
SceneDraw --> DrawFn
|
|
121
129
|
```
|
|
122
130
|
|
|
@@ -217,7 +225,7 @@ const chart = createLineChart({ ..., schedule: (fn) => queueMicrotask(fn) });
|
|
|
217
225
|
|
|
218
226
|
## Tooltip + crosshair
|
|
219
227
|
|
|
220
|
-
On by default. The crosshair vertical line snaps to the
|
|
228
|
+
On by default in v1.0.0-alpha.1. The crosshair vertical line snaps to the
|
|
221
229
|
nearest sample on the primary series (binary search on sorted xs); markers
|
|
222
230
|
on each additional series snap independently at the same domain x. The
|
|
223
231
|
tooltip is canvas-drawn (no DOM overlay), so it remains headless-testable.
|
|
@@ -265,7 +273,7 @@ against the mock canvas (no event simulation needed). The mock canvas in
|
|
|
265
273
|
`test/harness.js` doesn't implement `addEventListener`, so the DOM listener
|
|
266
274
|
is skipped in headless contexts -- the programmatic API is the only way in.
|
|
267
275
|
|
|
268
|
-
## Area chart
|
|
276
|
+
## Area chart (v1.0.0-alpha.2)
|
|
269
277
|
|
|
270
278
|
`createAreaChart(config)` shares everything with `createLineChart` -- same
|
|
271
279
|
data shape, same accessors, same scales, same reactivity, same crosshair
|
|
@@ -295,7 +303,7 @@ for sparse data, decimated per-column for dense. The decimated path fills
|
|
|
295
303
|
to the column's upper envelope (max), matching d3-area's default behavior;
|
|
296
304
|
ribbon-style min-max area is a separate primitive in v1.1+.
|
|
297
305
|
|
|
298
|
-
## Legend
|
|
306
|
+
## Legend (v1.0.0-alpha.3)
|
|
299
307
|
|
|
300
308
|
Rendered as a DOM element (sibling of the canvas, inside an auto-created
|
|
301
309
|
flex wrapper), so it's keyboard-accessible (each row is a `<button>` with
|
|
@@ -354,10 +362,9 @@ const showOnly = (idx) => {
|
|
|
354
362
|
};
|
|
355
363
|
```
|
|
356
364
|
|
|
357
|
-
## Path interpolation
|
|
365
|
+
## Path interpolation (v1.0.0)
|
|
358
366
|
|
|
359
|
-
|
|
360
|
-
Default is `'linear'` (the polyline). Three step variants for
|
|
367
|
+
Seven modes. Default is `'linear'` (the polyline). Three step variants for
|
|
361
368
|
discrete data (telemetry, state machines, financial OHLC). Two smoothing
|
|
362
369
|
modes for continuous data.
|
|
363
370
|
|
|
@@ -394,7 +401,7 @@ the direct path.
|
|
|
394
401
|
renders independently). Smoothing modes assume contiguous data; if you need
|
|
395
402
|
gaps, use linear or step.
|
|
396
403
|
|
|
397
|
-
## Markers
|
|
404
|
+
## Markers (v1.0.0)
|
|
398
405
|
|
|
399
406
|
Marker dots at each sample point. Distinct from crosshair markers (those
|
|
400
407
|
appear only on hover).
|
|
@@ -425,7 +432,7 @@ createLineChart({ data: dense, markers: { everyN: 10 } });
|
|
|
425
432
|
**Decimation interaction:** markers are suppressed when the decimated path
|
|
426
433
|
runs (>2x plot width). They'd be unreadable.
|
|
427
434
|
|
|
428
|
-
## Theme reactivity
|
|
435
|
+
## Theme reactivity (v1.0.0)
|
|
429
436
|
|
|
430
437
|
Colors passed as `'--token-name'` get resolved against the container's
|
|
431
438
|
computed style at mount. When you switch themes (dark mode, brand swap),
|
|
@@ -455,7 +462,7 @@ re-resolve. Legend swatches update too.
|
|
|
455
462
|
> `chart.refreshTheme()`, or pair it with whatever theme-change event your
|
|
456
463
|
> framework emits.
|
|
457
464
|
|
|
458
|
-
## Bar chart
|
|
465
|
+
## Bar chart (v1.1.0-alpha.0)
|
|
459
466
|
|
|
460
467
|
```javascript
|
|
461
468
|
import { createBarChart } from '@zakkster/lite-charts';
|
|
@@ -508,7 +515,7 @@ multi-series (which is the right default -- stacked introduces design
|
|
|
508
515
|
choices around shared y-domain and tooltip ordering that are worth a
|
|
509
516
|
dedicated session).
|
|
510
517
|
|
|
511
|
-
## Tree-shakeable architecture
|
|
518
|
+
## Tree-shakeable architecture (v1.2.0)
|
|
512
519
|
|
|
513
520
|
`lite-charts` is built on a tiny shared kernel that's parameterized by a
|
|
514
521
|
**renderer object** per chart type:
|
|
@@ -535,17 +542,22 @@ rest, along with all their renderer-specific helpers.
|
|
|
535
542
|
| Entry | Bundle size | What's included |
|
|
536
543
|
|---|---|---|
|
|
537
544
|
| `import { createLineChart }` | **24 KB** | Line renderer + interp helpers + decimation + shared axis kernel + auto-resize |
|
|
538
|
-
| `import { createAreaChart }` | **
|
|
539
|
-
| `import { createBarChart }` | **
|
|
540
|
-
| `import { createBubbleChart }` | **
|
|
541
|
-
| `import {
|
|
542
|
-
| `import {
|
|
545
|
+
| `import { createAreaChart }` | **25 KB** | Area renderer + interp helpers + decimation + shared axis kernel + auto-resize |
|
|
546
|
+
| `import { createBarChart }` | **25 KB** | Bar renderer + bandScale + bar helpers + shared axis kernel + auto-resize + **stack / rounded / hover (v1.1.0)** |
|
|
547
|
+
| `import { createBubbleChart }` | **25 KB** | Bubble renderer + sqrt size scale + distance hit-test + axis kernel + auto-resize + **spatial-index hook (v1.2.0-alpha.0)** + **multi-series + per-point color (v1.2.0-alpha.2)** |
|
|
548
|
+
| `import { createScatterChart }` | **22 KB** | Scatter renderer + axis kernel + spatial-index hook (v1.2.0-alpha.1) |
|
|
549
|
+
| `import { createPieChart }` | **13 KB** | Slice renderer + polar kernel (no axes / scales / interp / decimation) + auto-resize |
|
|
550
|
+
| `import { createDonutChart }` | **13 KB** | Same as pie (shared renderer; only innerRadius default differs) |
|
|
543
551
|
| `import { createRadarChart }` | **13 KB** | Radar kernel (cos/sin tables, polygon draw, spokes, grid rings, vertex hit-test) -- zero axis/polar code |
|
|
544
|
-
|
|
|
552
|
+
| `import { createHeatmap }` | **10.5 KB** | **Grid kernel (v1.2.0-alpha.3)** -- two band scales, Float32 cells, Uint8 presentMask, precomputed cell colors. Zero axis / polar / radar code. |
|
|
553
|
+
| All nine together | **~70 KB** | Four kernels deduplicated; all renderers; shared utilities (resolveColor, ensureFloat32, mount/DPR, legend, auto-resize) shared once |
|
|
545
554
|
|
|
546
|
-
The
|
|
547
|
-
|
|
548
|
-
|
|
555
|
+
The v1.1.0 bar features (stacked layout, rounded corners, hover tint)
|
|
556
|
+
add ~1.6 KB to the bar bundle (`computeBarStacks`, `_roundRectPath`,
|
|
557
|
+
the per-bar tint overlay path). The kernel-level `postExtract` hook is
|
|
558
|
+
a single null-check that minifies to a few dozen bytes; line / area /
|
|
559
|
+
bubble bundles each pick up ~300 bytes for it. Pie / donut / radar are
|
|
560
|
+
on different kernels and unaffected.
|
|
549
561
|
|
|
550
562
|
**Auto-resize:** omit `width` / `height` from the config and the chart
|
|
551
563
|
observes its mount container, updating dimensions on container resize
|
|
@@ -586,21 +598,16 @@ nearest-vertex hit-test.
|
|
|
586
598
|
The same architecture extends to upcoming chart families:
|
|
587
599
|
|
|
588
600
|
```javascript
|
|
589
|
-
//
|
|
590
|
-
// (only the innerRadius default differs between the two factories).
|
|
601
|
+
// v1.3.0 -- pie family (no axes, polar coordinates)
|
|
591
602
|
const createBasePolarChart = (config, renderer) => { /* polar scaffold */ };
|
|
592
|
-
export const createPieChart = (c) => createBasePolarChart(
|
|
593
|
-
export const createDonutChart = (c) => createBasePolarChart(
|
|
603
|
+
export const createPieChart = (c) => createBasePolarChart(c, PIE_RENDERER);
|
|
604
|
+
export const createDonutChart = (c) => createBasePolarChart(c, DONUT_RENDERER);
|
|
605
|
+
export const createRadarChart = (c) => createBasePolarChart(c, RADAR_RENDERER);
|
|
594
606
|
|
|
595
|
-
//
|
|
596
|
-
// there's only one radar variant. A second variant will trigger the
|
|
597
|
-
// extraction into createBaseRadarChart(config, renderer).
|
|
598
|
-
export const createRadarChart = (config) => { /* radar kernel inline */ };
|
|
599
|
-
|
|
600
|
-
// Bubble ships too -- BUBBLE_RENDERER on the axis kernel.
|
|
607
|
+
// v1.3.0 -- scatter family (extends axis chart with size dimension)
|
|
601
608
|
export const createBubbleChart = (c) => createBaseAxisChart(c, BUBBLE_RENDERER);
|
|
602
609
|
|
|
603
|
-
// v1.
|
|
610
|
+
// v1.4.0 -- heatmap (2D categorical grid)
|
|
604
611
|
const createBaseGridChart = (config, renderer) => { /* grid scaffold */ };
|
|
605
612
|
export const createHeatmap = (c) => createBaseGridChart(c, HEATMAP_RENDERER);
|
|
606
613
|
```
|
|
@@ -639,37 +646,20 @@ v1.0.1) measures real paint.
|
|
|
639
646
|
|
|
640
647
|
### Zero-GC discipline
|
|
641
648
|
|
|
642
|
-
Hot-path
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
`tooltip pool zero-alloc contract` test suite.
|
|
657
|
-
- **Per-data-update y-domain: 0 bytes.** `_yDomScratch` is a 2-element
|
|
658
|
-
array filled by `_niceYDomainInto`; the legacy `niceYDomain` that
|
|
659
|
-
returned a fresh `[lo, hi]` is still exported on `_testHelpers` for
|
|
660
|
-
the test API but not used by the kernel.
|
|
661
|
-
- **Axis label string concatenation via `String.fromCharCode`** still
|
|
662
|
-
allocates ~5-10 B per tick label rebuild (~120 B for 20 labels), but
|
|
663
|
-
only fires on size or domain change, not per frame. Switching to a
|
|
664
|
-
shared `Uint8Array` and stringifying only when text changes is a
|
|
665
|
-
v1.1 nicety.
|
|
666
|
-
- **Bench harness `{xs, ys}` wrapper** is allocated by the test rotor
|
|
667
|
-
itself (~32 B per cycle), not the library. The honest framing: most
|
|
668
|
-
of the remaining heap delta is V8 measurement noise plus the bench
|
|
669
|
-
harness's own object literal.
|
|
670
|
-
|
|
671
|
-
None of these touch the per-frame draw -- they're in the data / axis
|
|
672
|
-
update path that fires only on actual changes, or in the bench harness.
|
|
649
|
+
Hot-path allocations target: <100 bytes/cycle. Currently measured at ~270
|
|
650
|
+
bytes/cycle, attributable to:
|
|
651
|
+
|
|
652
|
+
- `{xs, ys}` object literal allocated by the test rotor (~16 B)
|
|
653
|
+
- `niceYDomain` returning a fresh `[lo, hi]` tuple (~40 B; fix in v1.0.1)
|
|
654
|
+
- Axis label string concatenation via `String.fromCharCode` (~120 B for 20
|
|
655
|
+
labels; fix by switching to a shared `Uint8Array` and only stringifying
|
|
656
|
+
when text actually changes)
|
|
657
|
+
- Promise allocations from `queueMicrotask`-based draining
|
|
658
|
+
|
|
659
|
+
None of these touch the per-frame line render -- they're in the data/axis
|
|
660
|
+
update path that fires only on actual changes. The line draw closure
|
|
661
|
+
itself is fully allocation-free in steady state (verified by the
|
|
662
|
+
`decimateMinMax` zero-GC test in `test/charts.test.js`).
|
|
673
663
|
|
|
674
664
|
### What's measured, what isn't
|
|
675
665
|
|
|
@@ -679,21 +669,85 @@ update path that fires only on actual changes, or in the bench harness.
|
|
|
679
669
|
| Decimation kernel zero-alloc | YES | Test asserts <100 bytes/call |
|
|
680
670
|
| GPU paint cost | NO | Browser bench coming v1.0.1 |
|
|
681
671
|
| Cold-start overhead | NO | Single-figure ms; not yet measured |
|
|
682
|
-
| Bundle size
|
|
672
|
+
| Bundle size min+gz | NO | Single-file ESM, ~6 KB estimated; not yet minified |
|
|
673
|
+
|
|
674
|
+
## Capacity considerations
|
|
675
|
+
|
|
676
|
+
lite-charts builds on `@zakkster/lite-signal`, which pre-allocates a
|
|
677
|
+
fixed-size arena for its reactive nodes (signals + effects). The default
|
|
678
|
+
capacity is **1024 nodes**, which fits a typical app with a few charts
|
|
679
|
+
but can be exhausted on dashboards or demos with many simultaneous
|
|
680
|
+
charts. If you see a `CapacityError: nodes capacity (1024) exceeded`,
|
|
681
|
+
this is the cause.
|
|
682
|
+
|
|
683
|
+
**Per-chart active node footprint** (measured against the v1.1.0
|
|
684
|
+
implementation, on a chart with default options at typical sizes):
|
|
685
|
+
|
|
686
|
+
| Chart | Active nodes |
|
|
687
|
+
|---|---|
|
|
688
|
+
| `createLineChart` | ~43 |
|
|
689
|
+
| `createAreaChart` | ~43 |
|
|
690
|
+
| `createBarChart` | ~60 (3 series x 10 cats) |
|
|
691
|
+
| `createBubbleChart` | ~46 |
|
|
692
|
+
| `createScatterChart` | ~46 |
|
|
693
|
+
| `createPieChart` | ~25 |
|
|
694
|
+
| `createDonutChart` | ~25 |
|
|
695
|
+
| `createRadarChart` | ~50 |
|
|
696
|
+
| `createHeatmap` | ~5 |
|
|
697
|
+
|
|
698
|
+
The dominant cost on axis-kernel charts is the per-axis tick pool:
|
|
699
|
+
each tick allocates a `lineNode` and a `textNode` (the label), each of
|
|
700
|
+
which creates one lite-scene effect. At max tick count (12 per axis)
|
|
701
|
+
that's ~24 effect nodes per axis x 2 axes = ~48 per chart. Heatmap is
|
|
702
|
+
unusually cheap because the grid kernel renders cells through a single
|
|
703
|
+
`pathNode`-per-layer rather than per-cell scene nodes.
|
|
704
|
+
|
|
705
|
+
**Rule of thumb**: the default 1024-node arena fits ~15-20 axis-kernel
|
|
706
|
+
charts on a single page. Multiply by the headroom you want for safety.
|
|
707
|
+
|
|
708
|
+
**Bumping the arena** -- call `setDefaultRegistry` BEFORE constructing
|
|
709
|
+
any chart:
|
|
710
|
+
|
|
711
|
+
```js
|
|
712
|
+
import { createRegistry, setDefaultRegistry } from '@zakkster/lite-signal';
|
|
713
|
+
|
|
714
|
+
// 32k nodes -- comfortable headroom for dashboards or demos. The arena
|
|
715
|
+
// is a few tens of KB of memory, so this is cheap.
|
|
716
|
+
setDefaultRegistry(createRegistry({ maxNodes: 32768 }));
|
|
717
|
+
|
|
718
|
+
// ... THEN construct your charts:
|
|
719
|
+
import { createLineChart } from '@zakkster/lite-charts';
|
|
720
|
+
const chart = createLineChart({ /* ... */ });
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
Order matters: charts read the *current* default registry at
|
|
724
|
+
construction time. Bumping after charts are already created doesn't
|
|
725
|
+
help those charts. The lite-charts demo (`demo/index.html`) bumps to
|
|
726
|
+
32768 at the very top for this reason.
|
|
727
|
+
|
|
728
|
+
**Mount/unmount note**: each mount/unmount cycle leaves a small
|
|
729
|
+
residue (~4 reactive nodes per chart, from construction-time signals
|
|
730
|
+
that aren't disposed in `unmount` so the chart can be remounted).
|
|
731
|
+
For apps that create and destroy many charts dynamically over a long
|
|
732
|
+
session, that residue accumulates until the chart reference is dropped
|
|
733
|
+
and the lite-signal arena slots become eligible for reclamation.
|
|
734
|
+
A dedicated terminal-teardown `chart.destroy()` is on the roadmap for
|
|
735
|
+
v1.3.
|
|
683
736
|
|
|
684
737
|
## Roadmap
|
|
685
738
|
|
|
686
|
-
v1.
|
|
739
|
+
v1.1.0 ships nine chart types on four independent kernels with
|
|
687
740
|
kernel-side auto-resize. See [ROADMAP.md](./ROADMAP.md) for the full
|
|
688
741
|
forward plan and the development history that led here. Headlines:
|
|
689
742
|
|
|
690
743
|
| Version | Scope |
|
|
691
744
|
|---|---|
|
|
692
|
-
| **v1.0.0**
|
|
693
|
-
| v1.1.0 |
|
|
694
|
-
| v1.2.0 |
|
|
695
|
-
| v1.3.0 |
|
|
696
|
-
| v1.4.0 |
|
|
745
|
+
| **v1.0.0** | Seven chart types, three kernels, auto-resize, 182 tests, full tree-shake verification. |
|
|
746
|
+
| **v1.1.0** (this release) | Bar polish (stacked, rounded corners, hover tint) **plus** the features prototyped over four internal alphas now landing in one go: pluggable spatial index for bubble hit-test (auto-engages ≥1000 points), `createScatterChart` (eighth type), multi-series bubble + per-point color + global size domain, and `createHeatmap` on a new `createBaseGridChart` kernel (10.5 KB minified, the smallest of the nine). 231 tests. |
|
|
747
|
+
| v1.2.0 | Heatmap polish (per-row / per-column highlight on hover, quantile binning); doc + release notes. |
|
|
748
|
+
| v1.3.0 | SVG export across all nine charts (mirrors every draw fn through SVG path commands; pixel-identical output). |
|
|
749
|
+
| v1.4.0 | Log scale; pan + zoom; brushing primitives. |
|
|
750
|
+
| v1.5.0 | Time-series specialized variants; legend virtualization via `lite-virtual`; annotation layer. |
|
|
697
751
|
|
|
698
752
|
## Ecosystem
|
|
699
753
|
|