@neo4j-ndl/react-graph 2.1.13 → 2.1.14
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/lib/cjs/graph-visualization.js +10 -6
- package/lib/cjs/graph-visualization.js.map +1 -1
- package/lib/cjs/use-managed-node-state.js +7 -7
- package/lib/cjs/use-managed-node-state.js.map +1 -1
- package/lib/esm/graph-visualization.js +10 -6
- package/lib/esm/graph-visualization.js.map +1 -1
- package/lib/esm/use-managed-node-state.js +7 -7
- package/lib/esm/use-managed-node-state.js.map +1 -1
- package/lib/types/graph-visualization.d.ts +11 -4
- package/lib/types/graph-visualization.d.ts.map +1 -1
- package/lib/types/use-managed-node-state.d.ts +2 -2
- package/lib/types/use-managed-node-state.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -98,6 +98,7 @@ exports.DEFAULT_NVL_OPTIONS = {
|
|
|
98
98
|
maxZoom: 3,
|
|
99
99
|
minZoom: 0.05,
|
|
100
100
|
relationshipThreshold: 0.55,
|
|
101
|
+
renderer: 'canvas',
|
|
101
102
|
};
|
|
102
103
|
const DEFAULT_COMPONENTS = {
|
|
103
104
|
bottomLeftIsland: null,
|
|
@@ -165,8 +166,11 @@ const DEFAULT_COMPONENTS = {
|
|
|
165
166
|
* @alpha
|
|
166
167
|
*/
|
|
167
168
|
function GraphVisualization(_a) {
|
|
168
|
-
var _b, _c;
|
|
169
|
-
var { nvlRef: rawNvlRef, nvlCallbacks, nvlOptions, sidepanel: rawSidepanel, nodes: rawNodes, rels: rawRels, highlightedNodeIds, highlightedRelationshipIds, topLeftIsland = DEFAULT_COMPONENTS.topLeftIsland, topRightIsland = DEFAULT_COMPONENTS.topRightIsland, bottomLeftIsland = DEFAULT_COMPONENTS.bottomLeftIsland, bottomCenterIsland = DEFAULT_COMPONENTS.bottomCenterIsland, bottomRightIsland = DEFAULT_COMPONENTS.bottomRightIsland, gesture = 'single', setGesture, layout: rawLayout, setLayout: rawSetLayout, portalTarget, selected: rawSelected, setSelected: rawSetSelected, interactionMode: rawInteractionMode, setInteractionMode: rawSetInteractionMode, mouseEventCallbacks = {}, className, style, htmlAttributes, ref, as, styleRules } = _a, restProps = __rest(_a, ["nvlRef", "nvlCallbacks", "nvlOptions", "sidepanel", "nodes", "rels", "highlightedNodeIds", "highlightedRelationshipIds", "topLeftIsland", "topRightIsland", "bottomLeftIsland", "bottomCenterIsland", "bottomRightIsland", "gesture", "setGesture", "layout", "setLayout", "portalTarget", "selected", "setSelected", "interactionMode", "setInteractionMode", "mouseEventCallbacks", "className", "style", "htmlAttributes", "ref", "as", "styleRules"]);
|
|
169
|
+
var _b, _c, _d;
|
|
170
|
+
var { nvlRef: rawNvlRef, nvlCallbacks, nvlOptions: rawNvlOptions, sidepanel: rawSidepanel, nodes: rawNodes, rels: rawRels, highlightedNodeIds, highlightedRelationshipIds, topLeftIsland = DEFAULT_COMPONENTS.topLeftIsland, topRightIsland = DEFAULT_COMPONENTS.topRightIsland, bottomLeftIsland = DEFAULT_COMPONENTS.bottomLeftIsland, bottomCenterIsland = DEFAULT_COMPONENTS.bottomCenterIsland, bottomRightIsland = DEFAULT_COMPONENTS.bottomRightIsland, gesture = 'single', setGesture, layout: rawLayout, layoutOptions, setLayout: rawSetLayout, portalTarget, selected: rawSelected, setSelected: rawSetSelected, interactionMode: rawInteractionMode, setInteractionMode: rawSetInteractionMode, mouseEventCallbacks = {}, className, style, htmlAttributes, ref, as, styleRules } = _a, restProps = __rest(_a, ["nvlRef", "nvlCallbacks", "nvlOptions", "sidepanel", "nodes", "rels", "highlightedNodeIds", "highlightedRelationshipIds", "topLeftIsland", "topRightIsland", "bottomLeftIsland", "bottomCenterIsland", "bottomRightIsland", "gesture", "setGesture", "layout", "layoutOptions", "setLayout", "portalTarget", "selected", "setSelected", "interactionMode", "setInteractionMode", "mouseEventCallbacks", "className", "style", "htmlAttributes", "ref", "as", "styleRules"]);
|
|
171
|
+
const _e = rawNvlOptions !== null && rawNvlOptions !== void 0 ? rawNvlOptions : {}, { useWebGL: isWebGLEnabled } = _e, nvlOptions = __rest(_e, ["useWebGL"]);
|
|
172
|
+
nvlOptions.renderer =
|
|
173
|
+
(_b = nvlOptions.renderer) !== null && _b !== void 0 ? _b : (isWebGLEnabled === true ? 'webgl' : exports.DEFAULT_NVL_OPTIONS.renderer);
|
|
170
174
|
const nvlRef = (0, react_3.useMemo)(() => rawNvlRef !== null && rawNvlRef !== void 0 ? rawNvlRef : react_3.default.createRef(), [rawNvlRef]);
|
|
171
175
|
const instanceId = (0, react_3.useId)();
|
|
172
176
|
// Respect NDL theme changes
|
|
@@ -208,12 +212,12 @@ function GraphVisualization(_a) {
|
|
|
208
212
|
const [isSidePanelOpen, setIsSidePanelOpen] = (0, use_semi_controlled_state_1.useSemicontrolledState)({
|
|
209
213
|
isControlled: (rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.isSidePanelOpen) !== undefined,
|
|
210
214
|
onChange: rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.setIsSidePanelOpen,
|
|
211
|
-
state: (
|
|
215
|
+
state: (_c = rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.isSidePanelOpen) !== null && _c !== void 0 ? _c : true,
|
|
212
216
|
});
|
|
213
217
|
const [sidePanelWidth, setSidePanelWidth] = (0, use_semi_controlled_state_1.useSemicontrolledState)({
|
|
214
218
|
isControlled: (rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.sidePanelWidth) !== undefined,
|
|
215
219
|
onChange: rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.onSidePanelResize,
|
|
216
|
-
state: (
|
|
220
|
+
state: (_d = rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.sidePanelWidth) !== null && _d !== void 0 ? _d : 400,
|
|
217
221
|
});
|
|
218
222
|
const sidepanel = (0, react_3.useMemo)(() => {
|
|
219
223
|
if (rawSidepanel === undefined) {
|
|
@@ -247,13 +251,13 @@ function GraphVisualization(_a) {
|
|
|
247
251
|
setGesture,
|
|
248
252
|
setLayout,
|
|
249
253
|
sidepanel,
|
|
250
|
-
}, children: [(0, jsx_runtime_1.jsxs)("div", { className: "ndl-graph-visualization", children: [(0, jsx_runtime_1.jsx)(react_2.InteractiveNvlWrapper, Object.assign({
|
|
254
|
+
}, children: [(0, jsx_runtime_1.jsxs)("div", { className: "ndl-graph-visualization", children: [(0, jsx_runtime_1.jsx)(react_2.InteractiveNvlWrapper, Object.assign({ nodes: nodesWithState, rels: relsWithState, nvlOptions: Object.assign(Object.assign(Object.assign(Object.assign({}, exports.DEFAULT_NVL_OPTIONS), { instanceId, styling: {
|
|
251
255
|
defaultRelationshipColor: border.strongest,
|
|
252
256
|
disabledItemColor: bg.strong,
|
|
253
257
|
disabledItemFontColor: text.weakest,
|
|
254
258
|
dropShadowColor: border.weak,
|
|
255
259
|
selectedInnerBorderColor: bg.default,
|
|
256
|
-
} }), nvlOptions), nvlCallbacks: Object.assign({ onLayoutComputing(isComputing) {
|
|
260
|
+
} }), nvlOptions), { layout, layoutOptions: layoutOptions !== null && layoutOptions !== void 0 ? layoutOptions : nvlOptions.layoutOptions }), nvlCallbacks: Object.assign({ onLayoutComputing(isComputing) {
|
|
257
261
|
var _a;
|
|
258
262
|
if (!isComputing) {
|
|
259
263
|
(_a = nvlRef.current) === null || _a === void 0 ? void 0 : _a.fit(nvlRef.current.getNodes().map((neighbors) => neighbors.id), { noPan: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-visualization.js","sourceRoot":"","sources":["../../src/graph-visualization.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkNA,gDA8MC;;AAhaD;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,0CAAyC;AACzC,4CAAmE;AAGnE,4CAG0B;AAC1B,4DAA2C;AAC3C,+CAAmE;AAEnE,+EAYuC;AACvC,+EAQuC;AACvC,mFAA8E;AAC9E,oHAA8G;AAE9G,6DAAwD;AACxD,qEAA+D;AAC/D,2EAAqE;AASrE,MAAM,UAAU,GAA8B;IAC5C,aAAa,EAAE,4DAA4D;IAC3E,eAAe,EACb,8DAA8D;IAChE,cAAc,EAAE,6DAA6D;IAC7E,UAAU,EAAE,yDAAyD;IACrE,WAAW,EAAE,0DAA0D;CACxE,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,SAAS,GAKV,EAAE,EAAE;IACH,OAAO,gCAAK,SAAS,EAAE,IAAA,oBAAE,EAAC,UAAU,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,YAAG,QAAQ,GAAO,CAAC;AAChF,CAAC,CAAC;AAEW,QAAA,mBAAmB,GAAG;IACjC,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,IAAI;IACb,qBAAqB,EAAE,IAAI;CAC5B,CAAC;AAEF,MAAM,kBAAkB,GAAG;IACzB,gBAAgB,EAAE,IAAI;IACtB,kBAAkB,EAAE,IAAI;IACxB,iBAAiB,EAAE,CACjB,wBAAC,uBAAe,IAAC,WAAW,EAAC,UAAU,EAAC,UAAU,QAAC,IAAI,EAAC,OAAO,aAC7D,uBAAC,0CAAY,KAAG,OAAC,uBAAC,2CAAa,KAAG,OAAC,uBAAC,6CAAe,KAAG,IACtC,CACnB;IACD,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,CACd,iCAAK,SAAS,EAAC,gDAAgD,aAC7D,uBAAC,4CAAc,KAAG,OAAC,uBAAC,mDAAqB,KAAG,IACxC,CACP;CACF,CAAC;AAyCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,SAAgB,kBAAkB,CAAsC,EA+B3C;;QA/B2C,EACtE,MAAM,EAAE,SAAS,EACjB,YAAY,EACZ,UAAU,EACV,SAAS,EAAE,YAAY,EACvB,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,OAAO,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,aAAa,GAAG,kBAAkB,CAAC,aAAa,EAChD,cAAc,GAAG,kBAAkB,CAAC,cAAc,EAClD,gBAAgB,GAAG,kBAAkB,CAAC,gBAAgB,EACtD,kBAAkB,GAAG,kBAAkB,CAAC,kBAAkB,EAC1D,iBAAiB,GAAG,kBAAkB,CAAC,iBAAiB,EACxD,OAAO,GAAG,QAAQ,EAClB,UAAU,EACV,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,YAAY,EACvB,YAAY,EACZ,QAAQ,EAAE,WAAW,EACrB,WAAW,EAAE,cAAc,EAC3B,eAAe,EAAE,kBAAkB,EACnC,kBAAkB,EAAE,qBAAqB,EACzC,mBAAmB,GAAG,EAAE,EACxB,SAAS,EACT,KAAK,EACL,cAAc,EACd,GAAG,EACH,EAAE,EACF,UAAU,OAEiB,EADxB,SAAS,cA9B0D,0bA+BvE,CADa;IAEZ,MAAM,MAAM,GAAG,IAAA,eAAO,EACpB,GAAG,EAAE,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,eAAK,CAAC,SAAS,EAAO,EACzC,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,UAAU,GAAG,IAAA,aAAK,GAAE,CAAC;IAE3B,4BAA4B;IAC5B,MAAM,EAAE,KAAK,EAAE,GAAG,IAAA,sBAAc,GAAE,CAAC;IACnC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,aAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IAE/D,4CAA4C;IAC5C,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAC,CAAC;IAClC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,IAAA,6BAAY,EACtE,QAAQ,EACR,OAAO,EACP,UAAU,CACX,CAAC;IAEF,oDAAoD;IACpD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACnE,YAAY,EAAE,kBAAkB,KAAK,SAAS;QAC9C,QAAQ,EAAE,qBAAqB;QAC/B,KAAK,EAAE,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,QAAQ;KACtC,CAAC,CAAC;IACH,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACrD,YAAY,EAAE,WAAW,KAAK,SAAS;QACvC,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE;KAC3D,CAAC,CAAC;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACjD,YAAY,EAAE,SAAS,KAAK,SAAS;QACrC,QAAQ,EAAE,YAAY;QACtB,KAAK,EAAE,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,SAAS;KAC9B,CAAC,CAAC;IAEH,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,0BAA0B,EAAE,GACjE,IAAA,4CAAmB,EAAC;QAClB,OAAO;QACP,kBAAkB;QAClB,0BAA0B;QAC1B,eAAe;QACf,mBAAmB;QACnB,QAAQ,EAAE,WAAW;QACrB,QAAQ;QACR,kBAAkB;QAClB,WAAW;KACZ,CAAC,CAAC;IAEL,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACnE,YAAY,EAAE,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,eAAe,MAAK,SAAS;QACzD,QAAQ,EAAE,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,kBAAkB;QAC1C,KAAK,EAAE,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,eAAe,mCAAI,IAAI;KAC7C,CAAC,CAAC;IACH,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACjE,YAAY,EAAE,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,cAAc,MAAK,SAAS;QACxD,QAAQ,EAAE,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,iBAAiB;QACzC,KAAK,EAAE,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,cAAc,mCAAI,GAAG;KAC3C,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAA,eAAO,EAAC,GAAqB,EAAE;QAC/C,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO;gBACL,QAAQ,EAAE,uBAAC,kBAAkB,CAAC,gCAAgC,KAAG;gBACjE,eAAe;gBACf,iBAAiB,EAAE,iBAAiB;gBACpC,kBAAkB;gBAClB,cAAc;aACf,CAAC;QACJ,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC,EAAE;QACD,YAAY;QACZ,eAAe;QACf,kBAAkB;QAClB,cAAc;QACd,iBAAiB;KAClB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAsB,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,KAAK,CAAC;IACjD,OAAO,CACL,uBAAC,SAAS,kBACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,IAAA,oBAAE,EAAC,mCAAmC,EAAE,SAAS,CAAC,EAC7D,KAAK,EAAE,KAAK,IACR,cAAc,cAElB,wBAAC,uDAAyB,CAAC,QAAQ,IACjC,KAAK,EAAE;gBACL,kBAAkB;gBAClB,OAAO;gBACP,eAAe;gBACf,MAAM;gBACN,cAAc;gBACd,QAAQ,EAAE,WAAW;gBACrB,WAAW,EAAE,MAAM;gBACnB,YAAY;gBACZ,QAAQ;gBACR,UAAU;gBACV,SAAS;gBACT,SAAS;aACV,aAED,iCAAK,SAAS,EAAC,yBAAyB,aACtC,uBAAC,6BAAqB,kBAEpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,aAAa,EACnB,UAAU,gDACL,2BAAmB,KACtB,UAAU,EACV,OAAO,EAAE;oCACP,wBAAwB,EAAE,MAAM,CAAC,SAAS;oCAC1C,iBAAiB,EAAE,EAAE,CAAC,MAAM;oCAC5B,qBAAqB,EAAE,IAAI,CAAC,OAAO;oCACnC,eAAe,EAAE,MAAM,CAAC,IAAI;oCAC5B,wBAAwB,EAAE,EAAE,CAAC,OAAO;iCACrC,KACE,UAAU,GAEf,YAAY,kBACV,iBAAiB,CAAC,WAAW;;oCAC3B,IAAI,CAAC,WAAW,EAAE,CAAC;wCACjB,MAAA,MAAM,CAAC,OAAO,0CAAE,GAAG,CACjB,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAC1D,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB,CAAC;oCACJ,CAAC;gCACH,CAAC,IACE,YAAY,GAEjB,mBAAmB,EAAE,0BAA0B,EAC/C,GAAG,EAAE,MAAM,IACP,SAAS,GA7BR,GAAG,CA8BR,EACD,aAAa,KAAK,IAAI,IAAI,CACzB,uBAAC,iBAAiB,IAAC,SAAS,EAAC,UAAU,YACpC,aAAa,GACI,CACrB,EAEA,cAAc,KAAK,IAAI,IAAI,CAC1B,uBAAC,iBAAiB,IAAC,SAAS,EAAC,WAAW,YACrC,cAAc,GACG,CACrB,EAEA,gBAAgB,KAAK,IAAI,IAAI,CAC5B,uBAAC,iBAAiB,IAAC,SAAS,EAAC,aAAa,YACvC,gBAAgB,GACC,CACrB,EAEA,kBAAkB,KAAK,IAAI,IAAI,CAC9B,uBAAC,iBAAiB,IAAC,SAAS,EAAC,eAAe,YACzC,kBAAkB,GACD,CACrB,EAEA,iBAAiB,KAAK,IAAI,IAAI,CAC7B,uBAAC,iBAAiB,IAAC,SAAS,EAAC,cAAc,YACxC,iBAAiB,GACA,CACrB,IACG,EACL,SAAS,IAAI,uBAAC,2DAA2B,IAAC,SAAS,EAAE,SAAS,GAAI,IAChC,IAC3B,CACb,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,kBAAkB,CAAC,YAAY,GAAG,0CAAY,CAAC;AAE/C;;;;;;;GAOG;AACH,kBAAkB,CAAC,aAAa,GAAG,2CAAa,CAAC;AAEjD;;;;;;;GAOG;AACH,kBAAkB,CAAC,eAAe,GAAG,6CAAe,CAAC;AAErD;;;;;;;;;;GAUG;AACH,kBAAkB,CAAC,qBAAqB,GAAG,mDAAqB,CAAC;AAEjE;;;;;;;;GAQG;AACH,kBAAkB,CAAC,cAAc,GAAG,4CAAc,CAAC;AAEnD;;;;;;;;;GASG;AACH,kBAAkB,CAAC,eAAe,GAAG,6CAAe,CAAC;AAErD;;;;;;;;;GASG;AACH,kBAAkB,CAAC,iBAAiB,GAAG,+CAAiB,CAAC;AAEzD;;;;;;;;GAQG;AACH,kBAAkB,CAAC,kBAAkB,GAAG,gDAAkB,CAAC;AAE3D;;;;;;;GAOG;AACH,kBAAkB,CAAC,YAAY,GAAG,0CAAY,CAAC;AAE/C;;;;;;;;;GASG;AACH,kBAAkB,CAAC,gCAAgC;IACjD,sEAAgC,CAAC;AAEnC;;;;;;;;;;;;GAYG;AACH,kBAAkB,CAAC,kBAAkB,GAAG,gDAAkB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,kBAAkB,CAAC,mBAAmB,GAAG,iDAAmB,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { tokens } from '@neo4j-ndl/base';\nimport { IconButtonArray, useNeedleTheme } from '@neo4j-ndl/react';\nimport type NVL from '@neo4j-nvl/base';\nimport { type Layout } from '@neo4j-nvl/base';\nimport {\n InteractiveNvlWrapper,\n type InteractiveNvlWrapperProps,\n} from '@neo4j-nvl/react';\nimport { default as cx } from 'classnames';\nimport React, { useEffect, useId, useMemo, useState } from 'react';\n\nimport {\n BoxSelectButton,\n DownloadButton,\n GestureSelectButton,\n LassoSelectButton,\n LayoutSelectButton,\n SearchButton,\n SingleSelectButton,\n ToggleSidePanelButton,\n ZoomInButton,\n ZoomOutButton,\n ZoomToFitButton,\n} from './graph-visualization-buttons';\nimport {\n type Gesture,\n type GraphSelection,\n GraphVisualizationContext,\n type InteractionMode,\n type NeoNode,\n type NeoRel,\n type Sidepanel,\n} from './graph-visualization-context';\nimport { GraphVisualizationSidepanel } from './graph-visualization-sidepanel';\nimport { SingleSelectionSidepanelContents } from './sidepanel-components/single-selection-sidepanel-contents';\nimport { type GraphStyleRule } from './styling/style-types';\nimport { useGraphData } from './styling/use-graph-data';\nimport { useManagedNodeState } from './use-managed-node-state';\nimport { useSemicontrolledState } from './use-semi-controlled-state';\n\ntype Placement =\n | 'top-right'\n | 'bottom-right'\n | 'top-left'\n | 'bottom-left'\n | 'bottom-center';\n\nconst PLACEMENTS: Record<Placement, string> = {\n 'bottom-left': 'ndl-graph-visualization-interaction-island ndl-bottom-left',\n 'bottom-center':\n 'ndl-graph-visualization-interaction-island ndl-bottom-center',\n 'bottom-right': 'ndl-graph-visualization-interaction-island ndl-bottom-right',\n 'top-left': 'ndl-graph-visualization-interaction-island ndl-top-left',\n 'top-right': 'ndl-graph-visualization-interaction-island ndl-top-right',\n};\n\nconst InteractionIsland = ({\n children,\n className,\n placement,\n}: {\n children: React.ReactNode;\n placement: Placement;\n className?: string;\n}) => {\n return <div className={cx(PLACEMENTS[placement], className)}>{children}</div>;\n};\n\nexport const DEFAULT_NVL_OPTIONS = {\n disableTelemetry: true,\n disableWebGL: true,\n maxZoom: 3,\n minZoom: 0.05,\n relationshipThreshold: 0.55,\n};\n\nconst DEFAULT_COMPONENTS = {\n bottomLeftIsland: null,\n bottomCenterIsland: null,\n bottomRightIsland: (\n <IconButtonArray orientation=\"vertical\" isFloating size=\"small\">\n <ZoomInButton /> <ZoomOutButton /> <ZoomToFitButton />\n </IconButtonArray>\n ),\n topLeftIsland: null,\n topRightIsland: (\n <div className=\"ndl-graph-visualization-default-download-group\">\n <DownloadButton /> <ToggleSidePanelButton />\n </div>\n ),\n};\n\nexport type GraphVisualizationProps<T extends React.ElementType = 'div'> = {\n nvlRef?: React.RefObject<NVL | null>;\n sidepanel?: Sidepanel | null;\n bottomLeftIsland?: React.ReactNode;\n bottomCenterIsland?: React.ReactNode;\n bottomRightIsland?: React.ReactNode;\n topLeftIsland?: React.ReactNode;\n topRightIsland?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n /**\n * Optional style rules to apply to graph elements.\n * Consumer-set `color` on individual `NeoNode`/`NeoRel` objects takes precedence over rules.\n * Compared by reference — memoize the array to avoid recompiling on every render.\n */\n styleRules?: GraphStyleRule[];\n\n gesture?: Gesture;\n setGesture?: (gesture: Gesture) => void;\n selected?: GraphSelection;\n setSelected?: (newSelection: GraphSelection) => void;\n interactionMode?: InteractionMode;\n setInteractionMode?: (interactionMode: InteractionMode) => void;\n layout?: Layout;\n setLayout?: (layout: Layout) => void;\n\n portalTarget?: HTMLElement | null;\n\n nodes: NeoNode[];\n rels: NeoRel[];\n\n highlightedNodeIds?: string[];\n highlightedRelationshipIds?: string[];\n\n as?: T;\n ref?: React.ComponentPropsWithRef<T>['ref'];\n htmlAttributes?: React.HTMLAttributes<T>;\n} & InteractiveNvlWrapperProps;\n\n/**\n * A comprehensive graph visualization component for rendering Neo4j-style graphs with interactive features.\n *\n * @remarks\n * This component provides a complete graph visualization solution with built-in interaction modes,\n * selection handling, zoom controls, and an optional sidepanel. It wraps the NVL (Neo4j Visualization Library)\n * with additional UI controls and state management.\n *\n * The component supports various interaction modes including single selection, box selection, and lasso selection.\n * It also provides customizable UI islands for placing controls at different corners of the visualization.\n *\n * @example\n * Basic usage:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * selected={selection}\n * setSelected={setSelection}\n * />\n * ```\n *\n * @example\n * With custom controls:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * topRightIsland={<CustomControls />}\n * sidepanel={{\n * contents: <CustomSidepanel />,\n * isSidePanelOpen: true,\n * setIsSidePanelOpen: setSidepanelOpen\n * sidePanelWidth: 400,\n * onSidePanelResize: setSidepanelWidth,\n * }}\n * />\n * ```\n *\n * @example\n * With highlighting:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * // undefined = no highlighting (default behavior)\n * // empty array = no search matches (dims all nodes)\n * // array with IDs = highlight only those items\n * highlightedNodeIds={searchResults.nodeIds}\n * highlightedRelationshipIds={searchResults.relationshipIds}\n * />\n * ```\n *\n * @param props - {@link GraphVisualizationProps}\n * @returns A React component that renders an interactive graph visualization\n *\n * @alpha\n */\nexport function GraphVisualization<T extends React.ElementType = 'div'>({\n nvlRef: rawNvlRef,\n nvlCallbacks,\n nvlOptions,\n sidepanel: rawSidepanel,\n nodes: rawNodes,\n rels: rawRels,\n highlightedNodeIds,\n highlightedRelationshipIds,\n topLeftIsland = DEFAULT_COMPONENTS.topLeftIsland,\n topRightIsland = DEFAULT_COMPONENTS.topRightIsland,\n bottomLeftIsland = DEFAULT_COMPONENTS.bottomLeftIsland,\n bottomCenterIsland = DEFAULT_COMPONENTS.bottomCenterIsland,\n bottomRightIsland = DEFAULT_COMPONENTS.bottomRightIsland,\n gesture = 'single',\n setGesture,\n layout: rawLayout,\n setLayout: rawSetLayout,\n portalTarget,\n selected: rawSelected,\n setSelected: rawSetSelected,\n interactionMode: rawInteractionMode,\n setInteractionMode: rawSetInteractionMode,\n mouseEventCallbacks = {},\n className,\n style,\n htmlAttributes,\n ref,\n as,\n styleRules,\n ...restProps\n}: GraphVisualizationProps<T>) {\n const nvlRef = useMemo(\n () => rawNvlRef ?? React.createRef<NVL>(),\n [rawNvlRef],\n );\n\n const instanceId = useId();\n\n // Respect NDL theme changes\n const { theme } = useNeedleTheme();\n const { bg, border, text } = tokens.theme[theme].color.neutral;\n\n // key required for nvl react responsiveness\n const [key, setKey] = useState(0);\n useEffect(() => {\n setKey((prevKey) => prevKey + 1);\n }, [theme]);\n\n const { styledGraph, metadataLookup, compiledStyleRules } = useGraphData(\n rawNodes,\n rawRels,\n styleRules,\n );\n\n // Semi-control interaction mode and selection state\n const [interactionMode, setInteractionMode] = useSemicontrolledState({\n isControlled: rawInteractionMode !== undefined,\n onChange: rawSetInteractionMode,\n state: rawInteractionMode ?? 'select',\n });\n const [selected, setSelected] = useSemicontrolledState({\n isControlled: rawSelected !== undefined,\n onChange: rawSetSelected,\n state: rawSelected ?? { nodeIds: [], relationshipIds: [] },\n });\n const [layout, setLayout] = useSemicontrolledState({\n isControlled: rawLayout !== undefined,\n onChange: rawSetLayout,\n state: rawLayout ?? 'd3Force',\n });\n\n const { nodesWithState, relsWithState, wrappedMouseEventCallbacks } =\n useManagedNodeState({\n gesture,\n highlightedNodeIds,\n highlightedRelationshipIds,\n interactionMode,\n mouseEventCallbacks,\n nvlGraph: styledGraph,\n selected,\n setInteractionMode,\n setSelected,\n });\n\n const [isSidePanelOpen, setIsSidePanelOpen] = useSemicontrolledState({\n isControlled: rawSidepanel?.isSidePanelOpen !== undefined,\n onChange: rawSidepanel?.setIsSidePanelOpen,\n state: rawSidepanel?.isSidePanelOpen ?? true,\n });\n const [sidePanelWidth, setSidePanelWidth] = useSemicontrolledState({\n isControlled: rawSidepanel?.sidePanelWidth !== undefined,\n onChange: rawSidepanel?.onSidePanelResize,\n state: rawSidepanel?.sidePanelWidth ?? 400,\n });\n\n const sidepanel = useMemo((): Sidepanel | null => {\n if (rawSidepanel === undefined) {\n return {\n children: <GraphVisualization.SingleSelectionSidePanelContents />,\n isSidePanelOpen,\n onSidePanelResize: setSidePanelWidth,\n setIsSidePanelOpen,\n sidePanelWidth,\n };\n }\n return rawSidepanel;\n }, [\n rawSidepanel,\n isSidePanelOpen,\n setIsSidePanelOpen,\n sidePanelWidth,\n setSidePanelWidth,\n ]);\n\n const Component: React.ElementType = as ?? 'div';\n return (\n <Component\n ref={ref}\n className={cx('ndl-graph-visualization-container', className)}\n style={style}\n {...htmlAttributes}\n >\n <GraphVisualizationContext.Provider\n value={{\n compiledStyleRules,\n gesture,\n interactionMode,\n layout,\n metadataLookup,\n nvlGraph: styledGraph,\n nvlInstance: nvlRef,\n portalTarget,\n selected,\n setGesture,\n setLayout,\n sidepanel,\n }}\n >\n <div className=\"ndl-graph-visualization\">\n <InteractiveNvlWrapper\n key={key}\n layout={layout}\n nodes={nodesWithState}\n rels={relsWithState}\n nvlOptions={{\n ...DEFAULT_NVL_OPTIONS,\n instanceId,\n styling: {\n defaultRelationshipColor: border.strongest,\n disabledItemColor: bg.strong,\n disabledItemFontColor: text.weakest,\n dropShadowColor: border.weak,\n selectedInnerBorderColor: bg.default,\n },\n ...nvlOptions,\n }}\n nvlCallbacks={{\n onLayoutComputing(isComputing) {\n if (!isComputing) {\n nvlRef.current?.fit(\n nvlRef.current.getNodes().map((neighbors) => neighbors.id),\n { noPan: true },\n );\n }\n },\n ...nvlCallbacks,\n }}\n mouseEventCallbacks={wrappedMouseEventCallbacks}\n ref={nvlRef}\n {...restProps}\n />\n {topLeftIsland !== null && (\n <InteractionIsland placement=\"top-left\">\n {topLeftIsland}\n </InteractionIsland>\n )}\n\n {topRightIsland !== null && (\n <InteractionIsland placement=\"top-right\">\n {topRightIsland}\n </InteractionIsland>\n )}\n\n {bottomLeftIsland !== null && (\n <InteractionIsland placement=\"bottom-left\">\n {bottomLeftIsland}\n </InteractionIsland>\n )}\n\n {bottomCenterIsland !== null && (\n <InteractionIsland placement=\"bottom-center\">\n {bottomCenterIsland}\n </InteractionIsland>\n )}\n\n {bottomRightIsland !== null && (\n <InteractionIsland placement=\"bottom-right\">\n {bottomRightIsland}\n </InteractionIsland>\n )}\n </div>\n {sidepanel && <GraphVisualizationSidepanel sidepanel={sidepanel} />}\n </GraphVisualizationContext.Provider>\n </Component>\n );\n}\n\n/**\n * Zoom in button for use within a GraphVisualization component.\n *\n * @remarks\n * Increases zoom level by 1.3x\n *\n * @alpha\n */\nGraphVisualization.ZoomInButton = ZoomInButton;\n\n/**\n * Zoom out button for use within a GraphVisualization component.\n *\n * @remarks\n * Decreases zoom level by 0.7x\n *\n * @alpha\n */\nGraphVisualization.ZoomOutButton = ZoomOutButton;\n\n/**\n * Zoom to fit button for use within a GraphVisualization component.\n *\n * @remarks\n * Automatically adjusts zoom and pan to show all nodes and relationships\n *\n * @alpha\n */\nGraphVisualization.ZoomToFitButton = ZoomToFitButton;\n\n/**\n * Sidepanel toggle button for use within a GraphVisualization component.\n *\n * @remarks\n * Shows or hides the sidepanel containing node and relationship details.\n * Requires a sidepanel to be configured in the GraphVisualization component.\n *\n * @throws Error when used without a configured sidepanel\n *\n * @alpha\n */\nGraphVisualization.ToggleSidePanelButton = ToggleSidePanelButton;\n\n/**\n * Download button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a dropdown menu with download options. Supports PNG and SVG formats.\n * Captures the current visualization state including zoom level.\n *\n * @alpha\n */\nGraphVisualization.DownloadButton = DownloadButton;\n\n/**\n * Box selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables box selection mode where dragging creates a rectangular selection area.\n * Disabled unless the `setGesture` callback is passed.\n * Shows active state when enabled and supports keyboard shortcut 'B'.\n *\n * @alpha\n */\nGraphVisualization.BoxSelectButton = BoxSelectButton;\n\n/**\n * Lasso selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables lasso selection mode where dragging creates a free-form selection area.\n * Disabled unless the `setGesture` callback is passed.\n * Shows active state when enabled and supports keyboard shortcut 'L'.\n *\n * @alpha\n */\nGraphVisualization.LassoSelectButton = LassoSelectButton;\n\n/**\n * Single node selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables single selection mode where clicking selects individual nodes or relationships.\n * Shows active state when enabled and supports keyboard shortcut 'S'.\n *\n * @alpha\n */\nGraphVisualization.SingleSelectButton = SingleSelectButton;\n\n/**\n * Search button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables search mode where clicking opens a search input for filtering nodes and relationships.\n *\n * @alpha\n */\nGraphVisualization.SearchButton = SearchButton;\n\n/**\n * Single node selection side panel for use within a GraphVisualization component.\n *\n * @remarks\n * Displays detailed information about the selected node or relationship.\n * Panel is automatically opened when a node or relationship is selected.\n * Also when user click on the show panel button in the top right corner.\n *\n * @alpha\n */\nGraphVisualization.SingleSelectionSidePanelContents =\n SingleSelectionSidepanelContents;\n\n/**\n * Layout selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a menu to select different graph layout algorithms.\n *\n * By default, the menu includes the **force-based** (`d3Force`) and\n * **hierarchical** layouts. Additional layouts can be enabled via configuration.\n *\n * @see {@link LayoutSelectOption} for the full set of layout options supported by NVL.\n *\n * @alpha\n */\nGraphVisualization.LayoutSelectButton = LayoutSelectButton;\n\n/**\n * Gesture selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a menu to select different interaction gestures.\n *\n * By default, the menu includes **single**, **box**, and **lasso** selection gestures.\n *\n * @see {@link GestureSelectOption} for the full set of gesture options supported by NVL.\n *\n * @alpha\n */\nGraphVisualization.GestureSelectButton = GestureSelectButton;\n"]}
|
|
1
|
+
{"version":3,"file":"graph-visualization.js","sourceRoot":"","sources":["../../src/graph-visualization.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0NA,gDAsNC;;AAhbD;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,0CAAyC;AACzC,4CAAmE;AAGnE,4CAG0B;AAC1B,4DAA2C;AAC3C,+CAAmE;AAEnE,+EAYuC;AACvC,+EAQuC;AACvC,mFAA8E;AAC9E,oHAA8G;AAE9G,6DAAwD;AACxD,qEAA+D;AAC/D,2EAAqE;AASrE,MAAM,UAAU,GAA8B;IAC5C,aAAa,EAAE,4DAA4D;IAC3E,eAAe,EACb,8DAA8D;IAChE,cAAc,EAAE,6DAA6D;IAC7E,UAAU,EAAE,yDAAyD;IACrE,WAAW,EAAE,0DAA0D;CACxE,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,SAAS,GAKV,EAAE,EAAE;IACH,OAAO,gCAAK,SAAS,EAAE,IAAA,oBAAE,EAAC,UAAU,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,YAAG,QAAQ,GAAO,CAAC;AAChF,CAAC,CAAC;AAEW,QAAA,mBAAmB,GAAG;IACjC,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,IAAI;IACb,qBAAqB,EAAE,IAAI;IAC3B,QAAQ,EAAE,QAAQ;CACE,CAAC;AAQvB,MAAM,kBAAkB,GAAG;IACzB,gBAAgB,EAAE,IAAI;IACtB,kBAAkB,EAAE,IAAI;IACxB,iBAAiB,EAAE,CACjB,wBAAC,uBAAe,IAAC,WAAW,EAAC,UAAU,EAAC,UAAU,QAAC,IAAI,EAAC,OAAO,aAC7D,uBAAC,0CAAY,KAAG,OAAC,uBAAC,2CAAa,KAAG,OAAC,uBAAC,6CAAe,KAAG,IACtC,CACnB;IACD,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,CACd,iCAAK,SAAS,EAAC,gDAAgD,aAC7D,uBAAC,4CAAc,KAAG,OAAC,uBAAC,mDAAqB,KAAG,IACxC,CACP;CACF,CAAC;AA0CF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,SAAgB,kBAAkB,CAAsC,EAiC3C;;QAjC2C,EACtE,MAAM,EAAE,SAAS,EACjB,YAAY,EACZ,UAAU,EAAE,aAAa,EACzB,SAAS,EAAE,YAAY,EACvB,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,OAAO,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,aAAa,GAAG,kBAAkB,CAAC,aAAa,EAChD,cAAc,GAAG,kBAAkB,CAAC,cAAc,EAClD,gBAAgB,GAAG,kBAAkB,CAAC,gBAAgB,EACtD,kBAAkB,GAAG,kBAAkB,CAAC,kBAAkB,EAC1D,iBAAiB,GAAG,kBAAkB,CAAC,iBAAiB,EACxD,OAAO,GAAG,QAAQ,EAClB,UAAU,EACV,MAAM,EAAE,SAAS,EAEjB,aAAa,EACb,SAAS,EAAE,YAAY,EACvB,YAAY,EACZ,QAAQ,EAAE,WAAW,EACrB,WAAW,EAAE,cAAc,EAC3B,eAAe,EAAE,kBAAkB,EACnC,kBAAkB,EAAE,qBAAqB,EACzC,mBAAmB,GAAG,EAAE,EACxB,SAAS,EACT,KAAK,EACL,cAAc,EACd,GAAG,EACH,EAAE,EACF,UAAU,OAEiB,EADxB,SAAS,cAhC0D,2cAiCvE,CADa;IAEZ,MAAM,KAA8C,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,EAAjE,EAAE,QAAQ,EAAE,cAAc,OAAuC,EAAlC,UAAU,cAAzC,YAA2C,CAAsB,CAAC;IACxE,UAAU,CAAC,QAAQ;QACjB,MAAA,UAAU,CAAC,QAAQ,mCACnB,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,2BAAmB,CAAC,QAAQ,CAAC,CAAC;IAErE,MAAM,MAAM,GAAG,IAAA,eAAO,EACpB,GAAG,EAAE,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,eAAK,CAAC,SAAS,EAAO,EACzC,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,MAAM,UAAU,GAAG,IAAA,aAAK,GAAE,CAAC;IAE3B,4BAA4B;IAC5B,MAAM,EAAE,KAAK,EAAE,GAAG,IAAA,sBAAc,GAAE,CAAC;IACnC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,aAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IAE/D,4CAA4C;IAC5C,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAC,CAAC;IAClC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,IAAA,6BAAY,EACtE,QAAQ,EACR,OAAO,EACP,UAAU,CACX,CAAC;IAEF,oDAAoD;IACpD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACnE,YAAY,EAAE,kBAAkB,KAAK,SAAS;QAC9C,QAAQ,EAAE,qBAAqB;QAC/B,KAAK,EAAE,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,QAAQ;KACtC,CAAC,CAAC;IACH,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACrD,YAAY,EAAE,WAAW,KAAK,SAAS;QACvC,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE;KAC3D,CAAC,CAAC;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACjD,YAAY,EAAE,SAAS,KAAK,SAAS;QACrC,QAAQ,EAAE,YAAY;QACtB,KAAK,EAAE,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,SAAS;KAC9B,CAAC,CAAC;IAEH,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,0BAA0B,EAAE,GACjE,IAAA,4CAAmB,EAAC;QAClB,OAAO;QACP,kBAAkB;QAClB,0BAA0B;QAC1B,eAAe;QACf,mBAAmB;QACnB,QAAQ,EAAE,WAAW;QACrB,QAAQ;QACR,kBAAkB;QAClB,WAAW;KACZ,CAAC,CAAC;IAEL,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACnE,YAAY,EAAE,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,eAAe,MAAK,SAAS;QACzD,QAAQ,EAAE,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,kBAAkB;QAC1C,KAAK,EAAE,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,eAAe,mCAAI,IAAI;KAC7C,CAAC,CAAC;IACH,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,IAAA,kDAAsB,EAAC;QACjE,YAAY,EAAE,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,cAAc,MAAK,SAAS;QACxD,QAAQ,EAAE,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,iBAAiB;QACzC,KAAK,EAAE,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,cAAc,mCAAI,GAAG;KAC3C,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAA,eAAO,EAAC,GAAqB,EAAE;QAC/C,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO;gBACL,QAAQ,EAAE,uBAAC,kBAAkB,CAAC,gCAAgC,KAAG;gBACjE,eAAe;gBACf,iBAAiB,EAAE,iBAAiB;gBACpC,kBAAkB;gBAClB,cAAc;aACf,CAAC;QACJ,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC,EAAE;QACD,YAAY;QACZ,eAAe;QACf,kBAAkB;QAClB,cAAc;QACd,iBAAiB;KAClB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAsB,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,KAAK,CAAC;IACjD,OAAO,CACL,uBAAC,SAAS,kBACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,IAAA,oBAAE,EAAC,mCAAmC,EAAE,SAAS,CAAC,EAC7D,KAAK,EAAE,KAAK,IACR,cAAc,cAElB,wBAAC,uDAAyB,CAAC,QAAQ,IACjC,KAAK,EAAE;gBACL,kBAAkB;gBAClB,OAAO;gBACP,eAAe;gBACf,MAAM;gBACN,cAAc;gBACd,QAAQ,EAAE,WAAW;gBACrB,WAAW,EAAE,MAAM;gBACnB,YAAY;gBACZ,QAAQ;gBACR,UAAU;gBACV,SAAS;gBACT,SAAS;aACV,aAED,iCAAK,SAAS,EAAC,yBAAyB,aACtC,uBAAC,6BAAqB,kBAEpB,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,aAAa,EACnB,UAAU,8DACL,2BAAmB,KACtB,UAAU,EACV,OAAO,EAAE;oCACP,wBAAwB,EAAE,MAAM,CAAC,SAAS;oCAC1C,iBAAiB,EAAE,EAAE,CAAC,MAAM;oCAC5B,qBAAqB,EAAE,IAAI,CAAC,OAAO;oCACnC,eAAe,EAAE,MAAM,CAAC,IAAI;oCAC5B,wBAAwB,EAAE,EAAE,CAAC,OAAO;iCACrC,KACE,UAAU,KACb,MAAM,EACN,aAAa,EAAE,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,UAAU,CAAC,aAAa,KAE1D,YAAY,kBACV,iBAAiB,CAAC,WAAW;;oCAC3B,IAAI,CAAC,WAAW,EAAE,CAAC;wCACjB,MAAA,MAAM,CAAC,OAAO,0CAAE,GAAG,CACjB,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAC1D,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB,CAAC;oCACJ,CAAC;gCACH,CAAC,IACE,YAAY,GAEjB,mBAAmB,EAAE,0BAA0B,EAC/C,GAAG,EAAE,MAAM,IACP,SAAS,GA9BR,GAAG,CA+BR,EACD,aAAa,KAAK,IAAI,IAAI,CACzB,uBAAC,iBAAiB,IAAC,SAAS,EAAC,UAAU,YACpC,aAAa,GACI,CACrB,EAEA,cAAc,KAAK,IAAI,IAAI,CAC1B,uBAAC,iBAAiB,IAAC,SAAS,EAAC,WAAW,YACrC,cAAc,GACG,CACrB,EAEA,gBAAgB,KAAK,IAAI,IAAI,CAC5B,uBAAC,iBAAiB,IAAC,SAAS,EAAC,aAAa,YACvC,gBAAgB,GACC,CACrB,EAEA,kBAAkB,KAAK,IAAI,IAAI,CAC9B,uBAAC,iBAAiB,IAAC,SAAS,EAAC,eAAe,YACzC,kBAAkB,GACD,CACrB,EAEA,iBAAiB,KAAK,IAAI,IAAI,CAC7B,uBAAC,iBAAiB,IAAC,SAAS,EAAC,cAAc,YACxC,iBAAiB,GACA,CACrB,IACG,EACL,SAAS,IAAI,uBAAC,2DAA2B,IAAC,SAAS,EAAE,SAAS,GAAI,IAChC,IAC3B,CACb,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,kBAAkB,CAAC,YAAY,GAAG,0CAAY,CAAC;AAE/C;;;;;;;GAOG;AACH,kBAAkB,CAAC,aAAa,GAAG,2CAAa,CAAC;AAEjD;;;;;;;GAOG;AACH,kBAAkB,CAAC,eAAe,GAAG,6CAAe,CAAC;AAErD;;;;;;;;;;GAUG;AACH,kBAAkB,CAAC,qBAAqB,GAAG,mDAAqB,CAAC;AAEjE;;;;;;;;GAQG;AACH,kBAAkB,CAAC,cAAc,GAAG,4CAAc,CAAC;AAEnD;;;;;;;;;GASG;AACH,kBAAkB,CAAC,eAAe,GAAG,6CAAe,CAAC;AAErD;;;;;;;;;GASG;AACH,kBAAkB,CAAC,iBAAiB,GAAG,+CAAiB,CAAC;AAEzD;;;;;;;;GAQG;AACH,kBAAkB,CAAC,kBAAkB,GAAG,gDAAkB,CAAC;AAE3D;;;;;;;GAOG;AACH,kBAAkB,CAAC,YAAY,GAAG,0CAAY,CAAC;AAE/C;;;;;;;;;GASG;AACH,kBAAkB,CAAC,gCAAgC;IACjD,sEAAgC,CAAC;AAEnC;;;;;;;;;;;;GAYG;AACH,kBAAkB,CAAC,kBAAkB,GAAG,gDAAkB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,kBAAkB,CAAC,mBAAmB,GAAG,iDAAmB,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { tokens } from '@neo4j-ndl/base';\nimport { IconButtonArray, useNeedleTheme } from '@neo4j-ndl/react';\nimport type NVL from '@neo4j-nvl/base';\nimport { type Layout, type NvlOptions } from '@neo4j-nvl/base';\nimport {\n InteractiveNvlWrapper,\n type InteractiveNvlWrapperProps,\n} from '@neo4j-nvl/react';\nimport { default as cx } from 'classnames';\nimport React, { useEffect, useId, useMemo, useState } from 'react';\n\nimport {\n BoxSelectButton,\n DownloadButton,\n GestureSelectButton,\n LassoSelectButton,\n LayoutSelectButton,\n SearchButton,\n SingleSelectButton,\n ToggleSidePanelButton,\n ZoomInButton,\n ZoomOutButton,\n ZoomToFitButton,\n} from './graph-visualization-buttons';\nimport {\n type Gesture,\n type GraphSelection,\n GraphVisualizationContext,\n type InteractionMode,\n type NeoNode,\n type NeoRel,\n type Sidepanel,\n} from './graph-visualization-context';\nimport { GraphVisualizationSidepanel } from './graph-visualization-sidepanel';\nimport { SingleSelectionSidepanelContents } from './sidepanel-components/single-selection-sidepanel-contents';\nimport { type GraphStyleRule } from './styling/style-types';\nimport { useGraphData } from './styling/use-graph-data';\nimport { useManagedNodeState } from './use-managed-node-state';\nimport { useSemicontrolledState } from './use-semi-controlled-state';\n\ntype Placement =\n | 'top-right'\n | 'bottom-right'\n | 'top-left'\n | 'bottom-left'\n | 'bottom-center';\n\nconst PLACEMENTS: Record<Placement, string> = {\n 'bottom-left': 'ndl-graph-visualization-interaction-island ndl-bottom-left',\n 'bottom-center':\n 'ndl-graph-visualization-interaction-island ndl-bottom-center',\n 'bottom-right': 'ndl-graph-visualization-interaction-island ndl-bottom-right',\n 'top-left': 'ndl-graph-visualization-interaction-island ndl-top-left',\n 'top-right': 'ndl-graph-visualization-interaction-island ndl-top-right',\n};\n\nconst InteractionIsland = ({\n children,\n className,\n placement,\n}: {\n children: React.ReactNode;\n placement: Placement;\n className?: string;\n}) => {\n return <div className={cx(PLACEMENTS[placement], className)}>{children}</div>;\n};\n\nexport const DEFAULT_NVL_OPTIONS = {\n disableTelemetry: true,\n disableWebGL: true,\n maxZoom: 3,\n minZoom: 0.05,\n relationshipThreshold: 0.55,\n renderer: 'canvas',\n} satisfies NvlOptions;\n\ntype BackwardsCompatibleNvlOptions = NvlOptions & {\n /** @deprecated Use {@link NvlOptions.renderer} instead. */\n // eslint-disable-next-line @typescript-eslint/naming-convention -- Matches the removed NVL option.\n useWebGL?: boolean;\n};\n\nconst DEFAULT_COMPONENTS = {\n bottomLeftIsland: null,\n bottomCenterIsland: null,\n bottomRightIsland: (\n <IconButtonArray orientation=\"vertical\" isFloating size=\"small\">\n <ZoomInButton /> <ZoomOutButton /> <ZoomToFitButton />\n </IconButtonArray>\n ),\n topLeftIsland: null,\n topRightIsland: (\n <div className=\"ndl-graph-visualization-default-download-group\">\n <DownloadButton /> <ToggleSidePanelButton />\n </div>\n ),\n};\n\nexport type GraphVisualizationProps<T extends React.ElementType = 'div'> = {\n nvlRef?: React.RefObject<NVL | null>;\n nvlOptions?: BackwardsCompatibleNvlOptions;\n sidepanel?: Sidepanel | null;\n bottomLeftIsland?: React.ReactNode;\n bottomCenterIsland?: React.ReactNode;\n bottomRightIsland?: React.ReactNode;\n topLeftIsland?: React.ReactNode;\n topRightIsland?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n /**\n * Optional style rules to apply to graph elements.\n * Consumer-set `color` on individual `NeoNode`/`NeoRel` objects takes precedence over rules.\n * Compared by reference — memoize the array to avoid recompiling on every render.\n */\n styleRules?: GraphStyleRule[];\n\n gesture?: Gesture;\n setGesture?: (gesture: Gesture) => void;\n selected?: GraphSelection;\n setSelected?: (newSelection: GraphSelection) => void;\n interactionMode?: InteractionMode;\n setInteractionMode?: (interactionMode: InteractionMode) => void;\n layout?: Layout;\n setLayout?: (layout: Layout) => void;\n\n portalTarget?: HTMLElement | null;\n\n nodes: NeoNode[];\n rels: NeoRel[];\n\n highlightedNodeIds?: string[];\n highlightedRelationshipIds?: string[];\n\n as?: T;\n ref?: React.ComponentPropsWithRef<T>['ref'];\n htmlAttributes?: React.HTMLAttributes<T>;\n} & InteractiveNvlWrapperProps;\n\n/**\n * A comprehensive graph visualization component for rendering Neo4j-style graphs with interactive features.\n *\n * @remarks\n * This component provides a complete graph visualization solution with built-in interaction modes,\n * selection handling, zoom controls, and an optional sidepanel. It wraps the NVL (Neo4j Visualization Library)\n * with additional UI controls and state management.\n *\n * The component supports various interaction modes including single selection, box selection, and lasso selection.\n * It also provides customizable UI islands for placing controls at different corners of the visualization.\n *\n * @example\n * Basic usage:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * selected={selection}\n * setSelected={setSelection}\n * />\n * ```\n *\n * @example\n * With custom controls:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * topRightIsland={<CustomControls />}\n * sidepanel={{\n * contents: <CustomSidepanel />,\n * isSidePanelOpen: true,\n * setIsSidePanelOpen: setSidepanelOpen\n * sidePanelWidth: 400,\n * onSidePanelResize: setSidepanelWidth,\n * }}\n * />\n * ```\n *\n * @example\n * With highlighting:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * // undefined = no highlighting (default behavior)\n * // empty array = no search matches (dims all nodes)\n * // array with IDs = highlight only those items\n * highlightedNodeIds={searchResults.nodeIds}\n * highlightedRelationshipIds={searchResults.relationshipIds}\n * />\n * ```\n *\n * @param props - {@link GraphVisualizationProps}\n * @returns A React component that renders an interactive graph visualization\n *\n * @alpha\n */\nexport function GraphVisualization<T extends React.ElementType = 'div'>({\n nvlRef: rawNvlRef,\n nvlCallbacks,\n nvlOptions: rawNvlOptions,\n sidepanel: rawSidepanel,\n nodes: rawNodes,\n rels: rawRels,\n highlightedNodeIds,\n highlightedRelationshipIds,\n topLeftIsland = DEFAULT_COMPONENTS.topLeftIsland,\n topRightIsland = DEFAULT_COMPONENTS.topRightIsland,\n bottomLeftIsland = DEFAULT_COMPONENTS.bottomLeftIsland,\n bottomCenterIsland = DEFAULT_COMPONENTS.bottomCenterIsland,\n bottomRightIsland = DEFAULT_COMPONENTS.bottomRightIsland,\n gesture = 'single',\n setGesture,\n layout: rawLayout,\n\n layoutOptions,\n setLayout: rawSetLayout,\n portalTarget,\n selected: rawSelected,\n setSelected: rawSetSelected,\n interactionMode: rawInteractionMode,\n setInteractionMode: rawSetInteractionMode,\n mouseEventCallbacks = {},\n className,\n style,\n htmlAttributes,\n ref,\n as,\n styleRules,\n ...restProps\n}: GraphVisualizationProps<T>) {\n const { useWebGL: isWebGLEnabled, ...nvlOptions } = rawNvlOptions ?? {};\n nvlOptions.renderer =\n nvlOptions.renderer ??\n (isWebGLEnabled === true ? 'webgl' : DEFAULT_NVL_OPTIONS.renderer);\n\n const nvlRef = useMemo(\n () => rawNvlRef ?? React.createRef<NVL>(),\n [rawNvlRef],\n );\n\n const instanceId = useId();\n\n // Respect NDL theme changes\n const { theme } = useNeedleTheme();\n const { bg, border, text } = tokens.theme[theme].color.neutral;\n\n // key required for nvl react responsiveness\n const [key, setKey] = useState(0);\n useEffect(() => {\n setKey((prevKey) => prevKey + 1);\n }, [theme]);\n\n const { styledGraph, metadataLookup, compiledStyleRules } = useGraphData(\n rawNodes,\n rawRels,\n styleRules,\n );\n\n // Semi-control interaction mode and selection state\n const [interactionMode, setInteractionMode] = useSemicontrolledState({\n isControlled: rawInteractionMode !== undefined,\n onChange: rawSetInteractionMode,\n state: rawInteractionMode ?? 'select',\n });\n const [selected, setSelected] = useSemicontrolledState({\n isControlled: rawSelected !== undefined,\n onChange: rawSetSelected,\n state: rawSelected ?? { nodeIds: [], relationshipIds: [] },\n });\n const [layout, setLayout] = useSemicontrolledState({\n isControlled: rawLayout !== undefined,\n onChange: rawSetLayout,\n state: rawLayout ?? 'd3Force',\n });\n\n const { nodesWithState, relsWithState, wrappedMouseEventCallbacks } =\n useManagedNodeState({\n gesture,\n highlightedNodeIds,\n highlightedRelationshipIds,\n interactionMode,\n mouseEventCallbacks,\n nvlGraph: styledGraph,\n selected,\n setInteractionMode,\n setSelected,\n });\n\n const [isSidePanelOpen, setIsSidePanelOpen] = useSemicontrolledState({\n isControlled: rawSidepanel?.isSidePanelOpen !== undefined,\n onChange: rawSidepanel?.setIsSidePanelOpen,\n state: rawSidepanel?.isSidePanelOpen ?? true,\n });\n const [sidePanelWidth, setSidePanelWidth] = useSemicontrolledState({\n isControlled: rawSidepanel?.sidePanelWidth !== undefined,\n onChange: rawSidepanel?.onSidePanelResize,\n state: rawSidepanel?.sidePanelWidth ?? 400,\n });\n\n const sidepanel = useMemo((): Sidepanel | null => {\n if (rawSidepanel === undefined) {\n return {\n children: <GraphVisualization.SingleSelectionSidePanelContents />,\n isSidePanelOpen,\n onSidePanelResize: setSidePanelWidth,\n setIsSidePanelOpen,\n sidePanelWidth,\n };\n }\n return rawSidepanel;\n }, [\n rawSidepanel,\n isSidePanelOpen,\n setIsSidePanelOpen,\n sidePanelWidth,\n setSidePanelWidth,\n ]);\n\n const Component: React.ElementType = as ?? 'div';\n return (\n <Component\n ref={ref}\n className={cx('ndl-graph-visualization-container', className)}\n style={style}\n {...htmlAttributes}\n >\n <GraphVisualizationContext.Provider\n value={{\n compiledStyleRules,\n gesture,\n interactionMode,\n layout,\n metadataLookup,\n nvlGraph: styledGraph,\n nvlInstance: nvlRef,\n portalTarget,\n selected,\n setGesture,\n setLayout,\n sidepanel,\n }}\n >\n <div className=\"ndl-graph-visualization\">\n <InteractiveNvlWrapper\n key={key}\n nodes={nodesWithState}\n rels={relsWithState}\n nvlOptions={{\n ...DEFAULT_NVL_OPTIONS,\n instanceId,\n styling: {\n defaultRelationshipColor: border.strongest,\n disabledItemColor: bg.strong,\n disabledItemFontColor: text.weakest,\n dropShadowColor: border.weak,\n selectedInnerBorderColor: bg.default,\n },\n ...nvlOptions,\n layout,\n layoutOptions: layoutOptions ?? nvlOptions.layoutOptions,\n }}\n nvlCallbacks={{\n onLayoutComputing(isComputing) {\n if (!isComputing) {\n nvlRef.current?.fit(\n nvlRef.current.getNodes().map((neighbors) => neighbors.id),\n { noPan: true },\n );\n }\n },\n ...nvlCallbacks,\n }}\n mouseEventCallbacks={wrappedMouseEventCallbacks}\n ref={nvlRef}\n {...restProps}\n />\n {topLeftIsland !== null && (\n <InteractionIsland placement=\"top-left\">\n {topLeftIsland}\n </InteractionIsland>\n )}\n\n {topRightIsland !== null && (\n <InteractionIsland placement=\"top-right\">\n {topRightIsland}\n </InteractionIsland>\n )}\n\n {bottomLeftIsland !== null && (\n <InteractionIsland placement=\"bottom-left\">\n {bottomLeftIsland}\n </InteractionIsland>\n )}\n\n {bottomCenterIsland !== null && (\n <InteractionIsland placement=\"bottom-center\">\n {bottomCenterIsland}\n </InteractionIsland>\n )}\n\n {bottomRightIsland !== null && (\n <InteractionIsland placement=\"bottom-right\">\n {bottomRightIsland}\n </InteractionIsland>\n )}\n </div>\n {sidepanel && <GraphVisualizationSidepanel sidepanel={sidepanel} />}\n </GraphVisualizationContext.Provider>\n </Component>\n );\n}\n\n/**\n * Zoom in button for use within a GraphVisualization component.\n *\n * @remarks\n * Increases zoom level by 1.3x\n *\n * @alpha\n */\nGraphVisualization.ZoomInButton = ZoomInButton;\n\n/**\n * Zoom out button for use within a GraphVisualization component.\n *\n * @remarks\n * Decreases zoom level by 0.7x\n *\n * @alpha\n */\nGraphVisualization.ZoomOutButton = ZoomOutButton;\n\n/**\n * Zoom to fit button for use within a GraphVisualization component.\n *\n * @remarks\n * Automatically adjusts zoom and pan to show all nodes and relationships\n *\n * @alpha\n */\nGraphVisualization.ZoomToFitButton = ZoomToFitButton;\n\n/**\n * Sidepanel toggle button for use within a GraphVisualization component.\n *\n * @remarks\n * Shows or hides the sidepanel containing node and relationship details.\n * Requires a sidepanel to be configured in the GraphVisualization component.\n *\n * @throws Error when used without a configured sidepanel\n *\n * @alpha\n */\nGraphVisualization.ToggleSidePanelButton = ToggleSidePanelButton;\n\n/**\n * Download button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a dropdown menu with download options. Supports PNG and SVG formats.\n * Captures the current visualization state including zoom level.\n *\n * @alpha\n */\nGraphVisualization.DownloadButton = DownloadButton;\n\n/**\n * Box selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables box selection mode where dragging creates a rectangular selection area.\n * Disabled unless the `setGesture` callback is passed.\n * Shows active state when enabled and supports keyboard shortcut 'B'.\n *\n * @alpha\n */\nGraphVisualization.BoxSelectButton = BoxSelectButton;\n\n/**\n * Lasso selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables lasso selection mode where dragging creates a free-form selection area.\n * Disabled unless the `setGesture` callback is passed.\n * Shows active state when enabled and supports keyboard shortcut 'L'.\n *\n * @alpha\n */\nGraphVisualization.LassoSelectButton = LassoSelectButton;\n\n/**\n * Single node selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables single selection mode where clicking selects individual nodes or relationships.\n * Shows active state when enabled and supports keyboard shortcut 'S'.\n *\n * @alpha\n */\nGraphVisualization.SingleSelectButton = SingleSelectButton;\n\n/**\n * Search button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables search mode where clicking opens a search input for filtering nodes and relationships.\n *\n * @alpha\n */\nGraphVisualization.SearchButton = SearchButton;\n\n/**\n * Single node selection side panel for use within a GraphVisualization component.\n *\n * @remarks\n * Displays detailed information about the selected node or relationship.\n * Panel is automatically opened when a node or relationship is selected.\n * Also when user click on the show panel button in the top right corner.\n *\n * @alpha\n */\nGraphVisualization.SingleSelectionSidePanelContents =\n SingleSelectionSidepanelContents;\n\n/**\n * Layout selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a menu to select different graph layout algorithms.\n *\n * By default, the menu includes the **force-based** (`d3Force`) and\n * **hierarchical** layouts. Additional layouts can be enabled via configuration.\n *\n * @see {@link LayoutSelectOption} for the full set of layout options supported by NVL.\n *\n * @alpha\n */\nGraphVisualization.LayoutSelectButton = LayoutSelectButton;\n\n/**\n * Gesture selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a menu to select different interaction gestures.\n *\n * By default, the menu includes **single**, **box**, and **lasso** selection gestures.\n *\n * @see {@link GestureSelectOption} for the full set of gesture options supported by NVL.\n *\n * @alpha\n */\nGraphVisualization.GestureSelectButton = GestureSelectButton;\n"]}
|
|
@@ -52,7 +52,7 @@ function useManagedNodeState({ selected, setSelected, gesture, interactionMode,
|
|
|
52
52
|
document.removeEventListener('keyup', stopPanningReleaseSpace);
|
|
53
53
|
};
|
|
54
54
|
}, [panOnSpace, stopPanningReleaseSpace]);
|
|
55
|
-
const { onBoxSelect: originalBoxSelect, onLassoSelect: originalOnLassoSelect, onLassoStarted, onBoxStarted, onPan = true, onHover, onHoverNodeMargin, onNodeClick: originalOnNodeClick, onRelationshipClick: originalOnRelationshipClick, onDragStart: originalOnDragStart, onDragEnd: originalOnDragEnd, onDrawEnded: originalOnDrawEnded, onDrawStarted: originalOnDrawStarted, onCanvasClick: originalOnCanvasClick, onNodeDoubleClick: originalOnNodeDoubleClick, onRelationshipDoubleClick: originalOnRelationshipDoubleClick, } = mouseEventCallbacks;
|
|
55
|
+
const { onBoxSelect: originalBoxSelect, onLassoSelect: originalOnLassoSelect, onLassoStarted, onBoxStarted, onPan = true, onHover, onHoverNodeMargin, onNodeClick: originalOnNodeClick, onRelationshipClick: originalOnRelationshipClick, onDragStart: originalOnDragStart, onDragEnd: originalOnDragEnd, onDrawEnded: originalOnDrawEnded, onDrawStarted: originalOnDrawStarted, onCanvasClick: originalOnCanvasClick, onNodeDoubleClick: originalOnNodeDoubleClick, onRelationshipDoubleClick: originalOnRelationshipDoubleClick, onZoom: originalOnZoom, onZoomAndPan: originalOnZoomAndPan, } = mouseEventCallbacks;
|
|
56
56
|
const onCanvasClick = (0, react_1.useCallback)((evt) => {
|
|
57
57
|
if (isClickingOnTextInput(evt)) {
|
|
58
58
|
return;
|
|
@@ -217,12 +217,10 @@ function useManagedNodeState({ selected, setSelected, gesture, interactionMode,
|
|
|
217
217
|
const shouldEnableLasso = isSelectMode && gesture === 'lasso';
|
|
218
218
|
const shouldEnablePan = interactionMode === 'pan' || (isSelectMode && gesture === 'single');
|
|
219
219
|
const canDrag = interactionMode === 'drag' || interactionMode === 'select';
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
: false, onZoom: (_a = mouseEventCallbacks.onZoom) !== null && _a !== void 0 ? _a : true }));
|
|
225
|
-
}, [
|
|
220
|
+
const hasCustomZoomCallback = originalOnZoom !== undefined || originalOnZoomAndPan !== undefined;
|
|
221
|
+
const wrappedMouseEventCallbacks = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, mouseEventCallbacks), { onBoxSelect: shouldEnableBox ? onBoxSelect : false, onBoxStarted: shouldEnableBox ? onBoxStarted : false, onCanvasClick: isSelectMode ? onCanvasClick : false, onDragEnd: canDrag ? onDragEnd : false, onDragStart: canDrag ? onDragStart : false, onDrawEnded: isDrawMode ? onDrawEnded : false, onDrawStarted: isDrawMode ? onDrawStarted : false, onHover: isSelectMode ? onHover : false, onHoverNodeMargin: isDrawMode ? onHoverNodeMargin : false, onLassoSelect: shouldEnableLasso ? onLassoSelect : false, onLassoStarted: shouldEnableLasso ? onLassoStarted : false, onNodeClick: isSelectMode ? onNodeClick : false, onNodeDoubleClick: isSelectMode ? onNodeDoubleClick : false, onPan: shouldEnablePan ? onPan : false, onRelationshipClick: isSelectMode ? onRelationshipClick : false, onRelationshipDoubleClick: isSelectMode
|
|
222
|
+
? onRelationshipDoubleClick
|
|
223
|
+
: false, onZoomAndPan: hasCustomZoomCallback ? originalOnZoomAndPan : true })), [
|
|
226
224
|
canDrag,
|
|
227
225
|
shouldEnableBox,
|
|
228
226
|
shouldEnableLasso,
|
|
@@ -246,6 +244,8 @@ function useManagedNodeState({ selected, setSelected, gesture, interactionMode,
|
|
|
246
244
|
onPan,
|
|
247
245
|
onRelationshipClick,
|
|
248
246
|
onRelationshipDoubleClick,
|
|
247
|
+
hasCustomZoomCallback,
|
|
248
|
+
originalOnZoomAndPan,
|
|
249
249
|
]);
|
|
250
250
|
const selectionSet = (0, react_1.useMemo)(() => ({
|
|
251
251
|
nodeIds: new Set(selected.nodeIds),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-managed-node-state.js","sourceRoot":"","sources":["../../src/use-managed-node-state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type HitTargets, type Node, type Relationship } from '@neo4j-nvl/base';\nimport { type MouseEventCallbacks } from '@neo4j-nvl/react';\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport {\n type Gesture,\n type GraphSelection,\n type InteractionMode,\n} from './graph-visualization-context';\nimport { isMac } from './utils';\n\nconst isMultiSelectKeyPressed = (evt: MouseEvent): boolean =>\n (!isMac && evt.ctrlKey) || (isMac && evt.metaKey);\n\nconst isClickingOnTextInput = (e: MouseEvent): boolean => {\n if (!(e.target instanceof HTMLElement)) {\n return false;\n }\n return (\n e.target.isContentEditable ||\n ['INPUT', 'TEXTAREA'].includes(e.target.tagName)\n );\n};\n\nexport type ManagedNodeStateArgs = {\n selected: GraphSelection;\n setSelected: (newSelection: GraphSelection) => void;\n gesture: Gesture;\n interactionMode: InteractionMode;\n setInteractionMode: (newInteractionMode: InteractionMode) => void;\n mouseEventCallbacks: MouseEventCallbacks;\n nvlGraph: {\n nodes: Node[];\n rels: Relationship[];\n };\n highlightedNodeIds?: string[];\n highlightedRelationshipIds?: string[];\n};\n\nexport function useManagedNodeState({\n selected,\n setSelected,\n gesture,\n interactionMode,\n setInteractionMode,\n mouseEventCallbacks,\n nvlGraph,\n highlightedNodeIds,\n highlightedRelationshipIds,\n}: ManagedNodeStateArgs) {\n const panOnSpace = useCallback(\n (evt: KeyboardEvent) => {\n // We could check the gesture here\n // but it doesn't really matter if we switch to panning mode even in single select\n if (interactionMode === 'select' && evt.key === ' ') {\n setInteractionMode('pan');\n }\n },\n [interactionMode, setInteractionMode],\n );\n\n const stopPanningReleaseSpace = useCallback(\n (evt: KeyboardEvent) => {\n if (interactionMode === 'pan' && evt.key === ' ') {\n setInteractionMode('select');\n }\n },\n [interactionMode, setInteractionMode],\n );\n\n useEffect(() => {\n document.addEventListener('keydown', panOnSpace);\n document.addEventListener('keyup', stopPanningReleaseSpace);\n return () => {\n document.removeEventListener('keydown', panOnSpace);\n document.removeEventListener('keyup', stopPanningReleaseSpace);\n };\n }, [panOnSpace, stopPanningReleaseSpace]);\n\n const {\n onBoxSelect: originalBoxSelect,\n onLassoSelect: originalOnLassoSelect,\n onLassoStarted,\n onBoxStarted,\n onPan = true,\n onHover,\n onHoverNodeMargin,\n onNodeClick: originalOnNodeClick,\n onRelationshipClick: originalOnRelationshipClick,\n onDragStart: originalOnDragStart,\n onDragEnd: originalOnDragEnd,\n onDrawEnded: originalOnDrawEnded,\n onDrawStarted: originalOnDrawStarted,\n onCanvasClick: originalOnCanvasClick,\n onNodeDoubleClick: originalOnNodeDoubleClick,\n onRelationshipDoubleClick: originalOnRelationshipDoubleClick,\n } = mouseEventCallbacks;\n\n const onCanvasClick = useCallback(\n (evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n // Clear selection\n setSelected({ nodeIds: [], relationshipIds: [] });\n\n if (typeof originalOnCanvasClick === 'function') {\n originalOnCanvasClick(evt);\n }\n },\n [originalOnCanvasClick, setSelected],\n );\n\n const onDragStart = useCallback(\n (draggedNodes: Node[], evt: MouseEvent) => {\n setInteractionMode('drag');\n\n // Update Selection\n const draggedNodeIds = draggedNodes.map((n) => n.id);\n if (selected.nodeIds.length === 0 || isMultiSelectKeyPressed(evt)) {\n setSelected({\n nodeIds: draggedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n return;\n }\n setSelected({\n nodeIds: draggedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n\n if (typeof originalOnDragStart === 'function') {\n originalOnDragStart(draggedNodes, evt);\n }\n },\n [setSelected, originalOnDragStart, selected, setInteractionMode],\n );\n\n const onDragEnd = useCallback(\n (draggedNodes: Node[], evt: MouseEvent) => {\n if (typeof originalOnDragEnd === 'function') {\n originalOnDragEnd(draggedNodes, evt);\n }\n setInteractionMode('select');\n },\n [originalOnDragEnd, setInteractionMode],\n );\n\n // wrapping so that there's a function passed, even if the original function is undefined\n const onDrawStarted = useCallback(\n (evt: MouseEvent) => {\n if (typeof originalOnDrawStarted === 'function') {\n originalOnDrawStarted(evt);\n }\n },\n [originalOnDrawStarted],\n );\n\n const onDrawEnded = useCallback(\n (\n newRelationshipToAdd: Relationship | null,\n newTargetNodeToAdd: Node | null,\n event: MouseEvent,\n ) => {\n if (typeof originalOnDrawEnded === 'function') {\n originalOnDrawEnded(newRelationshipToAdd, newTargetNodeToAdd, event);\n }\n },\n [originalOnDrawEnded],\n );\n\n const onNodeClick = useCallback(\n (node: Node, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n if (isMultiSelectKeyPressed(evt)) {\n // if not selected, add to selection, otherwise deselect\n const isNodeSelected = selected.nodeIds.includes(node.id);\n if (isNodeSelected) {\n const newSelectedNodeIds = selected.nodeIds.filter(\n (id) => id !== node.id,\n );\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n } else {\n const newSelectedNodeIds = [...selected.nodeIds, node.id];\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n }\n } else {\n setSelected({ nodeIds: [node.id], relationshipIds: [] });\n }\n if (typeof originalOnNodeClick === 'function') {\n originalOnNodeClick(node, hitElements, evt);\n }\n },\n [setSelected, selected, originalOnNodeClick],\n );\n\n const onRelationshipClick = useCallback(\n (relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n if (isMultiSelectKeyPressed(evt)) {\n // if not selected, add to selection, otherwise deselect\n const isRelationshipSelected = selected.relationshipIds.includes(\n relationship.id,\n );\n if (isRelationshipSelected) {\n const newSelectedRelIds = selected.relationshipIds.filter(\n (id) => id !== relationship.id,\n );\n setSelected({\n nodeIds: selected.nodeIds,\n relationshipIds: newSelectedRelIds,\n });\n } else {\n const newSelectedRelIds = [\n ...selected.relationshipIds,\n relationship.id,\n ];\n setSelected({\n nodeIds: selected.nodeIds,\n relationshipIds: newSelectedRelIds,\n });\n }\n } else {\n setSelected({ nodeIds: [], relationshipIds: [relationship.id] });\n }\n if (typeof originalOnRelationshipClick === 'function') {\n originalOnRelationshipClick(relationship, hitElements, evt);\n }\n },\n [setSelected, selected, originalOnRelationshipClick],\n );\n\n const onNodeDoubleClick = useCallback(\n (node: Node, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n if (typeof originalOnNodeDoubleClick === 'function') {\n originalOnNodeDoubleClick(node, hitElements, evt);\n }\n },\n [originalOnNodeDoubleClick],\n );\n\n const onRelationshipDoubleClick = useCallback(\n (relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n if (typeof originalOnRelationshipDoubleClick === 'function') {\n originalOnRelationshipDoubleClick(relationship, hitElements, evt);\n }\n },\n [originalOnRelationshipDoubleClick],\n );\n\n const onMultiSelect = useCallback(\n (nodes: Node[], rels: Relationship[], evt: MouseEvent) => {\n const nodeIds = nodes.map((n) => n.id);\n const relationshipIds = rels.map((r) => r.id);\n if (isMultiSelectKeyPressed(evt)) {\n const currentlySelectedNodeIds = selected.nodeIds;\n const currentlySelectedRelIds = selected.relationshipIds;\n\n // Toggle selection: items that are already selected should be removed from selection,\n // those that are not should be added\n const xor = (a: string[], b: string[]) => [\n ...new Set(\n [...a, ...b].filter((id) => !a.includes(id) || !b.includes(id)),\n ),\n ];\n\n const newSelectedNodeIds = xor(currentlySelectedNodeIds, nodeIds);\n const newSelectedRelIds = xor(currentlySelectedRelIds, relationshipIds);\n\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: newSelectedRelIds,\n });\n } else {\n // REPLACE selection\n setSelected({ nodeIds: nodeIds, relationshipIds: relationshipIds });\n }\n },\n [setSelected, selected],\n );\n\n const onLassoSelect = useCallback(\n (\n { nodes, rels }: { nodes: Node[]; rels: Relationship[] },\n evt: MouseEvent,\n ) => {\n onMultiSelect(nodes, rels, evt);\n if (typeof originalOnLassoSelect === 'function') {\n originalOnLassoSelect({ nodes, rels }, evt);\n }\n },\n [onMultiSelect, originalOnLassoSelect],\n );\n\n const onBoxSelect = useCallback(\n (\n { nodes, rels }: { nodes: Node[]; rels: Relationship[] },\n evt: MouseEvent,\n ) => {\n onMultiSelect(nodes, rels, evt);\n if (typeof originalBoxSelect === 'function') {\n originalBoxSelect({ nodes, rels }, evt);\n }\n },\n [onMultiSelect, originalBoxSelect],\n );\n\n const isDrawMode = interactionMode === 'draw';\n\n const isSelectMode = interactionMode === 'select';\n const shouldEnableBox = isSelectMode && gesture === 'box';\n const shouldEnableLasso = isSelectMode && gesture === 'lasso';\n\n const shouldEnablePan =\n interactionMode === 'pan' || (isSelectMode && gesture === 'single');\n\n const canDrag = interactionMode === 'drag' || interactionMode === 'select';\n\n const wrappedMouseEventCallbacks = useMemo(\n () => ({\n ...mouseEventCallbacks,\n onBoxSelect: shouldEnableBox ? onBoxSelect : false,\n onBoxStarted: shouldEnableBox ? onBoxStarted : false,\n onCanvasClick: isSelectMode ? onCanvasClick : false,\n onDragEnd: canDrag ? onDragEnd : false,\n onDragStart: canDrag ? onDragStart : false,\n onDrawEnded: isDrawMode ? onDrawEnded : false,\n onDrawStarted: isDrawMode ? onDrawStarted : false,\n onHover: isSelectMode ? onHover : false,\n onHoverNodeMargin: isDrawMode ? onHoverNodeMargin : false,\n onLassoSelect: shouldEnableLasso ? onLassoSelect : false,\n onLassoStarted: shouldEnableLasso ? onLassoStarted : false,\n onNodeClick: isSelectMode ? onNodeClick : false,\n onNodeDoubleClick: isSelectMode ? onNodeDoubleClick : false,\n onPan: shouldEnablePan ? onPan : false,\n onRelationshipClick: isSelectMode ? onRelationshipClick : false,\n onRelationshipDoubleClick: isSelectMode\n ? onRelationshipDoubleClick\n : false,\n onZoom: mouseEventCallbacks.onZoom ?? true,\n }),\n [\n canDrag,\n shouldEnableBox,\n shouldEnableLasso,\n shouldEnablePan,\n isDrawMode,\n isSelectMode,\n mouseEventCallbacks,\n onBoxSelect,\n onBoxStarted,\n onCanvasClick,\n onDragEnd,\n onDragStart,\n onDrawEnded,\n onDrawStarted,\n onHover,\n onHoverNodeMargin,\n onLassoSelect,\n onLassoStarted,\n onNodeClick,\n onNodeDoubleClick,\n onPan,\n onRelationshipClick,\n onRelationshipDoubleClick,\n ],\n );\n\n const selectionSet = useMemo(\n () => ({\n nodeIds: new Set(selected.nodeIds),\n relIds: new Set(selected.relationshipIds),\n }),\n [selected],\n );\n\n const highlightedNodeSet = useMemo(\n () =>\n highlightedNodeIds !== undefined ? new Set(highlightedNodeIds) : null,\n [highlightedNodeIds],\n );\n const highlightedRelSet = useMemo(\n () =>\n highlightedRelationshipIds !== undefined\n ? new Set(highlightedRelationshipIds)\n : null,\n [highlightedRelationshipIds],\n );\n\n const nodesWithState = useMemo(\n () =>\n nvlGraph.nodes.map((n) => ({\n ...n,\n disabled: highlightedNodeSet ? !highlightedNodeSet.has(n.id) : false,\n selected: selectionSet.nodeIds.has(n.id),\n })),\n [nvlGraph.nodes, selectionSet, highlightedNodeSet],\n );\n\n const relsWithState = useMemo(\n () =>\n nvlGraph.rels.map((r) => ({\n ...r,\n disabled: highlightedRelSet ? !highlightedRelSet.has(r.id) : false,\n selected: selectionSet.relIds.has(r.id),\n })),\n [nvlGraph.rels, selectionSet, highlightedRelSet],\n );\n\n return { nodesWithState, relsWithState, wrappedMouseEventCallbacks };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-managed-node-state.js","sourceRoot":"","sources":["../../src/use-managed-node-state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type HitTargets, type Node, type Relationship } from '@neo4j-nvl/base';\nimport { type MouseEventCallbacks } from '@neo4j-nvl/react';\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport {\n type Gesture,\n type GraphSelection,\n type InteractionMode,\n} from './graph-visualization-context';\nimport { isMac } from './utils';\n\nconst isMultiSelectKeyPressed = (evt: MouseEvent): boolean =>\n (!isMac && evt.ctrlKey) || (isMac && evt.metaKey);\n\nconst isClickingOnTextInput = (e: MouseEvent): boolean => {\n if (!(e.target instanceof HTMLElement)) {\n return false;\n }\n return (\n e.target.isContentEditable ||\n ['INPUT', 'TEXTAREA'].includes(e.target.tagName)\n );\n};\n\nexport type ManagedNodeStateArgs = {\n selected: GraphSelection;\n setSelected: (newSelection: GraphSelection) => void;\n gesture: Gesture;\n interactionMode: InteractionMode;\n setInteractionMode: (newInteractionMode: InteractionMode) => void;\n mouseEventCallbacks: MouseEventCallbacks;\n nvlGraph: {\n nodes: Node[];\n rels: Relationship[];\n };\n highlightedNodeIds?: string[];\n highlightedRelationshipIds?: string[];\n};\n\nexport function useManagedNodeState({\n selected,\n setSelected,\n gesture,\n interactionMode,\n setInteractionMode,\n mouseEventCallbacks,\n nvlGraph,\n highlightedNodeIds,\n highlightedRelationshipIds,\n}: ManagedNodeStateArgs) {\n const panOnSpace = useCallback(\n (evt: KeyboardEvent) => {\n // We could check the gesture here\n // but it doesn't really matter if we switch to panning mode even in single select\n if (interactionMode === 'select' && evt.key === ' ') {\n setInteractionMode('pan');\n }\n },\n [interactionMode, setInteractionMode],\n );\n\n const stopPanningReleaseSpace = useCallback(\n (evt: KeyboardEvent) => {\n if (interactionMode === 'pan' && evt.key === ' ') {\n setInteractionMode('select');\n }\n },\n [interactionMode, setInteractionMode],\n );\n\n useEffect(() => {\n document.addEventListener('keydown', panOnSpace);\n document.addEventListener('keyup', stopPanningReleaseSpace);\n return () => {\n document.removeEventListener('keydown', panOnSpace);\n document.removeEventListener('keyup', stopPanningReleaseSpace);\n };\n }, [panOnSpace, stopPanningReleaseSpace]);\n\n const {\n onBoxSelect: originalBoxSelect,\n onLassoSelect: originalOnLassoSelect,\n onLassoStarted,\n onBoxStarted,\n onPan = true,\n onHover,\n onHoverNodeMargin,\n onNodeClick: originalOnNodeClick,\n onRelationshipClick: originalOnRelationshipClick,\n onDragStart: originalOnDragStart,\n onDragEnd: originalOnDragEnd,\n onDrawEnded: originalOnDrawEnded,\n onDrawStarted: originalOnDrawStarted,\n onCanvasClick: originalOnCanvasClick,\n onNodeDoubleClick: originalOnNodeDoubleClick,\n onRelationshipDoubleClick: originalOnRelationshipDoubleClick,\n\n onZoom: originalOnZoom,\n onZoomAndPan: originalOnZoomAndPan,\n } = mouseEventCallbacks;\n\n const onCanvasClick = useCallback(\n (evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n // Clear selection\n setSelected({ nodeIds: [], relationshipIds: [] });\n\n if (typeof originalOnCanvasClick === 'function') {\n originalOnCanvasClick(evt);\n }\n },\n [originalOnCanvasClick, setSelected],\n );\n\n const onDragStart = useCallback(\n (draggedNodes: Node[], evt: MouseEvent) => {\n setInteractionMode('drag');\n\n // Update Selection\n const draggedNodeIds = draggedNodes.map((n) => n.id);\n if (selected.nodeIds.length === 0 || isMultiSelectKeyPressed(evt)) {\n setSelected({\n nodeIds: draggedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n return;\n }\n setSelected({\n nodeIds: draggedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n\n if (typeof originalOnDragStart === 'function') {\n originalOnDragStart(draggedNodes, evt);\n }\n },\n [setSelected, originalOnDragStart, selected, setInteractionMode],\n );\n\n const onDragEnd = useCallback(\n (draggedNodes: Node[], evt: MouseEvent) => {\n if (typeof originalOnDragEnd === 'function') {\n originalOnDragEnd(draggedNodes, evt);\n }\n setInteractionMode('select');\n },\n [originalOnDragEnd, setInteractionMode],\n );\n\n // wrapping so that there's a function passed, even if the original function is undefined\n const onDrawStarted = useCallback(\n (evt: MouseEvent) => {\n if (typeof originalOnDrawStarted === 'function') {\n originalOnDrawStarted(evt);\n }\n },\n [originalOnDrawStarted],\n );\n\n const onDrawEnded = useCallback(\n (\n newRelationshipToAdd: Relationship | null,\n newTargetNodeToAdd: Node | null,\n event: MouseEvent,\n ) => {\n if (typeof originalOnDrawEnded === 'function') {\n originalOnDrawEnded(newRelationshipToAdd, newTargetNodeToAdd, event);\n }\n },\n [originalOnDrawEnded],\n );\n\n const onNodeClick = useCallback(\n (node: Node, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n if (isMultiSelectKeyPressed(evt)) {\n // if not selected, add to selection, otherwise deselect\n const isNodeSelected = selected.nodeIds.includes(node.id);\n if (isNodeSelected) {\n const newSelectedNodeIds = selected.nodeIds.filter(\n (id) => id !== node.id,\n );\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n } else {\n const newSelectedNodeIds = [...selected.nodeIds, node.id];\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n }\n } else {\n setSelected({ nodeIds: [node.id], relationshipIds: [] });\n }\n if (typeof originalOnNodeClick === 'function') {\n originalOnNodeClick(node, hitElements, evt);\n }\n },\n [setSelected, selected, originalOnNodeClick],\n );\n\n const onRelationshipClick = useCallback(\n (relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n if (isMultiSelectKeyPressed(evt)) {\n // if not selected, add to selection, otherwise deselect\n const isRelationshipSelected = selected.relationshipIds.includes(\n relationship.id,\n );\n if (isRelationshipSelected) {\n const newSelectedRelIds = selected.relationshipIds.filter(\n (id) => id !== relationship.id,\n );\n setSelected({\n nodeIds: selected.nodeIds,\n relationshipIds: newSelectedRelIds,\n });\n } else {\n const newSelectedRelIds = [\n ...selected.relationshipIds,\n relationship.id,\n ];\n setSelected({\n nodeIds: selected.nodeIds,\n relationshipIds: newSelectedRelIds,\n });\n }\n } else {\n setSelected({ nodeIds: [], relationshipIds: [relationship.id] });\n }\n if (typeof originalOnRelationshipClick === 'function') {\n originalOnRelationshipClick(relationship, hitElements, evt);\n }\n },\n [setSelected, selected, originalOnRelationshipClick],\n );\n\n const onNodeDoubleClick = useCallback(\n (node: Node, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n if (typeof originalOnNodeDoubleClick === 'function') {\n originalOnNodeDoubleClick(node, hitElements, evt);\n }\n },\n [originalOnNodeDoubleClick],\n );\n\n const onRelationshipDoubleClick = useCallback(\n (relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n if (typeof originalOnRelationshipDoubleClick === 'function') {\n originalOnRelationshipDoubleClick(relationship, hitElements, evt);\n }\n },\n [originalOnRelationshipDoubleClick],\n );\n\n const onMultiSelect = useCallback(\n (nodes: Node[], rels: Relationship[], evt: MouseEvent) => {\n const nodeIds = nodes.map((n) => n.id);\n const relationshipIds = rels.map((r) => r.id);\n if (isMultiSelectKeyPressed(evt)) {\n const currentlySelectedNodeIds = selected.nodeIds;\n const currentlySelectedRelIds = selected.relationshipIds;\n\n // Toggle selection: items that are already selected should be removed from selection,\n // those that are not should be added\n const xor = (a: string[], b: string[]) => [\n ...new Set(\n [...a, ...b].filter((id) => !a.includes(id) || !b.includes(id)),\n ),\n ];\n\n const newSelectedNodeIds = xor(currentlySelectedNodeIds, nodeIds);\n const newSelectedRelIds = xor(currentlySelectedRelIds, relationshipIds);\n\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: newSelectedRelIds,\n });\n } else {\n // REPLACE selection\n setSelected({ nodeIds: nodeIds, relationshipIds: relationshipIds });\n }\n },\n [setSelected, selected],\n );\n\n const onLassoSelect = useCallback(\n (\n { nodes, rels }: { nodes: Node[]; rels: Relationship[] },\n evt: MouseEvent,\n ) => {\n onMultiSelect(nodes, rels, evt);\n if (typeof originalOnLassoSelect === 'function') {\n originalOnLassoSelect({ nodes, rels }, evt);\n }\n },\n [onMultiSelect, originalOnLassoSelect],\n );\n\n const onBoxSelect = useCallback(\n (\n { nodes, rels }: { nodes: Node[]; rels: Relationship[] },\n evt: MouseEvent,\n ) => {\n onMultiSelect(nodes, rels, evt);\n if (typeof originalBoxSelect === 'function') {\n originalBoxSelect({ nodes, rels }, evt);\n }\n },\n [onMultiSelect, originalBoxSelect],\n );\n\n const isDrawMode = interactionMode === 'draw';\n\n const isSelectMode = interactionMode === 'select';\n const shouldEnableBox = isSelectMode && gesture === 'box';\n const shouldEnableLasso = isSelectMode && gesture === 'lasso';\n\n const shouldEnablePan =\n interactionMode === 'pan' || (isSelectMode && gesture === 'single');\n\n const canDrag = interactionMode === 'drag' || interactionMode === 'select';\n\n const hasCustomZoomCallback =\n originalOnZoom !== undefined || originalOnZoomAndPan !== undefined;\n\n const wrappedMouseEventCallbacks = useMemo(\n () => ({\n ...mouseEventCallbacks,\n onBoxSelect: shouldEnableBox ? onBoxSelect : false,\n onBoxStarted: shouldEnableBox ? onBoxStarted : false,\n onCanvasClick: isSelectMode ? onCanvasClick : false,\n onDragEnd: canDrag ? onDragEnd : false,\n onDragStart: canDrag ? onDragStart : false,\n onDrawEnded: isDrawMode ? onDrawEnded : false,\n onDrawStarted: isDrawMode ? onDrawStarted : false,\n onHover: isSelectMode ? onHover : false,\n onHoverNodeMargin: isDrawMode ? onHoverNodeMargin : false,\n onLassoSelect: shouldEnableLasso ? onLassoSelect : false,\n onLassoStarted: shouldEnableLasso ? onLassoStarted : false,\n onNodeClick: isSelectMode ? onNodeClick : false,\n onNodeDoubleClick: isSelectMode ? onNodeDoubleClick : false,\n onPan: shouldEnablePan ? onPan : false,\n onRelationshipClick: isSelectMode ? onRelationshipClick : false,\n onRelationshipDoubleClick: isSelectMode\n ? onRelationshipDoubleClick\n : false,\n onZoomAndPan: hasCustomZoomCallback ? originalOnZoomAndPan : true,\n }),\n [\n canDrag,\n shouldEnableBox,\n shouldEnableLasso,\n shouldEnablePan,\n isDrawMode,\n isSelectMode,\n mouseEventCallbacks,\n onBoxSelect,\n onBoxStarted,\n onCanvasClick,\n onDragEnd,\n onDragStart,\n onDrawEnded,\n onDrawStarted,\n onHover,\n onHoverNodeMargin,\n onLassoSelect,\n onLassoStarted,\n onNodeClick,\n onNodeDoubleClick,\n onPan,\n onRelationshipClick,\n onRelationshipDoubleClick,\n hasCustomZoomCallback,\n originalOnZoomAndPan,\n ],\n );\n\n const selectionSet = useMemo(\n () => ({\n nodeIds: new Set(selected.nodeIds),\n relIds: new Set(selected.relationshipIds),\n }),\n [selected],\n );\n\n const highlightedNodeSet = useMemo(\n () =>\n highlightedNodeIds !== undefined ? new Set(highlightedNodeIds) : null,\n [highlightedNodeIds],\n );\n const highlightedRelSet = useMemo(\n () =>\n highlightedRelationshipIds !== undefined\n ? new Set(highlightedRelationshipIds)\n : null,\n [highlightedRelationshipIds],\n );\n\n const nodesWithState = useMemo(\n () =>\n nvlGraph.nodes.map((n) => ({\n ...n,\n disabled: highlightedNodeSet ? !highlightedNodeSet.has(n.id) : false,\n selected: selectionSet.nodeIds.has(n.id),\n })),\n [nvlGraph.nodes, selectionSet, highlightedNodeSet],\n );\n\n const relsWithState = useMemo(\n () =>\n nvlGraph.rels.map((r) => ({\n ...r,\n disabled: highlightedRelSet ? !highlightedRelSet.has(r.id) : false,\n selected: selectionSet.relIds.has(r.id),\n })),\n [nvlGraph.rels, selectionSet, highlightedRelSet],\n );\n\n return { nodesWithState, relsWithState, wrappedMouseEventCallbacks };\n}\n"]}
|
|
@@ -58,6 +58,7 @@ export const DEFAULT_NVL_OPTIONS = {
|
|
|
58
58
|
maxZoom: 3,
|
|
59
59
|
minZoom: 0.05,
|
|
60
60
|
relationshipThreshold: 0.55,
|
|
61
|
+
renderer: 'canvas',
|
|
61
62
|
};
|
|
62
63
|
const DEFAULT_COMPONENTS = {
|
|
63
64
|
bottomLeftIsland: null,
|
|
@@ -125,8 +126,11 @@ const DEFAULT_COMPONENTS = {
|
|
|
125
126
|
* @alpha
|
|
126
127
|
*/
|
|
127
128
|
export function GraphVisualization(_a) {
|
|
128
|
-
var _b, _c;
|
|
129
|
-
var { nvlRef: rawNvlRef, nvlCallbacks, nvlOptions, sidepanel: rawSidepanel, nodes: rawNodes, rels: rawRels, highlightedNodeIds, highlightedRelationshipIds, topLeftIsland = DEFAULT_COMPONENTS.topLeftIsland, topRightIsland = DEFAULT_COMPONENTS.topRightIsland, bottomLeftIsland = DEFAULT_COMPONENTS.bottomLeftIsland, bottomCenterIsland = DEFAULT_COMPONENTS.bottomCenterIsland, bottomRightIsland = DEFAULT_COMPONENTS.bottomRightIsland, gesture = 'single', setGesture, layout: rawLayout, setLayout: rawSetLayout, portalTarget, selected: rawSelected, setSelected: rawSetSelected, interactionMode: rawInteractionMode, setInteractionMode: rawSetInteractionMode, mouseEventCallbacks = {}, className, style, htmlAttributes, ref, as, styleRules } = _a, restProps = __rest(_a, ["nvlRef", "nvlCallbacks", "nvlOptions", "sidepanel", "nodes", "rels", "highlightedNodeIds", "highlightedRelationshipIds", "topLeftIsland", "topRightIsland", "bottomLeftIsland", "bottomCenterIsland", "bottomRightIsland", "gesture", "setGesture", "layout", "setLayout", "portalTarget", "selected", "setSelected", "interactionMode", "setInteractionMode", "mouseEventCallbacks", "className", "style", "htmlAttributes", "ref", "as", "styleRules"]);
|
|
129
|
+
var _b, _c, _d;
|
|
130
|
+
var { nvlRef: rawNvlRef, nvlCallbacks, nvlOptions: rawNvlOptions, sidepanel: rawSidepanel, nodes: rawNodes, rels: rawRels, highlightedNodeIds, highlightedRelationshipIds, topLeftIsland = DEFAULT_COMPONENTS.topLeftIsland, topRightIsland = DEFAULT_COMPONENTS.topRightIsland, bottomLeftIsland = DEFAULT_COMPONENTS.bottomLeftIsland, bottomCenterIsland = DEFAULT_COMPONENTS.bottomCenterIsland, bottomRightIsland = DEFAULT_COMPONENTS.bottomRightIsland, gesture = 'single', setGesture, layout: rawLayout, layoutOptions, setLayout: rawSetLayout, portalTarget, selected: rawSelected, setSelected: rawSetSelected, interactionMode: rawInteractionMode, setInteractionMode: rawSetInteractionMode, mouseEventCallbacks = {}, className, style, htmlAttributes, ref, as, styleRules } = _a, restProps = __rest(_a, ["nvlRef", "nvlCallbacks", "nvlOptions", "sidepanel", "nodes", "rels", "highlightedNodeIds", "highlightedRelationshipIds", "topLeftIsland", "topRightIsland", "bottomLeftIsland", "bottomCenterIsland", "bottomRightIsland", "gesture", "setGesture", "layout", "layoutOptions", "setLayout", "portalTarget", "selected", "setSelected", "interactionMode", "setInteractionMode", "mouseEventCallbacks", "className", "style", "htmlAttributes", "ref", "as", "styleRules"]);
|
|
131
|
+
const _e = rawNvlOptions !== null && rawNvlOptions !== void 0 ? rawNvlOptions : {}, { useWebGL: isWebGLEnabled } = _e, nvlOptions = __rest(_e, ["useWebGL"]);
|
|
132
|
+
nvlOptions.renderer =
|
|
133
|
+
(_b = nvlOptions.renderer) !== null && _b !== void 0 ? _b : (isWebGLEnabled === true ? 'webgl' : DEFAULT_NVL_OPTIONS.renderer);
|
|
130
134
|
const nvlRef = useMemo(() => rawNvlRef !== null && rawNvlRef !== void 0 ? rawNvlRef : React.createRef(), [rawNvlRef]);
|
|
131
135
|
const instanceId = useId();
|
|
132
136
|
// Respect NDL theme changes
|
|
@@ -168,12 +172,12 @@ export function GraphVisualization(_a) {
|
|
|
168
172
|
const [isSidePanelOpen, setIsSidePanelOpen] = useSemicontrolledState({
|
|
169
173
|
isControlled: (rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.isSidePanelOpen) !== undefined,
|
|
170
174
|
onChange: rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.setIsSidePanelOpen,
|
|
171
|
-
state: (
|
|
175
|
+
state: (_c = rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.isSidePanelOpen) !== null && _c !== void 0 ? _c : true,
|
|
172
176
|
});
|
|
173
177
|
const [sidePanelWidth, setSidePanelWidth] = useSemicontrolledState({
|
|
174
178
|
isControlled: (rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.sidePanelWidth) !== undefined,
|
|
175
179
|
onChange: rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.onSidePanelResize,
|
|
176
|
-
state: (
|
|
180
|
+
state: (_d = rawSidepanel === null || rawSidepanel === void 0 ? void 0 : rawSidepanel.sidePanelWidth) !== null && _d !== void 0 ? _d : 400,
|
|
177
181
|
});
|
|
178
182
|
const sidepanel = useMemo(() => {
|
|
179
183
|
if (rawSidepanel === undefined) {
|
|
@@ -207,13 +211,13 @@ export function GraphVisualization(_a) {
|
|
|
207
211
|
setGesture,
|
|
208
212
|
setLayout,
|
|
209
213
|
sidepanel,
|
|
210
|
-
}, children: [_jsxs("div", { className: "ndl-graph-visualization", children: [_jsx(InteractiveNvlWrapper, Object.assign({
|
|
214
|
+
}, children: [_jsxs("div", { className: "ndl-graph-visualization", children: [_jsx(InteractiveNvlWrapper, Object.assign({ nodes: nodesWithState, rels: relsWithState, nvlOptions: Object.assign(Object.assign(Object.assign(Object.assign({}, DEFAULT_NVL_OPTIONS), { instanceId, styling: {
|
|
211
215
|
defaultRelationshipColor: border.strongest,
|
|
212
216
|
disabledItemColor: bg.strong,
|
|
213
217
|
disabledItemFontColor: text.weakest,
|
|
214
218
|
dropShadowColor: border.weak,
|
|
215
219
|
selectedInnerBorderColor: bg.default,
|
|
216
|
-
} }), nvlOptions), nvlCallbacks: Object.assign({ onLayoutComputing(isComputing) {
|
|
220
|
+
} }), nvlOptions), { layout, layoutOptions: layoutOptions !== null && layoutOptions !== void 0 ? layoutOptions : nvlOptions.layoutOptions }), nvlCallbacks: Object.assign({ onLayoutComputing(isComputing) {
|
|
217
221
|
var _a;
|
|
218
222
|
if (!isComputing) {
|
|
219
223
|
(_a = nvlRef.current) === null || _a === void 0 ? void 0 : _a.fit(nvlRef.current.getNodes().map((neighbors) => neighbors.id), { noPan: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-visualization.js","sourceRoot":"","sources":["../../src/graph-visualization.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { tokens } from '@neo4j-ndl/base';\nimport { IconButtonArray, useNeedleTheme } from '@neo4j-ndl/react';\nimport type NVL from '@neo4j-nvl/base';\nimport { type Layout } from '@neo4j-nvl/base';\nimport {\n InteractiveNvlWrapper,\n type InteractiveNvlWrapperProps,\n} from '@neo4j-nvl/react';\nimport { default as cx } from 'classnames';\nimport React, { useEffect, useId, useMemo, useState } from 'react';\n\nimport {\n BoxSelectButton,\n DownloadButton,\n GestureSelectButton,\n LassoSelectButton,\n LayoutSelectButton,\n SearchButton,\n SingleSelectButton,\n ToggleSidePanelButton,\n ZoomInButton,\n ZoomOutButton,\n ZoomToFitButton,\n} from './graph-visualization-buttons';\nimport {\n type Gesture,\n type GraphSelection,\n GraphVisualizationContext,\n type InteractionMode,\n type NeoNode,\n type NeoRel,\n type Sidepanel,\n} from './graph-visualization-context';\nimport { GraphVisualizationSidepanel } from './graph-visualization-sidepanel';\nimport { SingleSelectionSidepanelContents } from './sidepanel-components/single-selection-sidepanel-contents';\nimport { type GraphStyleRule } from './styling/style-types';\nimport { useGraphData } from './styling/use-graph-data';\nimport { useManagedNodeState } from './use-managed-node-state';\nimport { useSemicontrolledState } from './use-semi-controlled-state';\n\ntype Placement =\n | 'top-right'\n | 'bottom-right'\n | 'top-left'\n | 'bottom-left'\n | 'bottom-center';\n\nconst PLACEMENTS: Record<Placement, string> = {\n 'bottom-left': 'ndl-graph-visualization-interaction-island ndl-bottom-left',\n 'bottom-center':\n 'ndl-graph-visualization-interaction-island ndl-bottom-center',\n 'bottom-right': 'ndl-graph-visualization-interaction-island ndl-bottom-right',\n 'top-left': 'ndl-graph-visualization-interaction-island ndl-top-left',\n 'top-right': 'ndl-graph-visualization-interaction-island ndl-top-right',\n};\n\nconst InteractionIsland = ({\n children,\n className,\n placement,\n}: {\n children: React.ReactNode;\n placement: Placement;\n className?: string;\n}) => {\n return <div className={cx(PLACEMENTS[placement], className)}>{children}</div>;\n};\n\nexport const DEFAULT_NVL_OPTIONS = {\n disableTelemetry: true,\n disableWebGL: true,\n maxZoom: 3,\n minZoom: 0.05,\n relationshipThreshold: 0.55,\n};\n\nconst DEFAULT_COMPONENTS = {\n bottomLeftIsland: null,\n bottomCenterIsland: null,\n bottomRightIsland: (\n <IconButtonArray orientation=\"vertical\" isFloating size=\"small\">\n <ZoomInButton /> <ZoomOutButton /> <ZoomToFitButton />\n </IconButtonArray>\n ),\n topLeftIsland: null,\n topRightIsland: (\n <div className=\"ndl-graph-visualization-default-download-group\">\n <DownloadButton /> <ToggleSidePanelButton />\n </div>\n ),\n};\n\nexport type GraphVisualizationProps<T extends React.ElementType = 'div'> = {\n nvlRef?: React.RefObject<NVL | null>;\n sidepanel?: Sidepanel | null;\n bottomLeftIsland?: React.ReactNode;\n bottomCenterIsland?: React.ReactNode;\n bottomRightIsland?: React.ReactNode;\n topLeftIsland?: React.ReactNode;\n topRightIsland?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n /**\n * Optional style rules to apply to graph elements.\n * Consumer-set `color` on individual `NeoNode`/`NeoRel` objects takes precedence over rules.\n * Compared by reference — memoize the array to avoid recompiling on every render.\n */\n styleRules?: GraphStyleRule[];\n\n gesture?: Gesture;\n setGesture?: (gesture: Gesture) => void;\n selected?: GraphSelection;\n setSelected?: (newSelection: GraphSelection) => void;\n interactionMode?: InteractionMode;\n setInteractionMode?: (interactionMode: InteractionMode) => void;\n layout?: Layout;\n setLayout?: (layout: Layout) => void;\n\n portalTarget?: HTMLElement | null;\n\n nodes: NeoNode[];\n rels: NeoRel[];\n\n highlightedNodeIds?: string[];\n highlightedRelationshipIds?: string[];\n\n as?: T;\n ref?: React.ComponentPropsWithRef<T>['ref'];\n htmlAttributes?: React.HTMLAttributes<T>;\n} & InteractiveNvlWrapperProps;\n\n/**\n * A comprehensive graph visualization component for rendering Neo4j-style graphs with interactive features.\n *\n * @remarks\n * This component provides a complete graph visualization solution with built-in interaction modes,\n * selection handling, zoom controls, and an optional sidepanel. It wraps the NVL (Neo4j Visualization Library)\n * with additional UI controls and state management.\n *\n * The component supports various interaction modes including single selection, box selection, and lasso selection.\n * It also provides customizable UI islands for placing controls at different corners of the visualization.\n *\n * @example\n * Basic usage:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * selected={selection}\n * setSelected={setSelection}\n * />\n * ```\n *\n * @example\n * With custom controls:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * topRightIsland={<CustomControls />}\n * sidepanel={{\n * contents: <CustomSidepanel />,\n * isSidePanelOpen: true,\n * setIsSidePanelOpen: setSidepanelOpen\n * sidePanelWidth: 400,\n * onSidePanelResize: setSidepanelWidth,\n * }}\n * />\n * ```\n *\n * @example\n * With highlighting:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * // undefined = no highlighting (default behavior)\n * // empty array = no search matches (dims all nodes)\n * // array with IDs = highlight only those items\n * highlightedNodeIds={searchResults.nodeIds}\n * highlightedRelationshipIds={searchResults.relationshipIds}\n * />\n * ```\n *\n * @param props - {@link GraphVisualizationProps}\n * @returns A React component that renders an interactive graph visualization\n *\n * @alpha\n */\nexport function GraphVisualization<T extends React.ElementType = 'div'>({\n nvlRef: rawNvlRef,\n nvlCallbacks,\n nvlOptions,\n sidepanel: rawSidepanel,\n nodes: rawNodes,\n rels: rawRels,\n highlightedNodeIds,\n highlightedRelationshipIds,\n topLeftIsland = DEFAULT_COMPONENTS.topLeftIsland,\n topRightIsland = DEFAULT_COMPONENTS.topRightIsland,\n bottomLeftIsland = DEFAULT_COMPONENTS.bottomLeftIsland,\n bottomCenterIsland = DEFAULT_COMPONENTS.bottomCenterIsland,\n bottomRightIsland = DEFAULT_COMPONENTS.bottomRightIsland,\n gesture = 'single',\n setGesture,\n layout: rawLayout,\n setLayout: rawSetLayout,\n portalTarget,\n selected: rawSelected,\n setSelected: rawSetSelected,\n interactionMode: rawInteractionMode,\n setInteractionMode: rawSetInteractionMode,\n mouseEventCallbacks = {},\n className,\n style,\n htmlAttributes,\n ref,\n as,\n styleRules,\n ...restProps\n}: GraphVisualizationProps<T>) {\n const nvlRef = useMemo(\n () => rawNvlRef ?? React.createRef<NVL>(),\n [rawNvlRef],\n );\n\n const instanceId = useId();\n\n // Respect NDL theme changes\n const { theme } = useNeedleTheme();\n const { bg, border, text } = tokens.theme[theme].color.neutral;\n\n // key required for nvl react responsiveness\n const [key, setKey] = useState(0);\n useEffect(() => {\n setKey((prevKey) => prevKey + 1);\n }, [theme]);\n\n const { styledGraph, metadataLookup, compiledStyleRules } = useGraphData(\n rawNodes,\n rawRels,\n styleRules,\n );\n\n // Semi-control interaction mode and selection state\n const [interactionMode, setInteractionMode] = useSemicontrolledState({\n isControlled: rawInteractionMode !== undefined,\n onChange: rawSetInteractionMode,\n state: rawInteractionMode ?? 'select',\n });\n const [selected, setSelected] = useSemicontrolledState({\n isControlled: rawSelected !== undefined,\n onChange: rawSetSelected,\n state: rawSelected ?? { nodeIds: [], relationshipIds: [] },\n });\n const [layout, setLayout] = useSemicontrolledState({\n isControlled: rawLayout !== undefined,\n onChange: rawSetLayout,\n state: rawLayout ?? 'd3Force',\n });\n\n const { nodesWithState, relsWithState, wrappedMouseEventCallbacks } =\n useManagedNodeState({\n gesture,\n highlightedNodeIds,\n highlightedRelationshipIds,\n interactionMode,\n mouseEventCallbacks,\n nvlGraph: styledGraph,\n selected,\n setInteractionMode,\n setSelected,\n });\n\n const [isSidePanelOpen, setIsSidePanelOpen] = useSemicontrolledState({\n isControlled: rawSidepanel?.isSidePanelOpen !== undefined,\n onChange: rawSidepanel?.setIsSidePanelOpen,\n state: rawSidepanel?.isSidePanelOpen ?? true,\n });\n const [sidePanelWidth, setSidePanelWidth] = useSemicontrolledState({\n isControlled: rawSidepanel?.sidePanelWidth !== undefined,\n onChange: rawSidepanel?.onSidePanelResize,\n state: rawSidepanel?.sidePanelWidth ?? 400,\n });\n\n const sidepanel = useMemo((): Sidepanel | null => {\n if (rawSidepanel === undefined) {\n return {\n children: <GraphVisualization.SingleSelectionSidePanelContents />,\n isSidePanelOpen,\n onSidePanelResize: setSidePanelWidth,\n setIsSidePanelOpen,\n sidePanelWidth,\n };\n }\n return rawSidepanel;\n }, [\n rawSidepanel,\n isSidePanelOpen,\n setIsSidePanelOpen,\n sidePanelWidth,\n setSidePanelWidth,\n ]);\n\n const Component: React.ElementType = as ?? 'div';\n return (\n <Component\n ref={ref}\n className={cx('ndl-graph-visualization-container', className)}\n style={style}\n {...htmlAttributes}\n >\n <GraphVisualizationContext.Provider\n value={{\n compiledStyleRules,\n gesture,\n interactionMode,\n layout,\n metadataLookup,\n nvlGraph: styledGraph,\n nvlInstance: nvlRef,\n portalTarget,\n selected,\n setGesture,\n setLayout,\n sidepanel,\n }}\n >\n <div className=\"ndl-graph-visualization\">\n <InteractiveNvlWrapper\n key={key}\n layout={layout}\n nodes={nodesWithState}\n rels={relsWithState}\n nvlOptions={{\n ...DEFAULT_NVL_OPTIONS,\n instanceId,\n styling: {\n defaultRelationshipColor: border.strongest,\n disabledItemColor: bg.strong,\n disabledItemFontColor: text.weakest,\n dropShadowColor: border.weak,\n selectedInnerBorderColor: bg.default,\n },\n ...nvlOptions,\n }}\n nvlCallbacks={{\n onLayoutComputing(isComputing) {\n if (!isComputing) {\n nvlRef.current?.fit(\n nvlRef.current.getNodes().map((neighbors) => neighbors.id),\n { noPan: true },\n );\n }\n },\n ...nvlCallbacks,\n }}\n mouseEventCallbacks={wrappedMouseEventCallbacks}\n ref={nvlRef}\n {...restProps}\n />\n {topLeftIsland !== null && (\n <InteractionIsland placement=\"top-left\">\n {topLeftIsland}\n </InteractionIsland>\n )}\n\n {topRightIsland !== null && (\n <InteractionIsland placement=\"top-right\">\n {topRightIsland}\n </InteractionIsland>\n )}\n\n {bottomLeftIsland !== null && (\n <InteractionIsland placement=\"bottom-left\">\n {bottomLeftIsland}\n </InteractionIsland>\n )}\n\n {bottomCenterIsland !== null && (\n <InteractionIsland placement=\"bottom-center\">\n {bottomCenterIsland}\n </InteractionIsland>\n )}\n\n {bottomRightIsland !== null && (\n <InteractionIsland placement=\"bottom-right\">\n {bottomRightIsland}\n </InteractionIsland>\n )}\n </div>\n {sidepanel && <GraphVisualizationSidepanel sidepanel={sidepanel} />}\n </GraphVisualizationContext.Provider>\n </Component>\n );\n}\n\n/**\n * Zoom in button for use within a GraphVisualization component.\n *\n * @remarks\n * Increases zoom level by 1.3x\n *\n * @alpha\n */\nGraphVisualization.ZoomInButton = ZoomInButton;\n\n/**\n * Zoom out button for use within a GraphVisualization component.\n *\n * @remarks\n * Decreases zoom level by 0.7x\n *\n * @alpha\n */\nGraphVisualization.ZoomOutButton = ZoomOutButton;\n\n/**\n * Zoom to fit button for use within a GraphVisualization component.\n *\n * @remarks\n * Automatically adjusts zoom and pan to show all nodes and relationships\n *\n * @alpha\n */\nGraphVisualization.ZoomToFitButton = ZoomToFitButton;\n\n/**\n * Sidepanel toggle button for use within a GraphVisualization component.\n *\n * @remarks\n * Shows or hides the sidepanel containing node and relationship details.\n * Requires a sidepanel to be configured in the GraphVisualization component.\n *\n * @throws Error when used without a configured sidepanel\n *\n * @alpha\n */\nGraphVisualization.ToggleSidePanelButton = ToggleSidePanelButton;\n\n/**\n * Download button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a dropdown menu with download options. Supports PNG and SVG formats.\n * Captures the current visualization state including zoom level.\n *\n * @alpha\n */\nGraphVisualization.DownloadButton = DownloadButton;\n\n/**\n * Box selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables box selection mode where dragging creates a rectangular selection area.\n * Disabled unless the `setGesture` callback is passed.\n * Shows active state when enabled and supports keyboard shortcut 'B'.\n *\n * @alpha\n */\nGraphVisualization.BoxSelectButton = BoxSelectButton;\n\n/**\n * Lasso selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables lasso selection mode where dragging creates a free-form selection area.\n * Disabled unless the `setGesture` callback is passed.\n * Shows active state when enabled and supports keyboard shortcut 'L'.\n *\n * @alpha\n */\nGraphVisualization.LassoSelectButton = LassoSelectButton;\n\n/**\n * Single node selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables single selection mode where clicking selects individual nodes or relationships.\n * Shows active state when enabled and supports keyboard shortcut 'S'.\n *\n * @alpha\n */\nGraphVisualization.SingleSelectButton = SingleSelectButton;\n\n/**\n * Search button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables search mode where clicking opens a search input for filtering nodes and relationships.\n *\n * @alpha\n */\nGraphVisualization.SearchButton = SearchButton;\n\n/**\n * Single node selection side panel for use within a GraphVisualization component.\n *\n * @remarks\n * Displays detailed information about the selected node or relationship.\n * Panel is automatically opened when a node or relationship is selected.\n * Also when user click on the show panel button in the top right corner.\n *\n * @alpha\n */\nGraphVisualization.SingleSelectionSidePanelContents =\n SingleSelectionSidepanelContents;\n\n/**\n * Layout selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a menu to select different graph layout algorithms.\n *\n * By default, the menu includes the **force-based** (`d3Force`) and\n * **hierarchical** layouts. Additional layouts can be enabled via configuration.\n *\n * @see {@link LayoutSelectOption} for the full set of layout options supported by NVL.\n *\n * @alpha\n */\nGraphVisualization.LayoutSelectButton = LayoutSelectButton;\n\n/**\n * Gesture selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a menu to select different interaction gestures.\n *\n * By default, the menu includes **single**, **box**, and **lasso** selection gestures.\n *\n * @see {@link GestureSelectOption} for the full set of gesture options supported by NVL.\n *\n * @alpha\n */\nGraphVisualization.GestureSelectButton = GestureSelectButton;\n"]}
|
|
1
|
+
{"version":3,"file":"graph-visualization.js","sourceRoot":"","sources":["../../src/graph-visualization.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { tokens } from '@neo4j-ndl/base';\nimport { IconButtonArray, useNeedleTheme } from '@neo4j-ndl/react';\nimport type NVL from '@neo4j-nvl/base';\nimport { type Layout, type NvlOptions } from '@neo4j-nvl/base';\nimport {\n InteractiveNvlWrapper,\n type InteractiveNvlWrapperProps,\n} from '@neo4j-nvl/react';\nimport { default as cx } from 'classnames';\nimport React, { useEffect, useId, useMemo, useState } from 'react';\n\nimport {\n BoxSelectButton,\n DownloadButton,\n GestureSelectButton,\n LassoSelectButton,\n LayoutSelectButton,\n SearchButton,\n SingleSelectButton,\n ToggleSidePanelButton,\n ZoomInButton,\n ZoomOutButton,\n ZoomToFitButton,\n} from './graph-visualization-buttons';\nimport {\n type Gesture,\n type GraphSelection,\n GraphVisualizationContext,\n type InteractionMode,\n type NeoNode,\n type NeoRel,\n type Sidepanel,\n} from './graph-visualization-context';\nimport { GraphVisualizationSidepanel } from './graph-visualization-sidepanel';\nimport { SingleSelectionSidepanelContents } from './sidepanel-components/single-selection-sidepanel-contents';\nimport { type GraphStyleRule } from './styling/style-types';\nimport { useGraphData } from './styling/use-graph-data';\nimport { useManagedNodeState } from './use-managed-node-state';\nimport { useSemicontrolledState } from './use-semi-controlled-state';\n\ntype Placement =\n | 'top-right'\n | 'bottom-right'\n | 'top-left'\n | 'bottom-left'\n | 'bottom-center';\n\nconst PLACEMENTS: Record<Placement, string> = {\n 'bottom-left': 'ndl-graph-visualization-interaction-island ndl-bottom-left',\n 'bottom-center':\n 'ndl-graph-visualization-interaction-island ndl-bottom-center',\n 'bottom-right': 'ndl-graph-visualization-interaction-island ndl-bottom-right',\n 'top-left': 'ndl-graph-visualization-interaction-island ndl-top-left',\n 'top-right': 'ndl-graph-visualization-interaction-island ndl-top-right',\n};\n\nconst InteractionIsland = ({\n children,\n className,\n placement,\n}: {\n children: React.ReactNode;\n placement: Placement;\n className?: string;\n}) => {\n return <div className={cx(PLACEMENTS[placement], className)}>{children}</div>;\n};\n\nexport const DEFAULT_NVL_OPTIONS = {\n disableTelemetry: true,\n disableWebGL: true,\n maxZoom: 3,\n minZoom: 0.05,\n relationshipThreshold: 0.55,\n renderer: 'canvas',\n} satisfies NvlOptions;\n\ntype BackwardsCompatibleNvlOptions = NvlOptions & {\n /** @deprecated Use {@link NvlOptions.renderer} instead. */\n // eslint-disable-next-line @typescript-eslint/naming-convention -- Matches the removed NVL option.\n useWebGL?: boolean;\n};\n\nconst DEFAULT_COMPONENTS = {\n bottomLeftIsland: null,\n bottomCenterIsland: null,\n bottomRightIsland: (\n <IconButtonArray orientation=\"vertical\" isFloating size=\"small\">\n <ZoomInButton /> <ZoomOutButton /> <ZoomToFitButton />\n </IconButtonArray>\n ),\n topLeftIsland: null,\n topRightIsland: (\n <div className=\"ndl-graph-visualization-default-download-group\">\n <DownloadButton /> <ToggleSidePanelButton />\n </div>\n ),\n};\n\nexport type GraphVisualizationProps<T extends React.ElementType = 'div'> = {\n nvlRef?: React.RefObject<NVL | null>;\n nvlOptions?: BackwardsCompatibleNvlOptions;\n sidepanel?: Sidepanel | null;\n bottomLeftIsland?: React.ReactNode;\n bottomCenterIsland?: React.ReactNode;\n bottomRightIsland?: React.ReactNode;\n topLeftIsland?: React.ReactNode;\n topRightIsland?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n /**\n * Optional style rules to apply to graph elements.\n * Consumer-set `color` on individual `NeoNode`/`NeoRel` objects takes precedence over rules.\n * Compared by reference — memoize the array to avoid recompiling on every render.\n */\n styleRules?: GraphStyleRule[];\n\n gesture?: Gesture;\n setGesture?: (gesture: Gesture) => void;\n selected?: GraphSelection;\n setSelected?: (newSelection: GraphSelection) => void;\n interactionMode?: InteractionMode;\n setInteractionMode?: (interactionMode: InteractionMode) => void;\n layout?: Layout;\n setLayout?: (layout: Layout) => void;\n\n portalTarget?: HTMLElement | null;\n\n nodes: NeoNode[];\n rels: NeoRel[];\n\n highlightedNodeIds?: string[];\n highlightedRelationshipIds?: string[];\n\n as?: T;\n ref?: React.ComponentPropsWithRef<T>['ref'];\n htmlAttributes?: React.HTMLAttributes<T>;\n} & InteractiveNvlWrapperProps;\n\n/**\n * A comprehensive graph visualization component for rendering Neo4j-style graphs with interactive features.\n *\n * @remarks\n * This component provides a complete graph visualization solution with built-in interaction modes,\n * selection handling, zoom controls, and an optional sidepanel. It wraps the NVL (Neo4j Visualization Library)\n * with additional UI controls and state management.\n *\n * The component supports various interaction modes including single selection, box selection, and lasso selection.\n * It also provides customizable UI islands for placing controls at different corners of the visualization.\n *\n * @example\n * Basic usage:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * selected={selection}\n * setSelected={setSelection}\n * />\n * ```\n *\n * @example\n * With custom controls:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * topRightIsland={<CustomControls />}\n * sidepanel={{\n * contents: <CustomSidepanel />,\n * isSidePanelOpen: true,\n * setIsSidePanelOpen: setSidepanelOpen\n * sidePanelWidth: 400,\n * onSidePanelResize: setSidepanelWidth,\n * }}\n * />\n * ```\n *\n * @example\n * With highlighting:\n * ```tsx\n * <GraphVisualization\n * nodes={nodes}\n * rels={relationships}\n * // undefined = no highlighting (default behavior)\n * // empty array = no search matches (dims all nodes)\n * // array with IDs = highlight only those items\n * highlightedNodeIds={searchResults.nodeIds}\n * highlightedRelationshipIds={searchResults.relationshipIds}\n * />\n * ```\n *\n * @param props - {@link GraphVisualizationProps}\n * @returns A React component that renders an interactive graph visualization\n *\n * @alpha\n */\nexport function GraphVisualization<T extends React.ElementType = 'div'>({\n nvlRef: rawNvlRef,\n nvlCallbacks,\n nvlOptions: rawNvlOptions,\n sidepanel: rawSidepanel,\n nodes: rawNodes,\n rels: rawRels,\n highlightedNodeIds,\n highlightedRelationshipIds,\n topLeftIsland = DEFAULT_COMPONENTS.topLeftIsland,\n topRightIsland = DEFAULT_COMPONENTS.topRightIsland,\n bottomLeftIsland = DEFAULT_COMPONENTS.bottomLeftIsland,\n bottomCenterIsland = DEFAULT_COMPONENTS.bottomCenterIsland,\n bottomRightIsland = DEFAULT_COMPONENTS.bottomRightIsland,\n gesture = 'single',\n setGesture,\n layout: rawLayout,\n\n layoutOptions,\n setLayout: rawSetLayout,\n portalTarget,\n selected: rawSelected,\n setSelected: rawSetSelected,\n interactionMode: rawInteractionMode,\n setInteractionMode: rawSetInteractionMode,\n mouseEventCallbacks = {},\n className,\n style,\n htmlAttributes,\n ref,\n as,\n styleRules,\n ...restProps\n}: GraphVisualizationProps<T>) {\n const { useWebGL: isWebGLEnabled, ...nvlOptions } = rawNvlOptions ?? {};\n nvlOptions.renderer =\n nvlOptions.renderer ??\n (isWebGLEnabled === true ? 'webgl' : DEFAULT_NVL_OPTIONS.renderer);\n\n const nvlRef = useMemo(\n () => rawNvlRef ?? React.createRef<NVL>(),\n [rawNvlRef],\n );\n\n const instanceId = useId();\n\n // Respect NDL theme changes\n const { theme } = useNeedleTheme();\n const { bg, border, text } = tokens.theme[theme].color.neutral;\n\n // key required for nvl react responsiveness\n const [key, setKey] = useState(0);\n useEffect(() => {\n setKey((prevKey) => prevKey + 1);\n }, [theme]);\n\n const { styledGraph, metadataLookup, compiledStyleRules } = useGraphData(\n rawNodes,\n rawRels,\n styleRules,\n );\n\n // Semi-control interaction mode and selection state\n const [interactionMode, setInteractionMode] = useSemicontrolledState({\n isControlled: rawInteractionMode !== undefined,\n onChange: rawSetInteractionMode,\n state: rawInteractionMode ?? 'select',\n });\n const [selected, setSelected] = useSemicontrolledState({\n isControlled: rawSelected !== undefined,\n onChange: rawSetSelected,\n state: rawSelected ?? { nodeIds: [], relationshipIds: [] },\n });\n const [layout, setLayout] = useSemicontrolledState({\n isControlled: rawLayout !== undefined,\n onChange: rawSetLayout,\n state: rawLayout ?? 'd3Force',\n });\n\n const { nodesWithState, relsWithState, wrappedMouseEventCallbacks } =\n useManagedNodeState({\n gesture,\n highlightedNodeIds,\n highlightedRelationshipIds,\n interactionMode,\n mouseEventCallbacks,\n nvlGraph: styledGraph,\n selected,\n setInteractionMode,\n setSelected,\n });\n\n const [isSidePanelOpen, setIsSidePanelOpen] = useSemicontrolledState({\n isControlled: rawSidepanel?.isSidePanelOpen !== undefined,\n onChange: rawSidepanel?.setIsSidePanelOpen,\n state: rawSidepanel?.isSidePanelOpen ?? true,\n });\n const [sidePanelWidth, setSidePanelWidth] = useSemicontrolledState({\n isControlled: rawSidepanel?.sidePanelWidth !== undefined,\n onChange: rawSidepanel?.onSidePanelResize,\n state: rawSidepanel?.sidePanelWidth ?? 400,\n });\n\n const sidepanel = useMemo((): Sidepanel | null => {\n if (rawSidepanel === undefined) {\n return {\n children: <GraphVisualization.SingleSelectionSidePanelContents />,\n isSidePanelOpen,\n onSidePanelResize: setSidePanelWidth,\n setIsSidePanelOpen,\n sidePanelWidth,\n };\n }\n return rawSidepanel;\n }, [\n rawSidepanel,\n isSidePanelOpen,\n setIsSidePanelOpen,\n sidePanelWidth,\n setSidePanelWidth,\n ]);\n\n const Component: React.ElementType = as ?? 'div';\n return (\n <Component\n ref={ref}\n className={cx('ndl-graph-visualization-container', className)}\n style={style}\n {...htmlAttributes}\n >\n <GraphVisualizationContext.Provider\n value={{\n compiledStyleRules,\n gesture,\n interactionMode,\n layout,\n metadataLookup,\n nvlGraph: styledGraph,\n nvlInstance: nvlRef,\n portalTarget,\n selected,\n setGesture,\n setLayout,\n sidepanel,\n }}\n >\n <div className=\"ndl-graph-visualization\">\n <InteractiveNvlWrapper\n key={key}\n nodes={nodesWithState}\n rels={relsWithState}\n nvlOptions={{\n ...DEFAULT_NVL_OPTIONS,\n instanceId,\n styling: {\n defaultRelationshipColor: border.strongest,\n disabledItemColor: bg.strong,\n disabledItemFontColor: text.weakest,\n dropShadowColor: border.weak,\n selectedInnerBorderColor: bg.default,\n },\n ...nvlOptions,\n layout,\n layoutOptions: layoutOptions ?? nvlOptions.layoutOptions,\n }}\n nvlCallbacks={{\n onLayoutComputing(isComputing) {\n if (!isComputing) {\n nvlRef.current?.fit(\n nvlRef.current.getNodes().map((neighbors) => neighbors.id),\n { noPan: true },\n );\n }\n },\n ...nvlCallbacks,\n }}\n mouseEventCallbacks={wrappedMouseEventCallbacks}\n ref={nvlRef}\n {...restProps}\n />\n {topLeftIsland !== null && (\n <InteractionIsland placement=\"top-left\">\n {topLeftIsland}\n </InteractionIsland>\n )}\n\n {topRightIsland !== null && (\n <InteractionIsland placement=\"top-right\">\n {topRightIsland}\n </InteractionIsland>\n )}\n\n {bottomLeftIsland !== null && (\n <InteractionIsland placement=\"bottom-left\">\n {bottomLeftIsland}\n </InteractionIsland>\n )}\n\n {bottomCenterIsland !== null && (\n <InteractionIsland placement=\"bottom-center\">\n {bottomCenterIsland}\n </InteractionIsland>\n )}\n\n {bottomRightIsland !== null && (\n <InteractionIsland placement=\"bottom-right\">\n {bottomRightIsland}\n </InteractionIsland>\n )}\n </div>\n {sidepanel && <GraphVisualizationSidepanel sidepanel={sidepanel} />}\n </GraphVisualizationContext.Provider>\n </Component>\n );\n}\n\n/**\n * Zoom in button for use within a GraphVisualization component.\n *\n * @remarks\n * Increases zoom level by 1.3x\n *\n * @alpha\n */\nGraphVisualization.ZoomInButton = ZoomInButton;\n\n/**\n * Zoom out button for use within a GraphVisualization component.\n *\n * @remarks\n * Decreases zoom level by 0.7x\n *\n * @alpha\n */\nGraphVisualization.ZoomOutButton = ZoomOutButton;\n\n/**\n * Zoom to fit button for use within a GraphVisualization component.\n *\n * @remarks\n * Automatically adjusts zoom and pan to show all nodes and relationships\n *\n * @alpha\n */\nGraphVisualization.ZoomToFitButton = ZoomToFitButton;\n\n/**\n * Sidepanel toggle button for use within a GraphVisualization component.\n *\n * @remarks\n * Shows or hides the sidepanel containing node and relationship details.\n * Requires a sidepanel to be configured in the GraphVisualization component.\n *\n * @throws Error when used without a configured sidepanel\n *\n * @alpha\n */\nGraphVisualization.ToggleSidePanelButton = ToggleSidePanelButton;\n\n/**\n * Download button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a dropdown menu with download options. Supports PNG and SVG formats.\n * Captures the current visualization state including zoom level.\n *\n * @alpha\n */\nGraphVisualization.DownloadButton = DownloadButton;\n\n/**\n * Box selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables box selection mode where dragging creates a rectangular selection area.\n * Disabled unless the `setGesture` callback is passed.\n * Shows active state when enabled and supports keyboard shortcut 'B'.\n *\n * @alpha\n */\nGraphVisualization.BoxSelectButton = BoxSelectButton;\n\n/**\n * Lasso selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables lasso selection mode where dragging creates a free-form selection area.\n * Disabled unless the `setGesture` callback is passed.\n * Shows active state when enabled and supports keyboard shortcut 'L'.\n *\n * @alpha\n */\nGraphVisualization.LassoSelectButton = LassoSelectButton;\n\n/**\n * Single node selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables single selection mode where clicking selects individual nodes or relationships.\n * Shows active state when enabled and supports keyboard shortcut 'S'.\n *\n * @alpha\n */\nGraphVisualization.SingleSelectButton = SingleSelectButton;\n\n/**\n * Search button for use within a GraphVisualization component.\n *\n * @remarks\n * Enables search mode where clicking opens a search input for filtering nodes and relationships.\n *\n * @alpha\n */\nGraphVisualization.SearchButton = SearchButton;\n\n/**\n * Single node selection side panel for use within a GraphVisualization component.\n *\n * @remarks\n * Displays detailed information about the selected node or relationship.\n * Panel is automatically opened when a node or relationship is selected.\n * Also when user click on the show panel button in the top right corner.\n *\n * @alpha\n */\nGraphVisualization.SingleSelectionSidePanelContents =\n SingleSelectionSidepanelContents;\n\n/**\n * Layout selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a menu to select different graph layout algorithms.\n *\n * By default, the menu includes the **force-based** (`d3Force`) and\n * **hierarchical** layouts. Additional layouts can be enabled via configuration.\n *\n * @see {@link LayoutSelectOption} for the full set of layout options supported by NVL.\n *\n * @alpha\n */\nGraphVisualization.LayoutSelectButton = LayoutSelectButton;\n\n/**\n * Gesture selection button for use within a GraphVisualization component.\n *\n * @remarks\n * Opens a menu to select different interaction gestures.\n *\n * By default, the menu includes **single**, **box**, and **lasso** selection gestures.\n *\n * @see {@link GestureSelectOption} for the full set of gesture options supported by NVL.\n *\n * @alpha\n */\nGraphVisualization.GestureSelectButton = GestureSelectButton;\n"]}
|
|
@@ -49,7 +49,7 @@ export function useManagedNodeState({ selected, setSelected, gesture, interactio
|
|
|
49
49
|
document.removeEventListener('keyup', stopPanningReleaseSpace);
|
|
50
50
|
};
|
|
51
51
|
}, [panOnSpace, stopPanningReleaseSpace]);
|
|
52
|
-
const { onBoxSelect: originalBoxSelect, onLassoSelect: originalOnLassoSelect, onLassoStarted, onBoxStarted, onPan = true, onHover, onHoverNodeMargin, onNodeClick: originalOnNodeClick, onRelationshipClick: originalOnRelationshipClick, onDragStart: originalOnDragStart, onDragEnd: originalOnDragEnd, onDrawEnded: originalOnDrawEnded, onDrawStarted: originalOnDrawStarted, onCanvasClick: originalOnCanvasClick, onNodeDoubleClick: originalOnNodeDoubleClick, onRelationshipDoubleClick: originalOnRelationshipDoubleClick, } = mouseEventCallbacks;
|
|
52
|
+
const { onBoxSelect: originalBoxSelect, onLassoSelect: originalOnLassoSelect, onLassoStarted, onBoxStarted, onPan = true, onHover, onHoverNodeMargin, onNodeClick: originalOnNodeClick, onRelationshipClick: originalOnRelationshipClick, onDragStart: originalOnDragStart, onDragEnd: originalOnDragEnd, onDrawEnded: originalOnDrawEnded, onDrawStarted: originalOnDrawStarted, onCanvasClick: originalOnCanvasClick, onNodeDoubleClick: originalOnNodeDoubleClick, onRelationshipDoubleClick: originalOnRelationshipDoubleClick, onZoom: originalOnZoom, onZoomAndPan: originalOnZoomAndPan, } = mouseEventCallbacks;
|
|
53
53
|
const onCanvasClick = useCallback((evt) => {
|
|
54
54
|
if (isClickingOnTextInput(evt)) {
|
|
55
55
|
return;
|
|
@@ -214,12 +214,10 @@ export function useManagedNodeState({ selected, setSelected, gesture, interactio
|
|
|
214
214
|
const shouldEnableLasso = isSelectMode && gesture === 'lasso';
|
|
215
215
|
const shouldEnablePan = interactionMode === 'pan' || (isSelectMode && gesture === 'single');
|
|
216
216
|
const canDrag = interactionMode === 'drag' || interactionMode === 'select';
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
: false, onZoom: (_a = mouseEventCallbacks.onZoom) !== null && _a !== void 0 ? _a : true }));
|
|
222
|
-
}, [
|
|
217
|
+
const hasCustomZoomCallback = originalOnZoom !== undefined || originalOnZoomAndPan !== undefined;
|
|
218
|
+
const wrappedMouseEventCallbacks = useMemo(() => (Object.assign(Object.assign({}, mouseEventCallbacks), { onBoxSelect: shouldEnableBox ? onBoxSelect : false, onBoxStarted: shouldEnableBox ? onBoxStarted : false, onCanvasClick: isSelectMode ? onCanvasClick : false, onDragEnd: canDrag ? onDragEnd : false, onDragStart: canDrag ? onDragStart : false, onDrawEnded: isDrawMode ? onDrawEnded : false, onDrawStarted: isDrawMode ? onDrawStarted : false, onHover: isSelectMode ? onHover : false, onHoverNodeMargin: isDrawMode ? onHoverNodeMargin : false, onLassoSelect: shouldEnableLasso ? onLassoSelect : false, onLassoStarted: shouldEnableLasso ? onLassoStarted : false, onNodeClick: isSelectMode ? onNodeClick : false, onNodeDoubleClick: isSelectMode ? onNodeDoubleClick : false, onPan: shouldEnablePan ? onPan : false, onRelationshipClick: isSelectMode ? onRelationshipClick : false, onRelationshipDoubleClick: isSelectMode
|
|
219
|
+
? onRelationshipDoubleClick
|
|
220
|
+
: false, onZoomAndPan: hasCustomZoomCallback ? originalOnZoomAndPan : true })), [
|
|
223
221
|
canDrag,
|
|
224
222
|
shouldEnableBox,
|
|
225
223
|
shouldEnableLasso,
|
|
@@ -243,6 +241,8 @@ export function useManagedNodeState({ selected, setSelected, gesture, interactio
|
|
|
243
241
|
onPan,
|
|
244
242
|
onRelationshipClick,
|
|
245
243
|
onRelationshipDoubleClick,
|
|
244
|
+
hasCustomZoomCallback,
|
|
245
|
+
originalOnZoomAndPan,
|
|
246
246
|
]);
|
|
247
247
|
const selectionSet = useMemo(() => ({
|
|
248
248
|
nodeIds: new Set(selected.nodeIds),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-managed-node-state.js","sourceRoot":"","sources":["../../src/use-managed-node-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAOxD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,uBAAuB,GAAG,CAAC,GAAe,EAAW,EAAE,CAC3D,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;AAEpD,MAAM,qBAAqB,GAAG,CAAC,CAAa,EAAW,EAAE;IACvD,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,YAAY,WAAW,CAAC,EAAE,CAAC;QACvC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CACL,CAAC,CAAC,MAAM,CAAC,iBAAiB;QAC1B,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACjD,CAAC;AACJ,CAAC,CAAC;AAiBF,MAAM,UAAU,mBAAmB,CAAC,EAClC,QAAQ,EACR,WAAW,EACX,OAAO,EACP,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,0BAA0B,GACL;IACrB,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,GAAkB,EAAE,EAAE;QACrB,kCAAkC;QAClC,kFAAkF;QAClF,IAAI,eAAe,KAAK,QAAQ,IAAI,GAAG,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACpD,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,EACD,CAAC,eAAe,EAAE,kBAAkB,CAAC,CACtC,CAAC;IAEF,MAAM,uBAAuB,GAAG,WAAW,CACzC,CAAC,GAAkB,EAAE,EAAE;QACrB,IAAI,eAAe,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACjD,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,EACD,CAAC,eAAe,EAAE,kBAAkB,CAAC,CACtC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACjD,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;QAC5D,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACpD,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;QACjE,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAE1C,MAAM,EACJ,WAAW,EAAE,iBAAiB,EAC9B,aAAa,EAAE,qBAAqB,EACpC,cAAc,EACd,YAAY,EACZ,KAAK,GAAG,IAAI,EACZ,OAAO,EACP,iBAAiB,EACjB,WAAW,EAAE,mBAAmB,EAChC,mBAAmB,EAAE,2BAA2B,EAChD,WAAW,EAAE,mBAAmB,EAChC,SAAS,EAAE,iBAAiB,EAC5B,WAAW,EAAE,mBAAmB,EAChC,aAAa,EAAE,qBAAqB,EACpC,aAAa,EAAE,qBAAqB,EACpC,iBAAiB,EAAE,yBAAyB,EAC5C,yBAAyB,EAAE,iCAAiC,GAC7D,GAAG,mBAAmB,CAAC;IAExB,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,GAAe,EAAE,EAAE;QAClB,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,kBAAkB;QAClB,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC,CAAC;QAElD,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;YAChD,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,EACD,CAAC,qBAAqB,EAAE,WAAW,CAAC,CACrC,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,YAAoB,EAAE,GAAe,EAAE,EAAE;QACxC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAE3B,mBAAmB;QACnB,MAAM,cAAc,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrD,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;YAClE,WAAW,CAAC;gBACV,OAAO,EAAE,cAAc;gBACvB,eAAe,EAAE,QAAQ,CAAC,eAAe;aAC1C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,WAAW,CAAC;YACV,OAAO,EAAE,cAAc;YACvB,eAAe,EAAE,QAAQ,CAAC,eAAe;SAC1C,CAAC,CAAC;QAEH,IAAI,OAAO,mBAAmB,KAAK,UAAU,EAAE,CAAC;YAC9C,mBAAmB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,EACD,CAAC,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CACjE,CAAC;IAEF,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,YAAoB,EAAE,GAAe,EAAE,EAAE;QACxC,IAAI,OAAO,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAC5C,iBAAiB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACvC,CAAC;QACD,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC,EACD,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CACxC,CAAC;IAEF,yFAAyF;IACzF,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,GAAe,EAAE,EAAE;QAClB,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;YAChD,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,EACD,CAAC,qBAAqB,CAAC,CACxB,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAC7B,CACE,oBAAyC,EACzC,kBAA+B,EAC/B,KAAiB,EACjB,EAAE;QACF,IAAI,OAAO,mBAAmB,KAAK,UAAU,EAAE,CAAC;YAC9C,mBAAmB,CAAC,oBAAoB,EAAE,kBAAkB,EAAE,KAAK,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,EACD,CAAC,mBAAmB,CAAC,CACtB,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,IAAU,EAAE,WAAuB,EAAE,GAAe,EAAE,EAAE;QACvD,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,wDAAwD;YACxD,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1D,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,kBAAkB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAChD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CACvB,CAAC;gBACF,WAAW,CAAC;oBACV,OAAO,EAAE,kBAAkB;oBAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;iBAC1C,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,kBAAkB,GAAG,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC1D,WAAW,CAAC;oBACV,OAAO,EAAE,kBAAkB;oBAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;iBAC1C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,OAAO,mBAAmB,KAAK,UAAU,EAAE,CAAC;YAC9C,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,EACD,CAAC,WAAW,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAC7C,CAAC;IAEF,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,YAA0B,EAAE,WAAuB,EAAE,GAAe,EAAE,EAAE;QACvE,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,wDAAwD;YACxD,MAAM,sBAAsB,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAC9D,YAAY,CAAC,EAAE,CAChB,CAAC;YACF,IAAI,sBAAsB,EAAE,CAAC;gBAC3B,MAAM,iBAAiB,GAAG,QAAQ,CAAC,eAAe,CAAC,MAAM,CACvD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,YAAY,CAAC,EAAE,CAC/B,CAAC;gBACF,WAAW,CAAC;oBACV,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,eAAe,EAAE,iBAAiB;iBACnC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,iBAAiB,GAAG;oBACxB,GAAG,QAAQ,CAAC,eAAe;oBAC3B,YAAY,CAAC,EAAE;iBAChB,CAAC;gBACF,WAAW,CAAC;oBACV,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,eAAe,EAAE,iBAAiB;iBACnC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,OAAO,2BAA2B,KAAK,UAAU,EAAE,CAAC;YACtD,2BAA2B,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,EACD,CAAC,WAAW,EAAE,QAAQ,EAAE,2BAA2B,CAAC,CACrD,CAAC;IAEF,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,IAAU,EAAE,WAAuB,EAAE,GAAe,EAAE,EAAE;QACvD,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,OAAO,yBAAyB,KAAK,UAAU,EAAE,CAAC;YACpD,yBAAyB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,EACD,CAAC,yBAAyB,CAAC,CAC5B,CAAC;IAEF,MAAM,yBAAyB,GAAG,WAAW,CAC3C,CAAC,YAA0B,EAAE,WAAuB,EAAE,GAAe,EAAE,EAAE;QACvE,IAAI,qBAAqB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,OAAO,iCAAiC,KAAK,UAAU,EAAE,CAAC;YAC5D,iCAAiC,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,EACD,CAAC,iCAAiC,CAAC,CACpC,CAAC;IAEF,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,KAAa,EAAE,IAAoB,EAAE,GAAe,EAAE,EAAE;QACvD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvC,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,wBAAwB,GAAG,QAAQ,CAAC,OAAO,CAAC;YAClD,MAAM,uBAAuB,GAAG,QAAQ,CAAC,eAAe,CAAC;YAEzD,sFAAsF;YACtF,qCAAqC;YACrC,MAAM,GAAG,GAAG,CAAC,CAAW,EAAE,CAAW,EAAE,EAAE,CAAC;gBACxC,GAAG,IAAI,GAAG,CACR,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAChE;aACF,CAAC;YAEF,MAAM,kBAAkB,GAAG,GAAG,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;YAClE,MAAM,iBAAiB,GAAG,GAAG,CAAC,uBAAuB,EAAE,eAAe,CAAC,CAAC;YAExE,WAAW,CAAC;gBACV,OAAO,EAAE,kBAAkB;gBAC3B,eAAe,EAAE,iBAAiB;aACnC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,oBAAoB;YACpB,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,EACD,CAAC,WAAW,EAAE,QAAQ,CAAC,CACxB,CAAC;IAEF,MAAM,aAAa,GAAG,WAAW,CAC/B,CACE,EAAE,KAAK,EAAE,IAAI,EAA2C,EACxD,GAAe,EACf,EAAE;QACF,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;YAChD,qBAAqB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,EACD,CAAC,aAAa,EAAE,qBAAqB,CAAC,CACvC,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAC7B,CACE,EAAE,KAAK,EAAE,IAAI,EAA2C,EACxD,GAAe,EACf,EAAE;QACF,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,OAAO,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAC5C,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,EACD,CAAC,aAAa,EAAE,iBAAiB,CAAC,CACnC,CAAC;IAEF,MAAM,UAAU,GAAG,eAAe,KAAK,MAAM,CAAC;IAE9C,MAAM,YAAY,GAAG,eAAe,KAAK,QAAQ,CAAC;IAClD,MAAM,eAAe,GAAG,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;IAC1D,MAAM,iBAAiB,GAAG,YAAY,IAAI,OAAO,KAAK,OAAO,CAAC;IAE9D,MAAM,eAAe,GACnB,eAAe,KAAK,KAAK,IAAI,CAAC,YAAY,IAAI,OAAO,KAAK,QAAQ,CAAC,CAAC;IAEtE,MAAM,OAAO,GAAG,eAAe,KAAK,MAAM,IAAI,eAAe,KAAK,QAAQ,CAAC;IAE3E,MAAM,0BAA0B,GAAG,OAAO,CACxC,GAAG,EAAE;;QAAC,OAAA,iCACD,mBAAmB,KACtB,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EAClD,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,EACpD,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,EACnD,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EACtC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EAC1C,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EAC7C,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,EACjD,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EACvC,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,EACzD,aAAa,EAAE,iBAAiB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,EACxD,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,EAC1D,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EAC/C,iBAAiB,EAAE,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,EAC3D,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EACtC,mBAAmB,EAAE,YAAY,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,KAAK,EAC/D,yBAAyB,EAAE,YAAY;gBACrC,CAAC,CAAC,yBAAyB;gBAC3B,CAAC,CAAC,KAAK,EACT,MAAM,EAAE,MAAA,mBAAmB,CAAC,MAAM,mCAAI,IAAI,IAC1C,CAAA;KAAA,EACF;QACE,OAAO;QACP,eAAe;QACf,iBAAiB;QACjB,eAAe;QACf,UAAU;QACV,YAAY;QACZ,mBAAmB;QACnB,WAAW;QACX,YAAY;QACZ,aAAa;QACb,SAAS;QACT,WAAW;QACX,WAAW;QACX,aAAa;QACb,OAAO;QACP,iBAAiB;QACjB,aAAa;QACb,cAAc;QACd,WAAW;QACX,iBAAiB;QACjB,KAAK;QACL,mBAAmB;QACnB,yBAAyB;KAC1B,CACF,CAAC;IAEF,MAAM,YAAY,GAAG,OAAO,CAC1B,GAAG,EAAE,CAAC,CAAC;QACL,OAAO,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClC,MAAM,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC;KAC1C,CAAC,EACF,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,MAAM,kBAAkB,GAAG,OAAO,CAChC,GAAG,EAAE,CACH,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,EACvE,CAAC,kBAAkB,CAAC,CACrB,CAAC;IACF,MAAM,iBAAiB,GAAG,OAAO,CAC/B,GAAG,EAAE,CACH,0BAA0B,KAAK,SAAS;QACtC,CAAC,CAAC,IAAI,GAAG,CAAC,0BAA0B,CAAC;QACrC,CAAC,CAAC,IAAI,EACV,CAAC,0BAA0B,CAAC,CAC7B,CAAC;IAEF,MAAM,cAAc,GAAG,OAAO,CAC5B,GAAG,EAAE,CACH,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iCACrB,CAAC,KACJ,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EACpE,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IACxC,CAAC,EACL,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,kBAAkB,CAAC,CACnD,CAAC;IAEF,MAAM,aAAa,GAAG,OAAO,CAC3B,GAAG,EAAE,CACH,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iCACpB,CAAC,KACJ,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAClE,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IACvC,CAAC,EACL,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,iBAAiB,CAAC,CACjD,CAAC;IAEF,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,0BAA0B,EAAE,CAAC;AACvE,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type HitTargets, type Node, type Relationship } from '@neo4j-nvl/base';\nimport { type MouseEventCallbacks } from '@neo4j-nvl/react';\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport {\n type Gesture,\n type GraphSelection,\n type InteractionMode,\n} from './graph-visualization-context';\nimport { isMac } from './utils';\n\nconst isMultiSelectKeyPressed = (evt: MouseEvent): boolean =>\n (!isMac && evt.ctrlKey) || (isMac && evt.metaKey);\n\nconst isClickingOnTextInput = (e: MouseEvent): boolean => {\n if (!(e.target instanceof HTMLElement)) {\n return false;\n }\n return (\n e.target.isContentEditable ||\n ['INPUT', 'TEXTAREA'].includes(e.target.tagName)\n );\n};\n\nexport type ManagedNodeStateArgs = {\n selected: GraphSelection;\n setSelected: (newSelection: GraphSelection) => void;\n gesture: Gesture;\n interactionMode: InteractionMode;\n setInteractionMode: (newInteractionMode: InteractionMode) => void;\n mouseEventCallbacks: MouseEventCallbacks;\n nvlGraph: {\n nodes: Node[];\n rels: Relationship[];\n };\n highlightedNodeIds?: string[];\n highlightedRelationshipIds?: string[];\n};\n\nexport function useManagedNodeState({\n selected,\n setSelected,\n gesture,\n interactionMode,\n setInteractionMode,\n mouseEventCallbacks,\n nvlGraph,\n highlightedNodeIds,\n highlightedRelationshipIds,\n}: ManagedNodeStateArgs) {\n const panOnSpace = useCallback(\n (evt: KeyboardEvent) => {\n // We could check the gesture here\n // but it doesn't really matter if we switch to panning mode even in single select\n if (interactionMode === 'select' && evt.key === ' ') {\n setInteractionMode('pan');\n }\n },\n [interactionMode, setInteractionMode],\n );\n\n const stopPanningReleaseSpace = useCallback(\n (evt: KeyboardEvent) => {\n if (interactionMode === 'pan' && evt.key === ' ') {\n setInteractionMode('select');\n }\n },\n [interactionMode, setInteractionMode],\n );\n\n useEffect(() => {\n document.addEventListener('keydown', panOnSpace);\n document.addEventListener('keyup', stopPanningReleaseSpace);\n return () => {\n document.removeEventListener('keydown', panOnSpace);\n document.removeEventListener('keyup', stopPanningReleaseSpace);\n };\n }, [panOnSpace, stopPanningReleaseSpace]);\n\n const {\n onBoxSelect: originalBoxSelect,\n onLassoSelect: originalOnLassoSelect,\n onLassoStarted,\n onBoxStarted,\n onPan = true,\n onHover,\n onHoverNodeMargin,\n onNodeClick: originalOnNodeClick,\n onRelationshipClick: originalOnRelationshipClick,\n onDragStart: originalOnDragStart,\n onDragEnd: originalOnDragEnd,\n onDrawEnded: originalOnDrawEnded,\n onDrawStarted: originalOnDrawStarted,\n onCanvasClick: originalOnCanvasClick,\n onNodeDoubleClick: originalOnNodeDoubleClick,\n onRelationshipDoubleClick: originalOnRelationshipDoubleClick,\n } = mouseEventCallbacks;\n\n const onCanvasClick = useCallback(\n (evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n // Clear selection\n setSelected({ nodeIds: [], relationshipIds: [] });\n\n if (typeof originalOnCanvasClick === 'function') {\n originalOnCanvasClick(evt);\n }\n },\n [originalOnCanvasClick, setSelected],\n );\n\n const onDragStart = useCallback(\n (draggedNodes: Node[], evt: MouseEvent) => {\n setInteractionMode('drag');\n\n // Update Selection\n const draggedNodeIds = draggedNodes.map((n) => n.id);\n if (selected.nodeIds.length === 0 || isMultiSelectKeyPressed(evt)) {\n setSelected({\n nodeIds: draggedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n return;\n }\n setSelected({\n nodeIds: draggedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n\n if (typeof originalOnDragStart === 'function') {\n originalOnDragStart(draggedNodes, evt);\n }\n },\n [setSelected, originalOnDragStart, selected, setInteractionMode],\n );\n\n const onDragEnd = useCallback(\n (draggedNodes: Node[], evt: MouseEvent) => {\n if (typeof originalOnDragEnd === 'function') {\n originalOnDragEnd(draggedNodes, evt);\n }\n setInteractionMode('select');\n },\n [originalOnDragEnd, setInteractionMode],\n );\n\n // wrapping so that there's a function passed, even if the original function is undefined\n const onDrawStarted = useCallback(\n (evt: MouseEvent) => {\n if (typeof originalOnDrawStarted === 'function') {\n originalOnDrawStarted(evt);\n }\n },\n [originalOnDrawStarted],\n );\n\n const onDrawEnded = useCallback(\n (\n newRelationshipToAdd: Relationship | null,\n newTargetNodeToAdd: Node | null,\n event: MouseEvent,\n ) => {\n if (typeof originalOnDrawEnded === 'function') {\n originalOnDrawEnded(newRelationshipToAdd, newTargetNodeToAdd, event);\n }\n },\n [originalOnDrawEnded],\n );\n\n const onNodeClick = useCallback(\n (node: Node, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n if (isMultiSelectKeyPressed(evt)) {\n // if not selected, add to selection, otherwise deselect\n const isNodeSelected = selected.nodeIds.includes(node.id);\n if (isNodeSelected) {\n const newSelectedNodeIds = selected.nodeIds.filter(\n (id) => id !== node.id,\n );\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n } else {\n const newSelectedNodeIds = [...selected.nodeIds, node.id];\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n }\n } else {\n setSelected({ nodeIds: [node.id], relationshipIds: [] });\n }\n if (typeof originalOnNodeClick === 'function') {\n originalOnNodeClick(node, hitElements, evt);\n }\n },\n [setSelected, selected, originalOnNodeClick],\n );\n\n const onRelationshipClick = useCallback(\n (relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n if (isMultiSelectKeyPressed(evt)) {\n // if not selected, add to selection, otherwise deselect\n const isRelationshipSelected = selected.relationshipIds.includes(\n relationship.id,\n );\n if (isRelationshipSelected) {\n const newSelectedRelIds = selected.relationshipIds.filter(\n (id) => id !== relationship.id,\n );\n setSelected({\n nodeIds: selected.nodeIds,\n relationshipIds: newSelectedRelIds,\n });\n } else {\n const newSelectedRelIds = [\n ...selected.relationshipIds,\n relationship.id,\n ];\n setSelected({\n nodeIds: selected.nodeIds,\n relationshipIds: newSelectedRelIds,\n });\n }\n } else {\n setSelected({ nodeIds: [], relationshipIds: [relationship.id] });\n }\n if (typeof originalOnRelationshipClick === 'function') {\n originalOnRelationshipClick(relationship, hitElements, evt);\n }\n },\n [setSelected, selected, originalOnRelationshipClick],\n );\n\n const onNodeDoubleClick = useCallback(\n (node: Node, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n if (typeof originalOnNodeDoubleClick === 'function') {\n originalOnNodeDoubleClick(node, hitElements, evt);\n }\n },\n [originalOnNodeDoubleClick],\n );\n\n const onRelationshipDoubleClick = useCallback(\n (relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n if (typeof originalOnRelationshipDoubleClick === 'function') {\n originalOnRelationshipDoubleClick(relationship, hitElements, evt);\n }\n },\n [originalOnRelationshipDoubleClick],\n );\n\n const onMultiSelect = useCallback(\n (nodes: Node[], rels: Relationship[], evt: MouseEvent) => {\n const nodeIds = nodes.map((n) => n.id);\n const relationshipIds = rels.map((r) => r.id);\n if (isMultiSelectKeyPressed(evt)) {\n const currentlySelectedNodeIds = selected.nodeIds;\n const currentlySelectedRelIds = selected.relationshipIds;\n\n // Toggle selection: items that are already selected should be removed from selection,\n // those that are not should be added\n const xor = (a: string[], b: string[]) => [\n ...new Set(\n [...a, ...b].filter((id) => !a.includes(id) || !b.includes(id)),\n ),\n ];\n\n const newSelectedNodeIds = xor(currentlySelectedNodeIds, nodeIds);\n const newSelectedRelIds = xor(currentlySelectedRelIds, relationshipIds);\n\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: newSelectedRelIds,\n });\n } else {\n // REPLACE selection\n setSelected({ nodeIds: nodeIds, relationshipIds: relationshipIds });\n }\n },\n [setSelected, selected],\n );\n\n const onLassoSelect = useCallback(\n (\n { nodes, rels }: { nodes: Node[]; rels: Relationship[] },\n evt: MouseEvent,\n ) => {\n onMultiSelect(nodes, rels, evt);\n if (typeof originalOnLassoSelect === 'function') {\n originalOnLassoSelect({ nodes, rels }, evt);\n }\n },\n [onMultiSelect, originalOnLassoSelect],\n );\n\n const onBoxSelect = useCallback(\n (\n { nodes, rels }: { nodes: Node[]; rels: Relationship[] },\n evt: MouseEvent,\n ) => {\n onMultiSelect(nodes, rels, evt);\n if (typeof originalBoxSelect === 'function') {\n originalBoxSelect({ nodes, rels }, evt);\n }\n },\n [onMultiSelect, originalBoxSelect],\n );\n\n const isDrawMode = interactionMode === 'draw';\n\n const isSelectMode = interactionMode === 'select';\n const shouldEnableBox = isSelectMode && gesture === 'box';\n const shouldEnableLasso = isSelectMode && gesture === 'lasso';\n\n const shouldEnablePan =\n interactionMode === 'pan' || (isSelectMode && gesture === 'single');\n\n const canDrag = interactionMode === 'drag' || interactionMode === 'select';\n\n const wrappedMouseEventCallbacks = useMemo(\n () => ({\n ...mouseEventCallbacks,\n onBoxSelect: shouldEnableBox ? onBoxSelect : false,\n onBoxStarted: shouldEnableBox ? onBoxStarted : false,\n onCanvasClick: isSelectMode ? onCanvasClick : false,\n onDragEnd: canDrag ? onDragEnd : false,\n onDragStart: canDrag ? onDragStart : false,\n onDrawEnded: isDrawMode ? onDrawEnded : false,\n onDrawStarted: isDrawMode ? onDrawStarted : false,\n onHover: isSelectMode ? onHover : false,\n onHoverNodeMargin: isDrawMode ? onHoverNodeMargin : false,\n onLassoSelect: shouldEnableLasso ? onLassoSelect : false,\n onLassoStarted: shouldEnableLasso ? onLassoStarted : false,\n onNodeClick: isSelectMode ? onNodeClick : false,\n onNodeDoubleClick: isSelectMode ? onNodeDoubleClick : false,\n onPan: shouldEnablePan ? onPan : false,\n onRelationshipClick: isSelectMode ? onRelationshipClick : false,\n onRelationshipDoubleClick: isSelectMode\n ? onRelationshipDoubleClick\n : false,\n onZoom: mouseEventCallbacks.onZoom ?? true,\n }),\n [\n canDrag,\n shouldEnableBox,\n shouldEnableLasso,\n shouldEnablePan,\n isDrawMode,\n isSelectMode,\n mouseEventCallbacks,\n onBoxSelect,\n onBoxStarted,\n onCanvasClick,\n onDragEnd,\n onDragStart,\n onDrawEnded,\n onDrawStarted,\n onHover,\n onHoverNodeMargin,\n onLassoSelect,\n onLassoStarted,\n onNodeClick,\n onNodeDoubleClick,\n onPan,\n onRelationshipClick,\n onRelationshipDoubleClick,\n ],\n );\n\n const selectionSet = useMemo(\n () => ({\n nodeIds: new Set(selected.nodeIds),\n relIds: new Set(selected.relationshipIds),\n }),\n [selected],\n );\n\n const highlightedNodeSet = useMemo(\n () =>\n highlightedNodeIds !== undefined ? new Set(highlightedNodeIds) : null,\n [highlightedNodeIds],\n );\n const highlightedRelSet = useMemo(\n () =>\n highlightedRelationshipIds !== undefined\n ? new Set(highlightedRelationshipIds)\n : null,\n [highlightedRelationshipIds],\n );\n\n const nodesWithState = useMemo(\n () =>\n nvlGraph.nodes.map((n) => ({\n ...n,\n disabled: highlightedNodeSet ? !highlightedNodeSet.has(n.id) : false,\n selected: selectionSet.nodeIds.has(n.id),\n })),\n [nvlGraph.nodes, selectionSet, highlightedNodeSet],\n );\n\n const relsWithState = useMemo(\n () =>\n nvlGraph.rels.map((r) => ({\n ...r,\n disabled: highlightedRelSet ? !highlightedRelSet.has(r.id) : false,\n selected: selectionSet.relIds.has(r.id),\n })),\n [nvlGraph.rels, selectionSet, highlightedRelSet],\n );\n\n return { nodesWithState, relsWithState, wrappedMouseEventCallbacks };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-managed-node-state.js","sourceRoot":"","sources":["../../src/use-managed-node-state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type HitTargets, type Node, type Relationship } from '@neo4j-nvl/base';\nimport { type MouseEventCallbacks } from '@neo4j-nvl/react';\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport {\n type Gesture,\n type GraphSelection,\n type InteractionMode,\n} from './graph-visualization-context';\nimport { isMac } from './utils';\n\nconst isMultiSelectKeyPressed = (evt: MouseEvent): boolean =>\n (!isMac && evt.ctrlKey) || (isMac && evt.metaKey);\n\nconst isClickingOnTextInput = (e: MouseEvent): boolean => {\n if (!(e.target instanceof HTMLElement)) {\n return false;\n }\n return (\n e.target.isContentEditable ||\n ['INPUT', 'TEXTAREA'].includes(e.target.tagName)\n );\n};\n\nexport type ManagedNodeStateArgs = {\n selected: GraphSelection;\n setSelected: (newSelection: GraphSelection) => void;\n gesture: Gesture;\n interactionMode: InteractionMode;\n setInteractionMode: (newInteractionMode: InteractionMode) => void;\n mouseEventCallbacks: MouseEventCallbacks;\n nvlGraph: {\n nodes: Node[];\n rels: Relationship[];\n };\n highlightedNodeIds?: string[];\n highlightedRelationshipIds?: string[];\n};\n\nexport function useManagedNodeState({\n selected,\n setSelected,\n gesture,\n interactionMode,\n setInteractionMode,\n mouseEventCallbacks,\n nvlGraph,\n highlightedNodeIds,\n highlightedRelationshipIds,\n}: ManagedNodeStateArgs) {\n const panOnSpace = useCallback(\n (evt: KeyboardEvent) => {\n // We could check the gesture here\n // but it doesn't really matter if we switch to panning mode even in single select\n if (interactionMode === 'select' && evt.key === ' ') {\n setInteractionMode('pan');\n }\n },\n [interactionMode, setInteractionMode],\n );\n\n const stopPanningReleaseSpace = useCallback(\n (evt: KeyboardEvent) => {\n if (interactionMode === 'pan' && evt.key === ' ') {\n setInteractionMode('select');\n }\n },\n [interactionMode, setInteractionMode],\n );\n\n useEffect(() => {\n document.addEventListener('keydown', panOnSpace);\n document.addEventListener('keyup', stopPanningReleaseSpace);\n return () => {\n document.removeEventListener('keydown', panOnSpace);\n document.removeEventListener('keyup', stopPanningReleaseSpace);\n };\n }, [panOnSpace, stopPanningReleaseSpace]);\n\n const {\n onBoxSelect: originalBoxSelect,\n onLassoSelect: originalOnLassoSelect,\n onLassoStarted,\n onBoxStarted,\n onPan = true,\n onHover,\n onHoverNodeMargin,\n onNodeClick: originalOnNodeClick,\n onRelationshipClick: originalOnRelationshipClick,\n onDragStart: originalOnDragStart,\n onDragEnd: originalOnDragEnd,\n onDrawEnded: originalOnDrawEnded,\n onDrawStarted: originalOnDrawStarted,\n onCanvasClick: originalOnCanvasClick,\n onNodeDoubleClick: originalOnNodeDoubleClick,\n onRelationshipDoubleClick: originalOnRelationshipDoubleClick,\n\n onZoom: originalOnZoom,\n onZoomAndPan: originalOnZoomAndPan,\n } = mouseEventCallbacks;\n\n const onCanvasClick = useCallback(\n (evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n // Clear selection\n setSelected({ nodeIds: [], relationshipIds: [] });\n\n if (typeof originalOnCanvasClick === 'function') {\n originalOnCanvasClick(evt);\n }\n },\n [originalOnCanvasClick, setSelected],\n );\n\n const onDragStart = useCallback(\n (draggedNodes: Node[], evt: MouseEvent) => {\n setInteractionMode('drag');\n\n // Update Selection\n const draggedNodeIds = draggedNodes.map((n) => n.id);\n if (selected.nodeIds.length === 0 || isMultiSelectKeyPressed(evt)) {\n setSelected({\n nodeIds: draggedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n return;\n }\n setSelected({\n nodeIds: draggedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n\n if (typeof originalOnDragStart === 'function') {\n originalOnDragStart(draggedNodes, evt);\n }\n },\n [setSelected, originalOnDragStart, selected, setInteractionMode],\n );\n\n const onDragEnd = useCallback(\n (draggedNodes: Node[], evt: MouseEvent) => {\n if (typeof originalOnDragEnd === 'function') {\n originalOnDragEnd(draggedNodes, evt);\n }\n setInteractionMode('select');\n },\n [originalOnDragEnd, setInteractionMode],\n );\n\n // wrapping so that there's a function passed, even if the original function is undefined\n const onDrawStarted = useCallback(\n (evt: MouseEvent) => {\n if (typeof originalOnDrawStarted === 'function') {\n originalOnDrawStarted(evt);\n }\n },\n [originalOnDrawStarted],\n );\n\n const onDrawEnded = useCallback(\n (\n newRelationshipToAdd: Relationship | null,\n newTargetNodeToAdd: Node | null,\n event: MouseEvent,\n ) => {\n if (typeof originalOnDrawEnded === 'function') {\n originalOnDrawEnded(newRelationshipToAdd, newTargetNodeToAdd, event);\n }\n },\n [originalOnDrawEnded],\n );\n\n const onNodeClick = useCallback(\n (node: Node, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n if (isMultiSelectKeyPressed(evt)) {\n // if not selected, add to selection, otherwise deselect\n const isNodeSelected = selected.nodeIds.includes(node.id);\n if (isNodeSelected) {\n const newSelectedNodeIds = selected.nodeIds.filter(\n (id) => id !== node.id,\n );\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n } else {\n const newSelectedNodeIds = [...selected.nodeIds, node.id];\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: selected.relationshipIds,\n });\n }\n } else {\n setSelected({ nodeIds: [node.id], relationshipIds: [] });\n }\n if (typeof originalOnNodeClick === 'function') {\n originalOnNodeClick(node, hitElements, evt);\n }\n },\n [setSelected, selected, originalOnNodeClick],\n );\n\n const onRelationshipClick = useCallback(\n (relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n\n if (isMultiSelectKeyPressed(evt)) {\n // if not selected, add to selection, otherwise deselect\n const isRelationshipSelected = selected.relationshipIds.includes(\n relationship.id,\n );\n if (isRelationshipSelected) {\n const newSelectedRelIds = selected.relationshipIds.filter(\n (id) => id !== relationship.id,\n );\n setSelected({\n nodeIds: selected.nodeIds,\n relationshipIds: newSelectedRelIds,\n });\n } else {\n const newSelectedRelIds = [\n ...selected.relationshipIds,\n relationship.id,\n ];\n setSelected({\n nodeIds: selected.nodeIds,\n relationshipIds: newSelectedRelIds,\n });\n }\n } else {\n setSelected({ nodeIds: [], relationshipIds: [relationship.id] });\n }\n if (typeof originalOnRelationshipClick === 'function') {\n originalOnRelationshipClick(relationship, hitElements, evt);\n }\n },\n [setSelected, selected, originalOnRelationshipClick],\n );\n\n const onNodeDoubleClick = useCallback(\n (node: Node, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n if (typeof originalOnNodeDoubleClick === 'function') {\n originalOnNodeDoubleClick(node, hitElements, evt);\n }\n },\n [originalOnNodeDoubleClick],\n );\n\n const onRelationshipDoubleClick = useCallback(\n (relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => {\n if (isClickingOnTextInput(evt)) {\n return;\n }\n if (typeof originalOnRelationshipDoubleClick === 'function') {\n originalOnRelationshipDoubleClick(relationship, hitElements, evt);\n }\n },\n [originalOnRelationshipDoubleClick],\n );\n\n const onMultiSelect = useCallback(\n (nodes: Node[], rels: Relationship[], evt: MouseEvent) => {\n const nodeIds = nodes.map((n) => n.id);\n const relationshipIds = rels.map((r) => r.id);\n if (isMultiSelectKeyPressed(evt)) {\n const currentlySelectedNodeIds = selected.nodeIds;\n const currentlySelectedRelIds = selected.relationshipIds;\n\n // Toggle selection: items that are already selected should be removed from selection,\n // those that are not should be added\n const xor = (a: string[], b: string[]) => [\n ...new Set(\n [...a, ...b].filter((id) => !a.includes(id) || !b.includes(id)),\n ),\n ];\n\n const newSelectedNodeIds = xor(currentlySelectedNodeIds, nodeIds);\n const newSelectedRelIds = xor(currentlySelectedRelIds, relationshipIds);\n\n setSelected({\n nodeIds: newSelectedNodeIds,\n relationshipIds: newSelectedRelIds,\n });\n } else {\n // REPLACE selection\n setSelected({ nodeIds: nodeIds, relationshipIds: relationshipIds });\n }\n },\n [setSelected, selected],\n );\n\n const onLassoSelect = useCallback(\n (\n { nodes, rels }: { nodes: Node[]; rels: Relationship[] },\n evt: MouseEvent,\n ) => {\n onMultiSelect(nodes, rels, evt);\n if (typeof originalOnLassoSelect === 'function') {\n originalOnLassoSelect({ nodes, rels }, evt);\n }\n },\n [onMultiSelect, originalOnLassoSelect],\n );\n\n const onBoxSelect = useCallback(\n (\n { nodes, rels }: { nodes: Node[]; rels: Relationship[] },\n evt: MouseEvent,\n ) => {\n onMultiSelect(nodes, rels, evt);\n if (typeof originalBoxSelect === 'function') {\n originalBoxSelect({ nodes, rels }, evt);\n }\n },\n [onMultiSelect, originalBoxSelect],\n );\n\n const isDrawMode = interactionMode === 'draw';\n\n const isSelectMode = interactionMode === 'select';\n const shouldEnableBox = isSelectMode && gesture === 'box';\n const shouldEnableLasso = isSelectMode && gesture === 'lasso';\n\n const shouldEnablePan =\n interactionMode === 'pan' || (isSelectMode && gesture === 'single');\n\n const canDrag = interactionMode === 'drag' || interactionMode === 'select';\n\n const hasCustomZoomCallback =\n originalOnZoom !== undefined || originalOnZoomAndPan !== undefined;\n\n const wrappedMouseEventCallbacks = useMemo(\n () => ({\n ...mouseEventCallbacks,\n onBoxSelect: shouldEnableBox ? onBoxSelect : false,\n onBoxStarted: shouldEnableBox ? onBoxStarted : false,\n onCanvasClick: isSelectMode ? onCanvasClick : false,\n onDragEnd: canDrag ? onDragEnd : false,\n onDragStart: canDrag ? onDragStart : false,\n onDrawEnded: isDrawMode ? onDrawEnded : false,\n onDrawStarted: isDrawMode ? onDrawStarted : false,\n onHover: isSelectMode ? onHover : false,\n onHoverNodeMargin: isDrawMode ? onHoverNodeMargin : false,\n onLassoSelect: shouldEnableLasso ? onLassoSelect : false,\n onLassoStarted: shouldEnableLasso ? onLassoStarted : false,\n onNodeClick: isSelectMode ? onNodeClick : false,\n onNodeDoubleClick: isSelectMode ? onNodeDoubleClick : false,\n onPan: shouldEnablePan ? onPan : false,\n onRelationshipClick: isSelectMode ? onRelationshipClick : false,\n onRelationshipDoubleClick: isSelectMode\n ? onRelationshipDoubleClick\n : false,\n onZoomAndPan: hasCustomZoomCallback ? originalOnZoomAndPan : true,\n }),\n [\n canDrag,\n shouldEnableBox,\n shouldEnableLasso,\n shouldEnablePan,\n isDrawMode,\n isSelectMode,\n mouseEventCallbacks,\n onBoxSelect,\n onBoxStarted,\n onCanvasClick,\n onDragEnd,\n onDragStart,\n onDrawEnded,\n onDrawStarted,\n onHover,\n onHoverNodeMargin,\n onLassoSelect,\n onLassoStarted,\n onNodeClick,\n onNodeDoubleClick,\n onPan,\n onRelationshipClick,\n onRelationshipDoubleClick,\n hasCustomZoomCallback,\n originalOnZoomAndPan,\n ],\n );\n\n const selectionSet = useMemo(\n () => ({\n nodeIds: new Set(selected.nodeIds),\n relIds: new Set(selected.relationshipIds),\n }),\n [selected],\n );\n\n const highlightedNodeSet = useMemo(\n () =>\n highlightedNodeIds !== undefined ? new Set(highlightedNodeIds) : null,\n [highlightedNodeIds],\n );\n const highlightedRelSet = useMemo(\n () =>\n highlightedRelationshipIds !== undefined\n ? new Set(highlightedRelationshipIds)\n : null,\n [highlightedRelationshipIds],\n );\n\n const nodesWithState = useMemo(\n () =>\n nvlGraph.nodes.map((n) => ({\n ...n,\n disabled: highlightedNodeSet ? !highlightedNodeSet.has(n.id) : false,\n selected: selectionSet.nodeIds.has(n.id),\n })),\n [nvlGraph.nodes, selectionSet, highlightedNodeSet],\n );\n\n const relsWithState = useMemo(\n () =>\n nvlGraph.rels.map((r) => ({\n ...r,\n disabled: highlightedRelSet ? !highlightedRelSet.has(r.id) : false,\n selected: selectionSet.relIds.has(r.id),\n })),\n [nvlGraph.rels, selectionSet, highlightedRelSet],\n );\n\n return { nodesWithState, relsWithState, wrappedMouseEventCallbacks };\n}\n"]}
|
|
@@ -19,20 +19,26 @@
|
|
|
19
19
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
20
|
*/
|
|
21
21
|
import type NVL from '@neo4j-nvl/base';
|
|
22
|
-
import { type Layout } from '@neo4j-nvl/base';
|
|
22
|
+
import { type Layout, type NvlOptions } from '@neo4j-nvl/base';
|
|
23
23
|
import { type InteractiveNvlWrapperProps } from '@neo4j-nvl/react';
|
|
24
24
|
import React from 'react';
|
|
25
25
|
import { type Gesture, type GraphSelection, type InteractionMode, type NeoNode, type NeoRel, type Sidepanel } from './graph-visualization-context';
|
|
26
26
|
import { type GraphStyleRule } from './styling/style-types';
|
|
27
27
|
export declare const DEFAULT_NVL_OPTIONS: {
|
|
28
|
-
disableTelemetry:
|
|
29
|
-
disableWebGL:
|
|
28
|
+
disableTelemetry: true;
|
|
29
|
+
disableWebGL: true;
|
|
30
30
|
maxZoom: number;
|
|
31
31
|
minZoom: number;
|
|
32
32
|
relationshipThreshold: number;
|
|
33
|
+
renderer: "canvas";
|
|
34
|
+
};
|
|
35
|
+
type BackwardsCompatibleNvlOptions = NvlOptions & {
|
|
36
|
+
/** @deprecated Use {@link NvlOptions.renderer} instead. */
|
|
37
|
+
useWebGL?: boolean;
|
|
33
38
|
};
|
|
34
39
|
export type GraphVisualizationProps<T extends React.ElementType = 'div'> = {
|
|
35
40
|
nvlRef?: React.RefObject<NVL | null>;
|
|
41
|
+
nvlOptions?: BackwardsCompatibleNvlOptions;
|
|
36
42
|
sidepanel?: Sidepanel | null;
|
|
37
43
|
bottomLeftIsland?: React.ReactNode;
|
|
38
44
|
bottomCenterIsland?: React.ReactNode;
|
|
@@ -122,7 +128,7 @@ export type GraphVisualizationProps<T extends React.ElementType = 'div'> = {
|
|
|
122
128
|
*
|
|
123
129
|
* @alpha
|
|
124
130
|
*/
|
|
125
|
-
export declare function GraphVisualization<T extends React.ElementType = 'div'>({ nvlRef: rawNvlRef, nvlCallbacks, nvlOptions, sidepanel: rawSidepanel, nodes: rawNodes, rels: rawRels, highlightedNodeIds, highlightedRelationshipIds, topLeftIsland, topRightIsland, bottomLeftIsland, bottomCenterIsland, bottomRightIsland, gesture, setGesture, layout: rawLayout, setLayout: rawSetLayout, portalTarget, selected: rawSelected, setSelected: rawSetSelected, interactionMode: rawInteractionMode, setInteractionMode: rawSetInteractionMode, mouseEventCallbacks, className, style, htmlAttributes, ref, as, styleRules, ...restProps }: GraphVisualizationProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
131
|
+
export declare function GraphVisualization<T extends React.ElementType = 'div'>({ nvlRef: rawNvlRef, nvlCallbacks, nvlOptions: rawNvlOptions, sidepanel: rawSidepanel, nodes: rawNodes, rels: rawRels, highlightedNodeIds, highlightedRelationshipIds, topLeftIsland, topRightIsland, bottomLeftIsland, bottomCenterIsland, bottomRightIsland, gesture, setGesture, layout: rawLayout, layoutOptions, setLayout: rawSetLayout, portalTarget, selected: rawSelected, setSelected: rawSetSelected, interactionMode: rawInteractionMode, setInteractionMode: rawSetInteractionMode, mouseEventCallbacks, className, style, htmlAttributes, ref, as, styleRules, ...restProps }: GraphVisualizationProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
126
132
|
export declare namespace GraphVisualization {
|
|
127
133
|
var ZoomInButton: ({ className, style, htmlAttributes, tooltipPlacement, }: {
|
|
128
134
|
tooltipPlacement?: import("@floating-ui/react").Placement | undefined;
|
|
@@ -270,4 +276,5 @@ export declare namespace GraphVisualization {
|
|
|
270
276
|
gestureOptions?: Partial<import("./graph-visualization-buttons").GestureSelectOption>;
|
|
271
277
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
272
278
|
}
|
|
279
|
+
export {};
|
|
273
280
|
//# sourceMappingURL=graph-visualization.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-visualization.d.ts","sourceRoot":"","sources":["../../src/graph-visualization.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"graph-visualization.d.ts","sourceRoot":"","sources":["../../src/graph-visualization.tsx"],"names":[],"mappings":"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"}
|
|
@@ -106,13 +106,13 @@ export declare function useManagedNodeState({ selected, setSelected, gesture, in
|
|
|
106
106
|
}, event: MouseEvent) => void);
|
|
107
107
|
onRelationshipClick: boolean | ((relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => void);
|
|
108
108
|
onRelationshipDoubleClick: boolean | ((relationship: Relationship, hitElements: HitTargets, evt: MouseEvent) => void);
|
|
109
|
-
|
|
109
|
+
onZoomAndPan: boolean | ((zoomLevel: number, panX: number, panY: number, event: WheelEvent) => void) | undefined;
|
|
110
110
|
onCanvasDoubleClick?: ((event: MouseEvent) => void) | boolean;
|
|
111
111
|
onCanvasRightClick?: ((event: MouseEvent) => void) | boolean;
|
|
112
112
|
onNodeRightClick?: ((node: Node, hitElements: HitTargets, event: MouseEvent) => void) | boolean;
|
|
113
113
|
onRelationshipRightClick?: ((relationship: Relationship, hitElements: HitTargets, event: MouseEvent) => void) | boolean;
|
|
114
114
|
onDrag?: ((nodes: Node[], evt: MouseEvent) => void) | boolean;
|
|
115
|
-
|
|
115
|
+
onZoom?: ((zoomLevel: number, event: WheelEvent) => void) | boolean;
|
|
116
116
|
};
|
|
117
117
|
};
|
|
118
118
|
//# sourceMappingURL=use-managed-node-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-managed-node-state.d.ts","sourceRoot":"","sources":["../../src/use-managed-node-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG5D,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAC;AAgBvC,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,CAAC,YAAY,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,CAAC,kBAAkB,EAAE,eAAe,KAAK,IAAI,CAAC;IAClE,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,QAAQ,EAAE;QACR,KAAK,EAAE,IAAI,EAAE,CAAC;QACd,IAAI,EAAE,YAAY,EAAE,CAAC;KACtB,CAAC;IACF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,0BAA0B,CAAC,EAAE,MAAM,EAAE,CAAC;CACvC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,WAAW,EACX,OAAO,EACP,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,0BAA0B,GAC3B,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;oBAEE,CAAC;gBAUV,CAAC;;;;;;;;;;;;;;;;;;;;oBAVQ,CAAC;gBAUV,CAAC;;;;
|
|
1
|
+
{"version":3,"file":"use-managed-node-state.d.ts","sourceRoot":"","sources":["../../src/use-managed-node-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG5D,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAC;AAgBvC,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,CAAC,YAAY,EAAE,cAAc,KAAK,IAAI,CAAC;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,CAAC,kBAAkB,EAAE,eAAe,KAAK,IAAI,CAAC;IAClE,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,QAAQ,EAAE;QACR,KAAK,EAAE,IAAI,EAAE,CAAC;QACd,IAAI,EAAE,YAAY,EAAE,CAAC;KACtB,CAAC;IACF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,0BAA0B,CAAC,EAAE,MAAM,EAAE,CAAC;CACvC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,WAAW,EACX,OAAO,EACP,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,0BAA0B,GAC3B,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;oBAEE,CAAC;gBAUV,CAAC;;;;;;;;;;;;;;;;;;;;oBAVQ,CAAC;gBAUV,CAAC;;;;kDAiQM;YAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YAAC,IAAI,EAAE,YAAY,EAAE,CAAA;SAAE,OACnD,UAAU;;wCAzNX,UAAU;6CAyCD,IAAI,EAAE,OAAO,UAAU;+CAzBvB,IAAI,EAAE,OAAO,UAAU;uDA8Cd,YAAY,GAAG,IAAI,sBACrB,IAAI,GAAG,IAAI,SACxB,UAAU;wCAZb,UAAU;;;oDAuJG;YAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YAAC,IAAI,EAAE,YAAY,EAAE,CAAA;SAAE,OACnD,UAAU;;uCAlIV,IAAI,eAAe,UAAU,OAAO,UAAU;6CAyE9C,IAAI,eAAe,UAAU,OAAO,UAAU;;;;;uDAvCtC,YAAY,eAAe,UAAU,OAAO,UAAU;6DAmDtD,YAAY,eAAe,UAAU,OAAO,UAAU;;;;;;;;;EAgLxE"}
|