Skip to content

Commit 1b21c5a

Browse files
committed
Add context7.json configuration file and update package dependencies
- Introduced a new context7.json file to define project metadata and rules for the chartgpu-react library. - Updated package-lock.json to reflect the new version of chartgpu as a dependency. - Modified package.json to align peer dependencies with the updated chartgpu version. - Enhanced README and documentation files to guide users on the new features and usage patterns.
1 parent fed8baf commit 1b21c5a

26 files changed

+2489
-680
lines changed

README.md

Lines changed: 108 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
React bindings for [ChartGPU](https://github.com/huntergemmer/chart-gpu) - a WebGPU-powered charting library delivering high-performance data visualization.
44

5-
## Features
5+
## Documentation
66

7-
- **WebGPU-Accelerated**: Leverages GPU compute and rendering for exceptional performance
8-
- **React 18+**: Built with modern React patterns (hooks, functional components)
9-
- **Type-Safe**: Full TypeScript support with comprehensive type definitions
10-
- **Production-Ready**: Handles async initialization, cleanup, and edge cases safely
11-
- **Flexible API**: Declarative options-based configuration
7+
- **Getting started**: [`docs/GETTING_STARTED.md`](./docs/GETTING_STARTED.md)
8+
- **API reference**: [`docs/API.md`](./docs/API.md)
9+
- **Recipes**:
10+
- [`onCrosshairMove`](./docs/recipes/crosshair-move.md)
11+
- [`useConnectCharts` / `connectCharts`](./docs/recipes/chart-sync.md)
12+
- [`createAnnotationAuthoring`](./docs/recipes/annotation-authoring.md)
13+
- [`appendData` streaming](./docs/recipes/streaming.md)
14+
- [`dataZoom` + `onZoomChange`](./docs/recipes/datazoom-basics.md)
1215

1316
## Installation
1417

@@ -29,10 +32,11 @@ Check browser compatibility at [caniuse.com/webgpu](https://caniuse.com/webgpu)
2932
## Quick Start
3033

3134
```tsx
32-
import { ChartGPUChart } from 'chartgpu-react';
35+
import { ChartGPU } from 'chartgpu-react';
36+
import type { ChartGPUOptions } from 'chartgpu-react';
3337

3438
function MyChart() {
35-
const options = {
39+
const options: ChartGPUOptions = {
3640
series: [
3741
{
3842
type: 'line',
@@ -53,133 +57,138 @@ function MyChart() {
5357
};
5458

5559
return (
56-
<ChartGPUChart
60+
<ChartGPU
5761
options={options}
5862
style={{ width: '100%', height: '400px' }}
5963
/>
6064
);
6165
}
6266
```
6367

64-
## Component API
68+
## What this package provides
6569

66-
### `ChartGPUChart`
70+
- **`ChartGPU`** React component (recommended)
71+
- lifecycle management (async create + dispose)
72+
- `ResizeObserver` resize (debounced)
73+
- event props: `onClick`, `onCrosshairMove`, `onZoomChange`, etc.
74+
- imperative `ref` API: `ChartGPUHandle` (`getChart`, `getContainer`, `appendData`, `setOption`)
75+
- **Hooks**
76+
- `useChartGPU(containerRef, options)` — create/manage a chart instance
77+
- `useConnectCharts([chartA, chartB, ...])` — sync crosshair/interaction-x across charts
78+
- **Deprecated**
79+
- `ChartGPUChart` (legacy adapter; use `ChartGPU` instead)
80+
- **Helper re-exports** (from peer dependency `chartgpu`)
81+
- `createChart`, `connectCharts`, `createAnnotationAuthoring`
6782

68-
Main React component wrapping ChartGPU functionality.
83+
For details, start with the [API reference](./docs/API.md).
6984

70-
#### Props
85+
## v0.2.3 feature snippets (ChartGPU core)
7186

72-
| Prop | Type | Required | Description |
73-
|------|------|----------|-------------|
74-
| `options` | `ChartGPUOptions` | Yes | Chart configuration (series, axes, styling) |
75-
| `className` | `string` | No | CSS class name for the container div |
76-
| `style` | `React.CSSProperties` | No | Inline styles for the container div |
77-
| `onInit` | `(instance: ChartGPUInstance) => void` | No | Callback fired when chart instance is created |
78-
| `onDispose` | `() => void` | No | Callback fired when chart instance is disposed |
87+
These snippets use helpers and events from the `chartgpu` core library (peer dependency of `chartgpu-react`).
7988

80-
#### Behavior
89+
### Crosshair / interaction X (`'crosshairMove'`)
8190

82-
**Lifecycle Management:**
83-
- Creates ChartGPU instance on mount via `ChartGPU.create()`
84-
- Safely handles async initialization race conditions
85-
- Automatically disposes instance on unmount
86-
- Prevents state updates after component unmount
91+
```tsx
92+
import { ChartGPU } from 'chartgpu-react';
93+
import type { ChartGPUCrosshairMovePayload } from 'chartgpu-react';
94+
95+
<ChartGPU
96+
options={options}
97+
onCrosshairMove={(p: ChartGPUCrosshairMovePayload) => {
98+
// p.x is the current interaction x (domain units), or null when cleared
99+
console.log('crosshair x:', p.x, 'source:', p.source);
100+
}}
101+
/>;
102+
```
87103

88-
**Options Updates:**
89-
- Calls `instance.setOption(options)` when `options` prop changes
90-
- Triggers automatic re-render of the chart
104+
### Connect charts (sync crosshair/tooltip)
91105

92-
**Resize Handling:**
93-
- Listens to window resize events
94-
- Calls `instance.resize()` automatically
95-
- Ensures chart maintains correct dimensions
106+
```tsx
107+
import { connectCharts } from 'chartgpu';
96108

97-
## Examples
109+
// When you have two ChartGPUInstance objects:
110+
const disconnect = connectCharts([chartA, chartB]);
111+
112+
// Later:
113+
disconnect();
114+
```
115+
116+
If you prefer a hook-driven approach, you can use `onReady` (or `useChartGPU`) to capture instances, then call `connectCharts(...)` once both are available.
98117

99-
### Multi-Series Line Chart
118+
### Annotation authoring UI (`createAnnotationAuthoring`)
100119

101120
```tsx
102-
import { ChartGPUChart } from 'chartgpu-react';
121+
import { useEffect, useRef, useState } from 'react';
122+
import { ChartGPU } from 'chartgpu-react';
123+
import type { ChartGPUHandle, ChartGPUInstance } from 'chartgpu-react';
124+
import { createAnnotationAuthoring } from 'chartgpu-react';
125+
126+
function AnnotationAuthoringExample() {
127+
const chartRef = useRef<ChartGPUHandle>(null);
128+
const [chart, setChart] = useState<ChartGPUInstance | null>(null);
129+
130+
useEffect(() => {
131+
const container = chartRef.current?.getContainer();
132+
const instance = chartRef.current?.getChart();
133+
if (!container || !instance) return;
134+
135+
const authoring = createAnnotationAuthoring(container, instance, {
136+
enableContextMenu: true,
137+
});
103138

104-
function MultiSeriesExample() {
105-
const options = {
106-
series: [
107-
{
108-
type: 'line',
109-
name: 'Revenue',
110-
data: generateData(50),
111-
lineStyle: { color: '#667eea', width: 2 },
112-
},
113-
{
114-
type: 'line',
115-
name: 'Expenses',
116-
data: generateData(50),
117-
lineStyle: { color: '#f093fb', width: 2 },
118-
},
119-
],
120-
xAxis: { type: 'value' },
121-
yAxis: { type: 'value' },
122-
grid: { left: 60, right: 40, top: 40, bottom: 40 },
123-
tooltip: { show: true },
124-
};
139+
// IMPORTANT: dispose authoring before disposing the chart
140+
return () => authoring.dispose();
141+
}, [chart]);
125142

126-
return (
127-
<ChartGPUChart
128-
options={options}
129-
style={{ width: '100%', height: '400px' }}
130-
/>
131-
);
143+
return <ChartGPU ref={chartRef} options={options} onReady={setChart} />;
132144
}
133145
```
134146

135-
### Area Chart with Gradient
147+
### Candlestick streaming (`appendData` + `OHLCDataPoint`)
136148

137149
```tsx
138-
function AreaChartExample() {
139-
const options = {
150+
import { useEffect, useRef } from 'react';
151+
import { ChartGPU } from 'chartgpu-react';
152+
import type { ChartGPUHandle, ChartGPUOptions } from 'chartgpu-react';
153+
import type { OHLCDataPoint } from 'chartgpu';
154+
155+
function CandlestickStreaming() {
156+
const ref = useRef<ChartGPUHandle>(null);
157+
158+
const options: ChartGPUOptions = {
159+
xAxis: { type: 'time' },
160+
dataZoom: [{ type: 'inside' }, { type: 'slider' }],
161+
autoScroll: true,
140162
series: [
141163
{
142-
type: 'line',
143-
data: generateSineWave(100),
144-
lineStyle: { color: '#667eea', width: 2 },
145-
areaStyle: { color: 'rgba(102, 126, 234, 0.2)' },
164+
type: 'candlestick',
165+
sampling: 'ohlc',
166+
data: [], // start empty; stream in candles below
146167
},
147168
],
148-
xAxis: { type: 'value' },
149-
yAxis: { type: 'value' },
150169
};
151170

152-
return <ChartGPUChart options={options} style={{ height: '300px' }} />;
171+
useEffect(() => {
172+
const timer = window.setInterval(() => {
173+
const next: OHLCDataPoint = {
174+
timestamp: Date.now(),
175+
open: 100,
176+
close: 102,
177+
low: 99,
178+
high: 103,
179+
};
180+
ref.current?.appendData(0, [next]);
181+
}, 500);
182+
return () => window.clearInterval(timer);
183+
}, []);
184+
185+
return <ChartGPU ref={ref} options={options} style={{ height: 360 }} />;
153186
}
154187
```
155188

156-
### Using Chart Instance Callbacks
157-
158-
```tsx
159-
function ChartWithCallbacks() {
160-
const handleInit = (instance: ChartGPUInstance) => {
161-
console.log('Chart initialized:', instance);
162-
163-
// Add event listeners
164-
instance.on('click', (payload) => {
165-
console.log('Chart clicked:', payload);
166-
});
167-
};
168-
169-
const handleDispose = () => {
170-
console.log('Chart cleaned up');
171-
};
189+
## Examples
172190

173-
return (
174-
<ChartGPUChart
175-
options={options}
176-
onInit={handleInit}
177-
onDispose={handleDispose}
178-
style={{ height: '400px' }}
179-
/>
180-
);
181-
}
182-
```
191+
See the runnable example app in [`examples/main.tsx`](./examples/main.tsx).
183192

184193
## Development
185194

@@ -246,54 +255,6 @@ import type {
246255
} from 'chartgpu-react';
247256
```
248257

249-
## Technical Details
250-
251-
### Async Initialization Safety
252-
253-
The component uses a mounted ref pattern to prevent React state updates after unmount:
254-
255-
```typescript
256-
useEffect(() => {
257-
mountedRef.current = true;
258-
259-
const initChart = async () => {
260-
const instance = await ChartGPU.create(container, options);
261-
262-
// Only update state if still mounted
263-
if (mountedRef.current) {
264-
instanceRef.current = instance;
265-
} else {
266-
// Dispose immediately if unmounted during async create
267-
instance.dispose();
268-
}
269-
};
270-
271-
initChart();
272-
273-
return () => {
274-
mountedRef.current = false;
275-
instanceRef.current?.dispose();
276-
};
277-
}, []);
278-
```
279-
280-
This pattern ensures:
281-
1. No memory leaks from orphaned chart instances
282-
2. No React warnings about setState on unmounted components
283-
3. Clean resource cleanup even if creation takes time
284-
285-
### Options Updates
286-
287-
Options changes trigger `setOption()` on the existing instance rather than recreating the chart:
288-
289-
```typescript
290-
useEffect(() => {
291-
instanceRef.current?.setOption(options);
292-
}, [options]);
293-
```
294-
295-
This provides better performance for dynamic data updates.
296-
297258
## Browser Compatibility
298259

299260
WebGPU is required. Check support at runtime:

context7.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$schema": "https://context7.com/schema/context7.json",
3+
"projectTitle": "chartgpu-react",
4+
"description": "React bindings for ChartGPU — a WebGPU-powered charting library.",
5+
"folders": ["docs", "examples"],
6+
"excludeFolders": ["node_modules", "dist", "coverage", ".git", ".github", ".cursor"],
7+
"excludeFiles": ["IMPLEMENTATION_REPORT.md", "package-lock.json"],
8+
"rules": [
9+
"Prefer the `ChartGPU` component; `ChartGPUChart` is deprecated and will be removed in a future major version.",
10+
"`options` is treated as a full replacement object; `setOption()` does not partial-merge.",
11+
"For streaming/real-time updates, prefer `ChartGPUHandle.appendData()` over replacing `options.series[].data`.",
12+
"If you use `createAnnotationAuthoring(container, chart, ...)`, dispose the authoring instance before disposing the chart.",
13+
"Ensure the chart container has an explicit, non-zero height; otherwise the chart may render blank.",
14+
"In React 18 StrictMode (dev), effects run twice (mount→unmount→mount); avoid retaining stale chart instances outside refs/onReady."
15+
]
16+
}

0 commit comments

Comments
 (0)