react-cheminfo 0.15.0 → 0.17.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/README.md +96 -0
- package/lib/core.d.ts +1 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +1 -0
- package/lib/core.js.map +1 -1
- package/lib/credits/core/credits.d.ts +17 -0
- package/lib/credits/core/credits.d.ts.map +1 -1
- package/lib/credits/core/credits.js +20 -0
- package/lib/credits/core/credits.js.map +1 -1
- package/lib/ecosystem/core/sites.d.ts.map +1 -1
- package/lib/ecosystem/core/sites.js +40 -0
- package/lib/ecosystem/core/sites.js.map +1 -1
- package/lib/ecosystem/core/types.d.ts +1 -1
- package/lib/ecosystem/core/types.d.ts.map +1 -1
- package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
- package/lib/ecosystem/ui/glyphs.js +11 -0
- package/lib/ecosystem/ui/glyphs.js.map +1 -1
- package/lib/parallel/core/index.d.ts +29 -0
- package/lib/parallel/core/index.d.ts.map +1 -0
- package/lib/parallel/core/index.js +22 -0
- package/lib/parallel/core/index.js.map +1 -0
- package/lib/parallel/core/parallelAxes.d.ts +103 -0
- package/lib/parallel/core/parallelAxes.d.ts.map +1 -0
- package/lib/parallel/core/parallelAxes.js +146 -0
- package/lib/parallel/core/parallelAxes.js.map +1 -0
- package/lib/parallel/core/parallelBrush.d.ts +100 -0
- package/lib/parallel/core/parallelBrush.d.ts.map +1 -0
- package/lib/parallel/core/parallelBrush.js +149 -0
- package/lib/parallel/core/parallelBrush.js.map +1 -0
- package/lib/parallel/core/parallelExtent.d.ts +28 -0
- package/lib/parallel/core/parallelExtent.d.ts.map +1 -0
- package/lib/parallel/core/parallelExtent.js +47 -0
- package/lib/parallel/core/parallelExtent.js.map +1 -0
- package/lib/parallel/core/parallelFilter.d.ts +49 -0
- package/lib/parallel/core/parallelFilter.d.ts.map +1 -0
- package/lib/parallel/core/parallelFilter.js +107 -0
- package/lib/parallel/core/parallelFilter.js.map +1 -0
- package/lib/parallel/core/parallelHit.d.ts +47 -0
- package/lib/parallel/core/parallelHit.d.ts.map +1 -0
- package/lib/parallel/core/parallelHit.js +81 -0
- package/lib/parallel/core/parallelHit.js.map +1 -0
- package/lib/parallel/core/parallelOrder.d.ts +36 -0
- package/lib/parallel/core/parallelOrder.d.ts.map +1 -0
- package/lib/parallel/core/parallelOrder.js +65 -0
- package/lib/parallel/core/parallelOrder.js.map +1 -0
- package/lib/parallel/core/parallelPaint.d.ts +108 -0
- package/lib/parallel/core/parallelPaint.d.ts.map +1 -0
- package/lib/parallel/core/parallelPaint.js +169 -0
- package/lib/parallel/core/parallelPaint.js.map +1 -0
- package/lib/parallel/core/parallelPalette.d.ts +40 -0
- package/lib/parallel/core/parallelPalette.d.ts.map +1 -0
- package/lib/parallel/core/parallelPalette.js +81 -0
- package/lib/parallel/core/parallelPalette.js.map +1 -0
- package/lib/parallel/core/parallelSelection.d.ts +43 -0
- package/lib/parallel/core/parallelSelection.d.ts.map +1 -0
- package/lib/parallel/core/parallelSelection.js +87 -0
- package/lib/parallel/core/parallelSelection.js.map +1 -0
- package/lib/parallel/core/parallelTicks.d.ts +34 -0
- package/lib/parallel/core/parallelTicks.d.ts.map +1 -0
- package/lib/parallel/core/parallelTicks.js +119 -0
- package/lib/parallel/core/parallelTicks.js.map +1 -0
- package/lib/parallel/core/parallelTypes.d.ts +140 -0
- package/lib/parallel/core/parallelTypes.d.ts.map +1 -0
- package/lib/parallel/core/parallelTypes.js +29 -0
- package/lib/parallel/core/parallelTypes.js.map +1 -0
- package/lib/parallel/ui/ParallelAxesLayer.d.ts +28 -0
- package/lib/parallel/ui/ParallelAxesLayer.d.ts.map +1 -0
- package/lib/parallel/ui/ParallelAxesLayer.js +29 -0
- package/lib/parallel/ui/ParallelAxesLayer.js.map +1 -0
- package/lib/parallel/ui/ParallelCoordinates.d.ts +21 -0
- package/lib/parallel/ui/ParallelCoordinates.d.ts.map +1 -0
- package/lib/parallel/ui/ParallelCoordinates.js +114 -0
- package/lib/parallel/ui/ParallelCoordinates.js.map +1 -0
- package/lib/parallel/ui/ParallelLabels.d.ts +32 -0
- package/lib/parallel/ui/ParallelLabels.d.ts.map +1 -0
- package/lib/parallel/ui/ParallelLabels.js +37 -0
- package/lib/parallel/ui/ParallelLabels.js.map +1 -0
- package/lib/parallel/ui/ParallelTooltip.d.ts +26 -0
- package/lib/parallel/ui/ParallelTooltip.d.ts.map +1 -0
- package/lib/parallel/ui/ParallelTooltip.js +30 -0
- package/lib/parallel/ui/ParallelTooltip.js.map +1 -0
- package/lib/parallel/ui/index.d.ts +29 -0
- package/lib/parallel/ui/index.d.ts.map +1 -0
- package/lib/parallel/ui/index.js +20 -0
- package/lib/parallel/ui/index.js.map +1 -0
- package/lib/parallel/ui/parallelCoordinatesProps.d.ts +203 -0
- package/lib/parallel/ui/parallelCoordinatesProps.d.ts.map +1 -0
- package/lib/parallel/ui/parallelCoordinatesProps.js +11 -0
- package/lib/parallel/ui/parallelCoordinatesProps.js.map +1 -0
- package/lib/parallel/ui/parallelGestureModel.d.ts +83 -0
- package/lib/parallel/ui/parallelGestureModel.d.ts.map +1 -0
- package/lib/parallel/ui/parallelGestureModel.js +110 -0
- package/lib/parallel/ui/parallelGestureModel.js.map +1 -0
- package/lib/parallel/ui/parallelInk.d.ts +76 -0
- package/lib/parallel/ui/parallelInk.d.ts.map +1 -0
- package/lib/parallel/ui/parallelInk.js +113 -0
- package/lib/parallel/ui/parallelInk.js.map +1 -0
- package/lib/parallel/ui/parallelPlotModel.d.ts +55 -0
- package/lib/parallel/ui/parallelPlotModel.d.ts.map +1 -0
- package/lib/parallel/ui/parallelPlotModel.js +113 -0
- package/lib/parallel/ui/parallelPlotModel.js.map +1 -0
- package/lib/parallel/ui/parallelStyles.d.ts +106 -0
- package/lib/parallel/ui/parallelStyles.d.ts.map +1 -0
- package/lib/parallel/ui/parallelStyles.js +153 -0
- package/lib/parallel/ui/parallelStyles.js.map +1 -0
- package/lib/parallel/ui/useParallelAxisDrag.d.ts +60 -0
- package/lib/parallel/ui/useParallelAxisDrag.d.ts.map +1 -0
- package/lib/parallel/ui/useParallelAxisDrag.js +96 -0
- package/lib/parallel/ui/useParallelAxisDrag.js.map +1 -0
- package/lib/parallel/ui/useParallelCanvas.d.ts +49 -0
- package/lib/parallel/ui/useParallelCanvas.d.ts.map +1 -0
- package/lib/parallel/ui/useParallelCanvas.js +58 -0
- package/lib/parallel/ui/useParallelCanvas.js.map +1 -0
- package/lib/parallel/ui/useParallelGesture.d.ts +72 -0
- package/lib/parallel/ui/useParallelGesture.d.ts.map +1 -0
- package/lib/parallel/ui/useParallelGesture.js +164 -0
- package/lib/parallel/ui/useParallelGesture.js.map +1 -0
- package/lib/structure/ui/useToolbarFloor.d.ts.map +1 -1
- package/lib/structure/ui/useToolbarFloor.js +29 -22
- package/lib/structure/ui/useToolbarFloor.js.map +1 -1
- package/lib/ui.d.ts +1 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +1 -0
- package/lib/ui.js.map +1 -1
- package/package.json +1 -1
- package/src/core.ts +1 -0
- package/src/credits/core/credits.ts +21 -0
- package/src/ecosystem/core/sites.ts +40 -0
- package/src/ecosystem/core/types.ts +4 -1
- package/src/ecosystem/ui/glyphs.tsx +46 -0
- package/src/parallel/core/index.ts +96 -0
- package/src/parallel/core/parallelAxes.ts +207 -0
- package/src/parallel/core/parallelBrush.ts +211 -0
- package/src/parallel/core/parallelExtent.ts +56 -0
- package/src/parallel/core/parallelFilter.ts +131 -0
- package/src/parallel/core/parallelHit.ts +106 -0
- package/src/parallel/core/parallelOrder.ts +73 -0
- package/src/parallel/core/parallelPaint.ts +242 -0
- package/src/parallel/core/parallelPalette.ts +93 -0
- package/src/parallel/core/parallelSelection.ts +99 -0
- package/src/parallel/core/parallelTicks.ts +168 -0
- package/src/parallel/core/parallelTypes.ts +159 -0
- package/src/parallel/ui/ParallelAxesLayer.tsx +129 -0
- package/src/parallel/ui/ParallelCoordinates.tsx +252 -0
- package/src/parallel/ui/ParallelLabels.tsx +77 -0
- package/src/parallel/ui/ParallelTooltip.tsx +55 -0
- package/src/parallel/ui/index.ts +65 -0
- package/src/parallel/ui/parallelCoordinatesProps.ts +217 -0
- package/src/parallel/ui/parallelGestureModel.ts +159 -0
- package/src/parallel/ui/parallelInk.ts +182 -0
- package/src/parallel/ui/parallelPlotModel.ts +130 -0
- package/src/parallel/ui/parallelStyles.ts +188 -0
- package/src/parallel/ui/useParallelAxisDrag.ts +147 -0
- package/src/parallel/ui/useParallelCanvas.ts +104 -0
- package/src/parallel/ui/useParallelGesture.ts +260 -0
- package/src/structure/ui/useToolbarFloor.ts +27 -22
- package/src/ui.ts +1 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every rule the figure is drawn with.
|
|
3
|
+
*
|
|
4
|
+
* The library ships no stylesheet for a figure — a chart writes inline style
|
|
5
|
+
* objects, so a site that never renders one pays nothing and a site that does
|
|
6
|
+
* cannot forget to import a file. The two colours that are not fixed here, the
|
|
7
|
+
* axis ink and the band's, are resolved off the page by `parallelInk.ts` and
|
|
8
|
+
* written onto the elements, so an override applies to the canvas and to the
|
|
9
|
+
* markup alike.
|
|
10
|
+
*/
|
|
11
|
+
import type { CSSProperties } from 'react';
|
|
12
|
+
/** A layer covering the whole figure, stacked over the ones before it. */
|
|
13
|
+
export declare const PARALLEL_LAYER_STYLE: {
|
|
14
|
+
readonly position: "absolute";
|
|
15
|
+
readonly inset: 0;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The block the figure occupies, which every layer is positioned against.
|
|
19
|
+
* @param height - Total height of the figure, in pixels.
|
|
20
|
+
* @returns The wrapper's rules.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parallelFigureStyle(height: number): CSSProperties;
|
|
23
|
+
/**
|
|
24
|
+
* One of the two canvases, stretched over the figure.
|
|
25
|
+
* @param height - Total height of the figure, in pixels.
|
|
26
|
+
* @returns The canvas's rules.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parallelCanvasStyle(height: number): CSSProperties;
|
|
29
|
+
/** The drawing surface the axes, the bands and the pointer target live in. */
|
|
30
|
+
export declare const PARALLEL_SVG_STYLE: {
|
|
31
|
+
readonly display: "block";
|
|
32
|
+
readonly overflow: "visible";
|
|
33
|
+
readonly position: "absolute";
|
|
34
|
+
readonly inset: 0;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* The layer the axis names sit in. It is HTML rather than SVG text so that a
|
|
38
|
+
* name can carry a tooltip, and it lets every pointer event through so that a
|
|
39
|
+
* brush started under a name still starts.
|
|
40
|
+
*/
|
|
41
|
+
export declare const PARALLEL_LABELS_STYLE: {
|
|
42
|
+
readonly pointerEvents: "none";
|
|
43
|
+
readonly position: "absolute";
|
|
44
|
+
readonly inset: 0;
|
|
45
|
+
};
|
|
46
|
+
/** How one axis name is placed, and whether it is being moved. */
|
|
47
|
+
export interface ParallelLabelPlacement {
|
|
48
|
+
/** Where the axis stands, in pixels from the figure's left edge. */
|
|
49
|
+
left: number;
|
|
50
|
+
/**
|
|
51
|
+
* Whether the name can be dragged to move its axis.
|
|
52
|
+
* @default false
|
|
53
|
+
*/
|
|
54
|
+
draggable?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* How far it has been dragged, in pixels, or `null` when it is not moving.
|
|
57
|
+
* @default null
|
|
58
|
+
*/
|
|
59
|
+
dx?: number | null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* One axis name, centred over its axis and taking the pointer back.
|
|
63
|
+
* @param placement - See {@link ParallelLabelPlacement}.
|
|
64
|
+
* @returns The name's rules. A name being dragged follows the pointer and is
|
|
65
|
+
* drawn over its neighbours, so it is never hidden behind the name it is
|
|
66
|
+
* about to change places with.
|
|
67
|
+
*/
|
|
68
|
+
export declare function parallelLabelStyle(placement: ParallelLabelPlacement): CSSProperties;
|
|
69
|
+
/**
|
|
70
|
+
* The axis a dragged name would take the place of, marked while it is moving.
|
|
71
|
+
* @param ink - The colour the figure singles things out in.
|
|
72
|
+
* @returns The mark's rules.
|
|
73
|
+
*/
|
|
74
|
+
export declare function parallelDropMarkStyle(ink: string): CSSProperties;
|
|
75
|
+
/** One tick written out, tabular so a column of them lines up on the point. */
|
|
76
|
+
export declare const PARALLEL_TICK_LABEL_STYLE: {
|
|
77
|
+
readonly fontSize: 10;
|
|
78
|
+
readonly fontVariantNumeric: "tabular-nums";
|
|
79
|
+
readonly userSelect: "none";
|
|
80
|
+
};
|
|
81
|
+
/** How far a tick mark reaches out of the axis, in pixels. */
|
|
82
|
+
export declare const PARALLEL_TICK_LENGTH = 4;
|
|
83
|
+
/** How far a tick label ends before its axis. */
|
|
84
|
+
export declare const PARALLEL_TICK_LABEL_INSET = 7;
|
|
85
|
+
/**
|
|
86
|
+
* The interval one brush keeps, filled in the site's own colour.
|
|
87
|
+
* @param ink - The colour to fill and outline it in.
|
|
88
|
+
* @returns The band's rules.
|
|
89
|
+
*/
|
|
90
|
+
export declare function parallelBandStyle(ink: string): CSSProperties;
|
|
91
|
+
/**
|
|
92
|
+
* Either edge of a band, drawn so the reader can see it can be dragged.
|
|
93
|
+
* @param ink - The colour to draw it in.
|
|
94
|
+
* @returns The handle's rules.
|
|
95
|
+
*/
|
|
96
|
+
export declare function parallelHandleStyle(ink: string): CSSProperties;
|
|
97
|
+
/** How tall an edge handle is drawn, in pixels. */
|
|
98
|
+
export declare const PARALLEL_HANDLE_HEIGHT = 3;
|
|
99
|
+
/**
|
|
100
|
+
* The card over the row under the pointer.
|
|
101
|
+
* @param left - Where it sits, in pixels from the figure's left edge.
|
|
102
|
+
* @param top - Where it sits, in pixels from its top edge.
|
|
103
|
+
* @returns The card's rules.
|
|
104
|
+
*/
|
|
105
|
+
export declare function parallelTooltipStyle(left: number, top: number): CSSProperties;
|
|
106
|
+
//# sourceMappingURL=parallelStyles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallelStyles.d.ts","sourceRoot":"","sources":["../../../src/parallel/ui/parallelStyles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAI3C,0EAA0E;AAC1E,eAAO,MAAM,oBAAoB;;;CAGC,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAMjE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAMjE;AAED,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB;;;;;CAIG,CAAC;AAEnC;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;CAGA,CAAC;AAEnC,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,sBAAsB,GAChC,aAAa,CAoBf;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAOhE;AAED,+EAA+E;AAC/E,eAAO,MAAM,yBAAyB;;;;CAIJ,CAAC;AAEnC,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,iDAAiD;AACjD,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAO5D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAE9D;AAED,mDAAmD;AACnD,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,CAiB7E"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every rule the figure is drawn with.
|
|
3
|
+
*
|
|
4
|
+
* The library ships no stylesheet for a figure — a chart writes inline style
|
|
5
|
+
* objects, so a site that never renders one pays nothing and a site that does
|
|
6
|
+
* cannot forget to import a file. The two colours that are not fixed here, the
|
|
7
|
+
* axis ink and the band's, are resolved off the page by `parallelInk.ts` and
|
|
8
|
+
* written onto the elements, so an override applies to the canvas and to the
|
|
9
|
+
* markup alike.
|
|
10
|
+
*/
|
|
11
|
+
import { TOKEN } from "../../tokens/core/familyTokens.js";
|
|
12
|
+
/** A layer covering the whole figure, stacked over the ones before it. */
|
|
13
|
+
export const PARALLEL_LAYER_STYLE = {
|
|
14
|
+
position: 'absolute',
|
|
15
|
+
inset: 0,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The block the figure occupies, which every layer is positioned against.
|
|
19
|
+
* @param height - Total height of the figure, in pixels.
|
|
20
|
+
* @returns The wrapper's rules.
|
|
21
|
+
*/
|
|
22
|
+
export function parallelFigureStyle(height) {
|
|
23
|
+
return {
|
|
24
|
+
position: 'relative',
|
|
25
|
+
height: Math.max(0, height),
|
|
26
|
+
minWidth: 0,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* One of the two canvases, stretched over the figure.
|
|
31
|
+
* @param height - Total height of the figure, in pixels.
|
|
32
|
+
* @returns The canvas's rules.
|
|
33
|
+
*/
|
|
34
|
+
export function parallelCanvasStyle(height) {
|
|
35
|
+
return {
|
|
36
|
+
...PARALLEL_LAYER_STYLE,
|
|
37
|
+
width: '100%',
|
|
38
|
+
height: Math.max(0, height),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** The drawing surface the axes, the bands and the pointer target live in. */
|
|
42
|
+
export const PARALLEL_SVG_STYLE = {
|
|
43
|
+
...PARALLEL_LAYER_STYLE,
|
|
44
|
+
display: 'block',
|
|
45
|
+
overflow: 'visible',
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The layer the axis names sit in. It is HTML rather than SVG text so that a
|
|
49
|
+
* name can carry a tooltip, and it lets every pointer event through so that a
|
|
50
|
+
* brush started under a name still starts.
|
|
51
|
+
*/
|
|
52
|
+
export const PARALLEL_LABELS_STYLE = {
|
|
53
|
+
...PARALLEL_LAYER_STYLE,
|
|
54
|
+
pointerEvents: 'none',
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* One axis name, centred over its axis and taking the pointer back.
|
|
58
|
+
* @param placement - See {@link ParallelLabelPlacement}.
|
|
59
|
+
* @returns The name's rules. A name being dragged follows the pointer and is
|
|
60
|
+
* drawn over its neighbours, so it is never hidden behind the name it is
|
|
61
|
+
* about to change places with.
|
|
62
|
+
*/
|
|
63
|
+
export function parallelLabelStyle(placement) {
|
|
64
|
+
const { left, draggable = false, dx = null } = placement;
|
|
65
|
+
const moving = dx !== null;
|
|
66
|
+
return {
|
|
67
|
+
position: 'absolute',
|
|
68
|
+
zIndex: moving ? 2 : undefined,
|
|
69
|
+
top: 2,
|
|
70
|
+
left,
|
|
71
|
+
transform: dx === null ? 'translateX(-50%)' : `translateX(calc(-50% + ${dx}px))`,
|
|
72
|
+
color: TOKEN.text,
|
|
73
|
+
fontSize: 11,
|
|
74
|
+
fontWeight: 600,
|
|
75
|
+
whiteSpace: 'nowrap',
|
|
76
|
+
pointerEvents: 'auto',
|
|
77
|
+
cursor: draggable ? (moving ? 'grabbing' : 'grab') : undefined,
|
|
78
|
+
opacity: moving ? 0.85 : undefined,
|
|
79
|
+
touchAction: draggable ? 'none' : undefined,
|
|
80
|
+
userSelect: draggable ? 'none' : undefined,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The axis a dragged name would take the place of, marked while it is moving.
|
|
85
|
+
* @param ink - The colour the figure singles things out in.
|
|
86
|
+
* @returns The mark's rules.
|
|
87
|
+
*/
|
|
88
|
+
export function parallelDropMarkStyle(ink) {
|
|
89
|
+
return {
|
|
90
|
+
stroke: ink,
|
|
91
|
+
strokeWidth: 2,
|
|
92
|
+
strokeOpacity: 0.7,
|
|
93
|
+
strokeDasharray: '4 3',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** One tick written out, tabular so a column of them lines up on the point. */
|
|
97
|
+
export const PARALLEL_TICK_LABEL_STYLE = {
|
|
98
|
+
fontSize: 10,
|
|
99
|
+
fontVariantNumeric: 'tabular-nums',
|
|
100
|
+
userSelect: 'none',
|
|
101
|
+
};
|
|
102
|
+
/** How far a tick mark reaches out of the axis, in pixels. */
|
|
103
|
+
export const PARALLEL_TICK_LENGTH = 4;
|
|
104
|
+
/** How far a tick label ends before its axis. */
|
|
105
|
+
export const PARALLEL_TICK_LABEL_INSET = 7;
|
|
106
|
+
/**
|
|
107
|
+
* The interval one brush keeps, filled in the site's own colour.
|
|
108
|
+
* @param ink - The colour to fill and outline it in.
|
|
109
|
+
* @returns The band's rules.
|
|
110
|
+
*/
|
|
111
|
+
export function parallelBandStyle(ink) {
|
|
112
|
+
return {
|
|
113
|
+
fill: ink,
|
|
114
|
+
fillOpacity: 0.16,
|
|
115
|
+
stroke: ink,
|
|
116
|
+
strokeOpacity: 0.55,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Either edge of a band, drawn so the reader can see it can be dragged.
|
|
121
|
+
* @param ink - The colour to draw it in.
|
|
122
|
+
* @returns The handle's rules.
|
|
123
|
+
*/
|
|
124
|
+
export function parallelHandleStyle(ink) {
|
|
125
|
+
return { fill: ink, fillOpacity: 0.9 };
|
|
126
|
+
}
|
|
127
|
+
/** How tall an edge handle is drawn, in pixels. */
|
|
128
|
+
export const PARALLEL_HANDLE_HEIGHT = 3;
|
|
129
|
+
/**
|
|
130
|
+
* The card over the row under the pointer.
|
|
131
|
+
* @param left - Where it sits, in pixels from the figure's left edge.
|
|
132
|
+
* @param top - Where it sits, in pixels from its top edge.
|
|
133
|
+
* @returns The card's rules.
|
|
134
|
+
*/
|
|
135
|
+
export function parallelTooltipStyle(left, top) {
|
|
136
|
+
return {
|
|
137
|
+
position: 'absolute',
|
|
138
|
+
zIndex: 5,
|
|
139
|
+
left,
|
|
140
|
+
top,
|
|
141
|
+
padding: '4px 8px',
|
|
142
|
+
borderRadius: 6,
|
|
143
|
+
background: TOKEN.text,
|
|
144
|
+
color: TOKEN.surface,
|
|
145
|
+
fontSize: 11,
|
|
146
|
+
fontVariantNumeric: 'tabular-nums',
|
|
147
|
+
lineHeight: 1.4,
|
|
148
|
+
pointerEvents: 'none',
|
|
149
|
+
whiteSpace: 'nowrap',
|
|
150
|
+
boxShadow: TOKEN.shadowMedium,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=parallelStyles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallelStyles.js","sourceRoot":"","sources":["../../../src/parallel/ui/parallelStyles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dragging an axis by its name to stand somewhere else.
|
|
3
|
+
*
|
|
4
|
+
* Two columns only show their relationship when they are neighbours, so the
|
|
5
|
+
* order the axes stand in is a question the reader asks, not a decision the
|
|
6
|
+
* caller takes once. The name is the handle: it is the only part of an axis
|
|
7
|
+
* that is not already spoken for by the brush, and it is what a reader reaches
|
|
8
|
+
* for anyway.
|
|
9
|
+
*
|
|
10
|
+
* The gesture moves the name and nothing else. Reordering the axes for real
|
|
11
|
+
* would repaint every line on every frame, which a library of ten thousand
|
|
12
|
+
* molecules cannot afford — so the figure shows where the axis would land and
|
|
13
|
+
* moves it once, on release.
|
|
14
|
+
*/
|
|
15
|
+
import type { KeyboardEvent, PointerEvent } from 'react';
|
|
16
|
+
import type { ParallelAxisLayout } from '../core/parallelAxes.ts';
|
|
17
|
+
/** What {@link useParallelAxisDrag} needs. */
|
|
18
|
+
export interface ParallelAxisDragOptions {
|
|
19
|
+
/** The axes, from left to right, already placed. */
|
|
20
|
+
layouts: readonly ParallelAxisLayout[];
|
|
21
|
+
/**
|
|
22
|
+
* Called with the axis ids in the order the reader put them in.
|
|
23
|
+
* @default undefined — the axes cannot be moved
|
|
24
|
+
*/
|
|
25
|
+
onAxisOrder?: ((ids: readonly string[]) => void) | undefined;
|
|
26
|
+
}
|
|
27
|
+
/** The name being dragged, and where it would land. */
|
|
28
|
+
export interface ParallelAxisDragState {
|
|
29
|
+
/** Which axis is moving, as an index into the axes. */
|
|
30
|
+
from: number;
|
|
31
|
+
/** How far its name has been dragged, in pixels. */
|
|
32
|
+
dx: number;
|
|
33
|
+
/** Which place it would take if let go now. */
|
|
34
|
+
to: number;
|
|
35
|
+
}
|
|
36
|
+
/** The reorder gesture, as the figure renders it. */
|
|
37
|
+
export interface ParallelAxisDrag {
|
|
38
|
+
/** Whether the axes can be moved at all. */
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
/** The name being dragged, or `null` when none is. */
|
|
41
|
+
active: ParallelAxisDragState | null;
|
|
42
|
+
/** Spread onto one axis's name. */
|
|
43
|
+
propsFor: (index: number) => ParallelAxisHandleProps;
|
|
44
|
+
}
|
|
45
|
+
/** What one axis name carries so it can be dragged and stepped with the keys. */
|
|
46
|
+
export interface ParallelAxisHandleProps {
|
|
47
|
+
onPointerDown: (event: PointerEvent<HTMLElement>) => void;
|
|
48
|
+
onPointerMove: (event: PointerEvent<HTMLElement>) => void;
|
|
49
|
+
onPointerUp: (event: PointerEvent<HTMLElement>) => void;
|
|
50
|
+
onPointerCancel: (event: PointerEvent<HTMLElement>) => void;
|
|
51
|
+
onKeyDown: (event: KeyboardEvent<HTMLElement>) => void;
|
|
52
|
+
tabIndex: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Move an axis by dragging its name, or by stepping it with the arrow keys.
|
|
56
|
+
* @param options - See {@link ParallelAxisDragOptions}.
|
|
57
|
+
* @returns The gesture. See {@link ParallelAxisDrag}.
|
|
58
|
+
*/
|
|
59
|
+
export declare function useParallelAxisDrag(options: ParallelAxisDragOptions): ParallelAxisDrag;
|
|
60
|
+
//# sourceMappingURL=useParallelAxisDrag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useParallelAxisDrag.d.ts","sourceRoot":"","sources":["../../../src/parallel/ui/useParallelAxisDrag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAGzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAOlE,8CAA8C;AAC9C,MAAM,WAAW,uBAAuB;IACtC,oDAAoD;IACpD,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC9D;AAED,uDAAuD;AACvD,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,mCAAmC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,uBAAuB,CAAC;CACtD;AAED,iFAAiF;AACjF,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC1D,aAAa,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC1D,WAAW,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACxD,eAAe,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC5D,SAAS,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACvD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAYD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CA2DlB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dragging an axis by its name to stand somewhere else.
|
|
3
|
+
*
|
|
4
|
+
* Two columns only show their relationship when they are neighbours, so the
|
|
5
|
+
* order the axes stand in is a question the reader asks, not a decision the
|
|
6
|
+
* caller takes once. The name is the handle: it is the only part of an axis
|
|
7
|
+
* that is not already spoken for by the brush, and it is what a reader reaches
|
|
8
|
+
* for anyway.
|
|
9
|
+
*
|
|
10
|
+
* The gesture moves the name and nothing else. Reordering the axes for real
|
|
11
|
+
* would repaint every line on every frame, which a library of ten thousand
|
|
12
|
+
* molecules cannot afford — so the figure shows where the axis would land and
|
|
13
|
+
* moves it once, on release.
|
|
14
|
+
*/
|
|
15
|
+
import { useRef, useState } from 'react';
|
|
16
|
+
import { parallelAxisOrder, parallelDropIndex, parallelMoveAxis, } from "../core/parallelOrder.js";
|
|
17
|
+
/** A name that has not been dragged, and is not moving anything. */
|
|
18
|
+
const IDLE = {
|
|
19
|
+
onPointerDown: noop,
|
|
20
|
+
onPointerMove: noop,
|
|
21
|
+
onPointerUp: noop,
|
|
22
|
+
onPointerCancel: noop,
|
|
23
|
+
onKeyDown: noop,
|
|
24
|
+
tabIndex: -1,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Move an axis by dragging its name, or by stepping it with the arrow keys.
|
|
28
|
+
* @param options - See {@link ParallelAxisDragOptions}.
|
|
29
|
+
* @returns The gesture. See {@link ParallelAxisDrag}.
|
|
30
|
+
*/
|
|
31
|
+
export function useParallelAxisDrag(options) {
|
|
32
|
+
const { layouts, onAxisOrder } = options;
|
|
33
|
+
const [active, setActive] = useState(null);
|
|
34
|
+
const originRef = useRef(0);
|
|
35
|
+
function move(from, to) {
|
|
36
|
+
if (onAxisOrder === undefined)
|
|
37
|
+
return;
|
|
38
|
+
const order = parallelAxisOrder(layouts);
|
|
39
|
+
if (to < 0 || to >= order.length || to === from)
|
|
40
|
+
return;
|
|
41
|
+
onAxisOrder(parallelMoveAxis(order, from, to));
|
|
42
|
+
}
|
|
43
|
+
function dropAt(from, dx) {
|
|
44
|
+
const layout = layouts[from];
|
|
45
|
+
if (layout === undefined)
|
|
46
|
+
return from;
|
|
47
|
+
return parallelDropIndex(layout.x + dx, layouts);
|
|
48
|
+
}
|
|
49
|
+
function propsFor(index) {
|
|
50
|
+
if (onAxisOrder === undefined)
|
|
51
|
+
return IDLE;
|
|
52
|
+
return {
|
|
53
|
+
tabIndex: 0,
|
|
54
|
+
onPointerDown: (event) => {
|
|
55
|
+
if (event.button !== 0)
|
|
56
|
+
return;
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
59
|
+
originRef.current = event.clientX;
|
|
60
|
+
setActive({ from: index, dx: 0, to: index });
|
|
61
|
+
},
|
|
62
|
+
onPointerMove: (event) => {
|
|
63
|
+
setActive((current) => {
|
|
64
|
+
if (current?.from !== index)
|
|
65
|
+
return current;
|
|
66
|
+
const dx = event.clientX - originRef.current;
|
|
67
|
+
return { from: index, dx, to: dropAt(index, dx) };
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
onPointerUp: (event) => {
|
|
71
|
+
event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
72
|
+
setActive((current) => {
|
|
73
|
+
if (current !== null && current.from === index) {
|
|
74
|
+
move(current.from, current.to);
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
onPointerCancel: () => {
|
|
80
|
+
setActive(null);
|
|
81
|
+
},
|
|
82
|
+
onKeyDown: (event) => {
|
|
83
|
+
const step = event.key === 'ArrowLeft' ? -1 : event.key === 'ArrowRight' ? 1 : 0;
|
|
84
|
+
if (step === 0)
|
|
85
|
+
return;
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
move(index, index + step);
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return { enabled: onAxisOrder !== undefined, active, propsFor };
|
|
92
|
+
}
|
|
93
|
+
function noop() {
|
|
94
|
+
// A figure whose axes are fixed hands its names no handlers at all.
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=useParallelAxisDrag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useParallelAxisDrag.js","sourceRoot":"","sources":["../../../src/parallel/ui/useParallelAxisDrag.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two canvases, and when they are repainted.
|
|
3
|
+
*
|
|
4
|
+
* Two rather than one, because the mass of lines changes when the data or the
|
|
5
|
+
* brushes do, while the row under the pointer changes on every frame the
|
|
6
|
+
* pointer moves. Repainting ten thousand lines to move one highlight is the
|
|
7
|
+
* difference between a figure that follows the pointer and one that lags it.
|
|
8
|
+
*/
|
|
9
|
+
import type { RefObject } from 'react';
|
|
10
|
+
import type { ParallelAxisLayout } from '../core/parallelAxes.ts';
|
|
11
|
+
import type { ParallelHighlight } from '../core/parallelPaint.ts';
|
|
12
|
+
import type { ParallelInkValues } from './parallelInk.ts';
|
|
13
|
+
/** What {@link useParallelCanvas} needs. */
|
|
14
|
+
export interface ParallelCanvasOptions {
|
|
15
|
+
/** Total width of the figure, in CSS pixels. */
|
|
16
|
+
width: number;
|
|
17
|
+
/** Its total height. */
|
|
18
|
+
height: number;
|
|
19
|
+
/** The axes, from left to right. */
|
|
20
|
+
layouts: readonly ParallelAxisLayout[];
|
|
21
|
+
/** Each axis's column, in the same order. */
|
|
22
|
+
values: ReadonlyArray<ArrayLike<number>>;
|
|
23
|
+
/** How many rows are drawn. */
|
|
24
|
+
count: number;
|
|
25
|
+
/** Which rows the brushes keep, or `null` when they keep every one. */
|
|
26
|
+
included: Uint8Array | null;
|
|
27
|
+
/** Which colour each row takes, or `null` when nothing is colouring them. */
|
|
28
|
+
steps: Uint8Array | null;
|
|
29
|
+
/** The colours a step indexes. */
|
|
30
|
+
palette: readonly string[];
|
|
31
|
+
/** The rows drawn over the mass, the last one on top. */
|
|
32
|
+
highlights: readonly ParallelHighlight[];
|
|
33
|
+
/** The colours to paint with. */
|
|
34
|
+
ink: ParallelInkValues;
|
|
35
|
+
}
|
|
36
|
+
/** The two canvases a figure stacks. */
|
|
37
|
+
export interface ParallelCanvases {
|
|
38
|
+
/** The mass of lines, underneath. */
|
|
39
|
+
lines: RefObject<HTMLCanvasElement | null>;
|
|
40
|
+
/** The singled-out rows, over them. */
|
|
41
|
+
marks: RefObject<HTMLCanvasElement | null>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Keep both canvases sized to the device pixel grid and painted.
|
|
45
|
+
* @param options - See {@link ParallelCanvasOptions}.
|
|
46
|
+
* @returns The two refs to hand to the `<canvas>` elements.
|
|
47
|
+
*/
|
|
48
|
+
export declare function useParallelCanvas(options: ParallelCanvasOptions): ParallelCanvases;
|
|
49
|
+
//# sourceMappingURL=useParallelCanvas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useParallelCanvas.d.ts","sourceRoot":"","sources":["../../../src/parallel/ui/useParallelCanvas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAOlE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,kCAAkC;IAClC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,yDAAyD;IACzD,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACzC,iCAAiC;IACjC,GAAG,EAAE,iBAAiB,CAAC;CACxB;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,KAAK,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC3C,uCAAuC;IACvC,KAAK,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CAC5C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,qBAAqB,GAC7B,gBAAgB,CA0ClB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two canvases, and when they are repainted.
|
|
3
|
+
*
|
|
4
|
+
* Two rather than one, because the mass of lines changes when the data or the
|
|
5
|
+
* brushes do, while the row under the pointer changes on every frame the
|
|
6
|
+
* pointer moves. Repainting ten thousand lines to move one highlight is the
|
|
7
|
+
* difference between a figure that follows the pointer and one that lags it.
|
|
8
|
+
*/
|
|
9
|
+
import { useEffect, useRef } from 'react';
|
|
10
|
+
import { paintParallelHighlights, paintParallelLines, preparePlotCanvas, } from "../core/parallelPaint.js";
|
|
11
|
+
/**
|
|
12
|
+
* Keep both canvases sized to the device pixel grid and painted.
|
|
13
|
+
* @param options - See {@link ParallelCanvasOptions}.
|
|
14
|
+
* @returns The two refs to hand to the `<canvas>` elements.
|
|
15
|
+
*/
|
|
16
|
+
export function useParallelCanvas(options) {
|
|
17
|
+
const { width, height, layouts, values, count } = options;
|
|
18
|
+
const { included, steps, palette, highlights, ink } = options;
|
|
19
|
+
const lines = useRef(null);
|
|
20
|
+
const marks = useRef(null);
|
|
21
|
+
const { line, excluded, includedAlpha, halo } = ink;
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const context = preparePlotCanvas(lines.current, width, height);
|
|
24
|
+
if (context === null)
|
|
25
|
+
return;
|
|
26
|
+
paintParallelLines(context, {
|
|
27
|
+
layouts,
|
|
28
|
+
values,
|
|
29
|
+
count,
|
|
30
|
+
included,
|
|
31
|
+
steps,
|
|
32
|
+
palette,
|
|
33
|
+
line,
|
|
34
|
+
excluded,
|
|
35
|
+
includedAlpha,
|
|
36
|
+
});
|
|
37
|
+
}, [
|
|
38
|
+
width,
|
|
39
|
+
height,
|
|
40
|
+
layouts,
|
|
41
|
+
values,
|
|
42
|
+
count,
|
|
43
|
+
included,
|
|
44
|
+
steps,
|
|
45
|
+
palette,
|
|
46
|
+
line,
|
|
47
|
+
excluded,
|
|
48
|
+
includedAlpha,
|
|
49
|
+
]);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const context = preparePlotCanvas(marks.current, width, height);
|
|
52
|
+
if (context === null)
|
|
53
|
+
return;
|
|
54
|
+
paintParallelHighlights(context, { highlights, layouts, values, halo });
|
|
55
|
+
}, [width, height, highlights, layouts, values, halo]);
|
|
56
|
+
return { lines, marks };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=useParallelCanvas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useParallelCanvas.js","sourceRoot":"","sources":["../../../src/parallel/ui/useParallelCanvas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAoClC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA8B;IAE9B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC1D,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAC9C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;IAEpD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAChE,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO;QAC7B,kBAAkB,CAAC,OAAO,EAAE;YAC1B,OAAO;YACP,MAAM;YACN,KAAK;YACL,QAAQ;YACR,KAAK;YACL,OAAO;YACP,IAAI;YACJ,QAAQ;YACR,aAAa;SACd,CAAC,CAAC;IACL,CAAC,EAAE;QACD,KAAK;QACL,MAAM;QACN,OAAO;QACP,MAAM;QACN,KAAK;QACL,QAAQ;QACR,KAAK;QACL,OAAO;QACP,IAAI;QACJ,QAAQ;QACR,aAAa;KACd,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAChE,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO;QAC7B,uBAAuB,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEvD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One pointer over the whole figure, serving both the brush and the hover.
|
|
3
|
+
*
|
|
4
|
+
* A hook cannot be called inside a `map`, so a brush per axis would have to
|
|
5
|
+
* live in refs and be attached by hand; one surface that works out from the
|
|
6
|
+
* press which axis was grabbed has no such problem, and it gives the hover
|
|
7
|
+
* search the same once-a-frame coalescing the drag already pays for.
|
|
8
|
+
*
|
|
9
|
+
* The band follows the pointer live and the interval is reported on release
|
|
10
|
+
* only: a table filtering on the reported interval is asked to re-render once
|
|
11
|
+
* per gesture rather than sixty times a second.
|
|
12
|
+
*/
|
|
13
|
+
import type { MouseEvent as ReactMouseEvent } from 'react';
|
|
14
|
+
import type { ScatterSurfaceProps } from '../../scatter/ui/lassoGesture.ts';
|
|
15
|
+
import type { ParallelAxisLayout } from '../core/parallelAxes.ts';
|
|
16
|
+
import type { ParallelBand } from '../core/parallelBrush.ts';
|
|
17
|
+
import type { ParallelRange, ParallelRanges } from '../core/parallelTypes.ts';
|
|
18
|
+
/** What {@link useParallelGesture} needs. */
|
|
19
|
+
export interface ParallelGestureOptions {
|
|
20
|
+
/** The axes, from left to right. */
|
|
21
|
+
layouts: readonly ParallelAxisLayout[];
|
|
22
|
+
/** Each axis's column, in the same order. */
|
|
23
|
+
values: ReadonlyArray<ArrayLike<number>>;
|
|
24
|
+
/** How many rows are drawn. */
|
|
25
|
+
count: number;
|
|
26
|
+
/** Height of the drawing area, in pixels. */
|
|
27
|
+
innerHeight: number;
|
|
28
|
+
/** Which rows a brush keeps, so an excluded line cannot be pointed at. */
|
|
29
|
+
included: Uint8Array | null;
|
|
30
|
+
/** The intervals in force, whoever owns them. */
|
|
31
|
+
ranges: ParallelRanges;
|
|
32
|
+
/**
|
|
33
|
+
* Whether one axis may keep several intervals at once.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
several?: boolean | undefined;
|
|
37
|
+
/** Called when a brush is released, with every interval that axis now keeps. */
|
|
38
|
+
onRangeChange: (axisId: string, ranges: readonly ParallelRange[]) => void;
|
|
39
|
+
/** Called on every frame a band grows. */
|
|
40
|
+
onRangePreview?: ((axisId: string, ranges: readonly ParallelRange[]) => void) | undefined;
|
|
41
|
+
/** The row the caller says is hovered, if it owns that. */
|
|
42
|
+
hovered?: number | undefined;
|
|
43
|
+
/** Called with the row under the pointer, or `-1`. */
|
|
44
|
+
onHoverChange?: ((index: number) => void) | undefined;
|
|
45
|
+
/** Called when a line is clicked, with the row, or `-1` for empty ground. */
|
|
46
|
+
onRowClick?: ((index: number) => void) | undefined;
|
|
47
|
+
}
|
|
48
|
+
/** The gesture, as the figure renders it. */
|
|
49
|
+
export interface ParallelGesture {
|
|
50
|
+
/** Spread onto the transparent rectangle laid over the figure. */
|
|
51
|
+
surface: ScatterSurfaceProps;
|
|
52
|
+
/** Put on the same rectangle, for the click that picks a line. */
|
|
53
|
+
onClick: (event: ReactMouseEvent<Element>) => void;
|
|
54
|
+
/** The bands to draw on each axis, the one being dragged included. */
|
|
55
|
+
bands: ReadonlyMap<string, ParallelBand[]>;
|
|
56
|
+
/** The row under the pointer, or `-1`. */
|
|
57
|
+
hovered: number;
|
|
58
|
+
/** Where the pointer is in the figure, or `null` when it is away. */
|
|
59
|
+
pointer: {
|
|
60
|
+
x: number;
|
|
61
|
+
y: number;
|
|
62
|
+
} | null;
|
|
63
|
+
/** Whether a band is being dragged right now. */
|
|
64
|
+
brushing: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The brush and the hover, over one surface.
|
|
68
|
+
* @param options - See {@link ParallelGestureOptions}.
|
|
69
|
+
* @returns The gesture. See {@link ParallelGesture}.
|
|
70
|
+
*/
|
|
71
|
+
export declare function useParallelGesture(options: ParallelGestureOptions): ParallelGesture;
|
|
72
|
+
//# sourceMappingURL=useParallelGesture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useParallelGesture.d.ts","sourceRoot":"","sources":["../../../src/parallel/ui/useParallelGesture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,KAAK,EACV,mBAAmB,EAEpB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,0BAA0B,CAAC;AAQhF,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAW9E,6CAA6C;AAC7C,MAAM,WAAW,sBAAsB;IACrC,oCAAoC;IACpC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,iDAAiD;IACjD,MAAM,EAAE,cAAc,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,gFAAgF;IAChF,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,aAAa,EAAE,KAAK,IAAI,CAAC;IAC1E,0CAA0C;IAC1C,cAAc,CAAC,EACb,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,aAAa,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3E,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,sDAAsD;IACtD,aAAa,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACtD,6EAA6E;IAC7E,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACpD;AAED,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,OAAO,EAAE,mBAAmB,CAAC;IAC7B,kEAAkE;IAClE,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACnD,sEAAsE;IACtE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3C,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,OAAO,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzC,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAmJjB"}
|