@chartml/react 1.0.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/LICENSE +21 -0
- package/README.md +437 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Alytic Pty Ltd
|
|
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
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
# @chartml/react
|
|
2
|
+
|
|
3
|
+
React wrapper component for ChartML - render beautiful data visualizations in React with ease.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **React Component** - Clean, idiomatic React API
|
|
8
|
+
- ✅ **useChartML Hook** - Manage ChartML instances with React hooks
|
|
9
|
+
- ✅ **Auto-Cleanup** - Automatic cleanup on unmount
|
|
10
|
+
- ✅ **Plugin Support** - Register custom chart renderers and data sources
|
|
11
|
+
- ✅ **Event Callbacks** - Progress, cache hit/miss, and error events
|
|
12
|
+
- ✅ **TypeScript Ready** - Includes TypeScript definitions
|
|
13
|
+
- ✅ **All Chart Types** - Includes pie, scatter, and metric chart plugins
|
|
14
|
+
- ✅ **Zero Config** - Works out of the box with sensible defaults
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @chartml/react
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Peer Dependencies:**
|
|
23
|
+
- `react` ^18.0.0
|
|
24
|
+
- `react-dom` ^18.0.0
|
|
25
|
+
|
|
26
|
+
The core ChartML library is included automatically.
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
### Basic Usage
|
|
31
|
+
|
|
32
|
+
```jsx
|
|
33
|
+
import { ChartMLChart } from '@chartml/react';
|
|
34
|
+
|
|
35
|
+
function SalesChart() {
|
|
36
|
+
const spec = `
|
|
37
|
+
type: chart
|
|
38
|
+
version: 1
|
|
39
|
+
|
|
40
|
+
data:
|
|
41
|
+
- month: "Jan"
|
|
42
|
+
revenue: 45000
|
|
43
|
+
- month: "Feb"
|
|
44
|
+
revenue: 52000
|
|
45
|
+
- month: "Mar"
|
|
46
|
+
revenue: 48000
|
|
47
|
+
|
|
48
|
+
visualize:
|
|
49
|
+
type: bar
|
|
50
|
+
columns: month
|
|
51
|
+
rows: revenue
|
|
52
|
+
style:
|
|
53
|
+
title: "Monthly Revenue"
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
return <ChartMLChart spec={spec} />;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### With Styling
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
<ChartMLChart
|
|
64
|
+
spec={spec}
|
|
65
|
+
className="my-chart"
|
|
66
|
+
style={{ maxWidth: '800px', margin: '0 auto' }}
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### With Event Callbacks
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
import { ChartMLChart } from '@chartml/react';
|
|
74
|
+
import { useState } from 'react';
|
|
75
|
+
|
|
76
|
+
function ChartWithStatus() {
|
|
77
|
+
const [status, setStatus] = useState('idle');
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<div>
|
|
81
|
+
<p>Status: {status}</p>
|
|
82
|
+
<ChartMLChart
|
|
83
|
+
spec={spec}
|
|
84
|
+
options={{
|
|
85
|
+
onProgress: (e) => setStatus(`Loading: ${e.percent}%`),
|
|
86
|
+
onCacheHit: () => setStatus('Loaded from cache'),
|
|
87
|
+
onCacheMiss: () => setStatus('Fetching data'),
|
|
88
|
+
onError: (err) => setStatus(`Error: ${err.message}`)
|
|
89
|
+
}}
|
|
90
|
+
/>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Advanced Usage
|
|
97
|
+
|
|
98
|
+
### Using the useChartML Hook
|
|
99
|
+
|
|
100
|
+
For more control, use the `useChartML` hook to manage your own ChartML instance:
|
|
101
|
+
|
|
102
|
+
```jsx
|
|
103
|
+
import { ChartMLChart, useChartML } from '@chartml/react';
|
|
104
|
+
import { useEffect } from 'react';
|
|
105
|
+
|
|
106
|
+
function CustomChart() {
|
|
107
|
+
const chartml = useChartML({
|
|
108
|
+
onProgress: (e) => console.log(`Progress: ${e.percent}%`),
|
|
109
|
+
palettes: {
|
|
110
|
+
custom: ['#ff0000', '#00ff00', '#0000ff']
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Register custom renderers if needed
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
// Custom plugins would be registered here
|
|
117
|
+
// chartml.registerChartRenderer('custom', myRenderer);
|
|
118
|
+
}, [chartml]);
|
|
119
|
+
|
|
120
|
+
return <ChartMLChart spec={spec} chartml={chartml} />;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Dynamic Specs with State
|
|
125
|
+
|
|
126
|
+
```jsx
|
|
127
|
+
import { ChartMLChart } from '@chartml/react';
|
|
128
|
+
import { useState } from 'react';
|
|
129
|
+
|
|
130
|
+
function DynamicChart() {
|
|
131
|
+
const [chartType, setChartType] = useState('bar');
|
|
132
|
+
|
|
133
|
+
const spec = `
|
|
134
|
+
type: chart
|
|
135
|
+
version: 1
|
|
136
|
+
|
|
137
|
+
data:
|
|
138
|
+
- month: "Jan"
|
|
139
|
+
revenue: 45000
|
|
140
|
+
- month: "Feb"
|
|
141
|
+
revenue: 52000
|
|
142
|
+
|
|
143
|
+
visualize:
|
|
144
|
+
type: ${chartType}
|
|
145
|
+
columns: month
|
|
146
|
+
rows: revenue
|
|
147
|
+
`;
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<div>
|
|
151
|
+
<button onClick={() => setChartType('bar')}>Bar</button>
|
|
152
|
+
<button onClick={() => setChartType('line')}>Line</button>
|
|
153
|
+
<button onClick={() => setChartType('area')}>Area</button>
|
|
154
|
+
<ChartMLChart spec={spec} />
|
|
155
|
+
</div>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Fetching Data from API
|
|
161
|
+
|
|
162
|
+
```jsx
|
|
163
|
+
import { ChartMLChart } from '@chartml/react';
|
|
164
|
+
import { useState, useEffect } from 'react';
|
|
165
|
+
|
|
166
|
+
function APIChart() {
|
|
167
|
+
const [chartData, setChartData] = useState(null);
|
|
168
|
+
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
fetch('/api/sales-data')
|
|
171
|
+
.then(res => res.json())
|
|
172
|
+
.then(data => {
|
|
173
|
+
const spec = {
|
|
174
|
+
type: 'chart',
|
|
175
|
+
version: 1,
|
|
176
|
+
data: data,
|
|
177
|
+
visualize: {
|
|
178
|
+
type: 'bar',
|
|
179
|
+
columns: 'month',
|
|
180
|
+
rows: 'revenue'
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
setChartData(spec);
|
|
184
|
+
});
|
|
185
|
+
}, []);
|
|
186
|
+
|
|
187
|
+
if (!chartData) return <div>Loading...</div>;
|
|
188
|
+
|
|
189
|
+
return <ChartMLChart spec={chartData} />;
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## All Chart Types Available
|
|
194
|
+
|
|
195
|
+
This package includes all ChartML chart plugins by default:
|
|
196
|
+
|
|
197
|
+
### Built-in Chart Types
|
|
198
|
+
- `bar` - Vertical and horizontal bar charts
|
|
199
|
+
- `line` - Single and multi-series line charts
|
|
200
|
+
- `area` - Stacked and normalized area charts
|
|
201
|
+
|
|
202
|
+
### Included Plugins
|
|
203
|
+
- `pie` - Pie charts (from @chartml/chart-pie)
|
|
204
|
+
- `doughnut` - Doughnut charts (from @chartml/chart-pie)
|
|
205
|
+
- `scatter` - Scatter plots and bubble charts (from @chartml/chart-scatter)
|
|
206
|
+
- `metric` - Metric cards for KPIs (from @chartml/chart-metric)
|
|
207
|
+
|
|
208
|
+
All types work out of the box - no additional imports needed!
|
|
209
|
+
|
|
210
|
+
## API Reference
|
|
211
|
+
|
|
212
|
+
### `<ChartMLChart>` Component
|
|
213
|
+
|
|
214
|
+
**Props:**
|
|
215
|
+
|
|
216
|
+
| Prop | Type | Description |
|
|
217
|
+
|------|------|-------------|
|
|
218
|
+
| `spec` | `string \| object` | ChartML specification (YAML string or object) |
|
|
219
|
+
| `chartml` | `ChartML` | Optional ChartML instance (for custom plugins) |
|
|
220
|
+
| `options` | `object` | Options for ChartML instance |
|
|
221
|
+
| `options.onProgress` | `function` | Progress callback: `(event) => void` |
|
|
222
|
+
| `options.onCacheHit` | `function` | Cache hit callback: `(event) => void` |
|
|
223
|
+
| `options.onCacheMiss` | `function` | Cache miss callback: `(event) => void` |
|
|
224
|
+
| `options.onError` | `function` | Error callback: `(error) => void` |
|
|
225
|
+
| `options.palettes` | `object` | Custom color palettes |
|
|
226
|
+
| `className` | `string` | CSS class for container |
|
|
227
|
+
| `style` | `object` | Inline styles for container |
|
|
228
|
+
|
|
229
|
+
**Example:**
|
|
230
|
+
|
|
231
|
+
```jsx
|
|
232
|
+
<ChartMLChart
|
|
233
|
+
spec={mySpec}
|
|
234
|
+
className="chart-container"
|
|
235
|
+
style={{ maxWidth: '100%' }}
|
|
236
|
+
options={{
|
|
237
|
+
onProgress: (e) => console.log(e.percent),
|
|
238
|
+
onError: (err) => console.error(err)
|
|
239
|
+
}}
|
|
240
|
+
/>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### `useChartML()` Hook
|
|
244
|
+
|
|
245
|
+
Creates and manages a ChartML instance with React hooks.
|
|
246
|
+
|
|
247
|
+
**Parameters:**
|
|
248
|
+
- `options` (object, optional) - ChartML options
|
|
249
|
+
|
|
250
|
+
**Returns:** `ChartML` instance
|
|
251
|
+
|
|
252
|
+
**Example:**
|
|
253
|
+
|
|
254
|
+
```jsx
|
|
255
|
+
const chartml = useChartML({
|
|
256
|
+
onProgress: (e) => console.log(`Loading: ${e.percent}%`),
|
|
257
|
+
palettes: {
|
|
258
|
+
custom: ['#ff0000', '#00ff00', '#0000ff']
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Examples
|
|
264
|
+
|
|
265
|
+
### Pie Chart
|
|
266
|
+
|
|
267
|
+
```jsx
|
|
268
|
+
const pieSpec = `
|
|
269
|
+
type: chart
|
|
270
|
+
version: 1
|
|
271
|
+
|
|
272
|
+
data:
|
|
273
|
+
- category: "Product A"
|
|
274
|
+
sales: 1200
|
|
275
|
+
- category: "Product B"
|
|
276
|
+
sales: 850
|
|
277
|
+
- category: "Product C"
|
|
278
|
+
sales: 1450
|
|
279
|
+
|
|
280
|
+
visualize:
|
|
281
|
+
type: pie
|
|
282
|
+
columns: category
|
|
283
|
+
rows: sales
|
|
284
|
+
style:
|
|
285
|
+
title: "Sales by Product"
|
|
286
|
+
`;
|
|
287
|
+
|
|
288
|
+
<ChartMLChart spec={pieSpec} />
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Scatter Plot
|
|
292
|
+
|
|
293
|
+
```jsx
|
|
294
|
+
const scatterSpec = `
|
|
295
|
+
type: chart
|
|
296
|
+
version: 1
|
|
297
|
+
|
|
298
|
+
data:
|
|
299
|
+
- temperature: 65
|
|
300
|
+
sales: 120
|
|
301
|
+
- temperature: 70
|
|
302
|
+
sales: 140
|
|
303
|
+
- temperature: 75
|
|
304
|
+
sales: 180
|
|
305
|
+
|
|
306
|
+
visualize:
|
|
307
|
+
type: scatter
|
|
308
|
+
columns: temperature
|
|
309
|
+
rows: sales
|
|
310
|
+
style:
|
|
311
|
+
title: "Sales vs Temperature"
|
|
312
|
+
`;
|
|
313
|
+
|
|
314
|
+
<ChartMLChart spec={scatterSpec} />
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Metric Card
|
|
318
|
+
|
|
319
|
+
```jsx
|
|
320
|
+
const metricSpec = `
|
|
321
|
+
type: chart
|
|
322
|
+
version: 1
|
|
323
|
+
|
|
324
|
+
data:
|
|
325
|
+
- value: 1234
|
|
326
|
+
|
|
327
|
+
visualize:
|
|
328
|
+
type: metric
|
|
329
|
+
rows: value
|
|
330
|
+
style:
|
|
331
|
+
title: "Total Revenue"
|
|
332
|
+
format: "$,.0f"
|
|
333
|
+
`;
|
|
334
|
+
|
|
335
|
+
<ChartMLChart spec={metricSpec} />
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## TypeScript Support
|
|
339
|
+
|
|
340
|
+
Type definitions are included:
|
|
341
|
+
|
|
342
|
+
```tsx
|
|
343
|
+
import { ChartMLChart, useChartML } from '@chartml/react';
|
|
344
|
+
import type { ChartML } from '@chartml/core';
|
|
345
|
+
|
|
346
|
+
interface ChartProps {
|
|
347
|
+
data: any[];
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function TypedChart({ data }: ChartProps) {
|
|
351
|
+
const chartml: ChartML = useChartML();
|
|
352
|
+
|
|
353
|
+
const spec = {
|
|
354
|
+
type: 'chart' as const,
|
|
355
|
+
version: 1,
|
|
356
|
+
data,
|
|
357
|
+
visualize: {
|
|
358
|
+
type: 'bar' as const,
|
|
359
|
+
columns: 'month',
|
|
360
|
+
rows: 'revenue'
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
return <ChartMLChart spec={spec} chartml={chartml} />;
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Best Practices
|
|
369
|
+
|
|
370
|
+
### 1. Memoize Spec Objects
|
|
371
|
+
|
|
372
|
+
If passing spec as an object (not string), memoize it to prevent unnecessary re-renders:
|
|
373
|
+
|
|
374
|
+
```jsx
|
|
375
|
+
import { useMemo } from 'react';
|
|
376
|
+
|
|
377
|
+
const spec = useMemo(() => ({
|
|
378
|
+
type: 'chart',
|
|
379
|
+
version: 1,
|
|
380
|
+
data: chartData,
|
|
381
|
+
visualize: { type: 'bar', columns: 'x', rows: 'y' }
|
|
382
|
+
}), [chartData]);
|
|
383
|
+
|
|
384
|
+
<ChartMLChart spec={spec} />
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### 2. Use String Specs for Static Charts
|
|
388
|
+
|
|
389
|
+
For static charts, YAML strings are more readable:
|
|
390
|
+
|
|
391
|
+
```jsx
|
|
392
|
+
const spec = `
|
|
393
|
+
type: chart
|
|
394
|
+
version: 1
|
|
395
|
+
data: [...]
|
|
396
|
+
visualize: { type: bar }
|
|
397
|
+
`;
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### 3. Handle Loading States
|
|
401
|
+
|
|
402
|
+
Always handle loading states for async data:
|
|
403
|
+
|
|
404
|
+
```jsx
|
|
405
|
+
if (!data) return <div>Loading chart...</div>;
|
|
406
|
+
return <ChartMLChart spec={buildSpec(data)} />;
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### 4. Error Boundaries
|
|
410
|
+
|
|
411
|
+
Wrap charts in error boundaries for production:
|
|
412
|
+
|
|
413
|
+
```jsx
|
|
414
|
+
<ErrorBoundary fallback={<div>Chart failed to load</div>}>
|
|
415
|
+
<ChartMLChart spec={spec} />
|
|
416
|
+
</ErrorBoundary>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
## Browser Support
|
|
420
|
+
|
|
421
|
+
- React 18+
|
|
422
|
+
- Modern browsers with SVG support
|
|
423
|
+
- IE11+ (with polyfills)
|
|
424
|
+
|
|
425
|
+
## Documentation
|
|
426
|
+
|
|
427
|
+
- **ChartML Specification**: https://chartml.org/spec
|
|
428
|
+
- **Examples**: https://chartml.org/examples
|
|
429
|
+
- **API Reference**: https://chartml.org/api
|
|
430
|
+
|
|
431
|
+
## License
|
|
432
|
+
|
|
433
|
+
MIT © 2025 Alytic Pty Ltd
|
|
434
|
+
|
|
435
|
+
## Powered By
|
|
436
|
+
|
|
437
|
+
ChartML is maintained by the team at [Kyomi](https://kyomi.ai) and is the visualization engine that powers the platform.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useRef as u, useEffect as l } from "react";
|
|
2
|
+
import { ChartML as f } from "@chartml/core";
|
|
3
|
+
function R({ spec: e, chartml: r, options: n = {}, className: o = "", style: i = {} }) {
|
|
4
|
+
const t = u(null), c = u(null);
|
|
5
|
+
return l(() => (c.current || (c.current = r || new f(n)), (async () => {
|
|
6
|
+
if (t.current && e)
|
|
7
|
+
try {
|
|
8
|
+
await c.current.render(e, t.current);
|
|
9
|
+
} catch (a) {
|
|
10
|
+
console.error("[ChartML React] Render failed:", a), n.onError && n.onError(a);
|
|
11
|
+
}
|
|
12
|
+
})(), () => {
|
|
13
|
+
t.current && (t.current.innerHTML = "");
|
|
14
|
+
}), [e, r, n]), /* @__PURE__ */ React.createElement("div", { ref: t, className: o, style: i });
|
|
15
|
+
}
|
|
16
|
+
function m(e = {}) {
|
|
17
|
+
const r = u(null);
|
|
18
|
+
return r.current || (r.current = new f(e)), r.current;
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
R as ChartMLChart,
|
|
22
|
+
R as default,
|
|
23
|
+
m as useChartML
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.jsx"],"sourcesContent":["/**\n * @chartml/react\n *\n * React wrapper component for ChartML\n * Provides a convenient React API for rendering ChartML specifications\n *\n * @example\n * import { ChartMLChart } from '@chartml/react';\n * import { ChartML } from '@chartml/core';\n *\n * function MyComponent() {\n * const spec = `\n * data:\n * - month: Jan\n * revenue: 45000\n * - month: Feb\n * revenue: 52000\n *\n * visualize:\n * type: bar\n * columns: month\n * rows: revenue\n * style:\n * title: \"Monthly Revenue\"\n * `;\n *\n * return <ChartMLChart spec={spec} />;\n * }\n */\n\nimport { useEffect, useRef } from 'react';\nimport { ChartML } from '@chartml/core';\n\n/**\n * ChartMLChart Component\n *\n * @param {Object} props\n * @param {string|object} props.spec - ChartML specification (YAML string or object)\n * @param {ChartML} [props.chartml] - Optional ChartML instance (for custom plugins)\n * @param {Object} [props.options] - Options for ChartML instance (if not providing instance)\n * @param {Function} [props.options.onProgress] - Progress callback\n * @param {Function} [props.options.onCacheHit] - Cache hit callback\n * @param {Function} [props.options.onCacheMiss] - Cache miss callback\n * @param {Function} [props.options.onError] - Error callback\n * @param {Object} [props.options.palettes] - Custom color palettes\n * @param {string} [props.className] - CSS class for container\n * @param {Object} [props.style] - Inline styles for container\n *\n * @example\n * // Basic usage\n * <ChartMLChart spec={yamlSpec} />\n *\n * @example\n * // With custom ChartML instance (for plugins)\n * const chartml = new ChartML();\n * chartml.registerChartRenderer('pie', pieRenderer);\n * <ChartMLChart spec={spec} chartml={chartml} />\n *\n * @example\n * // With hooks\n * <ChartMLChart\n * spec={spec}\n * options={{\n * onProgress: (event) => console.log(`Progress: ${event.percent}%`),\n * onCacheHit: (event) => console.log('Cache hit!'),\n * palettes: { myPalette: ['#ff0000', '#00ff00', '#0000ff'] }\n * }}\n * />\n */\nexport function ChartMLChart({ spec, chartml, options = {}, className = '', style = {} }) {\n const containerRef = useRef(null);\n const chartmlRef = useRef(null);\n\n useEffect(() => {\n // Create or use provided ChartML instance\n if (!chartmlRef.current) {\n chartmlRef.current = chartml || new ChartML(options);\n }\n\n // Render chart\n const renderChart = async () => {\n if (containerRef.current && spec) {\n try {\n await chartmlRef.current.render(spec, containerRef.current);\n } catch (error) {\n console.error('[ChartML React] Render failed:', error);\n if (options.onError) {\n options.onError(error);\n }\n }\n }\n };\n\n renderChart();\n\n // Cleanup function\n return () => {\n // Clear container on unmount\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n };\n }, [spec, chartml, options]);\n\n return <div ref={containerRef} className={className} style={style} />;\n}\n\n/**\n * useChartML Hook\n *\n * Creates and manages a ChartML instance with plugins\n *\n * @param {Object} options - ChartML options\n * @returns {ChartML} ChartML instance\n *\n * @example\n * import { useChartML } from '@chartml/react';\n * import { createPieChartRenderer } from '@chartml/chart-pie';\n *\n * function MyComponent() {\n * const chartml = useChartML({\n * onProgress: (e) => console.log(`Progress: ${e.percent}%`)\n * });\n *\n * useEffect(() => {\n * chartml.registerChartRenderer('pie', createPieChartRenderer());\n * }, [chartml]);\n *\n * return <ChartMLChart spec={spec} chartml={chartml} />;\n * }\n */\nexport function useChartML(options = {}) {\n const chartmlRef = useRef(null);\n\n if (!chartmlRef.current) {\n chartmlRef.current = new ChartML(options);\n }\n\n return chartmlRef.current;\n}\n\nexport default ChartMLChart;\n"],"names":["ChartMLChart","spec","chartml","options","className","style","containerRef","useRef","chartmlRef","useEffect","ChartML","error","useChartML"],"mappings":";;AAqEO,SAASA,EAAa,EAAE,MAAAC,GAAM,SAAAC,GAAS,SAAAC,IAAU,IAAI,WAAAC,IAAY,IAAI,OAAAC,IAAQ,CAAA,KAAM;AACxF,QAAMC,IAAeC,EAAO,IAAI,GAC1BC,IAAaD,EAAO,IAAI;AAE9B,SAAAE,EAAU,OAEHD,EAAW,YACdA,EAAW,UAAUN,KAAW,IAAIQ,EAAQP,CAAO,KAIjC,YAAY;AAC9B,QAAIG,EAAa,WAAWL;AAC1B,UAAI;AACF,cAAMO,EAAW,QAAQ,OAAOP,GAAMK,EAAa,OAAO;AAAA,MAC5D,SAASK,GAAO;AACd,gBAAQ,MAAM,kCAAkCA,CAAK,GACjDR,EAAQ,WACVA,EAAQ,QAAQQ,CAAK;AAAA,MAEzB;AAAA,EAEJ,GAEA,GAGO,MAAM;AAEX,IAAIL,EAAa,YACfA,EAAa,QAAQ,YAAY;AAAA,EAErC,IACC,CAACL,GAAMC,GAASC,CAAO,CAAC,GAEpB,sBAAA,cAAC,OAAA,EAAI,KAAKG,GAAc,WAAAF,GAAsB,OAAAC,GAAc;AACrE;AA0BO,SAASO,EAAWT,IAAU,IAAI;AACvC,QAAMK,IAAaD,EAAO,IAAI;AAE9B,SAAKC,EAAW,YACdA,EAAW,UAAU,IAAIE,EAAQP,CAAO,IAGnCK,EAAW;AACpB;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chartml/react",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "React wrapper component for ChartML",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "vite build",
|
|
21
|
+
"dev": "vite build --watch"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"chartml",
|
|
25
|
+
"react",
|
|
26
|
+
"chart",
|
|
27
|
+
"visualization",
|
|
28
|
+
"wrapper"
|
|
29
|
+
],
|
|
30
|
+
"author": "Jason Adams",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@chartml/core": "^1.0.0",
|
|
34
|
+
"@chartml/chart-pie": "^1.0.0",
|
|
35
|
+
"@chartml/chart-scatter": "^1.0.0",
|
|
36
|
+
"@chartml/chart-metric": "^1.0.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": "^18.0.0",
|
|
40
|
+
"react-dom": "^18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"vite": "^5.0.0"
|
|
44
|
+
},
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/chartml/chartml.git",
|
|
48
|
+
"directory": "packages/react"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://chartml.org"
|
|
51
|
+
}
|