@niekes/charts-3d 0.3.0 → 0.5.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/NOTICE +33 -0
- package/README.md +0 -1
- package/dist/index.d.ts +117 -40
- package/dist/index.js +1479 -642
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/NOTICE
CHANGED
|
@@ -31,3 +31,36 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
31
31
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
32
32
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
33
33
|
SOFTWARE.
|
|
34
|
+
|
|
35
|
+
charts-3d includes code adapted from React Bits (https://reactbits.dev),
|
|
36
|
+
the Scanner component in docs/components/scanner.tsx, which draws the
|
|
37
|
+
animated background of the landing page of the docs. It stays in the docs,
|
|
38
|
+
which are not part of the npm package: React Bits is licensed under the
|
|
39
|
+
MIT + Commons Clause License Condition v1.0, which permits use as part of
|
|
40
|
+
an application but forbids selling or redistributing the components
|
|
41
|
+
themselves.
|
|
42
|
+
|
|
43
|
+
Copyright (c) 2026 David Haz
|
|
44
|
+
|
|
45
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
46
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
47
|
+
in the Software without restriction, including without limitation the rights
|
|
48
|
+
to use, copy, modify, merge, publish, and distribute the Software as part of
|
|
49
|
+
an application, website, or product, subject to the following conditions:
|
|
50
|
+
|
|
51
|
+
The above copyright notice and this permission notice shall be included in all
|
|
52
|
+
copies or substantial portions of the Software.
|
|
53
|
+
|
|
54
|
+
Commons Clause Restriction
|
|
55
|
+
|
|
56
|
+
You may use this Software, including for any commercial purpose, so long as
|
|
57
|
+
you do not sell, sublicense, or redistribute the components themselves -
|
|
58
|
+
whether alone, in a bundle, or as a ported version.
|
|
59
|
+
|
|
60
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
61
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
62
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
63
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
64
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
65
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
66
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
</tr>
|
|
39
39
|
<tr style="background-color: #f6f8fa">
|
|
40
40
|
<td><a target="_blank" href="https://niekes.github.io/charts-3d/docs/components/surface-chart-3d"><img src="assets/examples/surface-chart-3d.png" alt="Surface Chart 3D"></a></td>
|
|
41
|
-
<td><a target="_blank" href="https://niekes.github.io/charts-3d/docs/components/sankey-chart-3d"><img src="assets/examples/sankey-chart-3d.png" alt="Sankey Chart 3D"></a></td>
|
|
42
41
|
</tr>
|
|
43
42
|
</table>
|
|
44
43
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import { AxesSpec, AxisSpec, Camera3DInstance, CubeFace, Point2D, TransformedPoint } from "d3-3d";
|
|
3
|
+
import { AxesSpec, AxisSpec, Camera3DInstance, CubeFace, Point2D, Point3D, ShapeInstance, TransformedPoint } from "d3-3d";
|
|
4
4
|
declare const THEMES: {
|
|
5
5
|
readonly light: "";
|
|
6
6
|
readonly dark: ".dark";
|
|
@@ -27,7 +27,7 @@ export type View3D = {
|
|
|
27
27
|
perspective?: number;
|
|
28
28
|
};
|
|
29
29
|
/** How the marks of a chart are drawn. The box, its labels, the tooltip and the legend are always SVG and HTML. */
|
|
30
|
-
export type Renderer3D = "svg" | "canvas";
|
|
30
|
+
export type Renderer3D = "svg" | "canvas" | "webgl";
|
|
31
31
|
/** Maps data values to the world box, which spans -1 to 1 on every axis, y up. */
|
|
32
32
|
export type World = Record<keyof AxesSpec, (value: number) => number>;
|
|
33
33
|
export type Tooltip3D = {
|
|
@@ -53,6 +53,19 @@ export type Mark3D = {
|
|
|
53
53
|
stroke?: string;
|
|
54
54
|
/** Shown while the pointer is over the mark. */
|
|
55
55
|
tooltip?: Tooltip3D;
|
|
56
|
+
/**
|
|
57
|
+
* The marks of the same element as this one: the faces of a bar, the
|
|
58
|
+
* segments of a flow. Pointing at a mark gives them an edge in the focus
|
|
59
|
+
* color - `--chart-3d-focus`, or their own fill lightened - until the
|
|
60
|
+
* pointer leaves the mark; the fill never changes on hover.
|
|
61
|
+
*/
|
|
62
|
+
groups?: string[];
|
|
63
|
+
};
|
|
64
|
+
/** The groups in focus, a store, so a change reaches the marks and labels without rendering the chart again. */
|
|
65
|
+
type Focus3D = {
|
|
66
|
+
get: () => string[] | undefined;
|
|
67
|
+
set: (groups?: string[]) => void;
|
|
68
|
+
subscribe: (listener: () => void) => () => void;
|
|
56
69
|
};
|
|
57
70
|
type ChartContext3D = {
|
|
58
71
|
config: ChartConfig;
|
|
@@ -61,11 +74,36 @@ type ChartContext3D = {
|
|
|
61
74
|
/** The marks of the chart, which the hover and the canvas read. */
|
|
62
75
|
scene: React.RefObject<Mark3D[]>;
|
|
63
76
|
repaint: () => void;
|
|
77
|
+
focus: Focus3D;
|
|
78
|
+
/** The time in ms a chart takes to glide into new data, 600 unless the container says. */
|
|
79
|
+
animationDuration?: number;
|
|
64
80
|
};
|
|
65
81
|
export declare function useChart3D(): ChartContext3D;
|
|
82
|
+
/** The actions a key triggers: each steps the camera, `help` opens the shortcut panel. */
|
|
83
|
+
export type KeyAction3D = "rotateLeft" | "rotateRight" | "rotateUp" | "rotateDown" | "panLeft" | "panRight" | "panUp" | "panDown" | "zoomIn" | "zoomOut" | "reset" | "help";
|
|
84
|
+
/** The gestures of the pointer, which `keymap` can turn off or rename but not rebind; the shortcut panel shows each with its modifier on the reader's platform. */
|
|
85
|
+
export type Gesture3D = "dragRotate" | "dragPan" | "wheelZoom" | "doubleClickReset";
|
|
86
|
+
/**
|
|
87
|
+
* The shortcuts of a chart over their defaults, per action: `false` turns an
|
|
88
|
+
* action off, keys replace its keys and a label renames it in the shortcut
|
|
89
|
+
* panel, where the actions of one label share a row. Keys are written the way
|
|
90
|
+
* `aria-keyshortcuts` writes them, such as `"Shift+ArrowLeft"` or
|
|
91
|
+
* `"Control+Plus"`, and the panel shows the first.
|
|
92
|
+
*/
|
|
93
|
+
export type Keymap3D = { [A in KeyAction3D]?: false | string[] | {
|
|
94
|
+
keys?: string[];
|
|
95
|
+
label?: string;
|
|
96
|
+
}; } & { [G in Gesture3D]?: false | {
|
|
97
|
+
label?: string;
|
|
98
|
+
}; };
|
|
66
99
|
export type ChartContainer3DProps = {
|
|
67
100
|
/** The series of the chart: a label and a color per key, as in the chart of shadcn/ui. */
|
|
68
101
|
config: ChartConfig;
|
|
102
|
+
/**
|
|
103
|
+
* The time in ms a chart takes to glide into new data; 0 makes it jump.
|
|
104
|
+
* @defaultValue 600
|
|
105
|
+
*/
|
|
106
|
+
animationDuration?: number;
|
|
69
107
|
/**
|
|
70
108
|
* Where the camera starts, and where a reset returns it.
|
|
71
109
|
* @defaultValue { yaw: π/6, tilt: π/6 }
|
|
@@ -87,9 +125,9 @@ export type ChartContainer3DProps = {
|
|
|
87
125
|
*/
|
|
88
126
|
legend?: boolean;
|
|
89
127
|
/**
|
|
90
|
-
* How the marks of the chart are drawn: "canvas" suits many marks.
|
|
91
|
-
* chart draws as SVG until the browser shows it has
|
|
92
|
-
* has none.
|
|
128
|
+
* How the marks of the chart are drawn: "canvas" suits many marks, "webgl" more.
|
|
129
|
+
* The chart draws as SVG until the browser shows it has the requested renderer,
|
|
130
|
+
* "webgl" falling back to "canvas", and where it has none, as SVG.
|
|
93
131
|
* @defaultValue "svg"
|
|
94
132
|
*/
|
|
95
133
|
renderer?: Renderer3D;
|
|
@@ -98,21 +136,57 @@ export type ChartContainer3DProps = {
|
|
|
98
136
|
* @defaultValue true
|
|
99
137
|
*/
|
|
100
138
|
shortcuts?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Rebinds, renames or turns off the keys and the gestures of the chart, per
|
|
141
|
+
* action; `false` turns them all off and the chart stands still.
|
|
142
|
+
* @defaultValue {}
|
|
143
|
+
*/
|
|
144
|
+
keymap?: Keymap3D | false;
|
|
145
|
+
/**
|
|
146
|
+
* The corner that shows the axes of the chart, turned with the camera; `false` hides them.
|
|
147
|
+
* @defaultValue "bottom-left"
|
|
148
|
+
*/
|
|
149
|
+
gizmo?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | false;
|
|
101
150
|
};
|
|
102
|
-
declare function ChartContainer3D({ id, config, defaultView, width, height, legend, renderer: requested, shortcuts, className, children, "aria-label": ariaLabel, ...props }: React.ComponentProps<"div"> & ChartContainer3DProps): React.JSX.Element;
|
|
151
|
+
declare function ChartContainer3D({ id, config, defaultView, width, height, animationDuration, legend, renderer: requested, shortcuts, keymap, gizmo, className, children, "aria-label": ariaLabel, ...props }: React.ComponentProps<"div"> & ChartContainer3DProps): React.JSX.Element;
|
|
152
|
+
/**
|
|
153
|
+
* Eases a chart into new data: the numbers of `values` glide from the ones
|
|
154
|
+
* on screen to these over the animationDuration of the container. A key
|
|
155
|
+
* that is new starts at `enter`, or where it ends; a key that is gone glides
|
|
156
|
+
* back to `enter`, the mirror of its entering - without one it stands where
|
|
157
|
+
* it is - and leaves when the glide is done. Without time, or with reduced
|
|
158
|
+
* motion, the numbers jump.
|
|
159
|
+
*/
|
|
160
|
+
declare function useTween(values: Record<string, number>, enter?: number): Record<string, number>;
|
|
161
|
+
/**
|
|
162
|
+
* `spec` gliding into new data with the marks: the ends of every axis glide
|
|
163
|
+
* as `useTween` glides the numbers, where ends rounded from the numbers on
|
|
164
|
+
* screen would jump from one round number to the next, and the box with
|
|
165
|
+
* them. The ticks stay those of `spec`; labels of ticks outside the gliding
|
|
166
|
+
* ends fade out in `edgeLabels` instead of popping out of the range. The
|
|
167
|
+
* outermost ticks glide too, so the line of the axis grows to a new tick and
|
|
168
|
+
* shrinks from a dropped one instead of jumping when the glide is done.
|
|
169
|
+
*/
|
|
170
|
+
declare function useTweenAxes(spec: AxesSpec): AxesSpec;
|
|
103
171
|
/**
|
|
104
172
|
* The marks of a chart, drawn by the renderer of the container: as SVG
|
|
105
173
|
* elements, or on the canvas over the chart box. The hover reads them too.
|
|
106
174
|
*/
|
|
107
175
|
declare function Marks3D({ marks }: {
|
|
108
176
|
marks: Mark3D[];
|
|
109
|
-
}): React.JSX.Element
|
|
110
|
-
/**
|
|
177
|
+
}): React.JSX.Element | null;
|
|
178
|
+
/**
|
|
179
|
+
* A label beside a mark, at `at` in the units of the view box. `toward`, a
|
|
180
|
+
* unit vector, lays the label on that side of `at`, touching it, and slides
|
|
181
|
+
* it round `at` as the vector turns; without it, `anchor` is the end of the
|
|
182
|
+
* text that sits at `at`.
|
|
183
|
+
*/
|
|
111
184
|
export type Label3D = {
|
|
112
185
|
key: string;
|
|
113
186
|
at: Point2D;
|
|
114
187
|
text: React.ReactNode;
|
|
115
|
-
anchor
|
|
188
|
+
anchor?: "start" | "middle" | "end";
|
|
189
|
+
toward?: Point2D;
|
|
116
190
|
};
|
|
117
191
|
/**
|
|
118
192
|
* The labels of the marks of a chart, ringed by the background so that they
|
|
@@ -126,7 +200,10 @@ declare function ChartLegend3D({ config }: {
|
|
|
126
200
|
}): React.JSX.Element;
|
|
127
201
|
/**
|
|
128
202
|
* The walls of the chart box that face away from the camera, with their
|
|
129
|
-
* gridlines,
|
|
203
|
+
* gridlines, the line of every axis along its edge with the mark of each of
|
|
204
|
+
* its ticks, and the labels of every axis on each of its four edges. Only the
|
|
205
|
+
* edge the axis sits on shows them, so when the axis moves to another edge,
|
|
206
|
+
* its line, its marks and its labels fade from one to the other.
|
|
130
207
|
*/
|
|
131
208
|
declare function Axes3D({ spec, world, format, titles }: {
|
|
132
209
|
spec: AxesSpec;
|
|
@@ -136,16 +213,34 @@ declare function Axes3D({ spec, world, format, titles }: {
|
|
|
136
213
|
}): React.JSX.Element;
|
|
137
214
|
/** A nice axis from `lo` to `hi` with about `count` ticks. */
|
|
138
215
|
declare function axis(lo: number, hi: number, count?: number): AxisSpec;
|
|
216
|
+
/**
|
|
217
|
+
* The axis `spec` with its domain widened by half a `cell` on each side, so
|
|
218
|
+
* the box keeps room between the outermost data and its walls. The ticks stay
|
|
219
|
+
* where they were, on the data.
|
|
220
|
+
*/
|
|
221
|
+
declare function pad(spec: AxisSpec, cell: number): AxisSpec;
|
|
139
222
|
/** The linear map from `domain` to `range`. */
|
|
140
223
|
declare function linear([d0, d1]: number[], [r0, r1]: number[]): (value: number) => number;
|
|
141
224
|
/** The world box of `spec`: x from -1 to 1, y up from 1 to -1, z from -`depth` to `depth`. */
|
|
142
225
|
declare function worldBox(spec: AxesSpec, depth?: number): World;
|
|
226
|
+
/**
|
|
227
|
+
* Hands the projection its accessors into the world box, so every chart maps
|
|
228
|
+
* its shapes onto the screen the same way.
|
|
229
|
+
*/
|
|
230
|
+
declare function intoWorld<Datum extends Point3D, T extends ShapeInstance<Datum>>(projection: T, world: World): T;
|
|
143
231
|
/**
|
|
144
232
|
* `color` lit by the light from the upper left: the face that looks at it
|
|
145
233
|
* keeps the color, one that turns away gets darker. A CSS color-mix, so the
|
|
146
234
|
* shade follows the theme variables.
|
|
147
235
|
*/
|
|
148
236
|
declare function shade(face: TransformedPoint<unknown>[], color: string): string;
|
|
237
|
+
/**
|
|
238
|
+
* `color` at `opacity`, from 0 to 1: a CSS color-mix with transparent, so a
|
|
239
|
+
* mark fades on every renderer while its color stays in CSS. Rounded to a
|
|
240
|
+
* percent, so the renderers that resolve colors cache a bounded few. Fade
|
|
241
|
+
* after `shade`, which would mix a translucent color back towards opaque.
|
|
242
|
+
*/
|
|
243
|
+
declare function faded(color: string, opacity: number): string;
|
|
149
244
|
/** The mean of the projected points, where a tooltip points at. */
|
|
150
245
|
declare function center(points: TransformedPoint<unknown>[]): Point2D;
|
|
151
246
|
/** The marks of a cube: its faces that look at the camera, shaded in `color`, each with `tooltip` on hover. */
|
|
@@ -153,7 +248,7 @@ declare function cubeMarks(id: string, faces: CubeFace[], color: string, tooltip
|
|
|
153
248
|
export type BarChart3DProps<T extends Record<string, unknown> = Record<string, unknown>> = {
|
|
154
249
|
/** One entry per row of bars, with a value per series. */
|
|
155
250
|
data: T[];
|
|
156
|
-
/** The field that names each entry, such as "month". */
|
|
251
|
+
/** The field that names each entry, such as "month"; a bar follows its name through updates, so the names should be unique. */
|
|
157
252
|
index: keyof T & string;
|
|
158
253
|
/**
|
|
159
254
|
* The fields that hold the series, one row of bars each.
|
|
@@ -188,6 +283,13 @@ export type ScatterChart3DProps<T extends Record<string, unknown> = Record<strin
|
|
|
188
283
|
y: keyof T & string;
|
|
189
284
|
/** The field of the position along z. */
|
|
190
285
|
z: keyof T & string;
|
|
286
|
+
/**
|
|
287
|
+
* The field that names an entry, so a point follows its name through
|
|
288
|
+
* updates: a new one grows, a gone one shrinks away, one that moves glides.
|
|
289
|
+
* The names should be unique.
|
|
290
|
+
* @defaultValue the position of the entry
|
|
291
|
+
*/
|
|
292
|
+
id?: keyof T & string;
|
|
191
293
|
/**
|
|
192
294
|
* The field whose value is the config key of the color of a point.
|
|
193
295
|
* @defaultValue the first key of the chart config for every point
|
|
@@ -207,12 +309,14 @@ export type ScatterChart3DProps<T extends Record<string, unknown> = Record<strin
|
|
|
207
309
|
* Points in the chart box, at the fields `x`, `y` and `z` of each entry.
|
|
208
310
|
* `series` names the field whose value is the config key of the color.
|
|
209
311
|
*/
|
|
210
|
-
export declare function ScatterChart3D<T extends Record<string, unknown>>({ data, x, y, z, series, radius, format, titles }: ScatterChart3DProps<T>): React.JSX.Element;
|
|
312
|
+
export declare function ScatterChart3D<T extends Record<string, unknown>>({ data, x, y, z, id, series, radius, format, titles }: ScatterChart3DProps<T>): React.JSX.Element;
|
|
211
313
|
export type SurfaceChart3DProps = {
|
|
212
314
|
/** The heights on the grid, `data[row][column]`. */
|
|
213
315
|
data: number[][];
|
|
214
316
|
/**
|
|
215
317
|
* The data values the first and the last column (x) and row (z) stand for.
|
|
318
|
+
* The chart keeps half a cell between the grid and the walls of its box; a
|
|
319
|
+
* domain given here names the box exactly, without that room.
|
|
216
320
|
* @defaultValue the indices of the columns and rows
|
|
217
321
|
*/
|
|
218
322
|
domain?: {
|
|
@@ -236,32 +340,5 @@ export type SurfaceChart3DProps = {
|
|
|
236
340
|
* of the chart config, by default its first two.
|
|
237
341
|
*/
|
|
238
342
|
export declare function SurfaceChart3D({ data, domain, colors, format, titles }: SurfaceChart3DProps): React.JSX.Element;
|
|
239
|
-
export
|
|
240
|
-
/** One entry per flow. `source` and `target` are keys of the chart config, which names and colors the nodes. */
|
|
241
|
-
data: {
|
|
242
|
-
source: string;
|
|
243
|
-
target: string;
|
|
244
|
-
value: number;
|
|
245
|
-
}[];
|
|
246
|
-
/**
|
|
247
|
-
* The width of a node, as a share of the distance between two columns.
|
|
248
|
-
* @defaultValue 0.2
|
|
249
|
-
*/
|
|
250
|
-
nodeWidth?: number;
|
|
251
|
-
/**
|
|
252
|
-
* The gap between two nodes of a column, as a share of the height.
|
|
253
|
-
* @defaultValue 0.05
|
|
254
|
-
*/
|
|
255
|
-
nodePadding?: number;
|
|
256
|
-
/** Formats the values in the tooltip. */
|
|
257
|
-
format?: (value: number) => React.ReactNode;
|
|
258
|
-
};
|
|
259
|
-
/**
|
|
260
|
-
* Flows from left to right: every node a box in its column, as high as the
|
|
261
|
-
* larger of what flows in and what flows out, and every flow a band from node
|
|
262
|
-
* to node, as thick as its value, that turns from the color of its source to
|
|
263
|
-
* the color of its target.
|
|
264
|
-
*/
|
|
265
|
-
export declare function SankeyChart3D({ data, nodeWidth, nodePadding, format }: SankeyChart3DProps): React.JSX.Element;
|
|
266
|
-
export { Axes3D, ChartContainer3D, ChartLegend3D, Labels3D, Marks3D, axis, center, cubeMarks, linear, shade, worldBox };
|
|
343
|
+
export { Axes3D, ChartContainer3D, ChartLegend3D, Labels3D, Marks3D, axis, center, cubeMarks, faded, intoWorld, linear, pad, shade, useTween, useTweenAxes, worldBox };
|
|
267
344
|
//# sourceMappingURL=index.d.ts.map
|