@neo4j-nvl/react 1.2.1 → 2.0.0-1e695738
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/CHANGELOG.md +66 -0
- package/README.md +6 -6
- package/lib/basic-wrapper/BasicNvlWrapper.d.ts +30 -41
- package/lib/basic-wrapper/BasicNvlWrapper.js +116 -149
- package/lib/index.d.ts +5 -8
- package/lib/index.js +3 -3
- package/lib/interactive-nvl-wrapper/InteractionHandlers.d.ts +8 -8
- package/lib/interactive-nvl-wrapper/InteractionHandlers.js +62 -57
- package/lib/interactive-nvl-wrapper/InteractiveNvlWrapper.d.ts +5 -5
- package/lib/interactive-nvl-wrapper/InteractiveNvlWrapper.js +54 -42
- package/lib/interactive-nvl-wrapper/hooks.d.ts +4 -4
- package/lib/interactive-nvl-wrapper/hooks.js +24 -27
- package/lib/interactive-nvl-wrapper/types.d.ts +9 -9
- package/lib/interactive-nvl-wrapper/types.js +0 -1
- package/lib/static-picture-wrapper/StaticPictureWrapper.d.ts +15 -15
- package/lib/static-picture-wrapper/StaticPictureWrapper.js +71 -55
- package/lib/utils/constants.d.ts +1 -1
- package/lib/utils/constants.js +4 -2
- package/lib/utils/graph-comparison.d.ts +5 -5
- package/lib/utils/graph-comparison.js +53 -68
- package/lib/utils/hooks.d.ts +2 -2
- package/lib/utils/hooks.js +10 -11
- package/package.json +26 -11
- package/lib/__tests__/BasicNvlWrapper.test.d.ts +0 -1
- package/lib/__tests__/BasicNvlWrapper.test.js +0 -135
- package/lib/__tests__/InteractiveNvlWrapper.test.d.ts +0 -1
- package/lib/__tests__/InteractiveNvlWrapper.test.js +0 -392
- package/lib/__tests__/StaticPictureWrapper.test.d.ts +0 -1
- package/lib/__tests__/StaticPictureWrapper.test.js +0 -85
- package/lib/__tests__/index.test.d.ts +0 -1
- package/lib/__tests__/index.test.js +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,72 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to NVL will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
4
4
|
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
This release adds keyboard actions for moving nodes, ships an agent skill for NVL, and makes all packages loadable as ESM in Node.js without a bundler.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* Keyboard interaction handler actions for moving nodes with the arrow keys, with a new `onNodeMove` callback.
|
|
12
|
+
* Agent skill files for NVL, shipped with `@neo4j-nvl/base`.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
* `@neo4j-nvl/react` and `@neo4j-nvl/interaction-handlers` are now spec-compliant ESM with `"type": "module"` and an `exports` map. Note that deep imports into `lib/` will no longer work.
|
|
17
|
+
* Replaced `lodash` with `lodash-es` in `@neo4j-nvl/react` and `@neo4j-nvl/interaction-handlers` (Jest users transforming `@neo4j-nvl/*` also need to transform `lodash-es`).
|
|
18
|
+
* Type declarations of `@neo4j-nvl/base` now resolve correctly with `moduleResolution: "nodenext"`.
|
|
19
|
+
* Container resizing uses the native `ResizeObserver` instead of the `resizelistener` dependency.
|
|
20
|
+
* Default `height` and `outline` styles of NVL containers can now be overridden by stylesheets.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
* `fit()` zooms out beyond `minZoom` when `allowDynamicMinZoom` is `true` and the graph does not fit the viewport.
|
|
25
|
+
* `onHover` callback's `element` parameter is now typed as possibly `undefined`, matching the runtime behaviour.
|
|
26
|
+
* Added missing caret for the React 18 peer dependency range in `@neo4j-nvl/react`.
|
|
27
|
+
|
|
28
|
+
## [2.0.0] - 2026-09-15
|
|
29
|
+
|
|
30
|
+
This 2.0.0 major release upgrades NVL to WebGL2 for both the renderer and physics engine, unlocking major performance improvements. It also adds new clustering capabilities with visual decorations to the force directed and hierarchical layouts.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
* `clusterBy` layout option for both force-directed and hierarchical layouts.
|
|
35
|
+
* Cluster interaction API for handling events on clustered elements.
|
|
36
|
+
* Support for rendering icons and arrowheads in the WebGL renderer.
|
|
37
|
+
* Configurable minimum and maximum FPS caps for the rendering loop.
|
|
38
|
+
* Circle seeding option for the physics layout.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
* Upgraded the WebGL renderer and physics engine to use WebGL2.
|
|
43
|
+
* Migrated the hierarchical layout engine dependency to `@dagrejs/dagre` 3.1.1.
|
|
44
|
+
* Greatly optimized physics layout performance and stabalisation speed.
|
|
45
|
+
* Improved rendering performance.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
* Added safety guards to harden the renderer against missing X/Y coordinate data.
|
|
50
|
+
|
|
51
|
+
### Removed
|
|
52
|
+
|
|
53
|
+
* **BREAKING:** Removed deprecated Cytoscape support settings.
|
|
54
|
+
* **BREAKING:** Removed deprecated standalone `layout` and `layoutOptions` props from the React wrappers in favour of the same props inside `NvlOptions`.
|
|
55
|
+
* **BREAKING:** Removed deprecated `intelWorkaround` layout setting APIs.
|
|
56
|
+
* **BREAKING:** Removed deprecated `onZoom` callback in favour of `onZoomAndPan`.
|
|
57
|
+
|
|
58
|
+
## [1.2.2] - 2026-09-11
|
|
59
|
+
|
|
60
|
+
This 1.2.2 patch release adds migration warnings for breaking changes planned for the next major release.
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
* `styling.overlayLineColor` for overlay UI stroke color (e.g. minimap viewport box).
|
|
64
|
+
* Note in documentation on changes to client/screen coordinates on `NVL.getNodes()` and `onLayoutStep` `x`/`y`, moving screen coordinates to `clientPosition`.
|
|
65
|
+
|
|
66
|
+
### Deprecated
|
|
67
|
+
* `styling.minimapViewportBoxColor` in favour of `styling.overlayLineColor` (old option still works as a fallback).
|
|
68
|
+
* `ForceDirectedOptions.intelWorkaround` (upgrade to WebGL2 in the next major release removes the need for it).
|
|
69
|
+
* Top-level React wrapper `layout` / `layoutOptions` props in favour of `nvlOptions.layout` / `nvlOptions.layoutOptions`.
|
|
70
|
+
|
|
5
71
|
## [1.2.1] - 2026-07-28
|
|
6
72
|
|
|
7
73
|
This 1.2.1 patch release contains several fixes and accessibility improvements.
|
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ const nvlRef = useRef<NVL>()
|
|
|
47
47
|
rels={[{ from: '0', to: '1', id: '10' }]}
|
|
48
48
|
ref={nvlRef}
|
|
49
49
|
/>
|
|
50
|
-
<button onClick={() => nvlRef.current?.
|
|
50
|
+
<button onClick={() => nvlRef.current?.fit(['0', '1'])}>Zoom to Nodes</button>
|
|
51
51
|
</div>
|
|
52
52
|
```
|
|
53
53
|
|
|
@@ -59,18 +59,18 @@ Events can be turned on and off by passing a callback function or a boolean valu
|
|
|
59
59
|
`mouseEventCallbacks` prop. The callback function will be called with the event's arguments when the event is triggered. If a boolean value is passed, the event will be turned on or off accordingly.
|
|
60
60
|
|
|
61
61
|
```tsx
|
|
62
|
-
const [
|
|
62
|
+
const [boxSelect, setBoxSelect] = useState(false)
|
|
63
63
|
<>
|
|
64
|
-
<button onClick={() =>
|
|
65
|
-
{
|
|
64
|
+
<button onClick={() => setBoxSelect(!boxSelect)}>
|
|
65
|
+
{boxSelect ? 'Disable' : 'Enable'} box select
|
|
66
66
|
</button>
|
|
67
67
|
<InteractiveNvlWrapper
|
|
68
68
|
nodes={nodes}
|
|
69
69
|
rels={relationships}
|
|
70
70
|
mouseEventCallbacks={{
|
|
71
|
-
onHover: (element) => console.log(element),
|
|
71
|
+
onHover: (element, hitElements) => console.log(element, hitElements),
|
|
72
72
|
onNodeClick: (node) => console.log(node),
|
|
73
|
-
|
|
73
|
+
onBoxSelect: boxSelect
|
|
74
74
|
}}
|
|
75
75
|
/>
|
|
76
76
|
</>
|
|
@@ -1,47 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { type HTMLProps } from 'react';
|
|
1
|
+
import NVL, { ExternalCallbacks, Node, NvlOptions, Relationship } from "@neo4j-nvl/base";
|
|
2
|
+
import { HTMLProps } from "react";
|
|
4
3
|
/**
|
|
5
4
|
* The properties that can be passed to the {@link BasicNvlWrapper} component.
|
|
6
5
|
*/
|
|
7
6
|
export interface BasicReactWrapperProps {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* @remarks If both zoom and pan are provided, the setZoomAndPan method will be used.
|
|
36
|
-
*/
|
|
37
|
-
pan?: {
|
|
38
|
-
/** The x coordinate of the pan. */
|
|
39
|
-
x: number;
|
|
40
|
-
/** The y coordinate of the pan. */
|
|
41
|
-
y: number;
|
|
42
|
-
};
|
|
43
|
-
/** A callback to handle any errors that happen during NVL initialization */
|
|
44
|
-
onInitializationError?: (error: unknown) => void;
|
|
7
|
+
/** The nodes of the graph of type Node[] */
|
|
8
|
+
nodes: Node[];
|
|
9
|
+
/** The rels of the graph of type Relationship[] */
|
|
10
|
+
rels: Relationship[];
|
|
11
|
+
/** an Object containing functions for callbacks on certain actions */
|
|
12
|
+
nvlCallbacks?: ExternalCallbacks;
|
|
13
|
+
/** An object containing options for the Nvl instance */
|
|
14
|
+
nvlOptions?: NvlOptions;
|
|
15
|
+
/** Sets the positions of the nodes in the graph using the setNodePositions method. */
|
|
16
|
+
positions?: Node[];
|
|
17
|
+
/**
|
|
18
|
+
* Sets the zoom level of the viewport using the setZoom method.
|
|
19
|
+
* @remarks If both zoom and pan are provided, the setZoomAndPan method will be used.
|
|
20
|
+
*/
|
|
21
|
+
zoom?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Sets the pan coordinates of the viewport using the setPan method.
|
|
24
|
+
* @remarks If both zoom and pan are provided, the setZoomAndPan method will be used.
|
|
25
|
+
*/
|
|
26
|
+
pan?: {
|
|
27
|
+
/** The x coordinate of the pan. */
|
|
28
|
+
x: number;
|
|
29
|
+
/** The y coordinate of the pan. */
|
|
30
|
+
y: number;
|
|
31
|
+
};
|
|
32
|
+
/** A callback to handle any errors that happen during NVL initialization */
|
|
33
|
+
onInitializationError?: (error: unknown) => void;
|
|
45
34
|
}
|
|
46
35
|
/**
|
|
47
36
|
*
|
|
@@ -51,4 +40,4 @@ export interface BasicReactWrapperProps {
|
|
|
51
40
|
*
|
|
52
41
|
* For examples, head to the {@link https://neo4j.com/docs/nvl/current/react-wrappers/#_basic_react_wrapper Basic React wrapper documentation page}.
|
|
53
42
|
*/
|
|
54
|
-
export declare const BasicNvlWrapper: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Omit<BasicReactWrapperProps & HTMLProps<HTMLDivElement>, "ref"> & import("react").RefAttributes<Partial<Pick<NVL, "restart" | "
|
|
43
|
+
export declare const BasicNvlWrapper: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Omit<BasicReactWrapperProps & HTMLProps<HTMLDivElement>, "ref"> & import("react").RefAttributes<Partial<Pick<NVL, "restart" | "addAndUpdateElementsInGraph" | "getSelectedNodes" | "getSelectedRelationships" | "removeNodesWithIds" | "removeRelationshipsWithIds" | "getNodes" | "getRelationships" | "getNodeById" | "getRelationshipById" | "getPositionById" | "getCurrentOptions" | "destroy" | "deselectAll" | "fit" | "resetZoom" | "setRenderer" | "setDisableWebGL" | "pinNode" | "unPinNode" | "setLayout" | "setLayoutOptions" | "getNodesOnScreen" | "getNodePositions" | "setNodePositions" | "isLayoutMoving" | "saveToFile" | "saveToSvg" | "getImageDataUrl" | "getSvgDataUrl" | "saveFullGraphToLargeFile" | "getZoomLimits" | "setZoom" | "getScale" | "getPan" | "getHits" | "getContainer">>>>>;
|
|
@@ -1,151 +1,118 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { BASIC_WRAPPER_ID } from "../utils/constants.js";
|
|
2
|
+
import { getMapDifferences, getNodeAttributeDifferences } from "../utils/graph-comparison.js";
|
|
3
|
+
import { useDeepCompareEffect } from "../utils/hooks.js";
|
|
4
|
+
import NVL from "@neo4j-nvl/base";
|
|
5
|
+
import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
// src/basic-wrapper/BasicNvlWrapper.tsx
|
|
7
8
|
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
nvlRef.current.setRenderer(nvlOptions.renderer);
|
|
117
|
-
}, [nvlOptions.renderer]);
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
if (nvlRef.current === null || nvlOptions.disableWebGL === undefined) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
nvlRef.current.setDisableWebGL(nvlOptions.disableWebGL);
|
|
123
|
-
}, [nvlOptions.disableWebGL]);
|
|
124
|
-
useEffect(() => {
|
|
125
|
-
if (nvlRef.current === null || positions.length === 0) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
nvlRef.current.setNodePositions(positions);
|
|
129
|
-
}, [positions]);
|
|
130
|
-
useEffect(() => {
|
|
131
|
-
if (nvlRef.current === null) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
const currentZoom = prevZoomRef.current;
|
|
135
|
-
const currentPan = prevPanRef.current;
|
|
136
|
-
const zoomHasChanged = zoom !== undefined && zoom !== currentZoom;
|
|
137
|
-
const panHasChanged = pan !== undefined && (pan.x !== currentPan?.x || pan.y !== currentPan.y);
|
|
138
|
-
if (zoomHasChanged && panHasChanged) {
|
|
139
|
-
nvlRef.current.setZoomAndPan(zoom, pan.x, pan.y);
|
|
140
|
-
}
|
|
141
|
-
else if (zoomHasChanged) {
|
|
142
|
-
nvlRef.current.setZoom(zoom);
|
|
143
|
-
}
|
|
144
|
-
else if (panHasChanged) {
|
|
145
|
-
nvlRef.current.setPan(pan.x, pan.y);
|
|
146
|
-
}
|
|
147
|
-
prevZoomRef.current = zoom;
|
|
148
|
-
prevPanRef.current = pan;
|
|
149
|
-
}, [zoom, pan]);
|
|
150
|
-
return _jsx("div", { id: BASIC_WRAPPER_ID, ref: containerRef, style: { height: '100%', outline: '0' }, ...nvlEvents });
|
|
9
|
+
*
|
|
10
|
+
* A basic React wrapper that wraps the NVL base library within a React component.
|
|
11
|
+
* It takes the class' arguments as properties, which are passed to the NVL constructor.
|
|
12
|
+
* Any changes in properties will be reflected in the NVL instance by calling the corresponding methods.
|
|
13
|
+
*
|
|
14
|
+
* For examples, head to the {@link https://neo4j.com/docs/nvl/current/react-wrappers/#_basic_react_wrapper Basic React wrapper documentation page}.
|
|
15
|
+
*/
|
|
16
|
+
const BasicNvlWrapper = memo(forwardRef(({ nodes, rels, nvlCallbacks = {}, nvlOptions = {}, positions = [], zoom, pan, onInitializationError, ...nvlEvents }, ref) => {
|
|
17
|
+
const nvlRef = useRef(null);
|
|
18
|
+
const prevZoomRef = useRef(void 0);
|
|
19
|
+
const prevPanRef = useRef(void 0);
|
|
20
|
+
useImperativeHandle(ref, () => {
|
|
21
|
+
return Object.getOwnPropertyNames(NVL.prototype).reduce((current, method) => ({
|
|
22
|
+
...current,
|
|
23
|
+
[method]: (...args) => {
|
|
24
|
+
if (nvlRef.current === null) return null;
|
|
25
|
+
return nvlRef.current[method](...args);
|
|
26
|
+
}
|
|
27
|
+
}), {});
|
|
28
|
+
});
|
|
29
|
+
const containerRef = useRef(null);
|
|
30
|
+
const [currentNodes, setCurrentNodes] = useState(nodes);
|
|
31
|
+
const [currentRels, setCurrentRels] = useState(rels);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
return () => {
|
|
34
|
+
nvlRef.current?.destroy();
|
|
35
|
+
nvlRef.current = null;
|
|
36
|
+
prevZoomRef.current = void 0;
|
|
37
|
+
prevPanRef.current = void 0;
|
|
38
|
+
};
|
|
39
|
+
}, []);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
let newNvl = null;
|
|
42
|
+
const minimapContainerIsReady = "minimapContainer" in nvlOptions ? nvlOptions.minimapContainer !== null : true;
|
|
43
|
+
if (containerRef.current !== null && minimapContainerIsReady) {
|
|
44
|
+
if (nvlRef.current === null) try {
|
|
45
|
+
newNvl = new NVL(containerRef.current, currentNodes, currentRels, nvlOptions, nvlCallbacks);
|
|
46
|
+
nvlRef.current = newNvl;
|
|
47
|
+
setCurrentRels(rels);
|
|
48
|
+
setCurrentNodes(nodes);
|
|
49
|
+
} catch (e) {
|
|
50
|
+
if (typeof onInitializationError === "function") onInitializationError(e);
|
|
51
|
+
else throw e;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}, [containerRef.current, nvlOptions.minimapContainer]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (nvlRef.current === null) return;
|
|
57
|
+
const nodeChanges = getMapDifferences(currentNodes, nodes);
|
|
58
|
+
const nodeDiff = getNodeAttributeDifferences(currentNodes, nodes);
|
|
59
|
+
const relChanges = getMapDifferences(currentRels, rels);
|
|
60
|
+
if (nodeChanges.added.length === 0 && nodeChanges.removed.length === 0 && nodeDiff.length === 0 && relChanges.added.length === 0 && relChanges.removed.length === 0 && relChanges.updated.length === 0) return;
|
|
61
|
+
setCurrentRels(rels);
|
|
62
|
+
setCurrentNodes(nodes);
|
|
63
|
+
const nodesToAddAndUpdate = [...nodeChanges.added, ...nodeDiff];
|
|
64
|
+
const relsToAddAndUpdate = [...relChanges.added, ...relChanges.updated];
|
|
65
|
+
nvlRef.current.addAndUpdateElementsInGraph(nodesToAddAndUpdate, relsToAddAndUpdate);
|
|
66
|
+
const relationshipsToRemove = relChanges.removed.map((r) => r.id);
|
|
67
|
+
const nodesToRemove = nodeChanges.removed.map((n) => n.id);
|
|
68
|
+
nvlRef.current.removeRelationshipsWithIds(relationshipsToRemove);
|
|
69
|
+
nvlRef.current.removeNodesWithIds(nodesToRemove);
|
|
70
|
+
}, [
|
|
71
|
+
currentNodes,
|
|
72
|
+
currentRels,
|
|
73
|
+
nodes,
|
|
74
|
+
rels
|
|
75
|
+
]);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (nvlRef.current === null || nvlOptions.layout === void 0) return;
|
|
78
|
+
nvlRef.current.setLayout(nvlOptions.layout);
|
|
79
|
+
}, [nvlOptions.layout]);
|
|
80
|
+
useDeepCompareEffect(() => {
|
|
81
|
+
if (nvlRef.current === null || nvlOptions.layoutOptions === void 0) return;
|
|
82
|
+
nvlRef.current.setLayoutOptions(nvlOptions.layoutOptions);
|
|
83
|
+
}, [nvlOptions.layoutOptions]);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (nvlRef.current === null || nvlOptions.renderer === void 0) return;
|
|
86
|
+
nvlRef.current.setRenderer(nvlOptions.renderer);
|
|
87
|
+
}, [nvlOptions.renderer]);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (nvlRef.current === null || nvlOptions.disableWebGL === void 0) return;
|
|
90
|
+
nvlRef.current.setDisableWebGL(nvlOptions.disableWebGL);
|
|
91
|
+
}, [nvlOptions.disableWebGL]);
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (nvlRef.current === null || positions.length === 0) return;
|
|
94
|
+
nvlRef.current.setNodePositions(positions);
|
|
95
|
+
}, [positions]);
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (nvlRef.current === null) return;
|
|
98
|
+
const currentZoom = prevZoomRef.current;
|
|
99
|
+
const currentPan = prevPanRef.current;
|
|
100
|
+
const zoomHasChanged = zoom !== void 0 && zoom !== currentZoom;
|
|
101
|
+
const panHasChanged = pan !== void 0 && (pan.x !== currentPan?.x || pan.y !== currentPan.y);
|
|
102
|
+
if (zoomHasChanged && panHasChanged) nvlRef.current.setZoomAndPan(zoom, pan.x, pan.y);
|
|
103
|
+
else if (zoomHasChanged) nvlRef.current.setZoom(zoom);
|
|
104
|
+
else if (panHasChanged) nvlRef.current.setPan(pan.x, pan.y);
|
|
105
|
+
prevZoomRef.current = zoom;
|
|
106
|
+
prevPanRef.current = pan;
|
|
107
|
+
}, [zoom, pan]);
|
|
108
|
+
return /* @__PURE__ */ jsx("div", {
|
|
109
|
+
id: BASIC_WRAPPER_ID,
|
|
110
|
+
ref: containerRef,
|
|
111
|
+
style: {
|
|
112
|
+
height: "100%",
|
|
113
|
+
outline: "0"
|
|
114
|
+
},
|
|
115
|
+
...nvlEvents
|
|
116
|
+
});
|
|
151
117
|
}));
|
|
118
|
+
export { BasicNvlWrapper };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { BasicNvlWrapper } from
|
|
2
|
-
import
|
|
3
|
-
import { InteractiveNvlWrapper } from
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import { StaticPictureWrapper } from './static-picture-wrapper/StaticPictureWrapper';
|
|
7
|
-
export { BasicNvlWrapper, InteractiveNvlWrapper, StaticPictureWrapper };
|
|
8
|
-
export type { MouseEventCallbacks, KeyboardEventCallbacks, MouseEvent, KeyboardEvent, BasicReactWrapperProps, InteractionOptions, InteractiveNvlWrapperProps, StaticPictureWrapperProps };
|
|
1
|
+
import { BasicNvlWrapper, BasicReactWrapperProps } from "./basic-wrapper/BasicNvlWrapper.js";
|
|
2
|
+
import { InteractionOptions, InteractiveNvlWrapperProps, KeyboardEvent, KeyboardEventCallbacks, MouseEvent, MouseEventCallbacks } from "./interactive-nvl-wrapper/types.js";
|
|
3
|
+
import { InteractiveNvlWrapper } from "./interactive-nvl-wrapper/InteractiveNvlWrapper.js";
|
|
4
|
+
import { StaticPictureWrapper, StaticPictureWrapperProps } from "./static-picture-wrapper/StaticPictureWrapper.js";
|
|
5
|
+
export { BasicNvlWrapper, type BasicReactWrapperProps, type InteractionOptions, InteractiveNvlWrapper, type InteractiveNvlWrapperProps, type KeyboardEvent, type KeyboardEventCallbacks, type MouseEvent, type MouseEventCallbacks, StaticPictureWrapper, type StaticPictureWrapperProps };
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BasicNvlWrapper } from
|
|
2
|
-
import { InteractiveNvlWrapper } from
|
|
3
|
-
import { StaticPictureWrapper } from
|
|
1
|
+
import { BasicNvlWrapper } from "./basic-wrapper/BasicNvlWrapper.js";
|
|
2
|
+
import { InteractiveNvlWrapper } from "./interactive-nvl-wrapper/InteractiveNvlWrapper.js";
|
|
3
|
+
import { StaticPictureWrapper } from "./static-picture-wrapper/StaticPictureWrapper.js";
|
|
4
4
|
export { BasicNvlWrapper, InteractiveNvlWrapper, StaticPictureWrapper };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { InteractionOptions, KeyboardEventCallbacks, MouseEventCallbacks } from "./types.js";
|
|
2
|
+
import NVL from "@neo4j-nvl/base";
|
|
3
|
+
import { MutableRefObject } from "react";
|
|
4
4
|
interface InteractionHandlersProps {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
nvlRef: MutableRefObject<NVL | null>;
|
|
6
|
+
mouseEventCallbacks: MouseEventCallbacks;
|
|
7
|
+
keyboardEventCallbacks: KeyboardEventCallbacks;
|
|
8
|
+
interactionOptions: InteractionOptions;
|
|
9
9
|
}
|
|
10
10
|
export declare const InteractionHandlers: React.FC<InteractionHandlersProps>;
|
|
11
|
-
export {};
|
|
11
|
+
export {};
|