@aiquants/chartjs-worker 0.0.0-stage → 0.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 +29 -0
- package/LICENSE +21 -0
- package/README.md +215 -2
- package/THIRD_PARTY_NOTICES.md +22 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/dist/react/index.d.mts +10 -0
- package/dist/react/index.d.ts +10 -0
- package/dist/react/index.js +1 -0
- package/dist/react/index.mjs +1 -0
- package/dist/types-B3UEONTF.d.mts +60 -0
- package/dist/types-B3UEONTF.d.ts +60 -0
- package/dist/worker/index.d.mts +149 -0
- package/dist/worker/index.mjs +6 -0
- package/dist/worker-env.d.mts +2 -0
- package/dist/worker-env.mjs +1 -0
- package/package.json +106 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@aiquants/chartjs-worker` are documented here.
|
|
4
|
+
見出しは版番号です。未公開の変更は `## Unreleased` の下へ書き、公開するときにその版番号と公開日の見出し (`## 0.1.0 (2026-11-02)` の形) へ改めます。
|
|
5
|
+
|
|
6
|
+
## 0.1.0 (2026-11-02)
|
|
7
|
+
|
|
8
|
+
初版。
|
|
9
|
+
|
|
10
|
+
### 追加
|
|
11
|
+
|
|
12
|
+
- **`createChartWorkerHost({ createWorker })`** (`.`): 1 本の worker にチャートを置く宿。`mount(container, spec)` が返す取っ手で `update`・`setInput`・`setSizing`・`setCanvasAttributes`・`command`・`on`・`onStateChange`・`destroy` を使う。
|
|
13
|
+
- `update` は、その props か後の props を描き終えたとき (アニメーションを含む) に解決する。入れ物の `data-chart-state` は最新の props の `drawing`・`drawn`・`error`。
|
|
14
|
+
- worker は大きさのある最初のチャートを置くときに作る (サーバーでの描画で読んでも `Worker` に触れない)。
|
|
15
|
+
- `supersede: "restart"` は、worker が前の `create`・`update` の途中なら worker を作り直し、全部のチャートを最新の props で置き直す。`"queue"` は待つ。
|
|
16
|
+
- 大きさは Chart.js の `getMaximumSize` で入れ物の中に決め、入れ物の大きさの変化・置くときに隠れていた入れ物 (大きさが付いてから作る)・`resize` に伴う倍率の変化に 1 フレームに 1 度まで従う。
|
|
17
|
+
- マウス・ペン・指の動きを 1 つのポインターの道で送る (ホバーは 1 フレームに 1 度にまとめる・指を置いた所でツールチップ・タップはクリック)。ホイールの `preventDefault` と、キャンバスの `touch-action` (`input.pan`・`input.pinch` から決める) はメインスレッドで決める。
|
|
18
|
+
- **`useWorkerChart(host, spec)`** (`./react`): 宣言の形の React の口。`props` は `Object.is` で、`input`・`sizing`・`canvasAttributes` は値で比べて送る。`kind`・`supersede`・宿が替わると置き直す。`StrictMode` でもキャンバスは 1 つ。
|
|
19
|
+
- **`@aiquants/chartjs-worker/worker-env`**: worker の大域を `window` として見せ、Chart.js のアニメーションを worker の `requestAnimationFrame` で動かす入口。worker の入口の最初の文で読む。何も読まず何も出さない。
|
|
20
|
+
- **`startChartWorker({ kinds })`・`defineChartKind`** (`./worker`): worker の中の土台と種類。`context.createChart` は worker のチャートに要る設定 (土台・`responsive: false`・`maintainAspectRatio: false`・倍率・内部の差し込み) を足し、同じ項目の指定があれば理由を書いたエラーで止まる。chart.js を `worker-env` より先に読んだ worker は、読む順番を書いたエラーで止まる。
|
|
21
|
+
- **chartjs-plugin-zoom 2.2.0 を worker の束に同梱**: ホイールのズーム、ドラッグと指の移動、2 本指のピンチを worker で動かす (`hammerjs` は何もしない代わりへ替え、移動とピンチの判断は差し込みと同じ規則で写した)。移動の直後のクリックは捨てる。
|
|
22
|
+
- **浮いた積み棒** (`./worker`): `toFloatingStacks` (Chart.js の `stacked: true` と同じ位置の浮いた棒)、`FloatingBarController` (`type: "floatingBar"`、軸の一覧とデータセットの組の位置を更新ごとに 1 度だけ求め、値の軸がもう 1 度積む設定はエラーにする)、`floatingValueOf` (ツールチップ用の元の値)。
|
|
23
|
+
- **エラー** (`.`): `ChartWorkerUnsupportedError`・`ChartWorkerKindError`・`ChartWorkerCrashedError`・`ChartWorkerDestroyedError`・`ChartWorkerRestartedError`。
|
|
24
|
+
|
|
25
|
+
### 扱わないもの
|
|
26
|
+
|
|
27
|
+
- 枠を引いてズーム (`zoom.drag.enabled`) は `createChart` がエラーで止まる。
|
|
28
|
+
- OffscreenCanvas の無いブラウザーでは `mount` が `ChartWorkerUnsupportedError` を投げる。
|
|
29
|
+
- キーボードの出来事。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AI Quants / fehde-k
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,216 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @aiquants/chartjs-worker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Draws Chart.js charts in a Web Worker on an OffscreenCanvas, so a heavy chart never blocks the page.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
Chart.js draws on the main thread. A chart with hundreds of thousands of elements keeps the main thread busy for seconds, and the page cannot scroll, type or click until it finishes. This package moves the whole chart into a worker and keeps what users expect from a Chart.js chart on the page:
|
|
8
|
+
|
|
9
|
+
- tooltips, hover and clicks (`options.onClick`, `options.onHover`)
|
|
10
|
+
- legend clicks
|
|
11
|
+
- wheel zoom, drag and touch panning and pinch zoom through chartjs-plugin-zoom 2.2.0 (bundled)
|
|
12
|
+
- animations (they run on the worker's `requestAnimationFrame`)
|
|
13
|
+
- responsive sizing that follows the rules Chart.js applies on the main thread
|
|
14
|
+
|
|
15
|
+
The main thread only measures the container, forwards pointer and wheel input and posts data. The worker runs your Chart.js code, written as *chart kinds*.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add @aiquants/chartjs-worker chart.js
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`chart.js` (`^4.5.1`) is a peer dependency, so the worker and your chart kinds share one Chart.js. `react` (`>=18`) is an optional peer dependency for `@aiquants/chartjs-worker/react`.
|
|
24
|
+
|
|
25
|
+
| Entry | Runs on | Contents |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| `@aiquants/chartjs-worker` | main thread | `createChartWorkerHost`, errors, types |
|
|
28
|
+
| `@aiquants/chartjs-worker/react` | main thread | `useWorkerChart` |
|
|
29
|
+
| `@aiquants/chartjs-worker/worker-env` | worker | makes `window` point at the worker scope; exports nothing |
|
|
30
|
+
| `@aiquants/chartjs-worker/worker` | worker | `startChartWorker`, `defineChartKind`, floating stacked bars |
|
|
31
|
+
|
|
32
|
+
## Quick start
|
|
33
|
+
|
|
34
|
+
### 1. The worker entry
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
// chartWorker.ts
|
|
38
|
+
import "@aiquants/chartjs-worker/worker-env" // must be the first statement
|
|
39
|
+
import { defineChartKind, startChartWorker } from "@aiquants/chartjs-worker/worker"
|
|
40
|
+
import { BarController, CategoryScale, Chart, LinearScale, Tooltip } from "chart.js"
|
|
41
|
+
|
|
42
|
+
Chart.register(BarController, CategoryScale, LinearScale, Tooltip)
|
|
43
|
+
|
|
44
|
+
type SalesProps = { labels: string[]; values: Float64Array }
|
|
45
|
+
|
|
46
|
+
const sales = defineChartKind<SalesProps>({
|
|
47
|
+
create: (props, context) =>
|
|
48
|
+
context.createChart({
|
|
49
|
+
type: "bar",
|
|
50
|
+
data: { labels: props.labels, datasets: [{ label: "Sales", data: Array.from(props.values) }] },
|
|
51
|
+
options: { onClick: (_event, elements) => context.emit("select", elements.map((element) => element.index)) },
|
|
52
|
+
}),
|
|
53
|
+
update: (chart, props) => {
|
|
54
|
+
chart.data.labels = props.labels
|
|
55
|
+
chart.data.datasets[0].data = Array.from(props.values)
|
|
56
|
+
},
|
|
57
|
+
commands: {
|
|
58
|
+
visibleRange: (chart) => ({ min: chart.scales.x.min, max: chart.scales.x.max }),
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
startChartWorker({ kinds: { sales } })
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- `@aiquants/chartjs-worker/worker-env` must be imported **before anything that imports `chart.js`**. Chart.js reads `window.requestAnimationFrame` once when it loads; without the shim it animates synchronously. If the order is wrong, `startChartWorker` throws an error that says so. Keep the import as a separate, first statement: it imports nothing, so a bundler that pre-bundles dependencies still evaluates it first.
|
|
66
|
+
- `context.createChart` adds what a worker chart needs (`responsive: false`, `maintainAspectRatio: false`, the page's `devicePixelRatio`, the worker platform and the package's internal plugins). It throws if your configuration sets one of these itself, and it must be called exactly once per `create`.
|
|
67
|
+
- `update` mutates `chart.data` and `chart.options`; the runtime calls `chart.update()` when the kind does not. Replacing `chart.options` as a whole drops the settings `createChart` added and makes the update fail with an error.
|
|
68
|
+
- `commands` run on demand from the main thread and return structured-cloneable values. `context.emit(name, payload)` sends events to the main thread.
|
|
69
|
+
- chartjs-plugin-zoom is registered by `startChartWorker`; a kind only writes `options.plugins.zoom`.
|
|
70
|
+
|
|
71
|
+
### 2. The main thread
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { createChartWorkerHost } from "@aiquants/chartjs-worker"
|
|
75
|
+
|
|
76
|
+
const host = createChartWorkerHost({
|
|
77
|
+
createWorker: () => new Worker(new URL("./chartWorker.ts", import.meta.url), { type: "module" }),
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const chart = host.mount(document.querySelector("[data-chart=sales]") as HTMLElement, {
|
|
81
|
+
kind: "sales",
|
|
82
|
+
props: { labels, values },
|
|
83
|
+
input: { events: ["mousemove", "mouseout", "click"], wheel: { enabled: false }, pan: { enabled: false }, pinch: { enabled: false } },
|
|
84
|
+
sizing: { maintainAspectRatio: false },
|
|
85
|
+
canvasAttributes: { role: "img", "aria-label": "Sales by month" },
|
|
86
|
+
supersede: "restart",
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
await chart.update({ labels, values: nextValues }) // resolves once these (or newer) props are drawn, animation included
|
|
90
|
+
chart.on("select", (indices) => console.log(indices))
|
|
91
|
+
const range = await chart.command<{ min: number; max: number }>("visibleRange", null)
|
|
92
|
+
chart.destroy()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The host creates its worker when the first chart with a size is mounted, so importing the module during server-side rendering never touches `Worker`. The container gets `data-chart-state` (`drawing`, `drawn` or `error`) for the latest props.
|
|
96
|
+
|
|
97
|
+
### 3. React
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { useWorkerChart } from "@aiquants/chartjs-worker/react"
|
|
101
|
+
|
|
102
|
+
function SalesChart({ labels, values }: { labels: string[]; values: Float64Array }) {
|
|
103
|
+
const props = useMemo(() => ({ labels, values }), [labels, values])
|
|
104
|
+
const chart = useWorkerChart(host, { kind: "sales", props, input, sizing, canvasAttributes, supersede: "restart" })
|
|
105
|
+
return <div ref={chart.containerRef} style={{ height: 320 }} />
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
- `props` is compared with `Object.is`: keep it with `useMemo`, or every render sends an update.
|
|
110
|
+
- `input`, `sizing` and `canvasAttributes` are compared by value; a change of `kind`, `supersede` or the host mounts the chart again.
|
|
111
|
+
- The result carries `state`, `error`, `command` (rejects while the chart is not mounted) and `on` (subscriptions survive remounts). It works under `StrictMode`.
|
|
112
|
+
|
|
113
|
+
### Vite
|
|
114
|
+
|
|
115
|
+
Vite's dependency scan does not follow `new Worker(new URL(...))`, so the dev server finds the worker's dependencies on first load, optimizes again and reloads the page. List them to avoid the reload:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
// vite.config.ts
|
|
119
|
+
export default defineConfig({
|
|
120
|
+
optimizeDeps: { include: ["@aiquants/chartjs-worker", "@aiquants/chartjs-worker/worker-env", "@aiquants/chartjs-worker/worker", "chart.js"] },
|
|
121
|
+
worker: { format: "es" },
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Data
|
|
126
|
+
|
|
127
|
+
- `props` must be structured-cloneable. Send series as typed arrays (`Float64Array`): cloning 590,000 values takes about 2 ms.
|
|
128
|
+
- `props` are cloned, not transferred, because the host sends them again when it restarts the worker.
|
|
129
|
+
|
|
130
|
+
## Input and touch
|
|
131
|
+
|
|
132
|
+
`input` mirrors the chart's own options; derive both from one place.
|
|
133
|
+
|
|
134
|
+
| Field | Mirrors | Effect on the main thread |
|
|
135
|
+
| --- | --- | --- |
|
|
136
|
+
| `events` | `options.events` | which of `mousemove`, `mouseout`, `click`, `dblclick` are forwarded |
|
|
137
|
+
| `wheel` | `plugins.zoom.zoom.wheel` | `preventDefault` on `wheel` when enabled and `modifierKey` is `null` or pressed |
|
|
138
|
+
| `pan` | `plugins.zoom.pan` | drag and one-finger panning after `threshold` pixels |
|
|
139
|
+
| `pinch` | `plugins.zoom.zoom.pinch` | two-finger pinch zoom |
|
|
140
|
+
|
|
141
|
+
Pointer, mouse and touch input all arrive through one pointer path. A finger that touches the chart shows the tooltip there, and a tap is a click. Hover moves are coalesced to one per animation frame. The canvas's `touch-action` follows `input`, so the browser keeps the gestures the chart does not use:
|
|
142
|
+
|
|
143
|
+
| `input.pan` | `input.pinch.enabled` | `touch-action` |
|
|
144
|
+
| --- | --- | --- |
|
|
145
|
+
| `mode: "x"` | any | `pan-y` (a vertical swipe scrolls the page) |
|
|
146
|
+
| `mode: "y"` | any | `pan-x` |
|
|
147
|
+
| `mode: "xy"` | any | `none` |
|
|
148
|
+
| disabled | `true` | `pan-x pan-y` |
|
|
149
|
+
| disabled | `false` | not set |
|
|
150
|
+
|
|
151
|
+
- The wheel decision cannot wait for the worker: when `onZoomStart` returns `false` in the worker, the page still does not scroll.
|
|
152
|
+
- The click right after a pan is dropped, as chartjs-plugin-zoom does.
|
|
153
|
+
- Panning and pinching are tracked by the package, not by the plugin, so `chart.isZoomingOrPanning()` stays `false` during a gesture.
|
|
154
|
+
- Callbacks such as `onPanStart` receive `{ type, pointerType, center, deltaX, deltaY, srcEvent }` in place of a Hammer.js event; positions are CSS pixels from the canvas's top left.
|
|
155
|
+
|
|
156
|
+
## Sizing
|
|
157
|
+
|
|
158
|
+
`sizing` is `{ maintainAspectRatio: false }` (fill the container) or `{ maintainAspectRatio: true, aspectRatio }`. The host measures the canvas with Chart.js's `getMaximumSize` inside the container, at most once per animation frame, and follows container resizes, a container that is hidden when the chart is mounted (the chart is created once it has a size; a chart hidden later keeps its last size) and device-pixel-ratio changes that come with a window `resize`, as Chart.js does. The worker's canvas gets the CSS size times the device pixel ratio, rounded down.
|
|
159
|
+
|
|
160
|
+
## Updates and restarts
|
|
161
|
+
|
|
162
|
+
One worker is one thread: the charts of a host are drawn one after another. `supersede` decides what an update does while the worker is still inside an earlier `create` or `update`:
|
|
163
|
+
|
|
164
|
+
- `"restart"`: the host terminates the worker, starts a new one and mounts every chart again with its latest props. Commands awaiting a reply reject with `ChartWorkerRestartedError`; earlier updates resolve when the newer props are drawn.
|
|
165
|
+
- `"queue"`: the update waits for the worker.
|
|
166
|
+
|
|
167
|
+
Give a heavy chart its own host when the other charts must not wait for it.
|
|
168
|
+
|
|
169
|
+
| Error | When |
|
|
170
|
+
| --- | --- |
|
|
171
|
+
| `ChartWorkerUnsupportedError` | `mount` on a browser without `Worker`, `OffscreenCanvas` or `transferControlToOffscreen` |
|
|
172
|
+
| `ChartWorkerKindError` | a kind's `create`, `update` or command threw; carries `workerStack` |
|
|
173
|
+
| `ChartWorkerCrashedError` | the worker stopped on an uncaught error or rejection; every chart turns `error`, and the next update or mount starts a new worker |
|
|
174
|
+
| `ChartWorkerDestroyedError` | pending updates and commands of a destroyed chart (or a terminated host) |
|
|
175
|
+
| `ChartWorkerRestartedError` | commands awaiting a reply when the worker was restarted |
|
|
176
|
+
|
|
177
|
+
## Floating stacked bars
|
|
178
|
+
|
|
179
|
+
Chart.js's bar controller walks every dataset for every bar (its axis list, its stack index and, on a stacked value axis, the stack sums), so the work grows with the square of the series count; a chart with 323 series of 1,826 bars spends most of its time there. Floating bars draw the same picture without stacking on the value axis:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { FloatingBarController, floatingValueOf, toFloatingStacks } from "@aiquants/chartjs-worker/worker"
|
|
183
|
+
|
|
184
|
+
const points = toFloatingStacks(labels, series) // series: { values, stack, order, hidden }[]
|
|
185
|
+
context.createChart({
|
|
186
|
+
type: "floatingBar",
|
|
187
|
+
data: { labels, datasets: series.map((s, index) => ({ data: points[index], stack: s.stack, order: s.order, hidden: s.hidden })) },
|
|
188
|
+
options: {
|
|
189
|
+
scales: { x: { stacked: true }, y: { stacked: false } }, // the bars are stacked already: never stack the value axis
|
|
190
|
+
plugins: { tooltip: { callbacks: { label: (item) => String(floatingValueOf(item)) } } },
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
- `toFloatingStacks` stacks as Chart.js does: visible series in `order`, positives on positives, negatives on negatives, zeros on all previous values; hidden series and `NaN` give `y: null`.
|
|
196
|
+
- Set `stacked: false` on the value axis explicitly: Chart.js stacks a value axis that has no `stacked` option when datasets have a `stack`. `FloatingBarController` throws when the value axis stacks.
|
|
197
|
+
- `FloatingBarController` (`type: "floatingBar"`, registered by `startChartWorker`) computes the axis list and each dataset's stack index once per update, instead of once per bar. With `skipNull`, the stack index depends on the bar, so it keeps Chart.js's per-bar cost.
|
|
198
|
+
- `floatingValueOf` reads the original value for tooltips (`parsed.y` is the stacked top).
|
|
199
|
+
|
|
200
|
+
## Not supported
|
|
201
|
+
|
|
202
|
+
- Drag-to-zoom (`zoom.drag.enabled`): `createChart` throws, because the plugin's drag path touches `document`.
|
|
203
|
+
- Browsers without OffscreenCanvas: `mount` throws `ChartWorkerUnsupportedError`; decide on your own fallback.
|
|
204
|
+
- Keyboard events.
|
|
205
|
+
|
|
206
|
+
## Browser support
|
|
207
|
+
|
|
208
|
+
Chrome and Edge 93+, Safari and iOS Safari 16.4+, Firefox 105+ (114+ for module workers, as in the Vite setup above): OffscreenCanvas 2D, `requestAnimationFrame` in workers and `Object.hasOwn`.
|
|
209
|
+
|
|
210
|
+
## Chart.js version
|
|
211
|
+
|
|
212
|
+
`FloatingBarController` relies on `BarController._getAxis` and `BarController._getStackIndex`, internal methods of Chart.js 4.5 (it stops at load time when they are missing), and the gesture bridge reproduces decisions of chartjs-plugin-zoom 2.2.0. Both are checked by the tests of this package; a Chart.js upgrade beyond 4.5 needs them to pass again.
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
MIT. The worker bundle includes chartjs-plugin-zoom (MIT); see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
`@aiquants/chartjs-worker` includes code from the following project.
|
|
4
|
+
|
|
5
|
+
## chartjs-plugin-zoom 2.2.0
|
|
6
|
+
|
|
7
|
+
- Source: <https://github.com/chartjs/chartjs-plugin-zoom>
|
|
8
|
+
- Used in:
|
|
9
|
+
- `dist/worker/index.mjs`: the plugin's code is bundled into the worker entry (its Hammer.js import is replaced by an inert stub). The bundle keeps the plugin's banner: `chartjs-plugin-zoom v2.2.0 (c) 2016-2024 chartjs-plugin-zoom Contributors, Released under the MIT License`.
|
|
10
|
+
- The gesture bridge of the worker entry reproduces the plugin's pan, pinch and click-filter decisions (`createEnabler`, `startPan`, `handlePan`, `endPan`, `getEnabledScalesByPoint`, `getScaleUnderPoint`, `directionEnabled`, `directionsEnabled`, `startPinch`, `handlePinch`, `endPinch`, `pinchAxes`, `getModifierKey`, `keyNotPressed` and `beforeEvent`).
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
The MIT License (MIT)
|
|
14
|
+
|
|
15
|
+
Copyright (c) 2013-2021 chartjs-plugin-zoom contributors
|
|
16
|
+
|
|
17
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { C as ChartWorkerHostOptions, a as ChartWorkerHost } from "./types-B3UEONTF.mjs";
|
|
2
|
+
export { b as ChartDrawState, c as ChartEventName, d as ChartInputOptions, e as ChartSizing, f as ChartStateListener, M as ModifierKey, P as PanInputOptions, g as PinchInputOptions, S as SupersedePolicy, W as WheelInputOptions, h as WorkerChartHandle, i as WorkerChartSpec } from "./types-B3UEONTF.mjs";
|
|
3
|
+
declare class ChartWorkerUnsupportedError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
declare class ChartWorkerKindError extends Error {
|
|
7
|
+
readonly workerStack: string;
|
|
8
|
+
constructor(message: string, workerStack: string);
|
|
9
|
+
}
|
|
10
|
+
declare class ChartWorkerDestroyedError extends Error {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
declare class ChartWorkerRestartedError extends Error {
|
|
14
|
+
constructor(message: string);
|
|
15
|
+
}
|
|
16
|
+
declare class ChartWorkerCrashedError extends Error {
|
|
17
|
+
readonly workerStack: string;
|
|
18
|
+
constructor(message: string, workerStack: string);
|
|
19
|
+
}
|
|
20
|
+
declare function createChartWorkerHost(options: ChartWorkerHostOptions): ChartWorkerHost;
|
|
21
|
+
export { ChartWorkerCrashedError, ChartWorkerDestroyedError, ChartWorkerHost, ChartWorkerHostOptions, ChartWorkerKindError, ChartWorkerRestartedError, ChartWorkerUnsupportedError, createChartWorkerHost };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { C as ChartWorkerHostOptions, a as ChartWorkerHost } from "./types-B3UEONTF.js";
|
|
2
|
+
export { b as ChartDrawState, c as ChartEventName, d as ChartInputOptions, e as ChartSizing, f as ChartStateListener, M as ModifierKey, P as PanInputOptions, g as PinchInputOptions, S as SupersedePolicy, W as WheelInputOptions, h as WorkerChartHandle, i as WorkerChartSpec } from "./types-B3UEONTF.js";
|
|
3
|
+
declare class ChartWorkerUnsupportedError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
declare class ChartWorkerKindError extends Error {
|
|
7
|
+
readonly workerStack: string;
|
|
8
|
+
constructor(message: string, workerStack: string);
|
|
9
|
+
}
|
|
10
|
+
declare class ChartWorkerDestroyedError extends Error {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
declare class ChartWorkerRestartedError extends Error {
|
|
14
|
+
constructor(message: string);
|
|
15
|
+
}
|
|
16
|
+
declare class ChartWorkerCrashedError extends Error {
|
|
17
|
+
readonly workerStack: string;
|
|
18
|
+
constructor(message: string, workerStack: string);
|
|
19
|
+
}
|
|
20
|
+
declare function createChartWorkerHost(options: ChartWorkerHostOptions): ChartWorkerHost;
|
|
21
|
+
export { ChartWorkerCrashedError, ChartWorkerDestroyedError, ChartWorkerHost, ChartWorkerHostOptions, ChartWorkerKindError, ChartWorkerRestartedError, ChartWorkerUnsupportedError, createChartWorkerHost };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var U=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var ie=Object.prototype.hasOwnProperty;var se=(n,e)=>{for(var r in e)U(n,r,{get:e[r],enumerable:!0})},oe=(n,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of ne(e))!ie.call(n,p)&&p!==r&&U(n,p,{get:()=>e[p],enumerable:!(s=re(e,p))||s.enumerable});return n};var ae=n=>oe(U({},"__esModule",{value:!0}),n);var ce={};se(ce,{ChartWorkerCrashedError:()=>M,ChartWorkerDestroyedError:()=>I,ChartWorkerKindError:()=>x,ChartWorkerRestartedError:()=>L,ChartWorkerUnsupportedError:()=>T,createChartWorkerHost:()=>Z});module.exports=ae(ce);var T=class extends Error{constructor(e){super(e),this.name="ChartWorkerUnsupportedError"}},x=class extends Error{constructor(e,r){super(e),this.name="ChartWorkerKindError",this.workerStack=r}},I=class extends Error{constructor(e){super(e),this.name="ChartWorkerDestroyedError"}},L=class extends Error{constructor(e){super(e),this.name="ChartWorkerRestartedError"}},M=class extends Error{constructor(e,r){super(e),this.name="ChartWorkerCrashedError",this.workerStack=r}};function N(n){return n.pan.enabled?n.pan.mode==="x"?"pan-y":n.pan.mode==="y"?"pan-x":"none":n.pinch.enabled?"pan-x pan-y":null}function q(n){return n==="mouse"||n==="touch"||n==="pen"?n:null}function O(n){return{ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:n.shiftKey,metaKey:n.metaKey}}function X(n,e){return Math.hypot(n.x-e.x,n.y-e.y)}function B(n,e){let r=new Map,s=null,p="mouse",v=null,g=!1,u=null,C=null,k=null,b=null,P=!1,E=!1,z=i=>e.input().events.includes(i),S=i=>{let a=n.getBoundingClientRect();return{x:Math.round(i.clientX-a.left),y:Math.round(i.clientY-a.top)}},R=()=>{if(C===null)return;let i=C;C=null,e.send(i)},H=()=>{P=!1,!E&&(R(),k!==null&&(e.send(k),k=null),b!==null&&(e.send(b),b=null))},t=()=>{P||(P=!0,e.view.requestAnimationFrame(H))},o=(i,a,d)=>{z("mousemove")&&(C={type:"pointer",event:"mousemove",x:i.x,y:i.y,pointerType:a,modifiers:O(d)},t())},c=(i,a,d)=>{let m=r.get(a[0]),y=r.get(a[1]);return{type:"pinch",phase:i,centerX:(m.x+y.x)/2,centerY:(m.y+y.y)/2,scale:d,pointers:[{x:m.x,y:m.y},{x:y.x,y:y.y}]}},l=(i,a,d,m)=>{g=!1,v=null,k!==null&&(e.send(k),k=null),e.send({type:"pan",phase:"end",x:i.x,y:i.y,deltaX:i.x-a.startX,deltaY:i.y-a.startY,pointerType:d,modifiers:O(m)})},h=i=>{let a=q(i.pointerType);if(a===null)return;p=a;let d=S(i);if(r.set(i.pointerId,{x:d.x,y:d.y,startX:d.x,startY:d.y}),n.setPointerCapture(i.pointerId),a==="touch"){if(s===null)s=i.pointerId,o(d,a,i);else if(u===null&&r.size===2&&e.input().pinch.enabled){let m=[...r.keys()],y=r.get(m[0]);g&&l(y,y,"touch",i),v=null,u={ids:m,distance:X(y,d)},e.send(c("start",m,1));return}}r.size===1&&(a!=="mouse"||i.button===0)&&(v=i.pointerId)},f=i=>{let a=q(i.pointerType);if(a===null)return;let d=S(i),m=r.get(i.pointerId);if(m!==void 0&&(m.x=d.x,m.y=d.y),(a!=="touch"||i.pointerId===s)&&o(d,a,i),u!==null){if(m!==void 0&&u.ids.includes(i.pointerId)){let ee=r.get(u.ids[0]),te=r.get(u.ids[1]);b=c("move",u.ids,X(ee,te)/u.distance),t()}return}if(m===void 0||i.pointerId!==v)return;let y=e.input();if(!y.pan.enabled)return;let Y=d.x-m.startX,$=d.y-m.startY,F={type:"pan",phase:"move",x:d.x,y:d.y,deltaX:Y,deltaY:$,pointerType:a,modifiers:O(i)};if(g){k=F,t();return}Math.hypot(Y,$)<=y.pan.threshold||(g=!0,e.send({...F,phase:"start"}))},w=i=>{let a=q(i.pointerType),d=r.get(i.pointerId);if(!(a===null||d===void 0)){if(i.pointerId===s&&(s=null),u!==null){if(u.ids.includes(i.pointerId)){let m=r.get(u.ids[0]),y=r.get(u.ids[1]);b=null,e.send(c("end",u.ids,X(m,y)/u.distance)),u=null}r.delete(i.pointerId);return}r.delete(i.pointerId),i.pointerId===v&&(g&&l(d,d,a,i),v=null)}},A=i=>{let a=q(i.pointerType);if(a===null||a==="touch"||(C=null,!z("mouseout")))return;let d=S(i);e.send({type:"pointer",event:"mouseout",x:d.x,y:d.y,pointerType:a,modifiers:O(i)})},W=i=>{let a=i.type==="dblclick"?"dblclick":"click";if(R(),!z(a))return;let d=S(i);e.send({type:"pointer",event:a,x:d.x,y:d.y,pointerType:p,modifiers:O(i)})},K=i=>{let a=e.input().wheel;if(!a.enabled)return;(a.modifierKey===null||i[`${a.modifierKey}Key`])&&i.preventDefault();let d=S(i);e.send({type:"wheel",x:d.x,y:d.y,deltaX:i.deltaX,deltaY:i.deltaY,deltaMode:i.deltaMode,modifiers:O(i)})},j=()=>{let i=N(e.input());if(i===null){n.style.removeProperty("touch-action");return}n.style.setProperty("touch-action",i)};return n.addEventListener("pointerdown",h),n.addEventListener("pointermove",f),n.addEventListener("pointerup",w),n.addEventListener("pointercancel",w),n.addEventListener("pointerleave",A),n.addEventListener("click",W),n.addEventListener("dblclick",W),n.addEventListener("wheel",K,{passive:!1}),j(),{refresh:j,dispose(){E=!0,n.removeEventListener("pointerdown",h),n.removeEventListener("pointermove",f),n.removeEventListener("pointerup",w),n.removeEventListener("pointercancel",w),n.removeEventListener("pointerleave",A),n.removeEventListener("click",W),n.removeEventListener("dblclick",W),n.removeEventListener("wheel",K)}}}var V=require("chart.js/helpers");function _(n,e,r,s){let p=e.maintainAspectRatio?e.aspectRatio:void 0,v=(0,V.getMaximumSize)(n,r,s,p);return{width:Math.floor(v.width),height:Math.floor(v.height)}}function G(n,e,r){let s=!1,p=[],v=!1,g=(...b)=>{p=b,!s&&(s=!0,e.requestAnimationFrame(()=>{if(s=!1,v)return;let P=n.clientWidth;r(...p),P<n.clientWidth&&r()}))},u=new ResizeObserver(b=>{let{width:P,height:E}=b[0].contentRect;P===0&&E===0||g(P,E)});u.observe(n);let C=e.devicePixelRatio,k=()=>{e.devicePixelRatio!==C&&(C=e.devicePixelRatio,g())};return e.addEventListener("resize",k),{dispose(){v=!0,u.disconnect(),e.removeEventListener("resize",k)}}}var de=new Set(["style","width","height"]);function J(n){for(let e of Object.keys(n))if(de.has(e.toLowerCase()))throw new Error(`The canvas attribute "${e}" is managed by @aiquants/chartjs-worker and cannot be set through canvasAttributes.`)}var D=class{constructor(e){this.revision=0;this.mounted=!1;this.size=null;this.state="drawing";this.error=null;this.commands=new Map;this.transferred=!1;this.updates=[];this.eventListeners=new Map;this.stateListeners=new Set;let r=e.container.ownerDocument.defaultView;if(r===null)throw new Error("The container must belong to a document that has a window.");J(e.spec.canvasAttributes),this.chartId=e.chartId,this.container=e.container,this.kind=e.spec.kind,this.supersede=e.spec.supersede,this.view=r,this.props=e.spec.props,this.input=e.spec.input,this.sizing=e.spec.sizing,this.attributes=e.spec.canvasAttributes,this.sendInput=e.sendInput,this.canvas=this.createCanvas(),this.container.append(this.canvas),this.pointer=this.attachInput(),this.writeState(),this.tracker=G(this.container,r,e.onContainerResize)}measure(e,r){let s=_(this.canvas,this.sizing,e,r);return s.width<=0||s.height<=0?null:(this.writeCanvasSize(s.width,s.height),{width:s.width,height:s.height,devicePixelRatio:this.view.devicePixelRatio})}takeOffscreenCanvas(){return this.transferred&&this.replaceCanvas(),this.transferred=!0,this.canvas.transferControlToOffscreen()}addUpdate(){let e=this.revision;return new Promise((r,s)=>{this.updates.push({revision:e,resolve:r,reject:s})})}drawn(e){for(let r of this.takeUpdates(e))r.resolve();e===this.revision&&this.setState("drawn",null)}failed(e,r){for(let s of this.takeUpdates(e))s.reject(r);e===this.revision&&this.setState("error",r)}detach(e){this.mounted=!1;for(let[r,s]of this.commands)s.sent&&(this.commands.delete(r),s.reject(e))}rejectAll(e){for(let r of this.updates.splice(0))r.reject(e);for(let r of this.commands.values())r.reject(e);this.commands.clear()}setState(e,r){if(!(this.state===e&&this.error===r)){this.state=e,this.error=r,this.writeState();for(let s of[...this.stateListeners])s(e,r)}}emit(e,r){let s=this.eventListeners.get(e);if(s!==void 0)for(let p of[...s])p(r)}on(e,r){let s=this.eventListeners.get(e);return s===void 0&&(s=new Set,this.eventListeners.set(e,s)),s.add(r),()=>{s.delete(r)}}onStateChange(e){return this.stateListeners.add(e),()=>{this.stateListeners.delete(e)}}setInput(e){this.input=e,this.pointer.refresh()}setAttributes(e){J(e);for(let r of Object.keys(this.attributes))Object.hasOwn(e,r)||this.canvas.removeAttribute(r);this.attributes=e,this.writeAttributes(this.canvas)}dispose(){this.tracker.dispose(),this.pointer.dispose(),this.canvas.remove(),this.container.removeAttribute("data-chart-state"),this.eventListeners.clear(),this.stateListeners.clear()}takeUpdates(e){let r=this.updates.findIndex(s=>s.revision>e);return this.updates.splice(0,r===-1?this.updates.length:r)}createCanvas(){let e=this.container.ownerDocument.createElement("canvas");return e.style.setProperty("display","block"),e.style.setProperty("box-sizing","border-box"),e.style.setProperty("user-select","none"),e.style.setProperty("-webkit-user-select","none"),e.style.setProperty("-webkit-touch-callout","none"),e.style.setProperty("-webkit-user-drag","none"),e.style.setProperty("-webkit-tap-highlight-color","rgba(0, 0, 0, 0)"),this.writeAttributes(e),e}replaceCanvas(){let e=this.canvas;this.pointer.dispose(),this.canvas=this.createCanvas(),this.size!==null&&this.writeCanvasSize(this.size.width,this.size.height),e.replaceWith(this.canvas),this.pointer=this.attachInput()}attachInput(){return B(this.canvas,{input:()=>this.input,send:this.sendInput,view:this.view})}writeCanvasSize(e,r){this.canvas.style.setProperty("width",`${e}px`),this.canvas.style.setProperty("height",`${r}px`)}writeAttributes(e){for(let[r,s]of Object.entries(this.attributes))e.setAttribute(r,s)}writeState(){this.container.setAttribute("data-chart-state",this.state)}};function Q(n){return typeof n.Worker!="function"?"Worker":typeof n.OffscreenCanvas!="function"?"OffscreenCanvas":n.HTMLCanvasElement===void 0||!("transferControlToOffscreen"in n.HTMLCanvasElement.prototype)?"HTMLCanvasElement.transferControlToOffscreen":null}function ue(n,e){return n!==null&&n.width===e.width&&n.height===e.height&&n.devicePixelRatio===e.devicePixelRatio}function Z(n){let e=new Map,r=new Set,s=null,p=!1,v=0,g=0,u=(t,o=[])=>{s.postMessage(t,o)},C=(t,o)=>{s?.terminate(),s=null,p=!0,r.clear();let c=new M(t,o);for(let l of e.values())l.mounted=!1,l.rejectAll(c),l.setState("error",c)},k=t=>{if(t.type==="fatal"){C(t.message,t.stack);return}if(t.type==="updating"){r.add(t.chartId);return}if(t.type==="updated"){r.delete(t.chartId);return}let o=e.get(t.chartId);if(o!==void 0)switch(t.type){case"drawn":o.drawn(t.revision);return;case"error":o.failed(t.revision,new x(t.message,t.stack));return;case"event":o.emit(t.name,t.payload);return;case"commandResult":{let c=o.commands.get(t.requestId);if(c===void 0)return;o.commands.delete(t.requestId),t.ok?c.resolve(t.value):c.reject(new x(t.message,t.stack));return}}},b=()=>{if(s!==null)return s;let t=n.createWorker();return t.addEventListener("message",o=>{s===t&&k(o.data)}),t.addEventListener("error",o=>{s===t&&C(o.message,"")}),t.addEventListener("messageerror",()=>{s===t&&C("A message from the chart worker could not be deserialized.","")}),s=t,p=!1,t},P=t=>{for(let[o,c]of t.commands)if(!c.sent)try{u({type:"command",chartId:t.chartId,requestId:o,name:c.name,payload:c.payload}),c.sent=!0}catch(l){t.commands.delete(o),c.reject(l)}},E=t=>{if(t.size===null)return;b();let o=t.takeOffscreenCanvas();try{u({type:"mount",chartId:t.chartId,kind:t.kind,canvas:o,size:t.size,props:t.props,revision:t.revision},[o])}catch(c){t.failed(t.revision,c);return}t.mounted=!0,P(t)},z=()=>{s?.terminate(),s=null,r.clear();let t=new L("The chart worker was restarted, so this command was dropped.");for(let o of e.values())o.detach(t);for(let o of e.values())E(o)},S=(t,o,c)=>{let l=t.measure(o,c);if(!(l===null||ue(t.size,l))&&(t.size=l,!p)){if(!t.mounted){E(t);return}u({type:"resize",chartId:t.chartId,size:l})}},R=t=>{if(p||t.mounted&&r.size>0&&t.supersede==="restart"){z();return}if(!t.mounted){E(t);return}try{u({type:"update",chartId:t.chartId,props:t.props,revision:t.revision})}catch(o){t.failed(t.revision,o)}},H=(t,o)=>{e.delete(t.chartId)&&(t.mounted&&u({type:"destroy",chartId:t.chartId}),t.rejectAll(new I(o)),t.dispose())};return{mount(t,o){let c=Q(globalThis);if(c!==null)throw new T(`This browser cannot draw charts in a worker: ${c} is missing.`);v+=1;let l=`chart-${v}`,h=new D({chartId:l,container:t,spec:o,sendInput:f=>{h.mounted&&u({...f,chartId:l})},onContainerResize:(f,w)=>S(h,f,w)});return e.set(l,h),S(h),p&&z(),{update(f){if(!e.has(l))return Promise.reject(new I(`The chart "${l}" has been destroyed.`));h.props=f,h.revision+=1;let w=h.addUpdate();return h.setState("drawing",null),R(h),w},setInput(f){h.setInput(f)},setSizing(f){h.sizing=f,S(h)},setCanvasAttributes(f){h.setAttributes(f)},command(f,w){if(!e.has(l))return Promise.reject(new I(`The chart "${l}" has been destroyed.`));g+=1;let A=g,W=new Promise((K,j)=>{h.commands.set(A,{name:f,payload:w,sent:!1,resolve:K,reject:j})});return h.mounted&&P(h),W},on(f,w){return h.on(f,w)},onStateChange(f){return h.onStateChange(f)},destroy(){H(h,`The chart "${l}" has been destroyed.`)}}},terminate(){for(let t of[...e.values()])H(t,"The chart worker host has been terminated.");s?.terminate(),s=null,p=!1,r.clear()}}}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var L=class extends Error{constructor(e){super(e),this.name="ChartWorkerUnsupportedError"}},W=class extends Error{constructor(e,r){super(e),this.name="ChartWorkerKindError",this.workerStack=r}},I=class extends Error{constructor(e){super(e),this.name="ChartWorkerDestroyedError"}},M=class extends Error{constructor(e){super(e),this.name="ChartWorkerRestartedError"}},O=class extends Error{constructor(e,r){super(e),this.name="ChartWorkerCrashedError",this.workerStack=r}};function F(n){return n.pan.enabled?n.pan.mode==="x"?"pan-y":n.pan.mode==="y"?"pan-x":"none":n.pinch.enabled?"pan-x pan-y":null}function q(n){return n==="mouse"||n==="touch"||n==="pen"?n:null}function T(n){return{ctrlKey:n.ctrlKey,altKey:n.altKey,shiftKey:n.shiftKey,metaKey:n.metaKey}}function U(n,e){return Math.hypot(n.x-e.x,n.y-e.y)}function N(n,e){let r=new Map,s=null,m="mouse",v=null,g=!1,u=null,C=null,k=null,b=null,P=!1,E=!1,x=i=>e.input().events.includes(i),S=i=>{let a=n.getBoundingClientRect();return{x:Math.round(i.clientX-a.left),y:Math.round(i.clientY-a.top)}},R=()=>{if(C===null)return;let i=C;C=null,e.send(i)},H=()=>{P=!1,!E&&(R(),k!==null&&(e.send(k),k=null),b!==null&&(e.send(b),b=null))},t=()=>{P||(P=!0,e.view.requestAnimationFrame(H))},o=(i,a,d)=>{x("mousemove")&&(C={type:"pointer",event:"mousemove",x:i.x,y:i.y,pointerType:a,modifiers:T(d)},t())},c=(i,a,d)=>{let f=r.get(a[0]),y=r.get(a[1]);return{type:"pinch",phase:i,centerX:(f.x+y.x)/2,centerY:(f.y+y.y)/2,scale:d,pointers:[{x:f.x,y:f.y},{x:y.x,y:y.y}]}},p=(i,a,d,f)=>{g=!1,v=null,k!==null&&(e.send(k),k=null),e.send({type:"pan",phase:"end",x:i.x,y:i.y,deltaX:i.x-a.startX,deltaY:i.y-a.startY,pointerType:d,modifiers:T(f)})},l=i=>{let a=q(i.pointerType);if(a===null)return;m=a;let d=S(i);if(r.set(i.pointerId,{x:d.x,y:d.y,startX:d.x,startY:d.y}),n.setPointerCapture(i.pointerId),a==="touch"){if(s===null)s=i.pointerId,o(d,a,i);else if(u===null&&r.size===2&&e.input().pinch.enabled){let f=[...r.keys()],y=r.get(f[0]);g&&p(y,y,"touch",i),v=null,u={ids:f,distance:U(y,d)},e.send(c("start",f,1));return}}r.size===1&&(a!=="mouse"||i.button===0)&&(v=i.pointerId)},h=i=>{let a=q(i.pointerType);if(a===null)return;let d=S(i),f=r.get(i.pointerId);if(f!==void 0&&(f.x=d.x,f.y=d.y),(a!=="touch"||i.pointerId===s)&&o(d,a,i),u!==null){if(f!==void 0&&u.ids.includes(i.pointerId)){let J=r.get(u.ids[0]),Q=r.get(u.ids[1]);b=c("move",u.ids,U(J,Q)/u.distance),t()}return}if(f===void 0||i.pointerId!==v)return;let y=e.input();if(!y.pan.enabled)return;let X=d.x-f.startX,Y=d.y-f.startY,$={type:"pan",phase:"move",x:d.x,y:d.y,deltaX:X,deltaY:Y,pointerType:a,modifiers:T(i)};if(g){k=$,t();return}Math.hypot(X,Y)<=y.pan.threshold||(g=!0,e.send({...$,phase:"start"}))},w=i=>{let a=q(i.pointerType),d=r.get(i.pointerId);if(!(a===null||d===void 0)){if(i.pointerId===s&&(s=null),u!==null){if(u.ids.includes(i.pointerId)){let f=r.get(u.ids[0]),y=r.get(u.ids[1]);b=null,e.send(c("end",u.ids,U(f,y)/u.distance)),u=null}r.delete(i.pointerId);return}r.delete(i.pointerId),i.pointerId===v&&(g&&p(d,d,a,i),v=null)}},A=i=>{let a=q(i.pointerType);if(a===null||a==="touch"||(C=null,!x("mouseout")))return;let d=S(i);e.send({type:"pointer",event:"mouseout",x:d.x,y:d.y,pointerType:a,modifiers:T(i)})},z=i=>{let a=i.type==="dblclick"?"dblclick":"click";if(R(),!x(a))return;let d=S(i);e.send({type:"pointer",event:a,x:d.x,y:d.y,pointerType:m,modifiers:T(i)})},K=i=>{let a=e.input().wheel;if(!a.enabled)return;(a.modifierKey===null||i[`${a.modifierKey}Key`])&&i.preventDefault();let d=S(i);e.send({type:"wheel",x:d.x,y:d.y,deltaX:i.deltaX,deltaY:i.deltaY,deltaMode:i.deltaMode,modifiers:T(i)})},j=()=>{let i=F(e.input());if(i===null){n.style.removeProperty("touch-action");return}n.style.setProperty("touch-action",i)};return n.addEventListener("pointerdown",l),n.addEventListener("pointermove",h),n.addEventListener("pointerup",w),n.addEventListener("pointercancel",w),n.addEventListener("pointerleave",A),n.addEventListener("click",z),n.addEventListener("dblclick",z),n.addEventListener("wheel",K,{passive:!1}),j(),{refresh:j,dispose(){E=!0,n.removeEventListener("pointerdown",l),n.removeEventListener("pointermove",h),n.removeEventListener("pointerup",w),n.removeEventListener("pointercancel",w),n.removeEventListener("pointerleave",A),n.removeEventListener("click",z),n.removeEventListener("dblclick",z),n.removeEventListener("wheel",K)}}}import{getMaximumSize as Z}from"chart.js/helpers";function B(n,e,r,s){let m=e.maintainAspectRatio?e.aspectRatio:void 0,v=Z(n,r,s,m);return{width:Math.floor(v.width),height:Math.floor(v.height)}}function V(n,e,r){let s=!1,m=[],v=!1,g=(...b)=>{m=b,!s&&(s=!0,e.requestAnimationFrame(()=>{if(s=!1,v)return;let P=n.clientWidth;r(...m),P<n.clientWidth&&r()}))},u=new ResizeObserver(b=>{let{width:P,height:E}=b[0].contentRect;P===0&&E===0||g(P,E)});u.observe(n);let C=e.devicePixelRatio,k=()=>{e.devicePixelRatio!==C&&(C=e.devicePixelRatio,g())};return e.addEventListener("resize",k),{dispose(){v=!0,u.disconnect(),e.removeEventListener("resize",k)}}}var ee=new Set(["style","width","height"]);function _(n){for(let e of Object.keys(n))if(ee.has(e.toLowerCase()))throw new Error(`The canvas attribute "${e}" is managed by @aiquants/chartjs-worker and cannot be set through canvasAttributes.`)}var D=class{constructor(e){this.revision=0;this.mounted=!1;this.size=null;this.state="drawing";this.error=null;this.commands=new Map;this.transferred=!1;this.updates=[];this.eventListeners=new Map;this.stateListeners=new Set;let r=e.container.ownerDocument.defaultView;if(r===null)throw new Error("The container must belong to a document that has a window.");_(e.spec.canvasAttributes),this.chartId=e.chartId,this.container=e.container,this.kind=e.spec.kind,this.supersede=e.spec.supersede,this.view=r,this.props=e.spec.props,this.input=e.spec.input,this.sizing=e.spec.sizing,this.attributes=e.spec.canvasAttributes,this.sendInput=e.sendInput,this.canvas=this.createCanvas(),this.container.append(this.canvas),this.pointer=this.attachInput(),this.writeState(),this.tracker=V(this.container,r,e.onContainerResize)}measure(e,r){let s=B(this.canvas,this.sizing,e,r);return s.width<=0||s.height<=0?null:(this.writeCanvasSize(s.width,s.height),{width:s.width,height:s.height,devicePixelRatio:this.view.devicePixelRatio})}takeOffscreenCanvas(){return this.transferred&&this.replaceCanvas(),this.transferred=!0,this.canvas.transferControlToOffscreen()}addUpdate(){let e=this.revision;return new Promise((r,s)=>{this.updates.push({revision:e,resolve:r,reject:s})})}drawn(e){for(let r of this.takeUpdates(e))r.resolve();e===this.revision&&this.setState("drawn",null)}failed(e,r){for(let s of this.takeUpdates(e))s.reject(r);e===this.revision&&this.setState("error",r)}detach(e){this.mounted=!1;for(let[r,s]of this.commands)s.sent&&(this.commands.delete(r),s.reject(e))}rejectAll(e){for(let r of this.updates.splice(0))r.reject(e);for(let r of this.commands.values())r.reject(e);this.commands.clear()}setState(e,r){if(!(this.state===e&&this.error===r)){this.state=e,this.error=r,this.writeState();for(let s of[...this.stateListeners])s(e,r)}}emit(e,r){let s=this.eventListeners.get(e);if(s!==void 0)for(let m of[...s])m(r)}on(e,r){let s=this.eventListeners.get(e);return s===void 0&&(s=new Set,this.eventListeners.set(e,s)),s.add(r),()=>{s.delete(r)}}onStateChange(e){return this.stateListeners.add(e),()=>{this.stateListeners.delete(e)}}setInput(e){this.input=e,this.pointer.refresh()}setAttributes(e){_(e);for(let r of Object.keys(this.attributes))Object.hasOwn(e,r)||this.canvas.removeAttribute(r);this.attributes=e,this.writeAttributes(this.canvas)}dispose(){this.tracker.dispose(),this.pointer.dispose(),this.canvas.remove(),this.container.removeAttribute("data-chart-state"),this.eventListeners.clear(),this.stateListeners.clear()}takeUpdates(e){let r=this.updates.findIndex(s=>s.revision>e);return this.updates.splice(0,r===-1?this.updates.length:r)}createCanvas(){let e=this.container.ownerDocument.createElement("canvas");return e.style.setProperty("display","block"),e.style.setProperty("box-sizing","border-box"),e.style.setProperty("user-select","none"),e.style.setProperty("-webkit-user-select","none"),e.style.setProperty("-webkit-touch-callout","none"),e.style.setProperty("-webkit-user-drag","none"),e.style.setProperty("-webkit-tap-highlight-color","rgba(0, 0, 0, 0)"),this.writeAttributes(e),e}replaceCanvas(){let e=this.canvas;this.pointer.dispose(),this.canvas=this.createCanvas(),this.size!==null&&this.writeCanvasSize(this.size.width,this.size.height),e.replaceWith(this.canvas),this.pointer=this.attachInput()}attachInput(){return N(this.canvas,{input:()=>this.input,send:this.sendInput,view:this.view})}writeCanvasSize(e,r){this.canvas.style.setProperty("width",`${e}px`),this.canvas.style.setProperty("height",`${r}px`)}writeAttributes(e){for(let[r,s]of Object.entries(this.attributes))e.setAttribute(r,s)}writeState(){this.container.setAttribute("data-chart-state",this.state)}};function G(n){return typeof n.Worker!="function"?"Worker":typeof n.OffscreenCanvas!="function"?"OffscreenCanvas":n.HTMLCanvasElement===void 0||!("transferControlToOffscreen"in n.HTMLCanvasElement.prototype)?"HTMLCanvasElement.transferControlToOffscreen":null}function te(n,e){return n!==null&&n.width===e.width&&n.height===e.height&&n.devicePixelRatio===e.devicePixelRatio}function re(n){let e=new Map,r=new Set,s=null,m=!1,v=0,g=0,u=(t,o=[])=>{s.postMessage(t,o)},C=(t,o)=>{s?.terminate(),s=null,m=!0,r.clear();let c=new O(t,o);for(let p of e.values())p.mounted=!1,p.rejectAll(c),p.setState("error",c)},k=t=>{if(t.type==="fatal"){C(t.message,t.stack);return}if(t.type==="updating"){r.add(t.chartId);return}if(t.type==="updated"){r.delete(t.chartId);return}let o=e.get(t.chartId);if(o!==void 0)switch(t.type){case"drawn":o.drawn(t.revision);return;case"error":o.failed(t.revision,new W(t.message,t.stack));return;case"event":o.emit(t.name,t.payload);return;case"commandResult":{let c=o.commands.get(t.requestId);if(c===void 0)return;o.commands.delete(t.requestId),t.ok?c.resolve(t.value):c.reject(new W(t.message,t.stack));return}}},b=()=>{if(s!==null)return s;let t=n.createWorker();return t.addEventListener("message",o=>{s===t&&k(o.data)}),t.addEventListener("error",o=>{s===t&&C(o.message,"")}),t.addEventListener("messageerror",()=>{s===t&&C("A message from the chart worker could not be deserialized.","")}),s=t,m=!1,t},P=t=>{for(let[o,c]of t.commands)if(!c.sent)try{u({type:"command",chartId:t.chartId,requestId:o,name:c.name,payload:c.payload}),c.sent=!0}catch(p){t.commands.delete(o),c.reject(p)}},E=t=>{if(t.size===null)return;b();let o=t.takeOffscreenCanvas();try{u({type:"mount",chartId:t.chartId,kind:t.kind,canvas:o,size:t.size,props:t.props,revision:t.revision},[o])}catch(c){t.failed(t.revision,c);return}t.mounted=!0,P(t)},x=()=>{s?.terminate(),s=null,r.clear();let t=new M("The chart worker was restarted, so this command was dropped.");for(let o of e.values())o.detach(t);for(let o of e.values())E(o)},S=(t,o,c)=>{let p=t.measure(o,c);if(!(p===null||te(t.size,p))&&(t.size=p,!m)){if(!t.mounted){E(t);return}u({type:"resize",chartId:t.chartId,size:p})}},R=t=>{if(m||t.mounted&&r.size>0&&t.supersede==="restart"){x();return}if(!t.mounted){E(t);return}try{u({type:"update",chartId:t.chartId,props:t.props,revision:t.revision})}catch(o){t.failed(t.revision,o)}},H=(t,o)=>{e.delete(t.chartId)&&(t.mounted&&u({type:"destroy",chartId:t.chartId}),t.rejectAll(new I(o)),t.dispose())};return{mount(t,o){let c=G(globalThis);if(c!==null)throw new L(`This browser cannot draw charts in a worker: ${c} is missing.`);v+=1;let p=`chart-${v}`,l=new D({chartId:p,container:t,spec:o,sendInput:h=>{l.mounted&&u({...h,chartId:p})},onContainerResize:(h,w)=>S(l,h,w)});return e.set(p,l),S(l),m&&x(),{update(h){if(!e.has(p))return Promise.reject(new I(`The chart "${p}" has been destroyed.`));l.props=h,l.revision+=1;let w=l.addUpdate();return l.setState("drawing",null),R(l),w},setInput(h){l.setInput(h)},setSizing(h){l.sizing=h,S(l)},setCanvasAttributes(h){l.setAttributes(h)},command(h,w){if(!e.has(p))return Promise.reject(new I(`The chart "${p}" has been destroyed.`));g+=1;let A=g,z=new Promise((K,j)=>{l.commands.set(A,{name:h,payload:w,sent:!1,resolve:K,reject:j})});return l.mounted&&P(l),z},on(h,w){return l.on(h,w)},onStateChange(h){return l.onStateChange(h)},destroy(){H(l,`The chart "${p}" has been destroyed.`)}}},terminate(){for(let t of[...e.values()])H(t,"The chart worker host has been terminated.");s?.terminate(),s=null,m=!1,r.clear()}}}export{O as ChartWorkerCrashedError,I as ChartWorkerDestroyedError,W as ChartWorkerKindError,M as ChartWorkerRestartedError,L as ChartWorkerUnsupportedError,re as createChartWorkerHost};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { b as ChartDrawState, a as ChartWorkerHost, i as WorkerChartSpec } from "../types-B3UEONTF.mjs";
|
|
2
|
+
type UseWorkerChartResult = {
|
|
3
|
+
containerRef: (element: HTMLElement | null) => void;
|
|
4
|
+
state: ChartDrawState;
|
|
5
|
+
error: Error | null;
|
|
6
|
+
command<R>(name: string, payload: unknown): Promise<R>;
|
|
7
|
+
on(event: string, listener: (payload: unknown) => void): () => void;
|
|
8
|
+
};
|
|
9
|
+
declare function useWorkerChart<P>(host: ChartWorkerHost, spec: WorkerChartSpec<P>): UseWorkerChartResult;
|
|
10
|
+
export { type UseWorkerChartResult, useWorkerChart };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { b as ChartDrawState, a as ChartWorkerHost, i as WorkerChartSpec } from "../types-B3UEONTF.js";
|
|
2
|
+
type UseWorkerChartResult = {
|
|
3
|
+
containerRef: (element: HTMLElement | null) => void;
|
|
4
|
+
state: ChartDrawState;
|
|
5
|
+
error: Error | null;
|
|
6
|
+
command<R>(name: string, payload: unknown): Promise<R>;
|
|
7
|
+
on(event: string, listener: (payload: unknown) => void): () => void;
|
|
8
|
+
};
|
|
9
|
+
declare function useWorkerChart<P>(host: ChartWorkerHost, spec: WorkerChartSpec<P>): UseWorkerChartResult;
|
|
10
|
+
export { type UseWorkerChartResult, useWorkerChart };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var b=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var j=(r,t)=>{for(var o in t)b(r,o,{get:t[o],enumerable:!0})},H=(r,t,o,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of E(t))!O.call(r,a)&&a!==o&&b(r,a,{get:()=>t[a],enumerable:!(i=A(t,a))||i.enumerable});return r};var P=r=>H(b({},"__esModule",{value:!0}),r);var M={};j(M,{useWorkerChart:()=>R});module.exports=P(M);var s=require("react");function f(r,t){let o=Object.entries(r);return o.length!==Object.keys(t).length?!1:o.every(([i,a])=>Object.hasOwn(t,i)&&Object.is(a,t[i]))}function I(r,t){return r.events.length===t.events.length&&r.events.every((o,i)=>o===t.events[i])&&f(r.wheel,t.wheel)&&f(r.pan,t.pan)&&f(r.pinch,t.pinch)}function R(r,t){let[o,i]=(0,s.useState)(null),[a,w]=(0,s.useState)({state:"drawing",error:null}),C=(0,s.useRef)(t),p=(0,s.useRef)(null),m=(0,s.useRef)(null),d=(0,s.useRef)(new Map),h=(0,s.useRef)(new Map);(0,s.useEffect)(()=>{C.current=t});let g=(0,s.useCallback)((n,e)=>{let u=n.on(e,c=>{let l=d.current.get(e);for(let k of[...l])k(c)});h.current.set(e,u)},[]),{kind:S,supersede:v}=t;(0,s.useEffect)(()=>{if(o===null)return;let n=C.current,e=r.mount(o,{...n,kind:S,supersede:v});p.current=e,m.current={props:n.props,input:n.input,sizing:n.sizing,canvasAttributes:n.canvasAttributes},w({state:"drawing",error:null});let u=e.onStateChange((l,k)=>w({state:l,error:k}));for(let l of d.current.keys())g(e,l);let c=h.current;return()=>{u();for(let l of c.values())l();c.clear(),p.current=null,m.current=null,e.destroy()}},[r,o,S,v,g]),(0,s.useEffect)(()=>{let n=p.current,e=m.current;n===null||e===null||(Object.is(e.props,t.props)||(e.props=t.props,n.update(t.props).catch(()=>{})),I(e.input,t.input)||(e.input=t.input,n.setInput(t.input)),f(e.sizing,t.sizing)||(e.sizing=t.sizing,n.setSizing(t.sizing)),f(e.canvasAttributes,t.canvasAttributes)||(e.canvasAttributes=t.canvasAttributes,n.setCanvasAttributes(t.canvasAttributes)))});let y=(0,s.useCallback)(n=>{i(n)},[]),W=(0,s.useCallback)((n,e)=>{let u=p.current;return u===null?Promise.reject(new Error(`The chart is not mounted, so command "${n}" cannot run.`)):u.command(n,e)},[]),z=(0,s.useCallback)((n,e)=>{let u=d.current.get(n);if(u===void 0){u=new Set,d.current.set(n,u);let c=p.current;c!==null&&g(c,n)}return u.add(e),()=>{!u.delete(e)||u.size>0||(d.current.delete(n),h.current.get(n)?.(),h.current.delete(n))}},[g]);return{containerRef:y,state:a.state,error:a.error,command:W,on:z}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useCallback as m,useEffect as w,useRef as p,useState as y}from"react";function d(s,t){let o=Object.entries(s);return o.length!==Object.keys(t).length?!1:o.every(([i,f])=>Object.hasOwn(t,i)&&Object.is(f,t[i]))}function E(s,t){return s.events.length===t.events.length&&s.events.every((o,i)=>o===t.events[i])&&d(s.wheel,t.wheel)&&d(s.pan,t.pan)&&d(s.pinch,t.pinch)}function O(s,t){let[o,i]=y(null),[f,C]=y({state:"drawing",error:null}),S=p(t),c=p(null),k=p(null),l=p(new Map),h=p(new Map);w(()=>{S.current=t});let g=m((n,e)=>{let r=n.on(e,u=>{let a=l.current.get(e);for(let b of[...a])b(u)});h.current.set(e,r)},[]),{kind:v,supersede:R}=t;w(()=>{if(o===null)return;let n=S.current,e=s.mount(o,{...n,kind:v,supersede:R});c.current=e,k.current={props:n.props,input:n.input,sizing:n.sizing,canvasAttributes:n.canvasAttributes},C({state:"drawing",error:null});let r=e.onStateChange((a,b)=>C({state:a,error:b}));for(let a of l.current.keys())g(e,a);let u=h.current;return()=>{r();for(let a of u.values())a();u.clear(),c.current=null,k.current=null,e.destroy()}},[s,o,v,R,g]),w(()=>{let n=c.current,e=k.current;n===null||e===null||(Object.is(e.props,t.props)||(e.props=t.props,n.update(t.props).catch(()=>{})),E(e.input,t.input)||(e.input=t.input,n.setInput(t.input)),d(e.sizing,t.sizing)||(e.sizing=t.sizing,n.setSizing(t.sizing)),d(e.canvasAttributes,t.canvasAttributes)||(e.canvasAttributes=t.canvasAttributes,n.setCanvasAttributes(t.canvasAttributes)))});let W=m(n=>{i(n)},[]),z=m((n,e)=>{let r=c.current;return r===null?Promise.reject(new Error(`The chart is not mounted, so command "${n}" cannot run.`)):r.command(n,e)},[]),A=m((n,e)=>{let r=l.current.get(n);if(r===void 0){r=new Set,l.current.set(n,r);let u=c.current;u!==null&&g(u,n)}return r.add(e),()=>{!r.delete(e)||r.size>0||(l.current.delete(n),h.current.get(n)?.(),h.current.delete(n))}},[g]);return{containerRef:W,state:f.state,error:f.error,command:z,on:A}}export{O as useWorkerChart};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
type ChartEventName = "mousemove" | "mouseout" | "click" | "dblclick";
|
|
2
|
+
type ModifierKey = "ctrl" | "alt" | "shift" | "meta";
|
|
3
|
+
type WheelInputOptions = {
|
|
4
|
+
enabled: false;
|
|
5
|
+
} | {
|
|
6
|
+
enabled: true;
|
|
7
|
+
modifierKey: ModifierKey | null;
|
|
8
|
+
};
|
|
9
|
+
type PanInputOptions = {
|
|
10
|
+
enabled: false;
|
|
11
|
+
} | {
|
|
12
|
+
enabled: true;
|
|
13
|
+
mode: "x" | "y" | "xy";
|
|
14
|
+
modifierKey: ModifierKey | null;
|
|
15
|
+
threshold: number;
|
|
16
|
+
};
|
|
17
|
+
type PinchInputOptions = {
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
};
|
|
20
|
+
type ChartInputOptions = {
|
|
21
|
+
events: readonly ChartEventName[];
|
|
22
|
+
wheel: WheelInputOptions;
|
|
23
|
+
pan: PanInputOptions;
|
|
24
|
+
pinch: PinchInputOptions;
|
|
25
|
+
};
|
|
26
|
+
type ChartSizing = {
|
|
27
|
+
maintainAspectRatio: false;
|
|
28
|
+
} | {
|
|
29
|
+
maintainAspectRatio: true;
|
|
30
|
+
aspectRatio: number;
|
|
31
|
+
};
|
|
32
|
+
type ChartDrawState = "drawing" | "drawn" | "error";
|
|
33
|
+
type SupersedePolicy = "restart" | "queue";
|
|
34
|
+
type WorkerChartSpec<P> = {
|
|
35
|
+
kind: string;
|
|
36
|
+
props: P;
|
|
37
|
+
input: ChartInputOptions;
|
|
38
|
+
sizing: ChartSizing;
|
|
39
|
+
canvasAttributes: Readonly<Record<string, string>>;
|
|
40
|
+
supersede: SupersedePolicy;
|
|
41
|
+
};
|
|
42
|
+
type ChartStateListener = (state: ChartDrawState, error: Error | null) => void;
|
|
43
|
+
type WorkerChartHandle<P> = {
|
|
44
|
+
update(props: P): Promise<void>;
|
|
45
|
+
setInput(input: ChartInputOptions): void;
|
|
46
|
+
setSizing(sizing: ChartSizing): void;
|
|
47
|
+
setCanvasAttributes(attributes: Readonly<Record<string, string>>): void;
|
|
48
|
+
command<R>(name: string, payload: unknown): Promise<R>;
|
|
49
|
+
on(event: string, listener: (payload: unknown) => void): () => void;
|
|
50
|
+
onStateChange(listener: ChartStateListener): () => void;
|
|
51
|
+
destroy(): void;
|
|
52
|
+
};
|
|
53
|
+
type ChartWorkerHostOptions = {
|
|
54
|
+
createWorker: () => Worker;
|
|
55
|
+
};
|
|
56
|
+
type ChartWorkerHost = {
|
|
57
|
+
mount<P>(container: HTMLElement, spec: WorkerChartSpec<P>): WorkerChartHandle<P>;
|
|
58
|
+
terminate(): void;
|
|
59
|
+
};
|
|
60
|
+
export type { ChartWorkerHostOptions as C, ModifierKey as M, PanInputOptions as P, SupersedePolicy as S, WheelInputOptions as W, ChartWorkerHost as a, ChartDrawState as b, ChartEventName as c, ChartInputOptions as d, ChartSizing as e, ChartStateListener as f, PinchInputOptions as g, WorkerChartHandle as h, WorkerChartSpec as i };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
type ChartEventName = "mousemove" | "mouseout" | "click" | "dblclick";
|
|
2
|
+
type ModifierKey = "ctrl" | "alt" | "shift" | "meta";
|
|
3
|
+
type WheelInputOptions = {
|
|
4
|
+
enabled: false;
|
|
5
|
+
} | {
|
|
6
|
+
enabled: true;
|
|
7
|
+
modifierKey: ModifierKey | null;
|
|
8
|
+
};
|
|
9
|
+
type PanInputOptions = {
|
|
10
|
+
enabled: false;
|
|
11
|
+
} | {
|
|
12
|
+
enabled: true;
|
|
13
|
+
mode: "x" | "y" | "xy";
|
|
14
|
+
modifierKey: ModifierKey | null;
|
|
15
|
+
threshold: number;
|
|
16
|
+
};
|
|
17
|
+
type PinchInputOptions = {
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
};
|
|
20
|
+
type ChartInputOptions = {
|
|
21
|
+
events: readonly ChartEventName[];
|
|
22
|
+
wheel: WheelInputOptions;
|
|
23
|
+
pan: PanInputOptions;
|
|
24
|
+
pinch: PinchInputOptions;
|
|
25
|
+
};
|
|
26
|
+
type ChartSizing = {
|
|
27
|
+
maintainAspectRatio: false;
|
|
28
|
+
} | {
|
|
29
|
+
maintainAspectRatio: true;
|
|
30
|
+
aspectRatio: number;
|
|
31
|
+
};
|
|
32
|
+
type ChartDrawState = "drawing" | "drawn" | "error";
|
|
33
|
+
type SupersedePolicy = "restart" | "queue";
|
|
34
|
+
type WorkerChartSpec<P> = {
|
|
35
|
+
kind: string;
|
|
36
|
+
props: P;
|
|
37
|
+
input: ChartInputOptions;
|
|
38
|
+
sizing: ChartSizing;
|
|
39
|
+
canvasAttributes: Readonly<Record<string, string>>;
|
|
40
|
+
supersede: SupersedePolicy;
|
|
41
|
+
};
|
|
42
|
+
type ChartStateListener = (state: ChartDrawState, error: Error | null) => void;
|
|
43
|
+
type WorkerChartHandle<P> = {
|
|
44
|
+
update(props: P): Promise<void>;
|
|
45
|
+
setInput(input: ChartInputOptions): void;
|
|
46
|
+
setSizing(sizing: ChartSizing): void;
|
|
47
|
+
setCanvasAttributes(attributes: Readonly<Record<string, string>>): void;
|
|
48
|
+
command<R>(name: string, payload: unknown): Promise<R>;
|
|
49
|
+
on(event: string, listener: (payload: unknown) => void): () => void;
|
|
50
|
+
onStateChange(listener: ChartStateListener): () => void;
|
|
51
|
+
destroy(): void;
|
|
52
|
+
};
|
|
53
|
+
type ChartWorkerHostOptions = {
|
|
54
|
+
createWorker: () => Worker;
|
|
55
|
+
};
|
|
56
|
+
type ChartWorkerHost = {
|
|
57
|
+
mount<P>(container: HTMLElement, spec: WorkerChartSpec<P>): WorkerChartHandle<P>;
|
|
58
|
+
terminate(): void;
|
|
59
|
+
};
|
|
60
|
+
export type { ChartWorkerHostOptions as C, ModifierKey as M, PanInputOptions as P, SupersedePolicy as S, WheelInputOptions as W, ChartWorkerHost as a, ChartDrawState as b, ChartEventName as c, ChartInputOptions as d, ChartSizing as e, ChartStateListener as f, PinchInputOptions as g, WorkerChartHandle as h, WorkerChartSpec as i };
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/// <reference types="chartjs-plugin-zoom" />
|
|
2
|
+
/// <reference types="chartjs-plugin-zoom" />
|
|
3
|
+
import { ChartType, ChartConfiguration, Chart, BarController, TooltipItem } from "chart.js";
|
|
4
|
+
type ChartKindContext = {
|
|
5
|
+
createChart<TType extends ChartType>(config: ChartConfiguration<TType>): Chart<TType>;
|
|
6
|
+
emit(event: string, payload: unknown): void;
|
|
7
|
+
};
|
|
8
|
+
type ChartKind<P> = {
|
|
9
|
+
create(props: P, context: ChartKindContext): Chart;
|
|
10
|
+
update(chart: Chart, props: P, context: ChartKindContext): void;
|
|
11
|
+
commands: Readonly<Record<string, (chart: Chart, payload: unknown, context: ChartKindContext) => unknown>>;
|
|
12
|
+
};
|
|
13
|
+
declare function defineChartKind<P>(kind: ChartKind<P>): ChartKind<P>;
|
|
14
|
+
type StackSeries = {
|
|
15
|
+
values: ArrayLike<number>;
|
|
16
|
+
stack: string;
|
|
17
|
+
order: number;
|
|
18
|
+
hidden: boolean;
|
|
19
|
+
};
|
|
20
|
+
type FloatingPoint<X> = {
|
|
21
|
+
x: X;
|
|
22
|
+
y: [
|
|
23
|
+
number,
|
|
24
|
+
number
|
|
25
|
+
] | null;
|
|
26
|
+
v: number | null;
|
|
27
|
+
};
|
|
28
|
+
declare function toFloatingStacks<X>(xs: readonly X[], series: readonly StackSeries[]): FloatingPoint<X>[][];
|
|
29
|
+
declare module "chart.js" {
|
|
30
|
+
interface ChartTypeRegistry {
|
|
31
|
+
floatingBar: {
|
|
32
|
+
chartOptions: ChartTypeRegistry["bar"]["chartOptions"];
|
|
33
|
+
datasetOptions: ChartTypeRegistry["bar"]["datasetOptions"];
|
|
34
|
+
defaultDataPoint: FloatingPoint<number | string>;
|
|
35
|
+
metaExtensions: ChartTypeRegistry["bar"]["metaExtensions"];
|
|
36
|
+
parsedDataType: ChartTypeRegistry["bar"]["parsedDataType"];
|
|
37
|
+
scales: ChartTypeRegistry["bar"]["scales"];
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
declare class FloatingBarController extends BarController {
|
|
42
|
+
static id: string;
|
|
43
|
+
static defaults: typeof BarController.defaults;
|
|
44
|
+
static overrides: unknown;
|
|
45
|
+
private held;
|
|
46
|
+
updateElements(...args: Parameters<BarController["updateElements"]>): void;
|
|
47
|
+
_getAxis(): string[];
|
|
48
|
+
_getStackIndex(datasetIndex: number, name: string | undefined, dataIndex: number | undefined): number;
|
|
49
|
+
}
|
|
50
|
+
declare function floatingValueOf(item: TooltipItem<"floatingBar">): number | null;
|
|
51
|
+
type ChartEventName = "mousemove" | "mouseout" | "click" | "dblclick";
|
|
52
|
+
type ChartSize = {
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
devicePixelRatio: number;
|
|
56
|
+
};
|
|
57
|
+
type Modifiers = {
|
|
58
|
+
ctrlKey: boolean;
|
|
59
|
+
altKey: boolean;
|
|
60
|
+
shiftKey: boolean;
|
|
61
|
+
metaKey: boolean;
|
|
62
|
+
};
|
|
63
|
+
type PointerKind = "mouse" | "touch" | "pen";
|
|
64
|
+
type CanvasPoint = {
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
};
|
|
68
|
+
type GesturePhase = "start" | "move" | "end";
|
|
69
|
+
type HostToWorker = {
|
|
70
|
+
type: "mount";
|
|
71
|
+
chartId: string;
|
|
72
|
+
kind: string;
|
|
73
|
+
canvas: OffscreenCanvas;
|
|
74
|
+
size: ChartSize;
|
|
75
|
+
props: unknown;
|
|
76
|
+
revision: number;
|
|
77
|
+
} | {
|
|
78
|
+
type: "update";
|
|
79
|
+
chartId: string;
|
|
80
|
+
props: unknown;
|
|
81
|
+
revision: number;
|
|
82
|
+
} | {
|
|
83
|
+
type: "resize";
|
|
84
|
+
chartId: string;
|
|
85
|
+
size: ChartSize;
|
|
86
|
+
} | {
|
|
87
|
+
type: "pointer";
|
|
88
|
+
chartId: string;
|
|
89
|
+
event: ChartEventName;
|
|
90
|
+
x: number;
|
|
91
|
+
y: number;
|
|
92
|
+
pointerType: PointerKind;
|
|
93
|
+
modifiers: Modifiers;
|
|
94
|
+
} | {
|
|
95
|
+
type: "wheel";
|
|
96
|
+
chartId: string;
|
|
97
|
+
x: number;
|
|
98
|
+
y: number;
|
|
99
|
+
deltaX: number;
|
|
100
|
+
deltaY: number;
|
|
101
|
+
deltaMode: number;
|
|
102
|
+
modifiers: Modifiers;
|
|
103
|
+
} | {
|
|
104
|
+
type: "pan";
|
|
105
|
+
chartId: string;
|
|
106
|
+
phase: GesturePhase;
|
|
107
|
+
x: number;
|
|
108
|
+
y: number;
|
|
109
|
+
deltaX: number;
|
|
110
|
+
deltaY: number;
|
|
111
|
+
pointerType: PointerKind;
|
|
112
|
+
modifiers: Modifiers;
|
|
113
|
+
} | {
|
|
114
|
+
type: "pinch";
|
|
115
|
+
chartId: string;
|
|
116
|
+
phase: GesturePhase;
|
|
117
|
+
centerX: number;
|
|
118
|
+
centerY: number;
|
|
119
|
+
scale: number;
|
|
120
|
+
pointers: readonly [
|
|
121
|
+
CanvasPoint,
|
|
122
|
+
CanvasPoint
|
|
123
|
+
];
|
|
124
|
+
} | {
|
|
125
|
+
type: "command";
|
|
126
|
+
chartId: string;
|
|
127
|
+
requestId: number;
|
|
128
|
+
name: string;
|
|
129
|
+
payload: unknown;
|
|
130
|
+
} | {
|
|
131
|
+
type: "destroy";
|
|
132
|
+
chartId: string;
|
|
133
|
+
};
|
|
134
|
+
type PanMessage = Extract<HostToWorker, {
|
|
135
|
+
type: "pan";
|
|
136
|
+
}>;
|
|
137
|
+
type ChartKinds = Readonly<Record<string, ChartKind<never>>>;
|
|
138
|
+
declare function startChartWorker(options: {
|
|
139
|
+
kinds: ChartKinds;
|
|
140
|
+
}): void;
|
|
141
|
+
type BridgeEvent = {
|
|
142
|
+
type: "panstart" | "pinchstart";
|
|
143
|
+
pointerType: PanMessage["pointerType"];
|
|
144
|
+
center: CanvasPoint;
|
|
145
|
+
deltaX: number;
|
|
146
|
+
deltaY: number;
|
|
147
|
+
srcEvent: Modifiers;
|
|
148
|
+
};
|
|
149
|
+
export { type BridgeEvent, type ChartKind, type ChartKindContext, type ChartKinds, FloatingBarController, type FloatingPoint, type StackSeries, defineChartKind, floatingValueOf, startChartWorker, toFloatingStacks };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
function _n(n){return n}import{BarController as T}from"chart.js";function nn(n){let e=T.prototype[n];if(typeof e!="function")throw new Error(`Chart.js BarController has no ${n}; FloatingBarController supports Chart.js 4.5.`);return e}var J=nn("_getAxis"),Q=nn("_getStackIndex"),b=class extends T{constructor(){super(...arguments);this.held=null}updateElements(...t){let o=this._cachedMeta;if(o._stacked)throw new Error(`FloatingBarController draws bars that are already stacked, but the value scale "${o.vScale?.id}" stacks them again: set stacked: false on that scale (Chart.js stacks a value scale that has no stacked option when datasets have a stack).`);this.held={axis:J.call(this),stackIndexes:new Map};try{super.updateElements(...t)}finally{this.held=null}}_getAxis(){return this.held===null?J.call(this):this.held.axis}_getStackIndex(t,o,i){if(this.held===null||i!==void 0)return Q.call(this,t,o,i);let r=o===void 0?String(t):`${t}:${o}`,a=this.held.stackIndexes.get(r);if(a!==void 0)return a;let l=Q.call(this,t,o,i);return this.held.stackIndexes.set(r,l),l}};b.id="floatingBar",b.defaults=T.defaults,b.overrides=T.overrides;function $n(n){let e=n.raw;if(typeof e!="object"||e===null||!("v"in e))throw new Error("The tooltip item is not a floating bar point made by toFloatingStacks.");let t=e.v;if(t!==null&&typeof t!="number")throw new Error("The floating bar point has a non-numeric value.");return t}function en(n,e,t){let o=n.get(e);if(o!==void 0)return o;let i=new Float64Array(t);return n.set(e,i),i}function Un(n,e){for(let[a,l]of e.entries()){if(l.values.length!==n.length)throw new Error(`series[${a}] has ${l.values.length} values for ${n.length} x values.`);if(l.stack==="")throw new Error(`series[${a}] has an empty stack.`);if(!Number.isFinite(l.order))throw new Error(`series[${a}] has a non-finite order.`)}let t=e.map(()=>n.map(a=>({x:a,y:null,v:null}))),o=e.map((a,l)=>({s:a,index:l})).filter(({s:a})=>!a.hidden).sort((a,l)=>a.s.order-l.s.order||a.index-l.index),i=new Map,r=new Map;for(let{s:a,index:l}of o){let c=en(i,a.stack,n.length),u=en(r,a.stack,n.length),f=t[l];for(let s=0;s<n.length;s++){let d=a.values[s];if(Number.isNaN(d))continue;let p=d>0?c[s]:d<0?u[s]:c[s]+u[s];f[s]={x:n[s],y:[p,p+d],v:d},d>0?c[s]+=d:d<0&&(u[s]+=d)}}return t}import{BarElement as qe,Chart as Xn}from"chart.js";import{requestAnimFrame as Ge}from"chart.js/helpers";var A=class{add(){}on(){}remove(){}destroy(){}},F=class{},L=class{},R={Manager:A,Pinch:F,Pan:L};import{each as k,valueOrDefault as I,almostEquals as tn,callback as h,sign as on,getRelativePosition as U,_isPointInArea as Vn}from"chart.js/helpers";/*!
|
|
2
|
+
* chartjs-plugin-zoom v2.2.0
|
|
3
|
+
* https://www.chartjs.org/chartjs-plugin-zoom/2.2.0/
|
|
4
|
+
* (c) 2016-2024 chartjs-plugin-zoom Contributors
|
|
5
|
+
* Released under the MIT License
|
|
6
|
+
*/var E=n=>n&&n.enabled&&n.modifierKey,yn=(n,e)=>n&&e[n+"Key"],V=(n,e)=>n&&!e[n+"Key"];function w(n,e,t){return n===void 0?!0:typeof n=="string"?n.indexOf(e)!==-1:typeof n=="function"?n({chart:t}).indexOf(e)!==-1:!1}function D(n,e){return typeof n=="function"&&(n=n({chart:e})),typeof n=="string"?{x:n.indexOf("x")!==-1,y:n.indexOf("y")!==-1}:{x:!1,y:!1}}function qn(n,e){let t;return function(){return clearTimeout(t),t=setTimeout(n,e),e}}function Gn({x:n,y:e},t){let o=t.scales,i=Object.keys(o);for(let r=0;r<i.length;r++){let a=o[i[r]];if(e>=a.top&&e<=a.bottom&&n>=a.left&&n<=a.right)return a}return null}function xn(n,e,t){let{mode:o="xy",scaleMode:i,overScaleMode:r}=n||{},a=Gn(e,t),l=D(o,t),c=D(i,t);if(r){let f=D(r,t);for(let s of["x","y"])f[s]&&(c[s]=l[s],l[s]=!1)}if(a&&c[a.axis])return[a];let u=[];return k(t.scales,function(f){l[f.axis]&&u.push(f)}),u}var N=new WeakMap;function m(n){let e=N.get(n);return e||(e={originalScaleLimits:{},updatedScaleLimits:{},handlers:{},panDelta:{},dragging:!1,panning:!1},N.set(n,e)),e}function Jn(n){N.delete(n)}function vn(n,e,t,o){let i=Math.max(0,Math.min(1,(n-e)/t||0)),r=1-i;return{min:o*i,max:o*r}}function Cn(n,e){let t=n.isHorizontal()?e.x:e.y;return n.getValueForPixel(t)}function bn(n,e,t){let o=n.max-n.min,i=o*(e-1),r=Cn(n,t);return vn(r,n.min,o,i)}function Qn(n,e,t){let o=Cn(n,t);if(o===void 0)return{min:n.min,max:n.max};let i=Math.log10(n.min),r=Math.log10(n.max),a=Math.log10(o),l=r-i,c=l*(e-1),u=vn(a,i,l,c);return{min:Math.pow(10,i+u.min),max:Math.pow(10,r-u.max)}}function ne(n,e){return e&&(e[n.id]||e[n.axis])||{}}function rn(n,e,t,o,i){let r=t[o];if(r==="original"){let a=n.originalScaleLimits[e.id][o];r=I(a.options,a.scale)}return I(r,i)}function ee(n,e,t){let o=n.getValueForPixel(e),i=n.getValueForPixel(t);return{min:Math.min(o,i),max:Math.max(o,i)}}function te(n,{min:e,max:t,minLimit:o,maxLimit:i},r){let a=(n-t+e)/2;e-=a,t+=a;let l=r.min.options??r.min.scale,c=r.max.options??r.max.scale,u=n/1e6;return tn(e,l,u)&&(e=l),tn(t,c,u)&&(t=c),e<o?(e=o,t=Math.min(o+n,i)):t>i&&(t=i,e=Math.max(i-n,o)),{min:e,max:t}}function P(n,{min:e,max:t},o,i=!1){let r=m(n.chart),{options:a}=n,l=ne(n,o),{minRange:c=0}=l,u=rn(r,n,l,"min",-1/0),f=rn(r,n,l,"max",1/0);if(i==="pan"&&(e<u||t>f))return!0;let s=n.max-n.min,d=i?Math.max(t-e,c):s;if(i&&d===c&&s<=c)return!0;let p=te(d,{min:e,max:t,minLimit:u,maxLimit:f},r.originalScaleLimits[n.id]);return a.min=p.min,a.max=p.max,r.updatedScaleLimits[n.id]=p,n.parse(p.min)!==n.min||n.parse(p.max)!==n.max}function oe(n,e,t,o){let i=bn(n,e,t),r={min:n.min+i.min,max:n.max-i.max};return P(n,r,o,!0)}function ie(n,e,t,o){let i=Qn(n,e,t);return P(n,i,o,!0)}function re(n,e,t,o){P(n,ee(n,e,t),o,!0)}var an=n=>n===0||isNaN(n)?0:n<0?Math.min(Math.round(n),-1):Math.max(Math.round(n),1);function ae(n){let t=n.getLabels().length-1;n.min>0&&(n.min-=1),n.max<t&&(n.max+=1)}function se(n,e,t,o){let i=bn(n,e,t);n.min===n.max&&e<1&&ae(n);let r={min:n.min+an(i.min),max:n.max-an(i.max)};return P(n,r,o,!0)}function le(n){return n.isHorizontal()?n.width:n.height}function de(n,e,t){let i=n.getLabels().length-1,{min:r,max:a}=n,l=Math.max(a-r,1),c=Math.round(le(n)/Math.max(l,10)),u=Math.round(Math.abs(e/c)),f;return e<-c?(a=Math.min(a+u,i),r=l===1?a:a-l,f=a===i):e>c&&(r=Math.max(0,r-u),a=l===1?r:r+l,f=r===0),P(n,{min:r,max:a},t)||f}var ce={second:500,minute:30*1e3,hour:1800*1e3,day:720*60*1e3,week:3.5*24*60*60*1e3,month:360*60*60*1e3,quarter:1440*60*60*1e3,year:4368*60*60*1e3};function wn(n,e,t,o=!1){let{min:i,max:r,options:a}=n,l=a.time&&a.time.round,c=ce[l]||0,u=n.getValueForPixel(n.getPixelForValue(i+c)-e),f=n.getValueForPixel(n.getPixelForValue(r+c)-e);return isNaN(u)||isNaN(f)?!0:P(n,{min:u,max:f},t,o?"pan":!1)}function sn(n,e,t){return wn(n,e,t,!0)}var H={category:se,default:oe,logarithmic:ie},X={default:re},Y={category:de,default:wn,logarithmic:sn,timeseries:sn};function ue(n,e,t){let{id:o,options:{min:i,max:r}}=n;if(!e[o]||!t[o])return!0;let a=t[o];return a.min!==i||a.max!==r}function ln(n,e){k(n,(t,o)=>{e[o]||delete n[o]})}function M(n,e){let{scales:t}=n,{originalScaleLimits:o,updatedScaleLimits:i}=e;return k(t,function(r){ue(r,o,i)&&(o[r.id]={min:{scale:r.min,options:r.options.min},max:{scale:r.max,options:r.options.max}})}),ln(o,t),ln(i,t),o}function dn(n,e,t,o){let i=H[n.type]||H.default;h(i,[n,e,t,o])}function cn(n,e,t,o){let i=X[n.type]||X.default;h(i,[n,e,t,o])}function fe(n){let e=n.chartArea;return{x:(e.left+e.right)/2,y:(e.top+e.bottom)/2}}function O(n,e,t="none",o="api"){let{x:i=1,y:r=1,focalPoint:a=fe(n)}=typeof e=="number"?{x:e,y:e}:e,l=m(n),{options:{limits:c,zoom:u}}=l;M(n,l);let f=i!==1,s=r!==1,d=xn(u,a,n);k(d||n.scales,function(p){p.isHorizontal()&&f?dn(p,i,a,c):!p.isHorizontal()&&s&&dn(p,r,a,c)}),n.update(t),h(u.onZoom,[{chart:n,trigger:o}])}function kn(n,e,t,o="none",i="api"){let r=m(n),{options:{limits:a,zoom:l}}=r,{mode:c="xy"}=l;M(n,r);let u=w(c,"x",n),f=w(c,"y",n);k(n.scales,function(s){s.isHorizontal()&&u?cn(s,e.x,t.x,a):!s.isHorizontal()&&f&&cn(s,e.y,t.y,a)}),n.update(o),h(l.onZoom,[{chart:n,trigger:i}])}function pe(n,e,t,o="none",i="api"){let r=m(n);M(n,r);let a=n.scales[e];P(a,t,void 0,!0),n.update(o),h(r.options.zoom?.onZoom,[{chart:n,trigger:i}])}function me(n,e="default"){let t=m(n),o=M(n,t);k(n.scales,function(i){let r=i.options;o[i.id]?(r.min=o[i.id].min.options,r.max=o[i.id].max.options):(delete r.min,delete r.max),delete t.updatedScaleLimits[i.id]}),n.update(e),h(t.options.zoom.onZoomComplete,[{chart:n}])}function he(n,e){let t=n.originalScaleLimits[e];if(!t)return;let{min:o,max:i}=t;return I(i.options,i.scale)-I(o.options,o.scale)}function ge(n){let e=m(n),t=1,o=1;return k(n.scales,function(i){let r=he(e,i.id);if(r){let a=Math.round(r/(i.max-i.min)*100)/100;t=Math.min(t,a),o=Math.max(o,a)}}),t<1?t:o}function un(n,e,t,o){let{panDelta:i}=o,r=i[n.id]||0;on(r)===on(e)&&(e+=r);let a=Y[n.type]||Y.default;h(a,[n,e,t])?i[n.id]=0:i[n.id]=e}function K(n,e,t,o="none"){let{x:i=0,y:r=0}=typeof e=="number"?{x:e,y:e}:e,a=m(n),{options:{pan:l,limits:c}}=a,{onPan:u}=l||{};M(n,a);let f=i!==0,s=r!==0;k(t||n.scales,function(d){d.isHorizontal()&&f?un(d,i,c,a):!d.isHorizontal()&&s&&un(d,r,c,a)}),n.update(o),h(u,[{chart:n}])}function Pn(n){let e=m(n);M(n,e);let t={};for(let o of Object.keys(n.scales)){let{min:i,max:r}=e.originalScaleLimits[o]||{min:{},max:{}};t[o]={min:i.scale,max:r.scale}}return t}function ye(n){let e=m(n),t={};for(let o of Object.keys(n.scales))t[o]=e.updatedScaleLimits[o];return t}function xe(n){let e=Pn(n);for(let t of Object.keys(n.scales)){let{min:o,max:i}=e[t];if(o!==void 0&&n.scales[t].min!==o||i!==void 0&&n.scales[t].max!==i)return!0}return!1}function fn(n){let e=m(n);return e.panning||e.dragging}var pn=(n,e,t)=>Math.min(t,Math.max(e,n));function y(n,e){let{handlers:t}=m(n),o=t[e];o&&o.target&&(o.target.removeEventListener(e,o),delete t[e])}function z(n,e,t,o){let{handlers:i,options:r}=m(n),a=i[t];if(a&&a.target===e)return;y(n,t),i[t]=c=>o(n,c,r),i[t].target=e;let l=t==="wheel"?!1:void 0;e.addEventListener(t,i[t],{passive:l})}function ve(n,e){let t=m(n);t.dragStart&&(t.dragging=!0,t.dragEnd=e,n.update("none"))}function Ce(n,e){let t=m(n);!t.dragStart||e.key!=="Escape"||(y(n,"keydown"),t.dragging=!1,t.dragStart=t.dragEnd=null,n.update("none"))}function _(n,e){if(n.target!==e.canvas){let t=e.canvas.getBoundingClientRect();return{x:n.clientX-t.left,y:n.clientY-t.top}}return U(n,e)}function Sn(n,e,t){let{onZoomStart:o,onZoomRejected:i}=t;if(o){let r=_(e,n);if(h(o,[{chart:n,event:e,point:r}])===!1)return h(i,[{chart:n,event:e}]),!1}}function be(n,e){if(n.legend){let r=U(e,n);if(Vn(r,n.legend))return}let t=m(n),{pan:o,zoom:i={}}=t.options;if(e.button!==0||yn(E(o),e)||V(E(i.drag),e))return h(i.onZoomRejected,[{chart:n,event:e}]);Sn(n,e,i)!==!1&&(t.dragStart=e,z(n,n.canvas.ownerDocument,"mousemove",ve),z(n,window.document,"keydown",Ce))}function we({begin:n,end:e},t){let o=e.x-n.x,i=e.y-n.y,r=Math.abs(o/i);r>t?o=Math.sign(o)*Math.abs(i*t):r<t&&(i=Math.sign(i)*Math.abs(o/t)),e.x=n.x+o,e.y=n.y+i}function mn(n,e,t,{min:o,max:i,prop:r}){n[o]=pn(Math.min(t.begin[r],t.end[r]),e[o],e[i]),n[i]=pn(Math.max(t.begin[r],t.end[r]),e[o],e[i])}function ke(n,e,t){let o={begin:_(e.dragStart,n),end:_(e.dragEnd,n)};if(t){let i=n.chartArea.width/n.chartArea.height;we(o,i)}return o}function Rn(n,e,t,o){let i=w(e,"x",n),r=w(e,"y",n),{top:a,left:l,right:c,bottom:u,width:f,height:s}=n.chartArea,d={top:a,left:l,right:c,bottom:u},p=ke(n,t,o&&i&&r);i&&mn(d,n.chartArea,p,{min:"left",max:"right",prop:"x"}),r&&mn(d,n.chartArea,p,{min:"top",max:"bottom",prop:"y"});let g=d.right-d.left,x=d.bottom-d.top;return{...d,width:g,height:x,zoomX:i&&g?1+(f-g)/f:1,zoomY:r&&x?1+(s-x)/s:1}}function Pe(n,e){let t=m(n);if(!t.dragStart)return;y(n,"mousemove");let{mode:o,onZoomComplete:i,drag:{threshold:r=0,maintainAspectRatio:a}}=t.options.zoom,l=Rn(n,o,{dragStart:t.dragStart,dragEnd:e},a),c=w(o,"x",n)?l.width:0,u=w(o,"y",n)?l.height:0,f=Math.sqrt(c*c+u*u);if(t.dragStart=t.dragEnd=null,f<=r){t.dragging=!1,n.update("none");return}kn(n,{x:l.left,y:l.top},{x:l.right,y:l.bottom},"zoom","drag"),t.dragging=!1,t.filterNextClick=!0,h(i,[{chart:n}])}function Se(n,e,t){if(V(E(t.wheel),e)){h(t.onZoomRejected,[{chart:n,event:e}]);return}if(Sn(n,e,t)!==!1&&(e.cancelable&&e.preventDefault(),e.deltaY!==void 0))return!0}function Re(n,e){let{handlers:{onZoomComplete:t},options:{zoom:o}}=m(n);if(!Se(n,e,o))return;let i=e.target.getBoundingClientRect(),r=o.wheel.speed,a=e.deltaY>=0?2-1/(1-r):1+r,l={x:a,y:a,focalPoint:{x:e.clientX-i.left,y:e.clientY-i.top}};O(n,l,"zoom","wheel"),h(t,[{chart:n}])}function Me(n,e,t,o){t&&(m(n).handlers[e]=qn(()=>h(t,[{chart:n}]),o))}function ze(n,e){let t=n.canvas,{wheel:o,drag:i,onZoomComplete:r}=e.zoom;o.enabled?(z(n,t,"wheel",Re),Me(n,"onZoomComplete",r,250)):y(n,"wheel"),i.enabled?(z(n,t,"mousedown",be),z(n,t.ownerDocument,"mouseup",Pe)):(y(n,"mousedown"),y(n,"mousemove"),y(n,"mouseup"),y(n,"keydown"))}function Ee(n){y(n,"mousedown"),y(n,"mousemove"),y(n,"mouseup"),y(n,"wheel"),y(n,"click"),y(n,"keydown")}function Oe(n,e){return function(t,o){let{pan:i,zoom:r={}}=e.options;if(!i||!i.enabled)return!1;let a=o&&o.srcEvent;return a&&!e.panning&&o.pointerType==="mouse"&&(V(E(i),a)||yn(E(r.drag),a))?(h(i.onPanRejected,[{chart:n,event:o}]),!1):!0}}function Te(n,e){let t=Math.abs(n.clientX-e.clientX),o=Math.abs(n.clientY-e.clientY),i=t/o,r,a;return i>.3&&i<1.7?r=a=!0:t>o?r=!0:a=!0,{x:r,y:a}}function Mn(n,e,t){if(e.scale){let{center:o,pointers:i}=t,r=1/e.scale*t.scale,a=t.target.getBoundingClientRect(),l=Te(i[0],i[1]),c=e.options.zoom.mode,u={x:l.x&&w(c,"x",n)?r:1,y:l.y&&w(c,"y",n)?r:1,focalPoint:{x:o.x-a.left,y:o.y-a.top}};O(n,u,"zoom","pinch"),e.scale=t.scale}}function Be(n,e,t){if(e.options.zoom.pinch.enabled){let o=U(t,n);h(e.options.zoom.onZoomStart,[{chart:n,event:t,point:o}])===!1?(e.scale=null,h(e.options.zoom.onZoomRejected,[{chart:n,event:t}])):e.scale=1}}function Ie(n,e,t){e.scale&&(Mn(n,e,t),e.scale=null,h(e.options.zoom.onZoomComplete,[{chart:n}]))}function zn(n,e,t){let o=e.delta;o&&(e.panning=!0,K(n,{x:t.deltaX-o.x,y:t.deltaY-o.y},e.panScales),e.delta={x:t.deltaX,y:t.deltaY})}function Ke(n,e,t){let{enabled:o,onPanStart:i,onPanRejected:r}=e.options.pan;if(!o)return;let a=t.target.getBoundingClientRect(),l={x:t.center.x-a.left,y:t.center.y-a.top};if(h(i,[{chart:n,event:t,point:l}])===!1)return h(r,[{chart:n,event:t}]);e.panScales=xn(e.options.pan,l,n),e.delta={x:0,y:0},zn(n,e,t)}function je(n,e){e.delta=null,e.panning&&(e.panning=!1,e.filterNextClick=!0,h(e.options.pan.onPanComplete,[{chart:n}]))}var $=new WeakMap;function hn(n,e){let t=m(n),o=n.canvas,{pan:i,zoom:r}=e,a=new R.Manager(o);r&&r.pinch.enabled&&(a.add(new R.Pinch),a.on("pinchstart",l=>Be(n,t,l)),a.on("pinch",l=>Mn(n,t,l)),a.on("pinchend",l=>Ie(n,t,l))),i&&i.enabled&&(a.add(new R.Pan({threshold:i.threshold,enable:Oe(n,t)})),a.on("panstart",l=>Ke(n,t,l)),a.on("panmove",l=>zn(n,t,l)),a.on("panend",()=>je(n,t))),$.set(n,a)}function gn(n){let e=$.get(n);e&&(e.remove("pinchstart"),e.remove("pinch"),e.remove("pinchend"),e.remove("panstart"),e.remove("pan"),e.remove("panend"),e.destroy(),$.delete(n))}function We(n,e){let{pan:t,zoom:o}=n,{pan:i,zoom:r}=e;return o?.zoom?.pinch?.enabled!==r?.zoom?.pinch?.enabled||t?.enabled!==i?.enabled||t?.threshold!==i?.threshold}var Ze="2.2.0";function B(n,e,t){let o=t.zoom.drag,{dragStart:i,dragEnd:r}=m(n);if(o.drawTime!==e||!r)return;let{left:a,top:l,width:c,height:u}=Rn(n,t.zoom.mode,{dragStart:i,dragEnd:r},o.maintainAspectRatio),f=n.ctx;f.save(),f.beginPath(),f.fillStyle=o.backgroundColor||"rgba(225,225,225,0.3)",f.fillRect(a,l,c,u),o.borderWidth>0&&(f.lineWidth=o.borderWidth,f.strokeStyle=o.borderColor||"rgba(225,225,225)",f.strokeRect(a,l,c,u)),f.restore()}var En={id:"zoom",version:Ze,defaults:{pan:{enabled:!1,mode:"xy",threshold:10,modifierKey:null},zoom:{wheel:{enabled:!1,speed:.1,modifierKey:null},drag:{enabled:!1,drawTime:"beforeDatasetsDraw",modifierKey:null},pinch:{enabled:!1},mode:"xy"}},start:function(n,e,t){let o=m(n);o.options=t,Object.prototype.hasOwnProperty.call(t.zoom,"enabled")&&console.warn("The option `zoom.enabled` is no longer supported. Please use `zoom.wheel.enabled`, `zoom.drag.enabled`, or `zoom.pinch.enabled`."),(Object.prototype.hasOwnProperty.call(t.zoom,"overScaleMode")||Object.prototype.hasOwnProperty.call(t.pan,"overScaleMode"))&&console.warn("The option `overScaleMode` is deprecated. Please use `scaleMode` instead (and update `mode` as desired)."),R&&hn(n,t),n.pan=(i,r,a)=>K(n,i,r,a),n.zoom=(i,r)=>O(n,i,r),n.zoomRect=(i,r,a)=>kn(n,i,r,a),n.zoomScale=(i,r,a)=>pe(n,i,r,a),n.resetZoom=i=>me(n,i),n.getZoomLevel=()=>ge(n),n.getInitialScaleBounds=()=>Pn(n),n.getZoomedScaleBounds=()=>ye(n),n.isZoomedOrPanned=()=>xe(n),n.isZoomingOrPanning=()=>fn(n)},beforeEvent(n,{event:e}){if(fn(n))return!1;if(e.type==="click"||e.type==="mouseup"){let t=m(n);if(t.filterNextClick)return t.filterNextClick=!1,!1}},beforeUpdate:function(n,e,t){let o=m(n),i=o.options;o.options=t,We(i,t)&&(gn(n),hn(n,t)),ze(n,t)},beforeDatasetsDraw(n,e,t){B(n,"beforeDatasetsDraw",t)},afterDatasetsDraw(n,e,t){B(n,"afterDatasetsDraw",t)},beforeDraw(n,e,t){B(n,"beforeDraw",t)},afterDraw(n,e,t){B(n,"afterDraw",t)},stop:function(n){Ee(n),R&&gn(n),Jn(n)},panFunctions:Y,zoomFunctions:H,zoomRectFunctions:X};import{Chart as Fe}from"chart.js";import{BasicPlatform as Ae}from"chart.js";var j=class extends Ae{constructor(){super(...arguments);this.listeners=new Map}updateConfig(t){}addEventListener(t,o,i){this.listeners.set(o,i)}removeEventListener(t,o){this.listeners.delete(o)}dispatch(t){let o=this.listeners.get(t.type);return o===void 0?!1:(o(t),!0)}};var Le=["responsive","maintainAspectRatio","devicePixelRatio"];function On(n,e){if(n.platform!==void 0)throw new Error("The chart config must not set platform: the worker runtime sets it.");let t=n.options;if(t!==void 0){for(let r of Le)if(r in t)throw new Error(`The chart config must not set options.${r}: the worker runtime sets it.`);if(t.plugins?.zoom?.zoom?.drag?.enabled===!0)throw new Error("options.plugins.zoom.zoom.drag is not supported in a worker.")}e.canvas.width=e.size.width,e.canvas.height=e.size.height;let o=[...n.plugins??[],...e.plugins],i={...n,platform:j,options:{...t,responsive:!1,maintainAspectRatio:!1,devicePixelRatio:e.size.devicePixelRatio},plugins:o};return new Fe(e.canvas,i)}function De(n,e){let t=n.options;if(t.responsive!==!1||t.maintainAspectRatio!==!1||t.devicePixelRatio!==e.devicePixelRatio)throw new Error("The chart lost responsive / maintainAspectRatio / devicePixelRatio set by the worker runtime; a kind must mutate chart.options instead of replacing it.")}function Tn(n,e){return{id:"chartjsWorkerRuntime",beforeUpdate(t){De(t,n),n.updateCalled=!0},afterRender(){let t=n.pendingRevision;t!==null&&(n.pendingRevision=null,e(t))}}}function Bn(n,e){Object.defineProperty(n,"getBoundingClientRect",{configurable:!0,value:()=>{let{width:t,height:o}=e();return{left:0,top:0,x:0,y:0,right:t,bottom:o,width:t,height:o}}})}function In(n,e){let t=new Event("wheel",{cancelable:!0}),o=i=>({value:i});Object.defineProperties(t,{deltaX:o(e.deltaX),deltaY:o(e.deltaY),deltaMode:o(e.deltaMode),clientX:o(e.x),clientY:o(e.y),ctrlKey:o(e.modifiers.ctrlKey),altKey:o(e.modifiers.altKey),shiftKey:o(e.modifiers.shiftKey),metaKey:o(e.modifiers.metaKey),native:o(null),x:o(e.x),y:o(e.y)}),n.dispatchEvent(t)}function Kn(n,e){if(n!==e.requestAnimationFrame)throw new Error('chart.js was loaded before "@aiquants/chartjs-worker/worker-env", so its animations would run synchronously. Import "@aiquants/chartjs-worker/worker-env" as the first statement of the worker entry.')}function jn(){return globalThis}import{each as Ne}from"chart.js/helpers";var He=O,Wn=new WeakMap;function G(n){let e=Wn.get(n);if(e!==void 0)return e;let t={panning:!1,delta:null,panScales:[],rejected:!1,scale:null,filterNextClick:!1};return Wn.set(n,t),t}function S(n,e){return n===void 0?void 0:n(e)}function An(n){let e=n.options.plugins.zoom;return typeof e!="object"||e===null?null:e}function Xe(n){return n.enabled&&n.modifierKey}function Ye(n,e){return!!n&&e[`${n}Key`]!==!0}function W(n,e){return typeof n=="string"&&n.includes(e)}function q(n){return{x:W(n,"x"),y:W(n,"y")}}function _e(n,e){for(let t of Object.values(e.scales))if(n.y>=t.top&&n.y<=t.bottom&&n.x>=t.left&&n.x<=t.right)return t;return null}function $e(n,e,t){let{mode:o="xy",scaleMode:i,overScaleMode:r}=n,a=_e(e,t),l=q(o),c=q(i);if(r){let f=q(r);for(let s of["x","y"])f[s]&&(c[s]=l[s],l[s]=!1)}if(a!==null&&c[a.axis])return[a];let u=[];return Ne(t.scales,f=>{l[f.axis]&&u.push(f)}),u}function Ue(n,e){let t=Math.abs(n.x-e.x),o=Math.abs(n.y-e.y),i=t/o;return i>.3&&i<1.7?{x:!0,y:!0}:t>o?{x:!0,y:!1}:{x:!1,y:!0}}function Fn(n,e){return e.type==="pan"?{type:n,pointerType:e.pointerType,center:{x:e.x,y:e.y},deltaX:e.deltaX,deltaY:e.deltaY,srcEvent:e.modifiers}:{type:n,pointerType:"touch",center:{x:e.centerX,y:e.centerY},deltaX:0,deltaY:0,srcEvent:{ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1}}}function Ln(n,e,t){let o=e.delta;o!==null&&(e.panning=!0,K(n,{x:t.deltaX-o.x,y:t.deltaY-o.y},e.panScales),e.delta={x:t.deltaX,y:t.deltaY})}function Dn(n,e){let t=An(n);if(t===null)return;let o=G(n);if(e.phase==="start"){Ve(n,t,o,e);return}if(o.rejected){e.phase==="end"&&(o.rejected=!1);return}if(e.phase==="move"){Ln(n,o,e);return}o.delta=null,o.panning&&(o.panning=!1,o.filterNextClick=!0,S(t.pan.onPanComplete,{chart:n}))}function Ve(n,e,t,o){let i=e.pan;if(t.rejected=!0,!i.enabled)return;let r=Fn("panstart",o);if(o.pointerType==="mouse"&&Ye(Xe(i),o.modifiers)){S(i.onPanRejected,{chart:n,event:r});return}let a={x:o.x,y:o.y};if(S(i.onPanStart,{chart:n,event:r,point:a})===!1){S(i.onPanRejected,{chart:n,event:r});return}t.rejected=!1,t.panScales=$e(i,a,n),t.delta={x:0,y:0},Ln(n,t,o)}function Zn(n,e,t,o){if(t.scale===null)return;let i=1/t.scale*o.scale,r=Ue(o.pointers[0],o.pointers[1]),a=e.zoom.mode,l={x:r.x&&W(a,"x")?i:1,y:r.y&&W(a,"y")?i:1,focalPoint:{x:o.centerX,y:o.centerY}};He(n,l,"zoom","pinch"),t.scale=o.scale}function Nn(n,e){let t=An(n);if(t===null)return;let o=G(n);if(e.phase==="start"){if(!t.zoom.pinch?.enabled)return;let i=Fn("pinchstart",e),r={x:e.centerX,y:e.centerY};if(S(t.zoom.onZoomStart,{chart:n,event:i,point:r})===!1){o.scale=null,S(t.zoom.onZoomRejected,{chart:n,event:i});return}o.scale=1;return}if(e.phase==="move"){Zn(n,t,o,e);return}o.scale!==null&&(Zn(n,t,o,e),o.scale=null,S(t.zoom.onZoomComplete,{chart:n}))}var Hn={id:"chartjsWorkerZoomBridge",beforeEvent(n,{event:e}){let t=G(n);if(t.panning)return!1;if((e.type==="click"||e.type==="mouseup")&&t.filterNextClick)return t.filterNextClick=!1,!1}};function Z(n){return n instanceof Error?{message:n.message,stack:n.stack??""}:{message:String(n),stack:""}}function Je(n){let e=jn();Kn(Ge,e),Xn.register(En,qe,b),Qe(e,n.kinds)}function Qe(n,e){let t=new Map,o=s=>n.postMessage(s),i=s=>{let d=t.get(s);if(d===void 0)throw new Error(`Unknown chart id "${s}".`);return d},r=(s,d,p)=>{o({type:"updating",chartId:s.chartId,revision:d}),s.runtime.pendingRevision=d,s.revisionRunning=!0,s.drawnWhileRunning=!1;try{l(s,p),s.revisionRunning=!1,s.drawnWhileRunning&&o({type:"drawn",chartId:s.chartId,revision:d})}catch(g){s.revisionRunning=!1,s.runtime.pendingRevision=null,o({type:"error",chartId:s.chartId,revision:d,...Z(g)})}o({type:"updated",chartId:s.chartId,revision:d})},a=(s,d)=>{if(s.revisionRunning){s.drawnWhileRunning=!0;return}o({type:"drawn",chartId:s.chartId,revision:d})},l=(s,d)=>{let p=s.kind;if(p===void 0)throw new Error(`Unknown chart kind "${s.kindName}".`);let g=s.chart;if(g===null){c(s,p,d);return}s.runtime.updateCalled=!1,p.update(g,d,s.context),s.runtime.updateCalled||g.update()},c=(s,d,p)=>{let g=null,x={...s.context,createChart:v=>{if(g!==null)throw new Error("context.createChart must be called once per create.");let C=On(v,{canvas:s.canvas,size:s.size,plugins:[Tn(s.runtime,Yn=>a(s,Yn)),Hn]});return g=C,C}};try{let v=d.create(p,x);if(g===null||v!==g)throw new Error("A chart kind's create must return the chart made by context.createChart.");s.chart=v}catch(v){throw Xn.getChart(s.canvas)?.destroy(),v}},u=s=>{switch(s.type){case"mount":{let d=Object.hasOwn(e,s.kind)?e[s.kind]:void 0,p={chartId:s.chartId,kind:d,kindName:s.kind,canvas:s.canvas,size:s.size,chart:null,runtime:{pendingRevision:null,updateCalled:!1,devicePixelRatio:s.size.devicePixelRatio},context:{createChart:()=>{throw new Error("context.createChart can only be called inside create.")},emit:(g,x)=>o({type:"event",chartId:s.chartId,name:g,payload:x})},revisionRunning:!1,drawnWhileRunning:!1};Bn(p.canvas,()=>p.size),t.set(s.chartId,p),r(p,s.revision,s.props);return}case"update":r(i(s.chartId),s.revision,s.props);return;case"resize":{let d=i(s.chartId);d.size=s.size,d.runtime.devicePixelRatio=s.size.devicePixelRatio;let p=d.chart;p!==null&&(p.options.devicePixelRatio=s.size.devicePixelRatio,p.resize(s.size.width,s.size.height));return}case"pointer":{let d=i(s.chartId).chart;if(d!==null){let p={type:s.event,pointerType:s.pointerType,...s.modifiers},g={type:s.event,native:p,x:s.x,y:s.y};d.platform.dispatch(g)}return}case"wheel":{let d=i(s.chartId);d.chart!==null&&In(d.canvas,s);return}case"pan":{let d=i(s.chartId).chart;d!==null&&Dn(d,s);return}case"pinch":{let d=i(s.chartId).chart;d!==null&&Nn(d,s);return}case"command":f(i(s.chartId),s.requestId,s.name,s.payload);return;case"destroy":{i(s.chartId).chart?.destroy(),t.delete(s.chartId);return}}},f=(s,d,p,g)=>{let x=C=>o({type:"commandResult",chartId:s.chartId,requestId:d,ok:!1,...Z(C)}),v=s.chart;if(v===null||s.kind===void 0){x(new Error(`The chart "${s.chartId}" has not been created, so command "${p}" cannot run.`));return}if(!Object.hasOwn(s.kind.commands,p)){x(new Error(`Unknown command "${p}" of chart kind "${s.kindName}".`));return}try{let C=s.kind.commands[p](v,g,s.context);o({type:"commandResult",chartId:s.chartId,requestId:d,ok:!0,value:C})}catch(C){x(C)}};n.addEventListener("message",s=>{try{u(s.data)}catch(d){o({type:"fatal",...Z(d)})}}),n.addEventListener("unhandledrejection",s=>{o({type:"fatal",...Z(s.reason)})})}export{b as FloatingBarController,_n as defineChartKind,$n as floatingValueOf,Je as startChartWorker,Un as toFloatingStacks};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
globalThis.window=globalThis;
|
package/package.json
CHANGED
|
@@ -1,6 +1,109 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiquants/chartjs-worker",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Draws Chart.js charts in a Web Worker on an OffscreenCanvas while keeping tooltips, clicks, legends, wheel zoom, drag and touch panning, pinch zoom and responsive sizing, so a heavy chart never blocks the page.",
|
|
5
|
+
"sideEffects": [
|
|
6
|
+
"./dist/worker-env.mjs"
|
|
7
|
+
],
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"module": "dist/index.mjs",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./react": {
|
|
18
|
+
"types": "./dist/react/index.d.ts",
|
|
19
|
+
"import": "./dist/react/index.mjs",
|
|
20
|
+
"require": "./dist/react/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./worker-env": {
|
|
23
|
+
"types": "./dist/worker-env.d.mts",
|
|
24
|
+
"import": "./dist/worker-env.mjs"
|
|
25
|
+
},
|
|
26
|
+
"./worker": {
|
|
27
|
+
"types": "./dist/worker/index.d.mts",
|
|
28
|
+
"import": "./dist/worker/index.mjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"CHANGELOG.md",
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"THIRD_PARTY_NOTICES.md"
|
|
37
|
+
],
|
|
38
|
+
"keywords": [
|
|
39
|
+
"chart.js",
|
|
40
|
+
"chartjs",
|
|
41
|
+
"web-worker",
|
|
42
|
+
"offscreencanvas",
|
|
43
|
+
"chartjs-plugin-zoom",
|
|
44
|
+
"react",
|
|
45
|
+
"typescript"
|
|
46
|
+
],
|
|
47
|
+
"author": {
|
|
48
|
+
"name": "fehde-k",
|
|
49
|
+
"url": "https://x.com/fehdek"
|
|
50
|
+
},
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"chartjs-plugin-zoom": "2.2.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"chart.js": "^4.5.1",
|
|
57
|
+
"react": ">=18"
|
|
58
|
+
},
|
|
59
|
+
"peerDependenciesMeta": {
|
|
60
|
+
"react": {
|
|
61
|
+
"optional": true
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@playwright/test": "^1.64.1",
|
|
66
|
+
"@testing-library/react": "^16.3.2",
|
|
67
|
+
"@types/node": "^25.9.1",
|
|
68
|
+
"@types/react": "^19.2.7",
|
|
69
|
+
"@types/react-dom": "^19.2.3",
|
|
70
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
71
|
+
"chart.js": "^4.5.1",
|
|
72
|
+
"jsdom": "^27.4.0",
|
|
73
|
+
"react": "^19.2.7",
|
|
74
|
+
"react-dom": "^19.2.7",
|
|
75
|
+
"rimraf": "^6.1.2",
|
|
76
|
+
"tsup": "^8.5.1",
|
|
77
|
+
"typescript": "^5.9.3",
|
|
78
|
+
"vite": "^7.3.1",
|
|
79
|
+
"vitest": "^4.1.10"
|
|
80
|
+
},
|
|
81
|
+
"engines": {
|
|
82
|
+
"node": ">=18.17.0",
|
|
83
|
+
"pnpm": ">=8.0.0"
|
|
84
|
+
},
|
|
85
|
+
"publishConfig": {
|
|
86
|
+
"access": "public"
|
|
87
|
+
},
|
|
88
|
+
"scripts": {
|
|
89
|
+
"build": "pnpm -w run workspace:build \"$PNPM_SCRIPT_SRC_DIR\"",
|
|
90
|
+
"prebuild:self": "pnpm -w run workspace:sync \"$PNPM_SCRIPT_SRC_DIR\"",
|
|
91
|
+
"build:self": "rimraf dist && tsup && node ../../.config/scripts/strip-dts-comments.mjs dist && node scripts/check-dist.mjs",
|
|
92
|
+
"build:watch": "tsup --watch",
|
|
93
|
+
"dev": "tsup --watch",
|
|
94
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.tests.json",
|
|
95
|
+
"clean": "rimraf dist",
|
|
96
|
+
"verify": "pnpm run typecheck && pnpm run check && pnpm run check:md && pnpm run test:coverage && pnpm run test:browser",
|
|
97
|
+
"publish:patch": "pnpm run verify && pnpm run build && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version patch --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks",
|
|
98
|
+
"publish:minor": "pnpm run verify && pnpm run build && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version minor --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks",
|
|
99
|
+
"publish:major": "pnpm run verify && pnpm run build && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version major --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks",
|
|
100
|
+
"lint": "biome lint src/ tests/",
|
|
101
|
+
"check": "biome check src/ tests/",
|
|
102
|
+
"check:fix": "biome check --write src/ tests/",
|
|
103
|
+
"check:md": "cd ../.. && node_modules/.bin/markdownlint-cli2 \"packages/chartjs-worker/**/*.md\"",
|
|
104
|
+
"license-check": "pnpm dlx license-checker --production --onlyAllow \"MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;Unlicense\"",
|
|
105
|
+
"test": "vitest run",
|
|
106
|
+
"test:coverage": "vitest run --coverage",
|
|
107
|
+
"test:browser": "pnpm run build && ../../node_modules/.bin/playwright test"
|
|
108
|
+
}
|
|
6
109
|
}
|