@aeriz/chart 1.0.1 → 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.
Files changed (72) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +53 -446
  3. package/dist/aeriz.cjs +2575 -2387
  4. package/dist/aeriz.esm.js +1576 -1423
  5. package/dist/aeriz.esm.min.js +264 -1
  6. package/dist/aeriz.js +2575 -2387
  7. package/dist/aeriz.min.cjs +266 -1
  8. package/dist/aeriz.min.js +266 -1
  9. package/dist/esm/base.js +73 -0
  10. package/dist/esm/cartesian.js +11 -0
  11. package/dist/esm/charts/area.js +9 -0
  12. package/dist/esm/charts/bar.js +4 -0
  13. package/dist/esm/charts/boxplot.js +4 -0
  14. package/dist/esm/charts/bubble.js +3 -0
  15. package/dist/esm/charts/composite.js +11 -0
  16. package/dist/esm/charts/funnel.js +3 -0
  17. package/dist/esm/charts/gauge.js +5 -0
  18. package/dist/esm/charts/grouped-bar.js +5 -0
  19. package/dist/esm/charts/hbar.js +6 -0
  20. package/dist/esm/charts/heatmap.js +7 -0
  21. package/dist/esm/charts/line.js +9 -0
  22. package/dist/esm/charts/multi-line.js +8 -0
  23. package/dist/esm/charts/pie.js +6 -0
  24. package/dist/esm/charts/polar.js +3 -0
  25. package/dist/esm/charts/radar.js +10 -0
  26. package/dist/esm/charts/realtime.js +12 -0
  27. package/dist/esm/charts/scatter.js +6 -0
  28. package/dist/esm/charts/sparkline.js +5 -0
  29. package/dist/esm/charts/stacked-bar.js +7 -0
  30. package/dist/esm/charts/treemap.js +10 -0
  31. package/dist/esm/charts/waterfall.js +5 -0
  32. package/dist/esm/engine.js +33 -0
  33. package/dist/esm/index.js +2 -0
  34. package/dist/esm/jquery.js +4 -0
  35. package/dist/esm/math.js +32 -0
  36. package/dist/esm/react.js +4 -0
  37. package/dist/esm/shallow.js +3 -0
  38. package/dist/esm/svelte.js +4 -0
  39. package/dist/esm/vue.js +2 -0
  40. package/{src → dist}/index.d.ts +160 -30
  41. package/dist/jquery.d.ts +10 -0
  42. package/dist/react.d.ts +22 -0
  43. package/dist/svelte.d.ts +17 -0
  44. package/dist/types/area.d.ts +1 -0
  45. package/dist/types/bar.d.ts +1 -0
  46. package/dist/types/boxplot.d.ts +1 -0
  47. package/dist/types/bubble.d.ts +1 -0
  48. package/dist/types/composite.d.ts +1 -0
  49. package/dist/types/funnel.d.ts +1 -0
  50. package/dist/types/gauge.d.ts +1 -0
  51. package/dist/types/grouped-bar.d.ts +1 -0
  52. package/dist/types/hbar.d.ts +1 -0
  53. package/dist/types/heatmap.d.ts +1 -0
  54. package/dist/types/line.d.ts +1 -0
  55. package/dist/types/multi-line.d.ts +1 -0
  56. package/dist/types/pie.d.ts +1 -0
  57. package/dist/types/polar.d.ts +1 -0
  58. package/dist/types/radar.d.ts +1 -0
  59. package/dist/types/realtime.d.ts +1 -0
  60. package/dist/types/scatter.d.ts +1 -0
  61. package/dist/types/sparkline.d.ts +1 -0
  62. package/dist/types/stacked-bar.d.ts +1 -0
  63. package/dist/types/treemap.d.ts +1 -0
  64. package/dist/types/waterfall.d.ts +1 -0
  65. package/dist/vue.d.ts +13 -0
  66. package/package.json +60 -29
  67. package/src/base.js +0 -562
  68. package/src/charts.js +0 -1365
  69. package/src/composite.js +0 -187
  70. package/src/engine.js +0 -287
  71. package/src/index.js +0 -18
  72. package/src/math.js +0 -178
package/README.md CHANGED
@@ -1,488 +1,95 @@
1
- # aeriz
1
+ # @aeriz/chart
2
2
 
3
- A focused, fast canvas charting library. **21 chart types**, single rendering core, zero dependencies.
3
+ Visualization, light as air. 21 canvas chart types from one options object, with zero dependencies.
4
4
 
5
- [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
6
- [![npm](https://img.shields.io/badge/npm-%40aeriz%2Fchart-cb3837.svg)](https://www.npmjs.com/package/@aeriz/chart)
7
- [![size](https://img.shields.io/badge/min-58_KB-green.svg)](dist/aeriz.min.js)
8
-
9
- ---
10
-
11
- ## At a glance
12
-
13
- - **21 chart types** — bar, line, area, scatter, pie, radar, gauge, heatmap, treemap, realtime, waterfall, **composite** (mixed bar + line + area + scatter, dual y-axis), and more
14
- - **~58 KB minified · ~94 KB unminified** · zero dependencies
15
- - **Live theming** via CSS variables — change colors at runtime, call `invalidate()`, redraws
16
- - **Pixel-perfect events** — hit testing attached to canvas, no DPR confusion
17
- - **Realtime streaming** — `RealtimeChart.push()` with rolling window
18
- - **State overlays** — `setLoading()`, `setEmpty()`, `setError()`, `clearState()`
19
- - **TypeScript types included** (`src/index.d.ts`)
20
-
21
- ---
22
-
23
- ## Install
24
-
25
- ### CDN
26
-
27
- ```html
28
- <!-- ✓ Production — pin a specific version (immutable, longest cache) -->
29
- <script src="https://cdn.jsdelivr.net/npm/@aeriz/chart@1.0.0/dist/aeriz.min.js"></script>
30
-
31
- <!-- Tracks the latest 1.x — auto-receives patches, never major bumps -->
32
- <script src="https://cdn.jsdelivr.net/npm/@aeriz/chart@^1.0.0/dist/aeriz.min.js"></script>
33
-
34
- <!-- Always-newest — convenient for prototyping, NOT for production -->
35
- <script src="https://cdn.jsdelivr.net/npm/@aeriz/chart@latest/dist/aeriz.min.js"></script>
36
-
37
- <!-- unpkg alternative (same files, different CDN) -->
38
- <script src="https://unpkg.com/@aeriz/chart@1.0.0/dist/aeriz.min.js"></script>
39
-
40
- <!-- ES Module — same versioning rules apply -->
41
- <script type="module">
42
- import { BarChart } from 'https://cdn.jsdelivr.net/npm/@aeriz/chart@1.0.0/dist/aeriz.esm.min.js';
43
- </script>
44
- ```
45
-
46
- > **Why pin a version?** Pinned URLs (e.g. `@1.0.0`) are immutable and benefit
47
- > from a one-year CDN cache. `@latest` redirects on every release and may pull
48
- > in breaking changes when a new major version ships. Use `@latest` only for
49
- > quick prototypes; pin a version everywhere else.
50
-
51
- ### npm / yarn / pnpm
5
+ **Docs and live demos: https://aeriz.dev/chart/**
52
6
 
53
7
  ```bash
54
8
  npm install @aeriz/chart
55
- yarn add @aeriz/chart
56
- pnpm add @aeriz/chart
57
- ```
58
-
59
- ```js
60
- import { BarChart, CompositeChart, math, PALETTE } from '@aeriz/chart';
61
- // or, in CommonJS:
62
- const Aeriz = require('@aeriz/chart');
63
- // or, the minified build (smaller install footprint at runtime):
64
- import * as Aeriz from '@aeriz/chart/min';
65
- ```
66
-
67
- ---
68
-
69
- ## Quick start
70
-
71
- ```html
72
- <div id="chart" style="height:320px"></div>
73
- <script src="https://cdn.jsdelivr.net/npm/@aeriz/chart@1.0.0/dist/aeriz.min.js"></script>
74
- <script>
75
- const chart = new Aeriz.BarChart('#chart', {
76
- data: [
77
- { label: 'Jan', value: 64 },
78
- { label: 'Feb', value: 42 },
79
- { label: 'Mar', value: 78 },
80
- ],
81
- yTickFormat: v => v + 'k',
82
- onClick: hit => hit && console.log(hit),
83
- });
84
- </script>
85
- ```
86
-
87
- ---
88
-
89
- ## Chart types
90
-
91
- All 21 types share the same lifecycle (`new` → `setData` → `destroy`) and the same state overlays.
92
-
93
- | Chart | Class | Notes |
94
- | ------------ | -------------------- | -------------------------------------------------- |
95
- | Bar | `BarChart` | Vertical, supports negative values |
96
- | H-Bar | `HBarChart` | Horizontal |
97
- | Line | `LineChart` | smooth · linear · step · log · time · auto-decimation |
98
- | Area | `AreaChart` | Single + stacked |
99
- | Stacked Bar | `StackedBarChart` | |
100
- | Grouped Bar | `GroupedBarChart` | Clustered |
101
- | Multi-Line | `MultiLineChart` | Shared crosshair tooltip |
102
- | Scatter | `ScatterChart` | Grouped, batched rendering |
103
- | Bubble | `BubbleChart` | Scatter with z → radius |
104
- | Pie | `PieChart` | |
105
- | Donut | `PieChart` + `innerRadius` | Hover-aware center label |
106
- | Radar | `RadarChart` | Multi-series, multi-axis |
107
- | Polar | `PolarChart` | Radial bars |
108
- | Gauge | `GaugeChart` | Animated `setValue()` |
109
- | Heatmap | `HeatmapChart` | Color interpolation |
110
- | Boxplot | `BoxplotChart` | IQR + outliers |
111
- | Funnel | `FunnelChart` | Conversion stages |
112
- | Treemap | `TreemapChart` | Squarified layout |
113
- | Sparkline | `Sparkline` | Mini, no axes |
114
- | Realtime | `RealtimeChart` | `push()` streaming, rolling window |
115
- | Waterfall | `WaterfallChart` | Cumulative + connector lines |
116
- | **Composite**| `CompositeChart` | **Mixed bar + line + area + scatter, dual y-axis** |
117
-
118
- ---
119
-
120
- ## Lifecycle
121
-
122
- ```js
123
- const chart = new Aeriz.BarChart('#card', { /* options */ });
124
-
125
- chart.setData(newData); // animated transition
126
- chart.setLoading('Fetching…');
127
- chart.setEmpty('No data');
128
- chart.setError('Network error');
129
- chart.clearState(); // restore prior render
130
- chart.invalidate(); // re-resolve theme + redraw
131
- chart.destroy(); // remove canvas, observers, listeners
132
9
  ```
133
10
 
134
- Methods other than `invalidate()` and `destroy()` return `this` for chaining.
135
-
136
- ### Type-specific methods
137
-
138
11
  ```js
139
- gauge.setValue(82); // GaugeChart — animated needle
140
- realtime.push([cpu, mem]); // RealtimeChart — append a sample
141
- realtime.push(value); // single-series shortcut
142
- realtime.clear(); // empty the rolling window
143
- ```
12
+ import { BarChart } from '@aeriz/chart';
144
13
 
145
- ---
146
-
147
- ## Composite (mixed) chart
148
-
149
- What other libraries call "complex chart configuration" — here in one call:
150
-
151
- ```js
152
- new Aeriz.CompositeChart('#card', {
153
- categories: ['Jan', 'Feb', 'Mar'],
154
- layers: [
155
- { type: 'bar', name: 'Revenue', values: [100, 130, 90] },
156
- { type: 'area', name: 'Forecast', values: [90, 120, 100] },
157
- { type: 'line', name: 'Margin %', values: [22, 28, 18], axis: 'right' },
158
- { type: 'scatter', name: 'Anomaly', values: [{ x: 1, y: 35 }] },
159
- ],
160
- yLeftTickFormat: v => '$' + v + 'k',
161
- yRightTickFormat: v => v + '%',
14
+ const chart = new BarChart('#sales', {
15
+ data: { Jan: 64, Feb: 42, Mar: 78, Apr: 55 },
162
16
  });
163
- ```
164
-
165
- ---
166
-
167
- ## Theming via CSS variables
168
-
169
- Set any of the tokens below on `:root`, on the chart container, or on any
170
- ancestor element. Then call `chart.invalidate()` and the chart re-resolves
171
- its theme and redraws.
172
17
 
173
- ```css
174
- :root {
175
- --aeriz-bg: #0a0e14;
176
- --aeriz-surface: transparent;
177
- --aeriz-text: #e7eef5;
178
- --aeriz-muted: #6a7a8a;
179
- --aeriz-grid: rgba(100, 200, 255, 0.08);
180
- --aeriz-axis: rgba(100, 200, 255, 0.25);
181
- --aeriz-accent: #64c8ff;
182
-
183
- --aeriz-color-1: #64c8ff;
184
- --aeriz-color-2: #10b981;
185
- /* … --aeriz-color-12 */
186
-
187
- --aeriz-font: ui-monospace, SFMono-Regular, Menlo, monospace;
188
- --aeriz-font-size: 13px;
189
- --aeriz-line-width: 2;
190
- --aeriz-point-radius: 3;
191
- --aeriz-bar-radius: 3;
192
-
193
- --aeriz-tooltip-bg: rgba(0, 0, 0, 0.92);
194
- --aeriz-tooltip-fg: #fff;
195
- }
18
+ chart.update({ data: { Jan: 30, Feb: 80 } }); // animates to the new values
196
19
  ```
197
20
 
198
- Then in JS:
199
-
200
- ```js
201
- document.documentElement.style.setProperty('--aeriz-accent', '#ff6b9d');
202
- chart.invalidate();
203
- ```
21
+ ## Why
204
22
 
205
- ---
23
+ - **One API.** Every type works the same: `new Chart(el, options)` → `update()` → `destroy()`.
24
+ - **Only what you use.** Each chart is its own module and the package has `"sideEffects": false`, so bundlers keep only the charts you import. One chart costs about 7–10 KB min+gzip, and all 21 cost about 19 KB.
25
+ - **Works anywhere.** Adapters for React, Vue, Svelte and jQuery are separate entry points.
26
+ - **Fast.** A million-point line draws in about 50 ms. Off-screen charts don't draw.
27
+ - **Fits in without config.** Text color, font and background come from the page, so charts match light and dark themes. Override any of it with `--aeriz-*` CSS variables.
28
+ - **Accessible.** You get keyboard navigation, screen-reader announcements, a clickable legend, and touch and pen tooltips.
206
29
 
207
- ## Realtime streaming
30
+ ## Charts
208
31
 
209
- ```js
210
- const rt = new Aeriz.RealtimeChart('#rt', {
211
- series: [{ name: 'CPU' }, { name: 'Memory' }],
212
- windowSize: 100,
213
- });
32
+ `BarChart` `HBarChart` `LineChart` `AreaChart` `StackedBarChart` `GroupedBarChart` `MultiLineChart` `ScatterChart` `BubbleChart` `PieChart` `RadarChart` `PolarChart` `GaugeChart` `HeatmapChart` `BoxplotChart` `FunnelChart` `TreemapChart` `Sparkline` `RealtimeChart` `WaterfallChart` `CompositeChart`
214
33
 
215
- setInterval(() => {
216
- rt.push([Math.random() * 100, Math.random() * 100]);
217
- }, 100);
218
- ```
219
-
220
- `push()` accepts a single number (one-series charts) or an array aligned
221
- with `series`. Older samples beyond `windowSize` are discarded automatically.
222
-
223
- ---
224
-
225
- ## State overlays
226
-
227
- ```js
228
- chart.setLoading('Fetching…'); // shows a spinner overlay
229
- chart.setEmpty('No data'); // empty state
230
- chart.setError('Network error'); // error state
231
- chart.clearState(); // dismiss overlay, resume rendering
232
- ```
34
+ Import one directly by its subpath: `@aeriz/chart/bar`, `@aeriz/chart/line`, `@aeriz/chart/multi-line` and so on.
233
35
 
234
- Overlays are non-destructive — `clearState()` restores whatever was
235
- rendered before.
236
-
237
- ---
238
-
239
- ## Framework usage
240
-
241
- The same constructor signature works in every framework. The patterns below
242
- are the ones the docs site demonstrates per chart type.
243
-
244
- <details>
245
- <summary><strong>React</strong></summary>
36
+ ## Frameworks
246
37
 
247
38
  ```jsx
248
- import { useEffect, useRef } from 'react';
249
- import * as Aeriz from '@aeriz/chart';
39
+ // React 16.8+
40
+ import { BarChart } from '@aeriz/chart/bar';
41
+ import { AerizChart } from '@aeriz/chart/react';
250
42
 
251
- export default function BarChartDemo() {
252
- const ref = useRef(null);
253
- useEffect(() => {
254
- const chart = new Aeriz.BarChart(ref.current, {
255
- data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],
256
- });
257
- return () => chart.destroy();
258
- }, []);
259
- return <div ref={ref} style={{ width: '100%', height: 320 }} />;
260
- }
43
+ <AerizChart type={BarChart} data={rows} style={{ height: 320 }} />;
261
44
  ```
262
- </details>
263
-
264
- <details>
265
- <summary><strong>Vue 3</strong></summary>
266
45
 
267
46
  ```vue
268
- <script setup>
269
- import { onMounted, onBeforeUnmount, ref } from 'vue';
270
- import * as Aeriz from '@aeriz/chart';
271
-
272
- const el = ref(null);
273
- let chart = null;
274
- onMounted(() => {
275
- chart = new Aeriz.BarChart(el.value, {
276
- data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],
277
- });
278
- });
279
- onBeforeUnmount(() => chart && chart.destroy());
280
- </script>
281
-
282
- <template>
283
- <div ref="el" style="width:100%;height:320px"></div>
284
- </template>
47
+ <!-- Vue 3.2+ -->
48
+ <AerizChart :type="LineChart" :data="rows" style="height: 300px" />
49
+ <!-- import { AerizChart } from '@aeriz/chart/vue' -->
285
50
  ```
286
- </details>
287
-
288
- <details>
289
- <summary><strong>Svelte</strong></summary>
290
51
 
291
52
  ```svelte
292
- <script>
293
- import { onMount } from 'svelte';
294
- import * as Aeriz from '@aeriz/chart';
295
-
296
- let el;
297
- onMount(() => {
298
- const chart = new Aeriz.BarChart(el, {
299
- data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],
300
- });
301
- return () => chart.destroy();
302
- });
303
- </script>
304
-
305
- <div bind:this={el} style="width:100%;height:320px"></div>
53
+ <!-- Svelte 3, 4, 5 (an action, so no compiler setup) -->
54
+ <div use:aeriz={{ type: BarChart, data: rows }} style="height: 300px"></div>
55
+ <!-- import { aeriz } from '@aeriz/chart/svelte' -->
306
56
  ```
307
- </details>
308
-
309
- <details>
310
- <summary><strong>jQuery</strong></summary>
311
57
 
312
58
  ```js
313
- $(function () {
314
- const chart = new Aeriz.BarChart($('#bar')[0], {
315
- data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],
316
- });
317
- });
59
+ // jQuery 1.7+
60
+ import { install } from '@aeriz/chart/jquery';
61
+ install($);
62
+ $('#share').aerizChart(PieChart, { data: { Chrome: 64, Safari: 19 } });
318
63
  ```
319
- </details>
320
-
321
- <details>
322
- <summary><strong>ExtJS</strong></summary>
323
-
324
- ```js
325
- Ext.create('Ext.Component', {
326
- renderTo: Ext.getBody(),
327
- width: '100%',
328
- height: 320,
329
- autoEl: { tag: 'div' },
330
- listeners: {
331
- afterrender(cmp) {
332
- cmp.aerizChart = new Aeriz.BarChart(cmp.getEl().dom, {
333
- data: [{ label: 'A', value: 5 }, { label: 'B', value: 9 }],
334
- });
335
- },
336
- beforedestroy(cmp) {
337
- cmp.aerizChart && cmp.aerizChart.destroy();
338
- },
339
- },
340
- });
341
- ```
342
- </details>
343
-
344
- ---
345
-
346
- ## TypeScript
347
-
348
- Types ship in the package — no `@types/aeriz__chart` needed.
349
-
350
- ```ts
351
- import {
352
- BarChart,
353
- CompositeChart,
354
- GaugeChart,
355
- RealtimeChart,
356
- math,
357
- PALETTE,
358
- } from '@aeriz/chart';
359
-
360
- const bar = new BarChart('#x', {
361
- data: [{ label: 'A', value: 5 }],
362
- onClick: hit => console.log(hit),
363
- });
364
-
365
- const gauge = new GaugeChart(document.body, { value: 50, max: 100 });
366
- gauge.setValue(82);
367
-
368
- const ticks: number[] = math.niceTicks(0, 100, 5);
369
- ```
370
-
371
- Discriminated unions cover composite layers — `type: 'bar'` requires
372
- `values: number[]` while `type: 'scatter'` requires `values: { x, y }[]`.
373
-
374
- ---
375
64
 
376
- ## API reference
65
+ ## CDN
377
66
 
378
- ### `Chart` (base class)
379
-
380
- | Method | Returns | Description |
381
- | ---------------------------- | ------- | --------------------------------------------- |
382
- | `new Chart(container, opts)` | — | `container`: CSS selector or `HTMLElement` |
383
- | `setData(data)` | `this` | Replace data with an animated transition |
384
- | `setLoading(msg?)` | `this` | Show loading overlay |
385
- | `setEmpty(msg?)` | `this` | Show empty-state overlay |
386
- | `setError(msg?)` | `this` | Show error overlay |
387
- | `clearState()` | `this` | Dismiss any overlay |
388
- | `invalidate()` | `void` | Re-resolve theme + palette and redraw |
389
- | `destroy()` | `void` | Tear down listeners, observers, canvas |
390
-
391
- ### Common options
392
-
393
- Accepted by every chart that has them:
394
-
395
- | Option | Type | Description |
396
- | ---------------- | -------------------------- | -------------------------------------------- |
397
- | `palette` | `string[]` | Override the default palette |
398
- | `dataLabels` | `boolean` | Render value labels on bars / points |
399
- | `onClick` | `(hit, point, chart) => void` | Click handler |
400
- | `xTickFormat` | `(value, index) => string` | Format x-axis ticks |
401
- | `yTickFormat` | `(value) => string` | Format y-axis ticks |
402
-
403
- ### Math helpers
404
-
405
- ```js
406
- import { math, PALETTE } from '@aeriz/chart';
407
-
408
- math.clamp(15, 0, 10); // 10
409
- math.lerp(0, 1, 0.5); // 0.5
410
- math.niceTicks(0, 100, 5); // [0, 20, 40, 60, 80, 100]
411
- math.niceDomain(3, 97, 5); // [0, 100]
412
- math.colorMix('#000', '#fff', 0.5);
413
- PALETTE; // 8-color qualitative palette
414
- ```
415
-
416
- Full list: `TAU`, `clamp`, `lerp`, `extent`, `niceTicks`, `niceDomain`,
417
- `timeNiceTicks`, `timeFormat`, `minMaxDecimate`, `shouldDecimate`,
418
- `bezierControlPoints`, `springStep`, `colorParse`, `colorAlpha`,
419
- `colorMix`, `PALETTE`.
420
-
421
- ---
422
-
423
- ## Files
424
-
425
- ```
426
- src/
427
- index.js # public entry — re-exports
428
- index.d.ts # TypeScript definitions
429
- math.js # scales, ticks, color, decimation
430
- engine.js # canvas primitives + DPR
431
- base.js # Chart base class
432
- charts.js # 20 chart types
433
- composite.js # mixed chart
434
-
435
- dist/
436
- aeriz.js # IIFE — window.Aeriz (~94 KB)
437
- aeriz.min.js # IIFE minified (~58 KB) — CDN default
438
- aeriz.esm.js # ES module
439
- aeriz.esm.min.js # ES module minified
440
- aeriz.cjs # CommonJS — for `require('@aeriz/chart')`
441
- aeriz.min.cjs # CommonJS minified
442
-
443
- scripts/
444
- build.mjs # build all 6 dist files
445
- test/
446
- verify.mjs # 53 unit + integration tests
447
- bundle.mjs # IIFE bundle integrity
448
- ```
449
-
450
- Total source: ~2,600 lines for 21 chart types.
451
-
452
- ---
453
-
454
- ## Build
455
-
456
- Zero dependencies. Just run:
67
+ ```html
68
+ <!-- Everything, as the global Aeriz (also installs the jQuery plugin if jQuery is present) -->
69
+ <script src="https://cdn.jsdelivr.net/npm/@aeriz/chart@1.1.0/dist/aeriz.min.js"></script>
457
70
 
458
- ```bash
459
- node scripts/build.mjs
71
+ <!-- One chart, as an ES module -->
72
+ <script type="module">
73
+ import { BarChart } from 'https://cdn.jsdelivr.net/npm/@aeriz/chart@1.1.0/dist/esm/charts/bar.js';
74
+ </script>
460
75
  ```
461
76
 
462
- Produces all 6 files in `dist/`.
463
-
464
- ---
465
-
466
- ## Test
467
-
468
- ```bash
469
- npm test
470
- ```
77
+ ## New in 1.1
471
78
 
472
- 53 tests covering:
79
+ 1.0 code keeps working. What 1.1 adds:
473
80
 
474
- - Engine DPR + dimensions
475
- - Math primitives (`clamp`, `lerp`, ticks, color ops)
476
- - Pixel-perfect mouse coordinates
477
- - `invalidate()` theme reactivity (palette + gradient cache)
478
- - All 21 chart types instantiate + render
479
- - State overlays (`loading`/`empty`/`error`/`clear`)
480
- - Tooltip lifecycle, click handlers, animation completion
481
- - Destroy cleanup (no leaked listeners or DOM)
81
+ - per-chart modules and subpath imports;
82
+ - the framework adapters;
83
+ - `update()`;
84
+ - a `format` option for numbers;
85
+ - a legend that toggles series;
86
+ - keyboard support and accessibility;
87
+ - local-time axes;
88
+ - right-axis composite charts;
89
+ - large-data decimation.
482
90
 
483
- ---
91
+ It also fixes a long list of 1.0 bugs. The full list is at https://aeriz.dev/chart/#changes.
484
92
 
485
93
  ## License
486
94
 
487
- [Apache License 2.0](LICENSE) — Copyright © 2026
488
- [code-repositories](https://github.com/code-repositories).
95
+ Apache-2.0