@neo4j-nvl/base 2.0.0-8a6da460 → 2.0.0-d21c8bbe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/base.mjs +35832 -39698
- package/dist/types/index.d.ts +4 -6
- package/dist/types/modules/state/types.d.ts +16 -5
- package/dist/types/renderers/domrenderer/canvasrenderer/CanvasRenderer.d.ts +1 -1
- package/package.json +6 -6
- package/skills/neo4j-nvl-skill/README.md +39 -0
- package/skills/neo4j-nvl-skill/SKILL.md +456 -0
- package/skills/neo4j-nvl-skill/references/api-surface.md +596 -0
- package/skills/neo4j-nvl-skill/references/troubleshooting.md +317 -0
- /package/dist/types/utils/{hittest.d.ts → hitTest.d.ts} +0 -0
- /package/dist/types/utils/{hittest.test.d.ts → hitTest.test.d.ts} +0 -0
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
# NVL — API Surface Reference
|
|
2
|
+
|
|
3
|
+
Source: `@neo4j-nvl/base@2.0`, `@neo4j-nvl/interaction-handlers@2.0`, `@neo4j-nvl/react@2.0`.
|
|
4
|
+
|
|
5
|
+
## Packages
|
|
6
|
+
|
|
7
|
+
| Package | Main export | Notes |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `@neo4j-nvl/base` | `NVL` (also default), types, `nvlResultTransformer`, layout constants | Framework-agnostic core |
|
|
10
|
+
| `@neo4j-nvl/interaction-handlers` | `ZoomInteraction`, `PanInteraction`, `ClickInteraction`, `HoverInteraction`, `DragNodeInteraction`, `BoxSelectInteraction`, `LassoInteraction`, `KeyboardInteraction` | Compose onto an `NVL` instance |
|
|
11
|
+
| `@neo4j-nvl/react` | `InteractiveNvlWrapper`, `BasicNvlWrapper`, `StaticPictureWrapper` | React 19 |
|
|
12
|
+
| `@neo4j-nvl/layout-workers` | (transitive) | Force-directed + hierarchical workers |
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## `NVL` Class
|
|
17
|
+
|
|
18
|
+
### Constructor
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
new NVL(
|
|
22
|
+
frame: HTMLElement,
|
|
23
|
+
nvlNodes?: Node[], // default []
|
|
24
|
+
nvlRels?: Relationship[], // default []
|
|
25
|
+
options?: NvlOptions, // default {}
|
|
26
|
+
callbacks?: ExternalCallbacks // default {}
|
|
27
|
+
)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Element CRUD
|
|
31
|
+
|
|
32
|
+
| Method | Signature | Purpose |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `addAndUpdateElementsInGraph` | `(nodes: Node[] \| PartialNode[], rels: Relationship[] \| PartialRelationship[]) => void` | Insert new; update existing by id |
|
|
35
|
+
| `addElementsToGraph` | `(nodes: Node[], rels: Relationship[]) => void` | Insert only |
|
|
36
|
+
| `updateElementsInGraph` | `(nodes: PartialNode[], rels: PartialRelationship[]) => void` | Update existing only; ignores unknown ids |
|
|
37
|
+
| `removeNodesWithIds` | `(ids: string[]) => void` | Remove nodes + adjacent relationships |
|
|
38
|
+
| `removeRelationshipsWithIds` | `(ids: string[]) => void` | Remove relationships |
|
|
39
|
+
|
|
40
|
+
### Element Read
|
|
41
|
+
|
|
42
|
+
| Method | Signature |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `getNodes` | `() => NodeWithClientPosition[]` |
|
|
45
|
+
| `getRelationships` | `() => Relationship[]` |
|
|
46
|
+
| `getNodeById` | `(id: string) => Node` |
|
|
47
|
+
| `getRelationshipById` | `(id: string) => Relationship` |
|
|
48
|
+
| `getPositionById` | `(id: string) => Node` |
|
|
49
|
+
| `getNodesOnScreen` | `() => { nodes: Node[]; rels: Relationship[] }` |
|
|
50
|
+
| `getNodePositions` | `() => (Node & Point)[]` |
|
|
51
|
+
| `setNodePositions` | `(data: Node[], updateLayout?: boolean) => void` |
|
|
52
|
+
| `getSelectedNodes` | `() => (Node & Point)[]` |
|
|
53
|
+
| `getSelectedRelationships` | `() => Relationship[]` |
|
|
54
|
+
| `deselectAll` | `() => void` |
|
|
55
|
+
|
|
56
|
+
### Viewport
|
|
57
|
+
|
|
58
|
+
| Method | Signature |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `fit` | `(nodeIds: string[], zoomOptions?: ZoomOptions) => void` (empty array = fit all) |
|
|
61
|
+
| `resetZoom` | `() => void` |
|
|
62
|
+
| `setZoom` | `(zoom: number) => void` |
|
|
63
|
+
| `setPan` | `(panX: number, panY: number) => void` |
|
|
64
|
+
| `setZoomAndPan` | `(zoom: number, panX: number, panY: number) => void` |
|
|
65
|
+
| `getScale` | `() => number` |
|
|
66
|
+
| `getPan` | `() => Point` |
|
|
67
|
+
| `getZoomLimits` | `() => { minZoom: number; maxZoom: number }` |
|
|
68
|
+
|
|
69
|
+
### Layout / Renderer / Pin
|
|
70
|
+
|
|
71
|
+
| Method | Signature |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `setLayout` | `(layout: Layout) => void` |
|
|
74
|
+
| `setLayoutOptions` | `(options: LayoutOptions) => void` |
|
|
75
|
+
| `isLayoutMoving` | `() => boolean` |
|
|
76
|
+
| `setRenderer` | `(renderer: 'canvas' \| 'webgl') => void` |
|
|
77
|
+
| `setDisableWebGL` | `(disabled?: boolean) => void` |
|
|
78
|
+
| `pinNode` | `(nodeId: string) => void` |
|
|
79
|
+
| `unPinNode` | `(nodeIds: string[]) => void` |
|
|
80
|
+
|
|
81
|
+
### Export / Save
|
|
82
|
+
|
|
83
|
+
| Method | Signature |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `saveToFile` | `(opts?: { filename?: string; backgroundColor?: string }) => void` (PNG of current view) |
|
|
86
|
+
| `saveFullGraphToLargeFile` | `(opts?: { filename?: string; backgroundColor?: string }) => void` (PNG of full graph) |
|
|
87
|
+
| `saveToSvg` | `(opts?: { filename?: string; backgroundColor?: string }) => void` (experimental) |
|
|
88
|
+
| `getImageDataUrl` | `(opts?: { backgroundColor?: string }) => string` |
|
|
89
|
+
| `getSvgDataUrl` | `(opts?: { backgroundColor?: string }) => Promise<string>` |
|
|
90
|
+
|
|
91
|
+
### Hit Testing
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
getHits(
|
|
95
|
+
evt: MouseEvent,
|
|
96
|
+
targets?: ('node' | 'relationship' | 'cluster')[], // default: all three
|
|
97
|
+
hitOptions?: { hitNodeMarginWidth: number } // default 0
|
|
98
|
+
): NvlMouseEvent
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Lifecycle / Misc
|
|
102
|
+
|
|
103
|
+
| Method | Signature |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `getCurrentOptions` | `() => NvlOptions` |
|
|
106
|
+
| `getContainer` | `() => HTMLElement` |
|
|
107
|
+
| `restart` | `(options?: NvlOptions, retainPositions?: boolean) => void` |
|
|
108
|
+
| `destroy` | `() => void` |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Core Types
|
|
113
|
+
|
|
114
|
+
### `Node`
|
|
115
|
+
|
|
116
|
+
| Field | Type | Notes |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| `id` | `string` | Required; unique across nodes AND relationships |
|
|
119
|
+
| `caption` | `string` | Single caption (superseded by `captions`) |
|
|
120
|
+
| `captions` | `StyledCaption[]` | Multi-line captions with styles |
|
|
121
|
+
| `captionSize` | `number` | Text size |
|
|
122
|
+
| `captionAlign` | `'top' \| 'bottom' \| 'center'` | |
|
|
123
|
+
| `color` | `string` | Fill color |
|
|
124
|
+
| `size` | `number` | Radius |
|
|
125
|
+
| `pinned` | `boolean` | Excluded from layout forces |
|
|
126
|
+
| `x` / `y` | `number` | Position |
|
|
127
|
+
| `selected` | `boolean` | |
|
|
128
|
+
| `hovered` | `boolean` | |
|
|
129
|
+
| `activated` | `boolean` | |
|
|
130
|
+
| `disabled` | `boolean` | |
|
|
131
|
+
| `icon` | `string` | URL to image inside node |
|
|
132
|
+
| `html` | `HTMLElement` | DOM overlay |
|
|
133
|
+
| `overlayIcon` | `{ url: string; position?: number[]; size?: number }` | |
|
|
134
|
+
|
|
135
|
+
`getNodes()` and `onLayoutStep` use:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
type NodeWithClientPosition = Node & Point & {
|
|
139
|
+
clientPosition: Point
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`x` and `y` are canvas/layout coordinates. `clientPosition` is relative to the canvas element.
|
|
144
|
+
|
|
145
|
+
### `Relationship`
|
|
146
|
+
|
|
147
|
+
| Field | Type | Notes |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `id` | `string` | Required; unique across nodes AND relationships |
|
|
150
|
+
| `from` | `string` | Source node id |
|
|
151
|
+
| `to` | `string` | Target node id |
|
|
152
|
+
| `type` | `string` | Relationship type label |
|
|
153
|
+
| `width` | `number` | |
|
|
154
|
+
| `color` | `string` | |
|
|
155
|
+
| `caption` / `captions` / `captionSize` / `captionAlign` | (same as Node) | |
|
|
156
|
+
| `captionHtml` | `HTMLElement` | DOM overlay on caption |
|
|
157
|
+
| `selected` / `hovered` / `disabled` | `boolean` | |
|
|
158
|
+
|
|
159
|
+
### Partial types
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
type PartialNode = Partial<Node> & { id: string }
|
|
163
|
+
type PartialRelationship = Partial<Relationship> & { id: string }
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## `NvlOptions`
|
|
169
|
+
|
|
170
|
+
| Field | Type | Default | Notes |
|
|
171
|
+
|---|---|---|---|
|
|
172
|
+
| `instanceId` | `string` | — | |
|
|
173
|
+
| `layout` | `Layout` | `'forceDirected'` | See Layout enum below |
|
|
174
|
+
| `layoutOptions` | `LayoutOptions` | — | Layout-specific |
|
|
175
|
+
| `layoutTimeLimit` | `number` | — | ms cap for layout iteration |
|
|
176
|
+
| `minFps` | `number` | `3` | Minimum presentation target while layout is active; capped to `1..120` |
|
|
177
|
+
| `maxFps` | `number` | `30` | Maximum presentation target while layout is active; capped to `1..120` |
|
|
178
|
+
| `minZoom` | `number` | `0.075` | |
|
|
179
|
+
| `maxZoom` | `number` | `10` | |
|
|
180
|
+
| `allowDynamicMinZoom` | `boolean` | `true` | Permits going below `minZoom` to fit |
|
|
181
|
+
| `initialZoom` | `number` | — | |
|
|
182
|
+
| `panX` / `panY` | `number` | — | |
|
|
183
|
+
| `renderer` | `'canvas' \| 'webgl'` | `'canvas'` | WebGL is WebGL2-only and does not render captions |
|
|
184
|
+
| `disableWebGL` | `boolean` | `false` | Force-off WebGL even if requested |
|
|
185
|
+
| `disableWebWorkers` | `boolean` | `false` | Use synchronous layout fallback |
|
|
186
|
+
| `disableTelemetry` | `boolean` | `false` | |
|
|
187
|
+
| `disableAria` | `boolean` | `false` | |
|
|
188
|
+
| `minimapContainer` | `HTMLElement \| null` | — | |
|
|
189
|
+
| `styling` | `StylingOptions` | — | |
|
|
190
|
+
| `callbacks` | `ExternalCallbacks` | — | (also passable as 5th constructor arg) |
|
|
191
|
+
| `logging` | `{ level: LogLevelDesc }` | — | |
|
|
192
|
+
|
|
193
|
+
### `StylingOptions`
|
|
194
|
+
|
|
195
|
+
| Field | Type |
|
|
196
|
+
|---|---|
|
|
197
|
+
| `defaultNodeColor` | `string` |
|
|
198
|
+
| `defaultRelationshipColor` | `string` |
|
|
199
|
+
| `nodeDefaultBorderColor` | `string` |
|
|
200
|
+
| `selectedBorderColor` | `string` |
|
|
201
|
+
| `selectedInnerBorderColor` | `string` |
|
|
202
|
+
| `dropShadowColor` | `string` |
|
|
203
|
+
| `disabledItemColor` | `string` |
|
|
204
|
+
| `disabledItemFontColor` | `string` |
|
|
205
|
+
| `overlayLineColor` | `string` |
|
|
206
|
+
| `minimapViewportBoxColor` | `string` (deprecated; use `overlayLineColor`) |
|
|
207
|
+
|
|
208
|
+
### Layout enum + constants
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
type Layout = 'forceDirected' | 'hierarchical' | 'grid' | 'free' | 'd3Force' | 'circular'
|
|
212
|
+
|
|
213
|
+
// Exported constants (string literals):
|
|
214
|
+
ForceDirectedLayoutType // 'forceDirected'
|
|
215
|
+
HierarchicalLayoutType // 'hierarchical'
|
|
216
|
+
GridLayoutType // 'grid'
|
|
217
|
+
FreeLayoutType // 'free'
|
|
218
|
+
d3ForceLayoutType // 'd3Force'
|
|
219
|
+
CircularLayoutType // 'circular'
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### `LayoutOptions` union
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
type LayoutOptions = ForceDirectedOptions | HierarchicalOptions | CircularOptions
|
|
226
|
+
|
|
227
|
+
interface ForceDirectedOptions {
|
|
228
|
+
seedingMethod?: 'box' | 'circle'
|
|
229
|
+
clustering?: ClusteringOptions
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
type ClusterId = string | number
|
|
233
|
+
type ClusterByFn = (nodeId: string) => ClusterId | undefined
|
|
234
|
+
|
|
235
|
+
interface ClusteringOptions {
|
|
236
|
+
clusterBy?: ClusterByFn
|
|
237
|
+
drawOutline?: boolean
|
|
238
|
+
drawHalo?: boolean
|
|
239
|
+
crossClusterRelationshipMultiplier?: number // experimental, capped to 0..1
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
interface HierarchicalOptions {
|
|
243
|
+
direction?: 'up' | 'down' | 'left' | 'right'
|
|
244
|
+
packing?: 'bin' | 'stack'
|
|
245
|
+
clusterBy?: ClusterByFn // experimental
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
interface CircularOptions {
|
|
249
|
+
sortFunction?: (nodes: Node[]) => Node[]
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### `ZoomOptions`
|
|
254
|
+
|
|
255
|
+
| Field | Type | Purpose |
|
|
256
|
+
|---|---|---|
|
|
257
|
+
| `noPan` | `boolean` | Zoom without changing pan |
|
|
258
|
+
| `outOnly` | `boolean` | Only zoom out to fit |
|
|
259
|
+
| `minZoom` | `number` | Override for this op |
|
|
260
|
+
| `maxZoom` | `number` | Override for this op |
|
|
261
|
+
| `animated` | `boolean` | Animate transition |
|
|
262
|
+
|
|
263
|
+
### Renderer constants
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
type Renderer = 'webgl' | 'canvas'
|
|
267
|
+
|
|
268
|
+
WebGLRendererType // 'webgl'
|
|
269
|
+
CanvasRendererType // 'canvas'
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### `StyledCaption`
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
type StyledCaption = {
|
|
276
|
+
styles: string[] // e.g. ['bold','italic']
|
|
277
|
+
value: string
|
|
278
|
+
key: string
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### `Point`
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
type Point = { x: number; y: number }
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## `ExternalCallbacks`
|
|
291
|
+
|
|
292
|
+
| Callback | Signature |
|
|
293
|
+
|---|---|
|
|
294
|
+
| `onInitialization` | `() => void` |
|
|
295
|
+
| `onLayoutDone` | `() => void` |
|
|
296
|
+
| `onLayoutStep` | `(nodes: NodeWithClientPosition[]) => void` |
|
|
297
|
+
| `onLayoutComputing` | `(isComputing: boolean) => void` |
|
|
298
|
+
| `onError` | `(error: Error) => void` |
|
|
299
|
+
| `onWebGLContextLost` | `(event: WebGLContextEvent) => void` |
|
|
300
|
+
| `onZoomTransitionDone` | `() => void` |
|
|
301
|
+
| `restart` | `() => void` |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Hit Testing Types
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
interface NvlMouseEvent extends MouseEvent {
|
|
309
|
+
nvlTargets: HitTargets
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
type HitTargets = {
|
|
313
|
+
nodes: HitTargetNode[]
|
|
314
|
+
relationships: HitTargetRelationship[]
|
|
315
|
+
clusters: HitTargetCluster[]
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
interface HitTargetNode {
|
|
319
|
+
data: Node
|
|
320
|
+
targetCoordinates: Point
|
|
321
|
+
pointerCoordinates: Point
|
|
322
|
+
distanceVector: Point
|
|
323
|
+
distance: number
|
|
324
|
+
insideNode: boolean
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
interface HitTargetRelationship {
|
|
328
|
+
data: Relationship
|
|
329
|
+
fromTargetCoordinates: Point
|
|
330
|
+
toTargetCoordinates: Point
|
|
331
|
+
pointerCoordinates: Point
|
|
332
|
+
distance: number
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
type Cluster = {
|
|
336
|
+
id: string | number
|
|
337
|
+
nodeIds: string[]
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
interface HitTargetCluster {
|
|
341
|
+
data: Cluster
|
|
342
|
+
pointerCoordinates: Point
|
|
343
|
+
hull: Point[]
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## `nvlResultTransformer`
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
import type { ResultTransformer, EagerResult } from 'neo4j-driver'
|
|
353
|
+
|
|
354
|
+
const nvlResultTransformer: ResultTransformer<
|
|
355
|
+
EagerResult,
|
|
356
|
+
{ nodes: Node[]; relationships: Relationship[] }
|
|
357
|
+
>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Usage: `driver.executeQuery(cypher, params, { database: 'neo4j', resultTransformer: nvlResultTransformer })`. Returns deduplicated `{ nodes, relationships }`.
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Named Exports — `@neo4j-nvl/base`
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
// values
|
|
368
|
+
export {
|
|
369
|
+
NVL, // also default export
|
|
370
|
+
nvlResultTransformer,
|
|
371
|
+
colorMapperFunctions,
|
|
372
|
+
CompatibilityError,
|
|
373
|
+
drawCircleBand,
|
|
374
|
+
getZoomTargetForNodePositions,
|
|
375
|
+
ForceDirectedLayoutType,
|
|
376
|
+
HierarchicalLayoutType,
|
|
377
|
+
GridLayoutType,
|
|
378
|
+
FreeLayoutType,
|
|
379
|
+
d3ForceLayoutType,
|
|
380
|
+
CircularLayoutType
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// types
|
|
384
|
+
export type {
|
|
385
|
+
NvlOptions, Renderer, Node, NodeWithClientPosition, Relationship,
|
|
386
|
+
PartialNode, PartialRelationship,
|
|
387
|
+
Layout, LayoutOptions, ForceDirectedOptions, ClusteringOptions,
|
|
388
|
+
Cluster, ClusterByFn, ClusterId, HierarchicalOptions, CircularOptions,
|
|
389
|
+
ExternalCallbacks, HitTargets, HitTargetNode, HitTargetRelationship,
|
|
390
|
+
HitTargetCluster, HitTestTarget,
|
|
391
|
+
Point, NvlMouseEvent, ZoomOptions, StyledCaption,
|
|
392
|
+
WebGLRendererType, CanvasRendererType
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Interaction Handlers
|
|
399
|
+
|
|
400
|
+
All extend `BaseInteraction<P>`:
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
class BaseInteraction<P> {
|
|
404
|
+
constructor(nvl: NVL, options?: P)
|
|
405
|
+
updateCallback(name: string, callback: ((...args: unknown[]) => void) | boolean): void
|
|
406
|
+
removeCallback(name: string): void
|
|
407
|
+
destroy(): void
|
|
408
|
+
readonly currentOptions: P
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Callback semantics: `function` = enable + invoke; `true` = enable as no-op; omitted/removed = disable.
|
|
413
|
+
|
|
414
|
+
### `ZoomInteraction`
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
new ZoomInteraction(nvl, options?: { controlledZoom?: boolean })
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
| Event | Signature |
|
|
421
|
+
|---|---|
|
|
422
|
+
| `onZoomAndPan` | `(zoomLevel: number, panX: number, panY: number, event: WheelEvent) => void` |
|
|
423
|
+
|
|
424
|
+
### `PanInteraction`
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
new PanInteraction(nvl, options?: { excludeNodeMargin?: boolean; controlledPan?: boolean })
|
|
428
|
+
panInteraction.updateTargets(targets: ('node'|'relationship')[], excludeNodeMargin: boolean): void
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
| Event | Signature |
|
|
432
|
+
|---|---|
|
|
433
|
+
| `onPan` | `(panning: { x: number; y: number }, event: MouseEvent) => void` |
|
|
434
|
+
|
|
435
|
+
### `ClickInteraction`
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
new ClickInteraction(nvl, options?: { selectOnClick?: boolean })
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
| Event | Signature |
|
|
442
|
+
|---|---|
|
|
443
|
+
| `onNodeClick` | `(node: Node, hits: HitTargets, event: MouseEvent) => void` |
|
|
444
|
+
| `onRelationshipClick` | `(rel: Relationship, hits: HitTargets, event: MouseEvent) => void` |
|
|
445
|
+
| `onClusterClick` | `(cluster: Cluster, hits: HitTargets, event: MouseEvent) => void` |
|
|
446
|
+
| `onCanvasClick` | `(event: MouseEvent) => void` |
|
|
447
|
+
| `onNodeDoubleClick` | `(node, hits, event) => void` |
|
|
448
|
+
| `onRelationshipDoubleClick` | `(rel, hits, event) => void` |
|
|
449
|
+
| `onClusterDoubleClick` | `(cluster, hits, event) => void` |
|
|
450
|
+
| `onCanvasDoubleClick` | `(event) => void` |
|
|
451
|
+
| `onNodeRightClick` | `(node, hits, event) => void` |
|
|
452
|
+
| `onRelationshipRightClick` | `(rel, hits, event) => void` |
|
|
453
|
+
| `onClusterRightClick` | `(cluster, hits, event) => void` |
|
|
454
|
+
| `onCanvasRightClick` | `(event) => void` |
|
|
455
|
+
|
|
456
|
+
### `HoverInteraction`
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
new HoverInteraction(nvl, options?: { drawShadowOnHover?: boolean })
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
| Event | Signature |
|
|
463
|
+
|---|---|
|
|
464
|
+
| `onHover` | `(element: Node \| Relationship \| undefined, hits: HitTargets, event: MouseEvent) => void` |
|
|
465
|
+
|
|
466
|
+
### `DragNodeInteraction`
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
new DragNodeInteraction(nvl)
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
| Event | Signature |
|
|
473
|
+
|---|---|
|
|
474
|
+
| `onDragStart` | `(nodes: Node[], event: MouseEvent) => void` |
|
|
475
|
+
| `onDrag` | `(nodes: Node[], event: MouseEvent) => void` |
|
|
476
|
+
| `onDragEnd` | `(nodes: Node[], event: MouseEvent) => void` |
|
|
477
|
+
|
|
478
|
+
### `BoxSelectInteraction`
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
new BoxSelectInteraction(nvl, options?: { selectOnRelease?: boolean })
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
| Event | Signature |
|
|
485
|
+
|---|---|
|
|
486
|
+
| `onBoxStarted` | `(event: MouseEvent) => void` |
|
|
487
|
+
| `onBoxSelect` | `(selection: { nodes: Node[]; rels: Relationship[] }, event: MouseEvent) => void` |
|
|
488
|
+
|
|
489
|
+
### `LassoInteraction`
|
|
490
|
+
|
|
491
|
+
```typescript
|
|
492
|
+
new LassoInteraction(nvl, options?: { selectOnRelease?: boolean })
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
| Event | Signature |
|
|
496
|
+
|---|---|
|
|
497
|
+
| `onLassoStarted` | `(event: MouseEvent) => void` |
|
|
498
|
+
| `onLassoSelect` | `(selection: { nodes: Node[]; rels: Relationship[] }, event: MouseEvent) => void` |
|
|
499
|
+
|
|
500
|
+
### `KeyboardInteraction`
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
new KeyboardInteraction(nvl, options?: {
|
|
504
|
+
enterGraphKey?: string[]
|
|
505
|
+
navigateForwardKey?: string[]
|
|
506
|
+
navigateBackwardKey?:string[]
|
|
507
|
+
exitGraphKey?: string[]
|
|
508
|
+
contextMenuKey?: string[]
|
|
509
|
+
})
|
|
510
|
+
keyboard.getFocused(): Node | Relationship | undefined
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
| Event | Signature |
|
|
514
|
+
|---|---|
|
|
515
|
+
| `onKeyDown` | `(event: KeyboardEvent, focused?: Node \| Relationship) => void` |
|
|
516
|
+
| `onKeyUp` | `(event: KeyboardEvent, focused?: Node \| Relationship) => void` |
|
|
517
|
+
| `onNodeFocus` / `onNodeBlur` | `(node: Node, event: KeyboardEvent) => void` |
|
|
518
|
+
| `onRelationshipFocus` / `onRelationshipBlur` | `(rel: Relationship, event: KeyboardEvent) => void` |
|
|
519
|
+
| `onCanvasFocus` / `onCanvasBlur` | `(event: FocusEvent) => void` |
|
|
520
|
+
| `onContextMenu` | `(element: Node \| Relationship \| undefined, event: KeyboardEvent) => void` |
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## React Components
|
|
525
|
+
|
|
526
|
+
### `<InteractiveNvlWrapper>`
|
|
527
|
+
|
|
528
|
+
| Prop | Type | Notes |
|
|
529
|
+
|---|---|---|
|
|
530
|
+
| `nodes` | `Node[]` | |
|
|
531
|
+
| `rels` | `Relationship[]` | |
|
|
532
|
+
| `nvlOptions` | `NvlOptions` | |
|
|
533
|
+
| `nvlCallbacks` | `ExternalCallbacks` | |
|
|
534
|
+
| `positions` | `Node[]` | |
|
|
535
|
+
| `zoom` | `number` | |
|
|
536
|
+
| `pan` | `{ x: number; y: number }` | |
|
|
537
|
+
| `mouseEventCallbacks` | `MouseEventCallbacks` | See below |
|
|
538
|
+
| `keyboardEventCallbacks` | `KeyboardEventCallbacks` | See below |
|
|
539
|
+
| `interactionOptions` | `InteractionOptions` | Defaults: `{ selectOnClick: false, drawShadowOnHover: true, selectOnRelease: false, excludeNodeMargin: true }` |
|
|
540
|
+
| `onInitializationError` | `(error: unknown) => void` | |
|
|
541
|
+
| `ref` | `Ref<NVL>` | Underlying NVL instance |
|
|
542
|
+
| (plus `HTMLProps<HTMLDivElement>`) | | |
|
|
543
|
+
|
|
544
|
+
### `<BasicNvlWrapper>`
|
|
545
|
+
|
|
546
|
+
Same prop set EXCEPT no `mouseEventCallbacks` / `keyboardEventCallbacks` / `interactionOptions`. `ref` resolves to `IncludeMethods<NVL>` — exposes all NVL public methods.
|
|
547
|
+
|
|
548
|
+
### `<StaticPictureWrapper>`
|
|
549
|
+
|
|
550
|
+
| Prop | Type | Default |
|
|
551
|
+
|---|---|---|
|
|
552
|
+
| `nodes` | `Node[]` | — |
|
|
553
|
+
| `rels` | `Relationship[]` | — |
|
|
554
|
+
| `nvlOptions` | `NvlOptions` | — |
|
|
555
|
+
| `width` | `number` | `500` |
|
|
556
|
+
| `height` | `number` | `500` |
|
|
557
|
+
| `format` | `'png' \| 'svg'` | `'png'` |
|
|
558
|
+
|
|
559
|
+
Renders an ephemeral NVL, fits viewport, captures, destroys. Returns `<img />`.
|
|
560
|
+
|
|
561
|
+
### `MouseEventCallbacks`
|
|
562
|
+
|
|
563
|
+
Union of all handler callbacks. Each value can be a function (with the signature above), `true` (enabled, no callback), or omitted / `false` (disabled):
|
|
564
|
+
|
|
565
|
+
```
|
|
566
|
+
onNodeClick, onRelationshipClick, onCanvasClick,
|
|
567
|
+
onClusterClick,
|
|
568
|
+
onNodeDoubleClick, onRelationshipDoubleClick, onClusterDoubleClick, onCanvasDoubleClick,
|
|
569
|
+
onNodeRightClick, onRelationshipRightClick, onClusterRightClick, onCanvasRightClick,
|
|
570
|
+
onHover,
|
|
571
|
+
onPan, onZoomAndPan,
|
|
572
|
+
onDragStart, onDrag, onDragEnd,
|
|
573
|
+
onBoxStarted, onBoxSelect,
|
|
574
|
+
onLassoStarted, onLassoSelect,
|
|
575
|
+
onHoverNodeMargin, onDrawStarted, onDrawEnded
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### `KeyboardEventCallbacks`
|
|
579
|
+
|
|
580
|
+
```
|
|
581
|
+
onKeyDown, onKeyUp,
|
|
582
|
+
onNodeFocus, onNodeBlur,
|
|
583
|
+
onRelationshipFocus, onRelationshipBlur,
|
|
584
|
+
onCanvasFocus, onCanvasBlur,
|
|
585
|
+
onContextMenu
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### `InteractionOptions`
|
|
589
|
+
|
|
590
|
+
Merged union of every handler's options:
|
|
591
|
+
|
|
592
|
+
```
|
|
593
|
+
{ selectOnClick?, drawShadowOnHover?, selectOnRelease?, excludeNodeMargin?, controlledZoom?,
|
|
594
|
+
controlledPan?, enterGraphKey?, navigateForwardKey?, navigateBackwardKey?, exitGraphKey?,
|
|
595
|
+
contextMenuKey?, ghostGraphStyling? }
|
|
596
|
+
```
|