Skip to content

Commit e536c3f

Browse files
authored
Merge pull request #14 from ChartGPU/chore/update-documentation
Add useGPUContext docs and multi-chart dashboard examples
2 parents 7037a30 + a2dd13b commit e536c3f

File tree

5 files changed

+454
-3
lines changed

5 files changed

+454
-3
lines changed

docs/API.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This package is a **React wrapper** around the `@chartgpu/chartgpu` core library
44

55
- A React component (`ChartGPU`) with lifecycle + resize management
66
- A small imperative ref API (`ChartGPUHandle`)
7-
- Two hooks (`useChartGPU`, `useConnectCharts`)
7+
- Three hooks (`useChartGPU`, `useGPUContext`, `useConnectCharts`)
88
- Convenience re-exports of a few core helpers + types
99

1010
For an LLM-oriented navigation entrypoint, see [`docs/api/llm-context.md`](./api/llm-context.md).
@@ -19,6 +19,7 @@ For an LLM-oriented navigation entrypoint, see [`docs/api/llm-context.md`](./api
1919
### Hooks
2020

2121
- **`useChartGPU(containerRef, options, gpuContext?)`** — create/manage an instance imperatively (3rd param optional shared context; init-only)
22+
- **`useGPUContext()`** — create a shared `GPUAdapter` + `GPUDevice` + `PipelineCache` for multi-chart dashboards; see [`docs/api/hooks.md#usegpucontext`](./api/hooks.md#usegpucontext)
2223
- **`useConnectCharts([chartA, chartB, ...], syncOptions?)`** — keep crosshair/interaction-x in sync (optionally sync zoom)
2324

2425
See [`docs/api/hooks.md`](./api/hooks.md).

docs/api/hooks.md

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Hooks
22

3-
This package provides two hooks:
3+
This package provides three hooks:
44

55
- `useChartGPU(containerRef, options, gpuContext?)` — create/manage a `ChartGPUInstance` (3rd param optional shared context; init-only)
6+
- `useGPUContext()` — create a shared `GPUAdapter` + `GPUDevice` + `PipelineCache` for multi-chart dashboards
67
- `useConnectCharts(charts, syncOptions?)` — connect instances for synced crosshair/interaction-x (and optionally zoom)
78

89
Related:
@@ -84,6 +85,100 @@ export function HookChart() {
8485
}
8586
```
8687

88+
## `useGPUContext()`
89+
90+
Creates a shared `GPUAdapter`, `GPUDevice`, and `PipelineCache` for multi-chart dashboards. Call this once in a parent component and pass the result to each `<ChartGPU gpuContext={...} />` (or to `useChartGPU`'s third argument). This avoids each chart requesting its own GPU device and compiling duplicate shader pipelines.
91+
92+
### Import
93+
94+
```ts
95+
import { useGPUContext } from 'chartgpu-react';
96+
import type { UseGPUContextResult } from 'chartgpu-react';
97+
```
98+
99+
### Signature
100+
101+
```ts
102+
function useGPUContext(): {
103+
adapter: GPUAdapter | null;
104+
device: GPUDevice | null;
105+
pipelineCache: PipelineCache | null;
106+
isReady: boolean;
107+
error: Error | null;
108+
}
109+
```
110+
111+
### Behavior
112+
113+
- On mount, requests a `GPUAdapter` (high-performance preference) and `GPUDevice`, then creates a `PipelineCache`.
114+
- All fields are `null` until initialization completes. `isReady` becomes `true` once both `adapter` and `device` are available.
115+
- If WebGPU is not supported or adapter/device acquisition fails, `error` is set and other fields remain `null`.
116+
- Safe in React 18 StrictMode dev (uses a ref guard to prevent double-initialization).
117+
- Initialization runs once on mount and cannot be re-triggered.
118+
119+
### Usage with `<ChartGPU>`
120+
121+
The `gpuContext` prop on `<ChartGPU>` accepts `{ adapter, device, pipelineCache }` which maps to the `ChartGPUCreateContext` type. This prop is **init-only** -- it is captured in a `useRef` at mount and only read during `ChartGPU.create(...)`. Changing it after mount has no effect.
122+
123+
### Example
124+
125+
```tsx
126+
import { useMemo, useState } from 'react';
127+
import { ChartGPU, useGPUContext } from 'chartgpu-react';
128+
import type { ChartGPUInstance, ChartGPUOptions } from 'chartgpu-react';
129+
130+
export function Dashboard() {
131+
const { adapter, device, pipelineCache, isReady, error } = useGPUContext();
132+
133+
const [chartA, setChartA] = useState<ChartGPUInstance | null>(null);
134+
const [chartB, setChartB] = useState<ChartGPUInstance | null>(null);
135+
136+
const optionsA: ChartGPUOptions = useMemo(
137+
() => ({
138+
series: [{ type: 'line', data: [{ x: 0, y: 1 }, { x: 1, y: 3 }] }],
139+
xAxis: { type: 'value' },
140+
yAxis: { type: 'value' },
141+
}),
142+
[]
143+
);
144+
145+
const optionsB: ChartGPUOptions = useMemo(
146+
() => ({
147+
series: [{ type: 'bar', data: [{ x: 0, y: 5 }, { x: 1, y: 2 }] }],
148+
xAxis: { type: 'value' },
149+
yAxis: { type: 'value' },
150+
}),
151+
[]
152+
);
153+
154+
if (error) return <div>WebGPU not supported: {error.message}</div>;
155+
if (!isReady) return <div>Initializing GPU...</div>;
156+
157+
// After the isReady check, adapter/device/pipelineCache are non-null.
158+
const gpuContext = { adapter: adapter!, device: device!, pipelineCache: pipelineCache! };
159+
160+
return (
161+
<>
162+
<ChartGPU
163+
options={optionsA}
164+
gpuContext={gpuContext}
165+
onReady={setChartA}
166+
style={{ height: 300 }}
167+
theme="dark"
168+
/>
169+
<div style={{ height: 12 }} />
170+
<ChartGPU
171+
options={optionsB}
172+
gpuContext={gpuContext}
173+
onReady={setChartB}
174+
style={{ height: 300 }}
175+
theme="dark"
176+
/>
177+
</>
178+
);
179+
}
180+
```
181+
87182
## `useConnectCharts(charts, syncOptions?)`
88183

89184
Connects multiple `ChartGPUInstance`s so they share interaction state (crosshair/tooltip x). Optionally syncs zoom/pan across charts.

docs/api/llm-context.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ The goal of this `llm-context.md` file is to give Context7 (and other LLM toolin
4848
- `docs/api/chartgpu-handle.md`
4949
- Source: `src/types.ts`, `src/ChartGPU.tsx`
5050
- **Multi-chart dashboards (shared GPU device + pipeline cache)**
51+
- [`docs/api/hooks.md#usegpucontext`](./hooks.md#usegpucontext)
5152
- Source: `src/useGPUContext.ts`, `src/types.ts`, `src/ChartGPU.tsx`, `src/useChartGPU.ts`
5253
- **Hooks (`useChartGPU`, `useConnectCharts`)**
5354
- `docs/api/hooks.md`

docs/recipes/chart-sync.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,83 @@ type ChartSyncOptions = Readonly<{
131131
- **`syncCrosshair`** (default `true`): sync crosshair + tooltip x across charts.
132132
- **`syncZoom`** (default `false`): sync zoom/pan range across charts.
133133

134+
## Complete dashboard: shared GPU + synced interaction
135+
136+
For multi-chart dashboards, combine `useGPUContext` (shared GPU resources) with `useConnectCharts` (synced interaction). This avoids duplicate GPU device allocation and keeps crosshair/zoom in sync across all charts.
137+
138+
See also: [`useGPUContext` hook docs](../api/hooks.md#usegpucontext)
139+
140+
```tsx
141+
import { useMemo, useState } from 'react';
142+
import { ChartGPU, useGPUContext, useConnectCharts } from 'chartgpu-react';
143+
import type { ChartGPUInstance, ChartGPUOptions } from 'chartgpu-react';
144+
145+
export function SyncedDashboard() {
146+
const { adapter, device, pipelineCache, isReady, error } = useGPUContext();
147+
148+
const [chartA, setChartA] = useState<ChartGPUInstance | null>(null);
149+
const [chartB, setChartB] = useState<ChartGPUInstance | null>(null);
150+
const [chartC, setChartC] = useState<ChartGPUInstance | null>(null);
151+
152+
// Sync crosshair and zoom across all three charts
153+
useConnectCharts([chartA, chartB, chartC], { syncZoom: true });
154+
155+
const optionsA: ChartGPUOptions = useMemo(
156+
() => ({
157+
series: [{ type: 'line', data: [{ x: 0, y: 1 }, { x: 1, y: 3 }] }],
158+
xAxis: { type: 'value' },
159+
yAxis: { type: 'value' },
160+
tooltip: { show: true, trigger: 'axis' },
161+
dataZoom: { enabled: true },
162+
}),
163+
[]
164+
);
165+
166+
const optionsB: ChartGPUOptions = useMemo(
167+
() => ({
168+
series: [{ type: 'bar', data: [{ x: 0, y: 5 }, { x: 1, y: 2 }] }],
169+
xAxis: { type: 'value' },
170+
yAxis: { type: 'value' },
171+
tooltip: { show: true, trigger: 'axis' },
172+
dataZoom: { enabled: true },
173+
}),
174+
[]
175+
);
176+
177+
const optionsC: ChartGPUOptions = useMemo(
178+
() => ({
179+
series: [{ type: 'line', data: [{ x: 0, y: 4 }, { x: 1, y: 1 }] }],
180+
xAxis: { type: 'value' },
181+
yAxis: { type: 'value' },
182+
tooltip: { show: true, trigger: 'axis' },
183+
dataZoom: { enabled: true },
184+
}),
185+
[]
186+
);
187+
188+
if (error) return <div>WebGPU not supported: {error.message}</div>;
189+
if (!isReady) return <div>Initializing GPU...</div>;
190+
191+
const gpuContext = { adapter: adapter!, device: device!, pipelineCache: pipelineCache! };
192+
193+
return (
194+
<>
195+
<ChartGPU options={optionsA} gpuContext={gpuContext} onReady={setChartA} style={{ height: 200 }} theme="dark" />
196+
<div style={{ height: 8 }} />
197+
<ChartGPU options={optionsB} gpuContext={gpuContext} onReady={setChartB} style={{ height: 200 }} theme="dark" />
198+
<div style={{ height: 8 }} />
199+
<ChartGPU options={optionsC} gpuContext={gpuContext} onReady={setChartC} style={{ height: 200 }} theme="dark" />
200+
</>
201+
);
202+
}
203+
```
204+
205+
Key points:
206+
207+
- `useGPUContext()` runs once in the parent and shares a single `GPUDevice` + `PipelineCache` across all charts, reducing shader compilation overhead.
208+
- `useConnectCharts` keeps crosshair and zoom in sync. It only activates once all chart instances are ready.
209+
- The `gpuContext` prop is **init-only** on each `<ChartGPU>` -- it is read once during chart creation and cannot be changed after mount.
210+
134211
## Notes
135212

136213
- Always disconnect on cleanup to avoid leaking listeners.

0 commit comments

Comments
 (0)