chartgpu 0.1.0 → 0.1.1
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/LICENSE +1 -1
- package/README.md +141 -9
- package/dist/ChartGPU.d.ts +5 -3
- package/dist/ChartGPU.d.ts.map +1 -1
- package/dist/assets/ChartGPU-zgkjfPqp.js +15 -0
- package/dist/assets/GPUContext-CgqhC6W6.js +1 -0
- package/dist/assets/basic-line-DfRo2Pom.js +1 -0
- package/dist/assets/chart-sync-Bjf8c5Oo.js +1 -0
- package/dist/assets/createChartSync-BUGadH_x.js +1 -0
- package/dist/assets/createDataZoomSlider-DLbAKjVh.js +162 -0
- package/dist/assets/data-update-animation-BYhFrQqE.js +1 -0
- package/dist/assets/grid-test-6lXNOD1c.js +1 -0
- package/dist/assets/grouped-bar-pr-ZGxGI.js +1 -0
- package/dist/assets/hello-world-B3dB8WNo.js +9 -0
- package/dist/assets/interactive-aPGxN-b-.js +14 -0
- package/dist/assets/live-streaming-N4vKWEcJ.js +1 -0
- package/dist/assets/million-points-DVnJu39j.js +1 -0
- package/dist/assets/pie-BR5SmRvW.js +1 -0
- package/dist/assets/pie-c06rKDKR.js +321 -0
- package/dist/assets/sampling-F-iafT6-.js +1 -0
- package/dist/assets/scales-D-5MHN10.js +37 -0
- package/dist/assets/scatter-CVFSpSfu.js +1 -0
- package/dist/components/formatTooltip.d.ts +7 -0
- package/dist/components/formatTooltip.d.ts.map +1 -1
- package/dist/config/OptionResolver.d.ts +21 -2
- package/dist/config/OptionResolver.d.ts.map +1 -1
- package/dist/config/defaults.d.ts +16 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/types.d.ts +49 -4
- package/dist/config/types.d.ts.map +1 -1
- package/dist/core/createRenderCoordinator.d.ts +2 -2
- package/dist/core/createRenderCoordinator.d.ts.map +1 -1
- package/dist/data/ohlcSample.d.ts +21 -0
- package/dist/data/ohlcSample.d.ts.map +1 -0
- package/dist/examples/basic-line/index.html +90 -0
- package/dist/examples/chart-sync/index.html +102 -0
- package/dist/examples/data-update-animation/index.html +193 -0
- package/dist/examples/grid-test/index.html +90 -0
- package/dist/examples/grouped-bar/index.html +91 -0
- package/dist/examples/hello-world/index.html +32 -0
- package/dist/examples/index.html +142 -0
- package/dist/examples/interactive/index.html +101 -0
- package/dist/examples/live-streaming/index.html +150 -0
- package/dist/examples/million-points/index.html +220 -0
- package/dist/examples/pie/index.html +132 -0
- package/dist/examples/sampling/index.html +249 -0
- package/dist/examples/scatter/index.html +91 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3922 -2904
- package/dist/index.js.map +1 -1
- package/dist/interaction/findCandlestick.d.ts +41 -0
- package/dist/interaction/findCandlestick.d.ts.map +1 -0
- package/dist/renderers/createAxisRenderer.d.ts +1 -1
- package/dist/renderers/createAxisRenderer.d.ts.map +1 -1
- package/dist/renderers/createCandlestickRenderer.d.ts +19 -0
- package/dist/renderers/createCandlestickRenderer.d.ts.map +1 -0
- package/package.json +3 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,25 +1,133 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/chart-gpu.jpg" alt="ChartGPU" width="400">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
High-performance charts powered by WebGPU
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://github.com/hunterg325/ChartGPU/blob/main/docs/GETTING_STARTED.md">Documentation</a> |
|
|
11
|
+
<a href="https://chartgpu.github.io/ChartGPU/">Live Demo</a> |
|
|
12
|
+
<a href="https://github.com/hunterg325/ChartGPU/tree/main/examples">Examples</a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<img src="https://img.shields.io/npm/v/chartgpu" alt="npm">
|
|
17
|
+
<img src="https://img.shields.io/npm/l/chartgpu" alt="license">
|
|
18
|
+
<a href="https://chartgpu.github.io/ChartGPU/">
|
|
19
|
+
<img src="https://img.shields.io/badge/demo-live-brightgreen" alt="Live Demo">
|
|
20
|
+
</a>
|
|
21
|
+
</p>
|
|
8
22
|
|
|
9
23
|
ChartGPU is a TypeScript charting library built on WebGPU for smooth, interactive rendering—especially when you have lots of data.
|
|
10
24
|
|
|
11
25
|
## Highlights
|
|
12
26
|
|
|
13
27
|
- 🚀 WebGPU-accelerated rendering for high FPS with large datasets
|
|
14
|
-
- 📈 Multiple series types: line, area, bar, scatter, pie
|
|
28
|
+
- 📈 Multiple series types: line, area, bar, scatter, pie, candlestick
|
|
15
29
|
- 🧭 Built-in interaction: hover highlight, tooltip, crosshair
|
|
16
30
|
- 🔁 Streaming updates via `appendData(...)` (cartesian series)
|
|
17
31
|
- 🔍 X-axis zoom (inside gestures + optional slider UI)
|
|
18
32
|
- 🎛️ Theme presets (`'dark' | 'light'`) and custom theme support
|
|
19
33
|
|
|
34
|
+
## Architecture
|
|
35
|
+
|
|
36
|
+
At a high level, `ChartGPU.create(...)` owns the canvas + WebGPU lifecycle, and delegates render orchestration (layout/scales/data upload/render passes + internal overlays) to the render coordinator. For deeper internal notes, see [`docs/API.md`](https://github.com/hunterg325/ChartGPU/blob/main/docs/API.md) (especially “Render coordinator”).
|
|
37
|
+
|
|
38
|
+
```mermaid
|
|
39
|
+
flowchart TB
|
|
40
|
+
UserApp["Consumer app"] --> PublicAPI["src/index.ts (Public API exports)"]
|
|
41
|
+
|
|
42
|
+
PublicAPI --> ChartCreate["ChartGPU.create(container, options)"]
|
|
43
|
+
PublicAPI --> SyncAPI["connectCharts(charts)"]
|
|
44
|
+
|
|
45
|
+
subgraph ChartInstance["Chart instance (src/ChartGPU.ts)"]
|
|
46
|
+
ChartCreate --> SupportCheck["checkWebGPUSupport()"]
|
|
47
|
+
ChartCreate --> Canvas["Create canvas + mount into container"]
|
|
48
|
+
ChartCreate --> Options["resolveOptions(options)"]
|
|
49
|
+
ChartCreate --> GPUInit["GPUContext.create(canvas)"]
|
|
50
|
+
ChartCreate --> Coordinator["createRenderCoordinator(gpuContext, resolvedOptions)"]
|
|
51
|
+
|
|
52
|
+
ChartCreate --> InstanceAPI["ChartGPUInstance APIs"]
|
|
53
|
+
InstanceAPI --> RequestRender["requestAnimationFrame (coalesced)"]
|
|
54
|
+
RequestRender --> Coordinator
|
|
55
|
+
|
|
56
|
+
InstanceAPI --> SetOption["setOption(...)"]
|
|
57
|
+
InstanceAPI --> AppendData["appendData(...)"]
|
|
58
|
+
InstanceAPI --> Resize["resize()"]
|
|
59
|
+
|
|
60
|
+
subgraph PublicEvents["Public events + hit-testing (ChartGPU.ts)"]
|
|
61
|
+
Canvas --> PointerHandlers["Pointer listeners"]
|
|
62
|
+
PointerHandlers --> PublicHitTest["findNearestPoint() / findPieSlice()"]
|
|
63
|
+
PointerHandlers --> EmitEvents["emit('click'/'mouseover'/'mouseout')"]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
DataZoomSlider["dataZoom slider UI (DOM)"] --> Coordinator
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
subgraph WebGPUCore["WebGPU core (src/core/GPUContext.ts)"]
|
|
70
|
+
GPUInit --> AdapterDevice["navigator.gpu.requestAdapter/device"]
|
|
71
|
+
GPUInit --> CanvasConfig["canvasContext.configure(format)"]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
subgraph RenderCoordinatorLayer["Render coordinator (src/core/createRenderCoordinator.ts)"]
|
|
75
|
+
Coordinator --> Layout["GridArea layout"]
|
|
76
|
+
Coordinator --> Scales["xScale/yScale (clip space for render)"]
|
|
77
|
+
Coordinator --> DataUpload["createDataStore(device) (GPU buffer upload/caching)"]
|
|
78
|
+
Coordinator --> RenderPass["Encode + submit render pass"]
|
|
79
|
+
|
|
80
|
+
subgraph InternalOverlays["Internal interaction overlays (coordinator)"]
|
|
81
|
+
Coordinator --> Events["createEventManager(canvas, gridArea)"]
|
|
82
|
+
Events --> OverlayHitTest["hover/tooltip hit-testing"]
|
|
83
|
+
Events --> InteractionX["interaction-x state (crosshair)"]
|
|
84
|
+
Coordinator --> OverlaysDOM["DOM overlays: legend / tooltip / text labels"]
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
subgraph Renderers["GPU renderers (src/renderers/*)"]
|
|
89
|
+
RenderPass --> GridR["Grid"]
|
|
90
|
+
RenderPass --> AreaR["Area"]
|
|
91
|
+
RenderPass --> BarR["Bar"]
|
|
92
|
+
RenderPass --> ScatterR["Scatter"]
|
|
93
|
+
RenderPass --> LineR["Line"]
|
|
94
|
+
RenderPass --> PieR["Pie"]
|
|
95
|
+
RenderPass --> CandlestickR["Candlestick"]
|
|
96
|
+
RenderPass --> CrosshairR["Crosshair overlay"]
|
|
97
|
+
RenderPass --> HighlightR["Hover highlight overlay"]
|
|
98
|
+
RenderPass --> AxisR["Axes/ticks"]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
subgraph Shaders["WGSL shaders (src/shaders/*)"]
|
|
102
|
+
GridR --> gridWGSL["grid.wgsl"]
|
|
103
|
+
AreaR --> areaWGSL["area.wgsl"]
|
|
104
|
+
BarR --> barWGSL["bar.wgsl"]
|
|
105
|
+
ScatterR --> scatterWGSL["scatter.wgsl"]
|
|
106
|
+
LineR --> lineWGSL["line.wgsl"]
|
|
107
|
+
PieR --> pieWGSL["pie.wgsl"]
|
|
108
|
+
CandlestickR --> candlestickWGSL["candlestick.wgsl"]
|
|
109
|
+
CrosshairR --> crosshairWGSL["crosshair.wgsl"]
|
|
110
|
+
HighlightR --> highlightWGSL["highlight.wgsl"]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
subgraph ChartSync["Chart sync (src/interaction/createChartSync.ts)"]
|
|
114
|
+
SyncAPI --> ListenX["listen: 'crosshairMove'"]
|
|
115
|
+
SyncAPI --> DriveX["setCrosshairX(...) on peers"]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
InteractionX --> ListenX
|
|
119
|
+
DriveX --> InstanceAPI
|
|
120
|
+
```
|
|
121
|
+
|
|
20
122
|
## Demo
|
|
21
123
|
|
|
22
|
-

|
|
125
|
+
|
|
126
|
+
### Candlestick Charts
|
|
127
|
+
|
|
128
|
+
Financial OHLC (open-high-low-close) candlestick rendering with classic/hollow style toggle and color customization.
|
|
129
|
+
|
|
130
|
+

|
|
23
131
|
|
|
24
132
|
## Quick start
|
|
25
133
|
|
|
@@ -35,6 +143,30 @@ await ChartGPU.create(container, {
|
|
|
35
143
|
|
|
36
144
|
`npm install chartgpu`
|
|
37
145
|
|
|
146
|
+
## React Integration
|
|
147
|
+
|
|
148
|
+
React bindings are available via [`chartgpu-react`](https://github.com/ChartGPU/chartgpu-react):
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npm install chartgpu-react
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import { ChartGPUChart } from 'chartgpu-react';
|
|
156
|
+
|
|
157
|
+
function MyChart() {
|
|
158
|
+
return (
|
|
159
|
+
<ChartGPUChart
|
|
160
|
+
options={{
|
|
161
|
+
series: [{ type: 'line', data: [[0, 1], [1, 3], [2, 2]] }],
|
|
162
|
+
}}
|
|
163
|
+
/>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
See the [chartgpu-react repository](https://github.com/ChartGPU/chartgpu-react) for full documentation and examples.
|
|
169
|
+
|
|
38
170
|
## Browser support (WebGPU required)
|
|
39
171
|
|
|
40
172
|
- Chrome 113+ or Edge 113+ (WebGPU enabled by default)
|
package/dist/ChartGPU.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChartGPUOptions, DataPoint } from './config/types';
|
|
1
|
+
import type { ChartGPUOptions, DataPoint, OHLCDataPoint } from './config/types';
|
|
2
2
|
export interface ChartGPUInstance {
|
|
3
3
|
readonly options: Readonly<ChartGPUOptions>;
|
|
4
4
|
readonly disposed: boolean;
|
|
@@ -6,9 +6,11 @@ export interface ChartGPUInstance {
|
|
|
6
6
|
/**
|
|
7
7
|
* Appends new points to a cartesian series at runtime (streaming).
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* For candlestick series, pass `OHLCDataPoint[]`.
|
|
10
|
+
* For other cartesian series (line, area, bar, scatter), pass `DataPoint[]`.
|
|
11
|
+
* Pie series are non-cartesian and are not supported by streaming append.
|
|
10
12
|
*/
|
|
11
|
-
appendData(seriesIndex: number, newPoints: DataPoint[]): void;
|
|
13
|
+
appendData(seriesIndex: number, newPoints: DataPoint[] | OHLCDataPoint[]): void;
|
|
12
14
|
resize(): void;
|
|
13
15
|
dispose(): void;
|
|
14
16
|
on(eventName: 'crosshairMove', callback: ChartGPUCrosshairMoveCallback): void;
|
package/dist/ChartGPU.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartGPU.d.ts","sourceRoot":"","sources":["../src/ChartGPU.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"ChartGPU.d.ts","sourceRoot":"","sources":["../src/ChartGPU.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAkB,aAAa,EAA4C,MAAM,gBAAgB,CAAC;AAY1I,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAC1C;;;;;;OAMG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,aAAa,EAAE,GAAG,IAAI,CAAC;IAChF,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAC9E,EAAE,CAAC,SAAS,EAAE,iBAAiB,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACxE,GAAG,CAAC,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAC/E,GAAG,CAAC,SAAS,EAAE,iBAAiB,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACzE;;;;;OAKG;IACH,eAAe,IAAI,MAAM,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1D;;OAEG;IACH,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACzF;;OAEG;IACH,YAAY,IAAI,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAChE;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAChD;AAID,MAAM,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAExC,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,eAAe,CAAC;AAErF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;CAC9B,CAAC,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;AAE5E,MAAM,MAAM,6BAA6B,GAAG,CAAC,OAAO,EAAE,4BAA4B,KAAK,IAAI,CAAC;AAqU5F,wBAAsB,cAAc,CAClC,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAw0B3B;AAED,eAAO,MAAM,QAAQ;;CAEpB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import{G as Ve}from"./GPUContext-CgqhC6W6.js";import{r as qe,a as Be,b as $e,f as je,e as Je}from"./createDataZoomSlider-DLbAKjVh.js";import{a as De}from"./scales-D-5MHN10.js";let K=null;async function Ke(){return K||(K=(async()=>{if(typeof window>"u")return{supported:!1,reason:"Not running in a browser environment (window is undefined)."};if(typeof navigator>"u")return{supported:!1,reason:"Navigator is not available in this environment."};if(!navigator.gpu)return{supported:!1,reason:"WebGPU API (navigator.gpu) is not available. Your browser does not support WebGPU."};try{let i=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});return i||(i=await navigator.gpu.requestAdapter()),i?{supported:!0}:{supported:!1,reason:"No compatible WebGPU adapter found. This may occur if: (1) no GPU is available, (2) GPU drivers are outdated or incompatible, (3) running in a VM or headless environment, or (4) WebGPU is disabled in browser settings."}}catch(i){let a="Failed to request WebGPU adapter.";return i instanceof DOMException?(a=`Failed to request WebGPU adapter: ${i.name}`,i.message&&(a+=` - ${i.message}`)):i instanceof Error?a=`Failed to request WebGPU adapter: ${i.message}`:a=`Failed to request WebGPU adapter: ${String(i)}`,{supported:!1,reason:a}}})(),K)}const Qe=6,et=500,Te=32,Ae=8,Ge=Te+Ae,tt=i=>Array.isArray(i),Q=i=>tt(i)?{x:i[0],y:i[1]}:{x:i.x,y:i.y},Ue=i=>{var a;return((a=i.dataZoom)==null?void 0:a.some(o=>(o==null?void 0:o.type)==="slider"))??!1},ae=(i,a,o)=>Math.min(o,Math.max(a,i)),Ee=i=>{const a={...qe(i),tooltip:i.tooltip};return Ue(i)?{...a,grid:{...a.grid,bottom:a.grid.bottom+Ge}}:a},_e=i=>{let a=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY;for(let l=0;l<i.length;l++){const{x:t,y:d}=Q(i[l]);!Number.isFinite(t)||!Number.isFinite(d)||(t<a&&(a=t),t>o&&(o=t),d<n&&(n=d),d>s&&(s=d))}return!Number.isFinite(a)||!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(s)?null:(a===o&&(o=a+1),n===s&&(s=n+1),{xMin:a,xMax:o,yMin:n,yMax:s})},nt=(i,a)=>{if(a.length===0)return i;let o=i;if(!o){const d=_e(a);if(!d)return i;o=d}let n=o.xMin,s=o.xMax,l=o.yMin,t=o.yMax;for(let d=0;d<a.length;d++){const{x:N,y:g}=Q(a[d]);!Number.isFinite(N)||!Number.isFinite(g)||(N<n&&(n=N),N>s&&(s=N),g<l&&(l=g),g>t&&(t=g))}return n===s&&(s=n+1),l===t&&(t=l+1),{xMin:n,xMax:s,yMin:l,yMax:t}},le=(i,a)=>{let o=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY;for(let t=0;t<i.length;t++){const d=i[t];if(d.type==="pie")continue;const N=(a==null?void 0:a[t])??null;if(N){const m=N;if(Number.isFinite(m.xMin)&&Number.isFinite(m.xMax)&&Number.isFinite(m.yMin)&&Number.isFinite(m.yMax)){m.xMin<o&&(o=m.xMin),m.xMax>n&&(n=m.xMax),m.yMin<s&&(s=m.yMin),m.yMax>l&&(l=m.yMax);continue}}const g=d.rawBounds??null;if(g){const m=g;if(Number.isFinite(m.xMin)&&Number.isFinite(m.xMax)&&Number.isFinite(m.yMin)&&Number.isFinite(m.yMax)){m.xMin<o&&(o=m.xMin),m.xMax>n&&(n=m.xMax),m.yMin<s&&(s=m.yMin),m.yMax>l&&(l=m.yMax);continue}}const P=d.data;for(let m=0;m<P.length;m++){const{x:c,y:w}=Q(P[m]);!Number.isFinite(c)||!Number.isFinite(w)||(c<o&&(o=c),c>n&&(n=c),w<s&&(s=w),w>l&&(l=w))}}return!Number.isFinite(o)||!Number.isFinite(n)||!Number.isFinite(s)||!Number.isFinite(l)?{xMin:0,xMax:1,yMin:0,yMax:1}:(o===n&&(n=o+1),s===l&&(l=s+1),{xMin:o,xMax:n,yMin:s,yMax:l})},ue=(i,a)=>{let o=i,n=a;if((!Number.isFinite(o)||!Number.isFinite(n))&&(o=0,n=1),o===n)n=o+1;else if(o>n){const s=o;o=n,n=s}return{min:o,max:n}},q=(i,a)=>{if(typeof i=="number")return Number.isFinite(i)?i:null;if(typeof i!="string")return null;const o=i.trim();if(o.length===0)return null;if(o.endsWith("%")){const s=Number.parseFloat(o.slice(0,-1));return Number.isFinite(s)?s/100*a:null}const n=Number.parseFloat(o);return Number.isFinite(n)?n:null},it=(i,a,o)=>{const n=(i==null?void 0:i[0])??"50%",s=(i==null?void 0:i[1])??"50%",l=q(n,a),t=q(s,o);return{x:Number.isFinite(l)?l:a*.5,y:Number.isFinite(t)?t:o*.5}},rt=i=>Array.isArray(i),st=(i,a)=>{if(i==null)return{inner:0,outer:a*.7};if(rt(i)){const s=q(i[0],a),l=q(i[1],a),t=Math.max(0,Number.isFinite(s)?s:0),d=Math.max(t,Number.isFinite(l)?l:a*.7);return{inner:t,outer:Math.min(a,d)}}const o=q(i,a),n=Math.max(0,Number.isFinite(o)?o:a*.7);return{inner:0,outer:Math.min(a,n)}};async function ot(i,a){var Fe;const o=await Ke();if(!o.supported){const e=o.reason||"Unknown reason";throw new Error(`ChartGPU: WebGPU is not available.
|
|
2
|
+
Reason: ${e}
|
|
3
|
+
Browser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.
|
|
4
|
+
Resources:
|
|
5
|
+
- MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API
|
|
6
|
+
- Browser compatibility: https://caniuse.com/webgpu
|
|
7
|
+
- WebGPU specification: https://www.w3.org/TR/webgpu/
|
|
8
|
+
- Check your system: https://webgpureport.org/`)}const n=document.createElement("canvas");n.style.display="block",n.style.width="100%",n.style.height="100%",i.appendChild(n);let s=!1,l=null,t=null,d=null,N=null,g=null,P=null,m=a,c=Ee(m),w=new Array(c.series.length).fill(null).map(()=>[]),D=new Array(c.series.length).fill(null),A=null;const ce=()=>{w=new Array(c.series.length).fill(null).map(()=>[]),D=new Array(c.series.length).fill(null),A=null;for(let e=0;e<c.series.length;e++){const r=c.series[e];if(r.type==="pie")continue;const u=r.rawData??r.data;w[e]=u.length===0?[]:u.slice(),D[e]=r.rawBounds??null??_e(u)}},Ze=()=>A||(A=c.series.map((e,r)=>e.type==="pie"?e:{...e,data:w[r]??e.data}),A);ce();let G=le(c.series,D),x=null;const F={click:new Set,mouseover:new Set,mouseout:new Set,crosshairMove:new Set};let I=null,O=null,ee=null;const me=new Set;let U=null,k=null;const B=()=>F.mouseover.size>0||F.mouseout.size>0,fe=()=>F.click.size>0,Xe=()=>{U!==null&&(cancelAnimationFrame(U),U=null)},Y=()=>{s||U===null&&(U=requestAnimationFrame(()=>{U=null,!s&&($(!1),t==null||t.render())}))},te=()=>{if(N)try{N()}finally{N=null}},pe=()=>{P==null||P.dispose(),P=null},Le=()=>{g==null||g.remove(),g=null},de=()=>{pe(),Le()},We=()=>{if(g)return g;try{window.getComputedStyle(i).position==="static"&&(i.style.position="relative")}catch{}const e=document.createElement("div");return e.style.position="absolute",e.style.left="0",e.style.right="0",e.style.bottom="0",e.style.height=`${Ge}px`,e.style.paddingTop=`${Ae}px`,e.style.boxSizing="border-box",e.style.pointerEvents="auto",e.style.zIndex="5",i.appendChild(e),g=e,e},he=(e,r)=>{const u=e.end-e.start;return!Number.isFinite(u)||u===0?.5:ae((r-e.start)/u,0,1)},Oe=()=>({getRange:()=>(t==null?void 0:t.getZoomRange())??{start:0,end:100},setRange:(f,p)=>{t==null||t.setZoomRange(f,p)},zoomIn:(f,p)=>{if(!Number.isFinite(f)||!Number.isFinite(p)||p<=1)return;const h=t==null?void 0:t.getZoomRange();if(!h)return;const y=ae(f,0,100),E=he(h,y),S=(h.end-h.start)/p,T=y-E*S;t==null||t.setZoomRange(T,T+S)},zoomOut:(f,p)=>{if(!Number.isFinite(f)||!Number.isFinite(p)||p<=1)return;const h=t==null?void 0:t.getZoomRange();if(!h)return;const y=ae(f,0,100),E=he(h,y),S=(h.end-h.start)*p,T=y-E*S;t==null||t.setZoomRange(T,T+S)},pan:f=>{if(!Number.isFinite(f))return;const p=t==null?void 0:t.getZoomRange();p&&(t==null||t.setZoomRange(p.start+f,p.end+f))},onChange:f=>(t==null?void 0:t.onZoomRangeChange(f))??(()=>{})}),ne=()=>{if(!Ue(m)){de();return}if(!t||!t.getZoomRange())return;const r=We();P||(P=$e(r,Oe(),{height:Te,marginTop:0})),P.update(c.theme)},ke=()=>{te(),!s&&t&&(N=t.onInteractionXChange((e,r)=>{_("crosshairMove",{x:e,source:r})}))},ge=()=>{if(s||!l||!l.initialized)return;const e=(t==null?void 0:t.getZoomRange())??null;te(),pe(),t==null||t.dispose(),t=Be(l,c,{onRequestRender:Y}),d=l.preferredFormat,ke(),e&&t.setZoomRange(e.start,e.end),ne()},$=e=>{var Z;if(s)return;const r=n.getBoundingClientRect(),u=window.devicePixelRatio||1,b=((Z=l==null?void 0:l.device)==null?void 0:Z.limits.maxTextureDimension2D)??8192,v=Math.min(b,Math.max(1,Math.round(r.width*u))),M=Math.min(b,Math.max(1,Math.round(r.height*u))),f=n.width!==v||n.height!==M;f&&(n.width=v,n.height=M);const p=l==null?void 0:l.device,h=l==null?void 0:l.canvasContext,y=l==null?void 0:l.preferredFormat;let E=!1;p&&h&&y&&(f||!k||k.width!==n.width||k.height!==n.height||k.format!==y)&&(h.configure({device:p,format:y,alphaMode:"opaque"}),k={width:n.width,height:n.height,format:y},E=!0,t&&d!==y&&ge()),e&&(f||E)&&Y()},Ye=()=>$(!0),be=e=>{const r=n.getBoundingClientRect();if(!(r.width>0)||!(r.height>0))return{match:null,isInGrid:!1};const u=e.clientX-r.left,b=e.clientY-r.top,v=c.grid.left,M=c.grid.top,f=r.width-c.grid.left-c.grid.right,p=r.height-c.grid.top-c.grid.bottom;if(!(f>0)||!(p>0))return{match:null,isInGrid:!1};const h=u-v,y=b-M;if(!(h>=0&&h<=f&&y>=0&&y<=p))return{match:null,isInGrid:!1};const Z=c.xAxis.min??G.xMin,S=c.xAxis.max??G.xMax,T=c.yAxis.min??G.yMin,ze=c.yAxis.max??G.yMax,X=ue(Z,S),re=(t==null?void 0:t.getZoomRange())??null,L=(()=>{if(!re)return X;const C=X.max-X.min;if(!Number.isFinite(C)||C===0)return X;const R=re.start,j=re.end,V=X.min+R/100*C,se=X.min+j/100*C;return ue(V,se)})(),W=ue(T,ze);if(!(x!==null&&x.rectWidthCss===r.width&&x.rectHeightCss===r.height&&x.plotWidthCss===f&&x.plotHeightCss===p&&x.xDomainMin===L.min&&x.xDomainMax===L.max&&x.yDomainMin===W.min&&x.yDomainMax===W.max)){const C=De().domain(L.min,L.max).range(0,f),R=De().domain(W.min,W.max).range(p,0);x={rectWidthCss:r.width,rectHeightCss:r.height,plotWidthCss:f,plotHeightCss:p,xDomainMin:L.min,xDomainMax:L.max,yDomainMin:W.min,yDomainMax:W.max,xScale:C,yScale:R}}const Ce=x,Se=(()=>{const C=.5*Math.min(f,p);if(!(C>0))return null;for(let R=c.series.length-1;R>=0;R--){const j=c.series[R];if(j.type!=="pie")continue;const V=j,se=it(V.center,f,p),He=st(V.radius,C),J=je(h,y,{seriesIndex:R,series:V},se,He);if(!J)continue;const oe=J.slice.value;return{kind:"pie",seriesIndex:J.seriesIndex,dataIndex:J.dataIndex,sliceValue:typeof oe=="number"&&Number.isFinite(oe)?oe:0}}return null})();if(Se)return{match:Se,isInGrid:!0};const Re=Je(Ze(),h,y,Ce.xScale,Ce.yScale);return{match:Re?{kind:"cartesian",match:Re}:null,isInGrid:!0}},z=(e,r)=>{if(!e)return{seriesIndex:null,dataIndex:null,value:null,seriesName:null,event:r};const u=e.kind==="cartesian"?e.match.seriesIndex:e.seriesIndex,b=e.kind==="cartesian"?e.match.dataIndex:e.dataIndex,v=c.series[u],M=(v==null?void 0:v.name)??null,f=M&&M.trim().length>0?M:null;if(e.kind==="pie")return{seriesIndex:u,dataIndex:b,value:[0,e.sliceValue],seriesName:f,event:r};const{x:p,y:h}=Q(e.match.point);return{seriesIndex:u,dataIndex:b,value:[p,h],seriesName:f,event:r}},_=(e,r)=>{if(!s)for(const u of F[e])u(r)},H=(e,r)=>{const u=ee;if(ee=e,u===null&&e===null)return;if(u===null&&e!==null){_("mouseover",z(e,r));return}if(u!==null&&e===null){_("mouseout",z(u,r));return}if(u===null||e===null)return;const b=u.kind==="cartesian"?u.match.seriesIndex:u.seriesIndex,v=u.kind==="cartesian"?u.match.dataIndex:u.dataIndex,M=e.kind==="cartesian"?e.match.seriesIndex:e.seriesIndex,f=e.kind==="cartesian"?e.match.dataIndex:e.dataIndex;b===M&&v===f||(_("mouseout",z(u,r)),_("mouseover",z(e,r)))},ie=e=>{I&&e.isPrimary&&e.pointerId===I.pointerId&&(I=null)},ye=e=>{if(s||!B())return;const{match:r,isInGrid:u}=be(e);if(!u){H(null,e);return}H(r,e)},xe=e=>{s||!B()&&!I||(ie(e),H(null,e))},Ie=e=>{s||!B()&&!I||(ie(e),H(null,e))},Me=e=>{if(!s&&!(!B()&&!I&&O!==e.pointerId)){if(O===e.pointerId){O=null;return}ie(e),H(null,e)}},Ne=e=>{if(!s&&fe()&&e.isPrimary&&!(e.pointerType==="mouse"&&e.button!==0)){I={pointerId:e.pointerId,startClientX:e.clientX,startClientY:e.clientY,startTimeMs:e.timeStamp};try{n.setPointerCapture(e.pointerId)}catch{}}},ve=e=>{if(s||!fe()||!e.isPrimary||!I||e.pointerId!==I.pointerId)return;const r=e.timeStamp-I.startTimeMs,u=e.clientX-I.startClientX,b=e.clientY-I.startClientY,v=u*u+b*b;I=null;try{n.hasPointerCapture(e.pointerId)&&(O=e.pointerId,n.releasePointerCapture(e.pointerId))}catch{}const M=Qe;if(!(r<=et&&v<=M*M))return;const{match:p}=be(e);_("click",z(p,e))};n.addEventListener("pointermove",ye,{passive:!0}),n.addEventListener("pointerleave",xe,{passive:!0}),n.addEventListener("pointercancel",Ie,{passive:!0}),n.addEventListener("lostpointercapture",Me,{passive:!0}),n.addEventListener("pointerdown",Ne,{passive:!0}),n.addEventListener("pointerup",ve,{passive:!0});const we=()=>{if(!s){s=!0;try{Xe(),de(),te(),t==null||t.dispose(),t=null,d=null,l==null||l.destroy()}finally{I=null,O=null,ee=null,x=null,n.removeEventListener("pointermove",ye),n.removeEventListener("pointerleave",xe),n.removeEventListener("pointercancel",Ie),n.removeEventListener("lostpointercapture",Me),n.removeEventListener("pointerdown",Ne),n.removeEventListener("pointerup",ve),F.click.clear(),F.mouseover.clear(),F.mouseout.clear(),F.crosshairMove.clear(),l=null,n.remove()}}},Pe={get options(){return m},get disposed(){return s},setOption(e){s||(m=e,c=Ee(e),t==null||t.setOptions(c),ce(),G=le(c.series,D),x=null,ne(),Y())},appendData(e,r){if(s||!Number.isFinite(e)||e<0||e>=c.series.length||!r||r.length===0)return;if(c.series[e].type==="pie"){me.has(e)||(me.add(e),console.warn(`ChartGPU.appendData(${e}, ...): pie series are not supported by streaming append. Use setOption(...) to replace pie data.`));return}t==null||t.appendData(e,r);const b=w[e]??[];b.push(...r),w[e]=b,D[e]=nt(D[e],r),G=le(c.series,D),A=null,x=null,Y()},resize:Ye,dispose:we,on(e,r){s||F[e].add(r)},off(e,r){F[e].delete(r)},getInteractionX(){return s?null:(t==null?void 0:t.getInteractionX())??null},setInteractionX(e,r){s||t==null||t.setInteractionX(e,r)},setCrosshairX(e,r){s||t==null||t.setInteractionX(e,r)},onInteractionXChange(e){return s?()=>{}:(t==null?void 0:t.onInteractionXChange(e))??(()=>{})},getZoomRange(){return s?null:(t==null?void 0:t.getZoomRange())??null},setZoomRange(e,r){s||t==null||t.setZoomRange(e,r)}};try{$(!1);try{l=await Ve.create(n)}catch(e){const r=e instanceof Error?e.message:String(e);throw new Error(`ChartGPU: WebGPU is not available.
|
|
9
|
+
Reason: ${r}
|
|
10
|
+
Browser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.
|
|
11
|
+
Resources:
|
|
12
|
+
- MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API
|
|
13
|
+
- Browser compatibility: https://caniuse.com/webgpu
|
|
14
|
+
- WebGPU specification: https://www.w3.org/TR/webgpu/
|
|
15
|
+
- Check your system: https://webgpureport.org/`)}return(Fe=l.device)==null||Fe.lost.then(e=>{s||(e.reason!=="destroyed"&&console.warn("WebGPU device lost:",e),we())}),$(!1),ge(),ne(),Y(),Pe}catch(e){throw Pe.dispose(),e}}const mt={create:ot};export{mt as C};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))i(r);new MutationObserver(r=>{for(const a of r)if(a.type==="childList")for(const o of a.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function n(r){const a={};return r.integrity&&(a.integrity=r.integrity),r.referrerPolicy&&(a.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?a.credentials="include":r.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function i(r){if(r.ep)return;r.ep=!0;const a=n(r);fetch(r.href,a)}})();function v(e){return{adapter:null,device:null,initialized:!1,canvas:e||null,canvasContext:null,preferredFormat:null}}async function g(e){var n;if(e.initialized)throw new Error("GPUContext is already initialized. Call destroyGPUContext() before reinitializing.");if(!navigator.gpu)throw new Error("WebGPU is not available in this browser. Please use a browser that supports WebGPU (Chrome 113+, Edge 113+, or Safari 18+). Ensure WebGPU is enabled in browser flags if needed.");let t=null;try{const i=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});if(!i)throw new Error("Failed to request WebGPU adapter. No compatible adapter found. This may occur if no GPU is available or WebGPU is disabled.");if(t=await i.requestDevice(),!t)throw new Error("Failed to request WebGPU device from adapter.");t.addEventListener("uncapturederror",o=>{console.error("WebGPU uncaptured error:",o.error)});let r=null,a=null;if(e.canvas){const o=e.canvas.getContext("webgpu");if(!o){try{t.destroy()}catch(h){console.warn("Error destroying device during canvas setup failure:",h)}throw new Error("Failed to get WebGPU context from canvas.")}const s=window.devicePixelRatio||1,u=e.canvas.clientWidth||e.canvas.width,f=e.canvas.clientHeight||e.canvas.height;e.canvas.width=Math.max(1,Math.floor(u*s)),e.canvas.height=Math.max(1,Math.floor(f*s));const c=i;a=((n=c.getPreferredCanvasFormat)==null?void 0:n.call(c))||"bgra8unorm",o.configure({device:t,format:a}),r=o}return{adapter:i,device:t,initialized:!0,canvas:e.canvas,canvasContext:r,preferredFormat:a}}catch(i){if(t)try{t.destroy()}catch(r){console.warn("Error destroying device during initialization failure:",r)}throw i instanceof Error?i:new Error(`Failed to initialize GPUContext: ${String(i)}`)}}function l(e){if(!e.canvas)throw new Error("Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.canvasContext)throw new Error("GPUContext is not initialized. Call initializeGPUContext() first.");return e.canvasContext.getCurrentTexture()}function p(e,t,n,i,r){if(t<0||t>1||n<0||n>1||i<0||i>1||r<0||r>1)throw new Error("Color components must be in the range [0.0, 1.0]");if(!e.canvas)throw new Error("Canvas is not configured. Provide a canvas element when creating the context.");if(!e.initialized||!e.device||!e.canvasContext)throw new Error("GPUContext is not initialized. Call initializeGPUContext() first.");const a=l(e),o=e.device.createCommandEncoder();o.beginRenderPass({colorAttachments:[{view:a.createView(),clearValue:{r:t,g:n,b:i,a:r},loadOp:"clear",storeOp:"store"}]}).end(),e.device.queue.submit([o.finish()])}function w(e){if(e.device)try{e.device.destroy()}catch(t){console.warn("Error destroying GPU device:",t)}return{adapter:null,device:null,initialized:!1,canvas:e.canvas,canvasContext:null,preferredFormat:null}}class d{get adapter(){return this._state.adapter}get device(){return this._state.device}get initialized(){return this._state.initialized}get canvas(){return this._state.canvas}get canvasContext(){return this._state.canvasContext}get preferredFormat(){return this._state.preferredFormat}constructor(t){this._state=v(t)}async initialize(){this._state=await g(this._state)}static async create(t){const n=new d(t);return await n.initialize(),n}getCanvasTexture(){return l(this._state)}clearScreen(t,n,i,r){p(this._state,t,n,i,r)}destroy(){this._state=w(this._state)}}export{d as G,v as c,l as g,g as i};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./GPUContext-CgqhC6W6.js";import{c as w}from"./createDataZoomSlider-DLbAKjVh.js";import{C as x}from"./ChartGPU-zgkjfPqp.js";import"./scales-D-5MHN10.js";import"./pie-c06rKDKR.js";const u=(e,t)=>{const s=Math.max(2,Math.floor(e)),d=new Array(s),l=(t==null?void 0:t.phase)??0,o=(t==null?void 0:t.amplitude)??1;for(let a=0;a<s;a++){const i=a/(s-1)*Math.PI*2,r=Math.sin(i+l)*o;d[a]=[i,r]}return d},y=e=>{const t=document.getElementById("error");t&&(t.textContent=e,t.style.display="block")};async function v(){const e=document.getElementById("chart");if(!e)throw new Error("Chart container not found");const t=u(300,{phase:0,amplitude:1}),s=u(300,{phase:Math.PI/3,amplitude:1}),d=u(300,{phase:2*Math.PI/3,amplitude:1}),l=Math.PI*2,o={grid:{left:70,right:24,top:24,bottom:56},xAxis:{type:"value",min:0,max:l,name:"Angle (rad)"},yAxis:{type:"value",min:-1.1,max:1.1,name:"Amplitude"},palette:["#4a9eff","#ff4ab0","#40d17c"],animation:{duration:900,easing:"cubicOut",delay:0},series:[{type:"line",name:"sin(x) (filled)",data:t,color:"#4a9eff",areaStyle:{opacity:.2},lineStyle:{width:2,opacity:1}},{type:"line",name:"sin(x + π/3)",data:s,lineStyle:{width:2,opacity:1}},{type:"line",name:"sin(x + 2π/3)",data:d,lineStyle:{width:2,opacity:1}}]},a=await x.create(e,o);a.on("click",n=>console.log("[click]",n)),a.on("mouseover",n=>console.log("[mouseover]",n)),a.on("mouseout",n=>console.log("[mouseout]",n));const c=e.querySelector("canvas");if(!(c instanceof HTMLCanvasElement))throw new Error("Chart canvas not found");const i=()=>{var n,f,g,p;return{left:((n=o.grid)==null?void 0:n.left)??0,right:((f=o.grid)==null?void 0:f.right)??0,top:((g=o.grid)==null?void 0:g.top)??0,bottom:((p=o.grid)==null?void 0:p.bottom)??0,canvasWidth:c.width,canvasHeight:c.height}},r=w(c,i());r.on("mousemove",n=>{console.log(n.gridX,n.gridY,n.isInGrid)});let m=!1;const h=new ResizeObserver(()=>{m||(m=!0,requestAnimationFrame(()=>{m=!1,a.resize(),r.updateGridArea(i())}))});h.observe(e),a.resize(),r.updateGridArea(i()),window.addEventListener("beforeunload",()=>{h.disconnect(),r.dispose(),a.dispose()})}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{v().catch(e=>{console.error(e),y(e instanceof Error?e.message:String(e))})}):v().catch(e=>{console.error(e),y(e instanceof Error?e.message:String(e))});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./GPUContext-CgqhC6W6.js";import{C as m}from"./ChartGPU-zgkjfPqp.js";import{c as b}from"./createChartSync-BUGadH_x.js";import"./createDataZoomSlider-DLbAKjVh.js";import"./scales-D-5MHN10.js";import"./pie-c06rKDKR.js";const l=(t,e)=>{const o=Math.max(2,Math.floor(t)),a=new Array(o);for(let n=0;n<o;n++){const r=n/(o-1)*Math.PI*2,i=e.fn==="sin"?Math.sin(r+e.phase):Math.cos(r+e.phase);a[n]=[r,i*e.amplitude]}return a},h=t=>{const e=document.getElementById("error");e&&(e.textContent=t,e.style.display="block")},u=(t,e,o)=>{const a=Math.PI*2;return{grid:{left:70,right:24,top:24,bottom:56},xAxis:{type:"value",min:0,max:a,name:"Angle (rad)"},yAxis:{type:"value",min:-1.2,max:1.2,name:t},palette:[o],tooltip:{trigger:"axis"},animation:{duration:900,easing:"cubicOut",delay:0},series:[{type:"line",name:t,data:e,color:o,lineStyle:{width:2,opacity:1}}]}};async function f(){const t=document.getElementById("chart-a"),e=document.getElementById("chart-b");if(!t||!e)throw new Error("Chart containers not found");const o=l(400,{fn:"sin",phase:0,amplitude:1}),a=l(400,{fn:"cos",phase:Math.PI/6,amplitude:.9}),n=await m.create(t,u("sin(x)",o,"#4a9eff")),s=await m.create(e,u("cos(x + π/6)",a,"#ff4ab0")),r=b([n,s]),i=(g,x)=>{let c=!1;const d=new ResizeObserver(()=>{c||(c=!0,requestAnimationFrame(()=>{c=!1,x.resize()}))});return d.observe(g),d},p=i(t,n),y=i(e,s);n.resize(),s.resize(),window.addEventListener("beforeunload",()=>{p.disconnect(),y.disconnect(),r(),n.dispose(),s.dispose()})}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{f().catch(t=>{console.error(t),h(t instanceof Error?t.message:String(t))})}):f().catch(t=>{console.error(t),h(t instanceof Error?t.message:String(t))});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function u(t){const r=Symbol("ChartGPU.connectCharts");let e=!1;const c=[],f=(o,s)=>{for(const n of t)n!==o&&(n.disposed||n.setCrosshairX(s,r))};for(const o of t){if(o.disposed)continue;const s=i=>{e||i.source!==r&&(o.disposed||f(o,i.x))};o.on("crosshairMove",s);const n=()=>o.off("crosshairMove",s);c.push(n)}return()=>{if(!e){e=!0;for(const o of c)o();c.length=0;for(const o of t)o.disposed||o.setCrosshairX(null,r)}}}export{u as c};
|