@neo4j-nvl/base 1.2.2 → 2.0.0-1e695738

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/CHANGELOG.md +54 -1
  2. package/README.md +8 -0
  3. package/dist/base.mjs +35891 -2
  4. package/dist/types/index.d.ts +382 -386
  5. package/dist/types/layouts/animatedlayout/AnimatedLayout.d.ts +23 -23
  6. package/dist/types/layouts/animatedlayout/animationUtils.d.ts +3 -3
  7. package/dist/types/layouts/circularLayout/CircularLayout.d.ts +14 -14
  8. package/dist/types/layouts/d3forcelayout/circularLayout.d.ts +4 -4
  9. package/dist/types/layouts/d3forcelayout/constants.d.ts +3 -4
  10. package/dist/types/layouts/d3forcelayout/d3ForceLayout.d.ts +31 -31
  11. package/dist/types/layouts/d3forcelayout/types.d.ts +7 -7
  12. package/dist/types/layouts/forcedirectedlayout/PhysLayout.d.ts +275 -0
  13. package/dist/types/layouts/forcedirectedlayout/clustering/ClusterByMerger.d.ts +62 -0
  14. package/dist/types/layouts/forcedirectedlayout/clustering/SolarMerger.d.ts +56 -0
  15. package/dist/types/layouts/forcedirectedlayout/clustering/clustering-utils.d.ts +143 -0
  16. package/dist/types/layouts/forcedirectedlayout/clustering/types.d.ts +59 -0
  17. package/dist/types/layouts/forcedirectedlayout/glwrapper.d.ts +4 -0
  18. package/dist/types/layouts/forcedirectedlayout/shaders/multilevel-fragment.d.ts +2 -0
  19. package/dist/types/layouts/forcedirectedlayout/shaders/multilevel-repulsive-fragment.d.ts +2 -0
  20. package/dist/types/layouts/forcedirectedlayout/shaders/multilevel-update-fragment.d.ts +2 -0
  21. package/dist/types/layouts/forcedirectedlayout/shaders/sim-vertex.d.ts +2 -0
  22. package/dist/types/layouts/freeLayout/FreeLayout.d.ts +23 -25
  23. package/dist/types/layouts/gridLayout/GridLayout.d.ts +26 -30
  24. package/dist/types/layouts/hierarchicallayout/HierarchicalLayout.d.ts +28 -23
  25. package/dist/types/layouts/hierarchicallayout/constants.d.ts +2 -2
  26. package/dist/types/modules/CallbackHelper.d.ts +23 -23
  27. package/dist/types/modules/ExternalCallbackHandler.d.ts +33 -39
  28. package/dist/types/modules/NvlController.d.ts +212 -129
  29. package/dist/types/modules/Shader.d.ts +17 -17
  30. package/dist/types/modules/ZoomTransitionHandler.d.ts +24 -24
  31. package/dist/types/modules/dataset.d.ts +26 -24
  32. package/dist/types/modules/logging.d.ts +4 -4
  33. package/dist/types/modules/state/constants.d.ts +2 -2
  34. package/dist/types/modules/state/state.d.ts +2 -2
  35. package/dist/types/modules/state/types.d.ts +338 -228
  36. package/dist/types/modules/state/utils.d.ts +36 -36
  37. package/dist/types/renderers/ClusterOverlay.d.ts +73 -0
  38. package/dist/types/renderers/domrenderer/BaseRenderer.d.ts +69 -69
  39. package/dist/types/renderers/domrenderer/canvasrenderer/Animation.d.ts +57 -57
  40. package/dist/types/renderers/domrenderer/canvasrenderer/AnimationHandler.d.ts +65 -65
  41. package/dist/types/renderers/domrenderer/canvasrenderer/CanvasRenderer.d.ts +84 -85
  42. package/dist/types/renderers/domrenderer/canvasrenderer/arrowDrawing.d.ts +31 -31
  43. package/dist/types/renderers/domrenderer/canvasrenderer/nodeDrawing.d.ts +32 -32
  44. package/dist/types/renderers/domrenderer/shared/ImageCache.d.ts +16 -15
  45. package/dist/types/renderers/domrenderer/shared/arrows/ArrowBundle.d.ts +89 -89
  46. package/dist/types/renderers/domrenderer/shared/arrows/ArrowBundler.d.ts +42 -42
  47. package/dist/types/renderers/domrenderer/shared/arrows/arrows.d.ts +49 -49
  48. package/dist/types/renderers/domrenderer/shared/arrows/constants.d.ts +4 -4
  49. package/dist/types/renderers/domrenderer/shared/nodes/nodes.d.ts +21 -21
  50. package/dist/types/renderers/domrenderer/shared/types.d.ts +29 -30
  51. package/dist/types/renderers/domrenderer/shared/util.d.ts +4 -4
  52. package/dist/types/renderers/domrenderer/shared/vectorUtils.d.ts +10 -10
  53. package/dist/types/renderers/domrenderer/shared/wordwrap.d.ts +10 -10
  54. package/dist/types/renderers/domrenderer/svgrenderer/SvgRenderer.d.ts +18 -19
  55. package/dist/types/renderers/domrenderer/svgrenderer/arrowDrawing.d.ts +15 -15
  56. package/dist/types/renderers/domrenderer/svgrenderer/nodeDrawing.d.ts +4 -4
  57. package/dist/types/renderers/domrenderer/svgrenderer/svgUtils.d.ts +21 -21
  58. package/dist/types/renderers/webglrenderer/Controller.d.ts +83 -61
  59. package/dist/types/renderers/webglrenderer/IconLayerRegistry.d.ts +14 -0
  60. package/dist/types/renderers/webglrenderer/Renderer.d.ts +91 -51
  61. package/dist/types/renderers/webglrenderer/node-animation-fragment.d.ts +2 -2
  62. package/dist/types/renderers/webglrenderer/node-animation-vertex.d.ts +2 -2
  63. package/dist/types/renderers/webglrenderer/node-fragment-point.d.ts +2 -2
  64. package/dist/types/renderers/webglrenderer/node-vertex-point.d.ts +2 -2
  65. package/dist/types/renderers/webglrenderer/rel-fragment-line.d.ts +2 -2
  66. package/dist/types/renderers/webglrenderer/rel-glsl-utils.d.ts +1 -0
  67. package/dist/types/renderers/webglrenderer/rel-vertex-arrow.d.ts +2 -0
  68. package/dist/types/renderers/webglrenderer/rel-vertex-line.d.ts +2 -2
  69. package/dist/types/renderers/webglrenderer/viewport-box-fragment.d.ts +2 -2
  70. package/dist/types/renderers/webglrenderer/viewport-box-vertex.d.ts +2 -2
  71. package/dist/types/types/graph-element.d.ts +109 -101
  72. package/dist/types/types/nvl-window-functions.d.ts +12 -13
  73. package/dist/types/types/utils.d.ts +1 -1
  74. package/dist/types/utils/ariaUtils.d.ts +2 -2
  75. package/dist/types/utils/canvasManagement.d.ts +8 -2
  76. package/dist/types/utils/circularUtils.d.ts +2 -2
  77. package/dist/types/utils/clusterGeometry.d.ts +14 -0
  78. package/dist/types/utils/clusterHitRegions.d.ts +42 -0
  79. package/dist/types/utils/colorUtils.d.ts +2 -2
  80. package/dist/types/utils/constants.d.ts +12 -6
  81. package/dist/types/utils/errors.d.ts +6 -6
  82. package/dist/types/utils/geometry.d.ts +91 -48
  83. package/dist/types/utils/graphObjectUtils.d.ts +9 -9
  84. package/dist/types/utils/hitTest.d.ts +84 -0
  85. package/dist/types/utils/jsDriverResultTransformer.d.ts +27 -25
  86. package/dist/types/utils/layoutSeeding.d.ts +7 -0
  87. package/dist/types/utils/mouseUtils.d.ts +5 -5
  88. package/dist/types/utils/segmentAnalytics.d.ts +42 -42
  89. package/dist/types/utils/webWorkerUtils.d.ts +2 -2
  90. package/dist/types/utils/zoomFunctions.d.ts +24 -16
  91. package/package.json +15 -15
  92. package/skills/neo4j-nvl-skill/README.md +39 -0
  93. package/skills/neo4j-nvl-skill/SKILL.md +296 -0
  94. package/skills/neo4j-nvl-skill/references/api/base/classes/NVL.md +977 -0
  95. package/skills/neo4j-nvl-skill/references/api/base/functions/getZoomTargetForNodePositions.md +37 -0
  96. package/skills/neo4j-nvl-skill/references/api/base/index.md +71 -0
  97. package/skills/neo4j-nvl-skill/references/api/base/interfaces/CircularOptions.md +11 -0
  98. package/skills/neo4j-nvl-skill/references/api/base/interfaces/ClusteringOptions.md +14 -0
  99. package/skills/neo4j-nvl-skill/references/api/base/interfaces/ExternalCallbacks.md +18 -0
  100. package/skills/neo4j-nvl-skill/references/api/base/interfaces/ForceDirectedOptions.md +12 -0
  101. package/skills/neo4j-nvl-skill/references/api/base/interfaces/HierarchicalOptions.md +13 -0
  102. package/skills/neo4j-nvl-skill/references/api/base/interfaces/HitTargetCluster.md +13 -0
  103. package/skills/neo4j-nvl-skill/references/api/base/interfaces/HitTargetNode.md +16 -0
  104. package/skills/neo4j-nvl-skill/references/api/base/interfaces/HitTargetRelationship.md +15 -0
  105. package/skills/neo4j-nvl-skill/references/api/base/interfaces/Node.md +32 -0
  106. package/skills/neo4j-nvl-skill/references/api/base/interfaces/NvlMouseEvent.md +16 -0
  107. package/skills/neo4j-nvl-skill/references/api/base/interfaces/NvlOptions.md +38 -0
  108. package/skills/neo4j-nvl-skill/references/api/base/interfaces/Point.md +12 -0
  109. package/skills/neo4j-nvl-skill/references/api/base/interfaces/Relationship.md +32 -0
  110. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/CanvasRendererType.md +14 -0
  111. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/Cluster.md +20 -0
  112. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/ClusterByFn.md +20 -0
  113. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/ClusterId.md +10 -0
  114. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/HitTargets.md +22 -0
  115. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/HitTestTarget.md +7 -0
  116. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/Layout.md +15 -0
  117. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/LayoutOptions.md +12 -0
  118. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/NodeWithClientPosition.md +18 -0
  119. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/PartialNode.md +17 -0
  120. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/PartialRelationship.md +17 -0
  121. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/Renderer.md +9 -0
  122. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/StyledCaption.md +21 -0
  123. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/WebGLRendererType.md +14 -0
  124. package/skills/neo4j-nvl-skill/references/api/base/type-aliases/ZoomOptions.md +25 -0
  125. package/skills/neo4j-nvl-skill/references/api/base/variables/CircularLayoutType.md +11 -0
  126. package/skills/neo4j-nvl-skill/references/api/base/variables/ForceDirectedLayoutType.md +9 -0
  127. package/skills/neo4j-nvl-skill/references/api/base/variables/FreeLayoutType.md +9 -0
  128. package/skills/neo4j-nvl-skill/references/api/base/variables/GridLayoutType.md +9 -0
  129. package/skills/neo4j-nvl-skill/references/api/base/variables/HierarchicalLayoutType.md +9 -0
  130. package/skills/neo4j-nvl-skill/references/api/base/variables/d3ForceLayoutType.md +9 -0
  131. package/skills/neo4j-nvl-skill/references/api/base/variables/nvlResultTransformer.md +38 -0
  132. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/classes/BoxSelectInteraction.md +163 -0
  133. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/classes/ClickInteraction.md +163 -0
  134. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/classes/DragNodeInteraction.md +164 -0
  135. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/classes/HoverInteraction.md +160 -0
  136. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/classes/KeyboardInteraction.md +185 -0
  137. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/classes/LassoInteraction.md +163 -0
  138. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/classes/PanInteraction.md +196 -0
  139. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/classes/ZoomInteraction.md +164 -0
  140. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/index.md +37 -0
  141. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/BoxSelectInteractionCallbacks.md +19 -0
  142. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/BoxSelectInteractionOptions.md +17 -0
  143. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/ClickInteractionCallbacks.md +39 -0
  144. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/ClickInteractionOptions.md +17 -0
  145. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/DragNodeInteractionCallbacks.md +21 -0
  146. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/DrawInteractionOptions.md +22 -0
  147. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/HoverInteractionCallbacks.md +17 -0
  148. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/HoverInteractionOptions.md +17 -0
  149. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/KeyboardInteractionCallbacks.md +35 -0
  150. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/KeyboardInteractionOptions.md +55 -0
  151. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/LassoInteractionCallbacks.md +19 -0
  152. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/LassoInteractionOptions.md +17 -0
  153. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/PanInteractionCallbacks.md +17 -0
  154. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/PanInteractionOptions.md +19 -0
  155. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/ZoomInteractionCallbacks.md +17 -0
  156. package/skills/neo4j-nvl-skill/references/api/interaction-handlers/type-aliases/ZoomInteractionOptions.md +17 -0
  157. package/skills/neo4j-nvl-skill/references/api/react/functions/StaticPictureWrapper.md +35 -0
  158. package/skills/neo4j-nvl-skill/references/api/react/index.md +34 -0
  159. package/skills/neo4j-nvl-skill/references/api/react/interfaces/BasicReactWrapperProps.md +24 -0
  160. package/skills/neo4j-nvl-skill/references/api/react/interfaces/InteractiveNvlWrapperProps.md +27 -0
  161. package/skills/neo4j-nvl-skill/references/api/react/type-aliases/InteractionOptions.md +10 -0
  162. package/skills/neo4j-nvl-skill/references/api/react/type-aliases/KeyboardEvent.md +7 -0
  163. package/skills/neo4j-nvl-skill/references/api/react/type-aliases/KeyboardEventCallbacks.md +10 -0
  164. package/skills/neo4j-nvl-skill/references/api/react/type-aliases/MouseEvent.md +10 -0
  165. package/skills/neo4j-nvl-skill/references/api/react/type-aliases/MouseEventCallbacks.md +10 -0
  166. package/skills/neo4j-nvl-skill/references/api/react/type-aliases/StaticPictureWrapperProps.md +27 -0
  167. package/skills/neo4j-nvl-skill/references/api/react/variables/BasicNvlWrapper.md +50 -0
  168. package/skills/neo4j-nvl-skill/references/api/react/variables/InteractiveNvlWrapper.md +17 -0
  169. package/skills/neo4j-nvl-skill/references/clustering.md +87 -0
  170. package/skills/neo4j-nvl-skill/references/data-from-neo4j.md +67 -0
  171. package/skills/neo4j-nvl-skill/references/labels-and-overlays.md +76 -0
  172. package/skills/neo4j-nvl-skill/references/layouts-and-positions.md +65 -0
  173. package/skills/neo4j-nvl-skill/references/lifecycle-and-updates.md +65 -0
  174. package/skills/neo4j-nvl-skill/references/migrating-1x-to-2.md +50 -0
  175. package/skills/neo4j-nvl-skill/references/react-wrappers.md +88 -0
  176. package/skills/neo4j-nvl-skill/references/verifying-nvl-apps.md +52 -0
  177. package/skills/neo4j-nvl-skill/references/vite-and-bundlers.md +62 -0
  178. package/dist/base.mjs.LICENSE.txt +0 -21
  179. package/dist/types/layouts/animatedlayout/AnimatedLayout.test.d.ts +0 -1
  180. package/dist/types/layouts/animatedlayout/animationUtils.test.d.ts +0 -1
  181. package/dist/types/layouts/d3forcelayout/__mocks__/d3ForceLayout.d.ts +0 -10
  182. package/dist/types/layouts/d3forcelayout/circularLayout.test.d.ts +0 -1
  183. package/dist/types/layouts/d3forcelayout/d3ForceLayout.test.d.ts +0 -1
  184. package/dist/types/layouts/forcedirectedlayout/ForceCytoLayout.d.ts +0 -22
  185. package/dist/types/layouts/forcedirectedlayout/cosebilkentlayout/CoseBilkentLayout.d.ts +0 -33
  186. package/dist/types/layouts/forcedirectedlayout/physlayout/PhysLayout.d.ts +0 -174
  187. package/dist/types/layouts/forcedirectedlayout/physlayout/PhysLayout.test.d.ts +0 -1
  188. package/dist/types/layouts/forcedirectedlayout/physlayout/glwrapper.d.ts +0 -4
  189. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-fragment.d.ts +0 -2
  190. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-repulsive-fragment.d.ts +0 -2
  191. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-update-fragment.d.ts +0 -2
  192. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/sim-vertex.d.ts +0 -2
  193. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/workaround-fragment.d.ts +0 -2
  194. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/SolarMerger.bench.d.ts +0 -1
  195. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/SolarMerger.d.ts +0 -21
  196. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/SolarMerger.test.d.ts +0 -1
  197. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/solar-placer.d.ts +0 -2
  198. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/solar-placer.test.d.ts +0 -1
  199. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/types.d.ts +0 -49
  200. package/dist/types/modules/NvlController.test.d.ts +0 -1
  201. package/dist/types/modules/ZoomTransitionHandler.test.d.ts +0 -1
  202. package/dist/types/modules/dataset.test.d.ts +0 -1
  203. package/dist/types/modules/state/state.test.d.ts +0 -1
  204. package/dist/types/modules/state/utils.test.d.ts +0 -1
  205. package/dist/types/renderers/domrenderer/BaseRenderer.test.d.ts +0 -1
  206. package/dist/types/renderers/domrenderer/canvasrenderer/Animation.test.d.ts +0 -1
  207. package/dist/types/renderers/domrenderer/canvasrenderer/CanvasRenderer.test.d.ts +0 -1
  208. package/dist/types/renderers/domrenderer/canvasrenderer/arrowDrawing.test.d.ts +0 -1
  209. package/dist/types/renderers/domrenderer/canvasrenderer/nodeDrawing.test.d.ts +0 -1
  210. package/dist/types/renderers/domrenderer/shared/ImageCache.test.d.ts +0 -1
  211. package/dist/types/renderers/domrenderer/shared/arrows/ArrowBundle.test.d.ts +0 -1
  212. package/dist/types/renderers/domrenderer/shared/arrows/ArrowBundler.test.d.ts +0 -1
  213. package/dist/types/renderers/domrenderer/shared/arrows/arrows.test.d.ts +0 -1
  214. package/dist/types/renderers/domrenderer/shared/nodes/nodes.test.d.ts +0 -1
  215. package/dist/types/renderers/domrenderer/shared/util.test.d.ts +0 -1
  216. package/dist/types/renderers/domrenderer/shared/wordwrap.test.d.ts +0 -1
  217. package/dist/types/renderers/domrenderer/svgrenderer/SvgRenderer.test.d.ts +0 -1
  218. package/dist/types/renderers/domrenderer/svgrenderer/arrowDrawing.test.d.ts +0 -1
  219. package/dist/types/renderers/domrenderer/svgrenderer/nodeDrawing.test.d.ts +0 -1
  220. package/dist/types/renderers/domrenderer/svgrenderer/svgUtils.test.d.ts +0 -1
  221. package/dist/types/renderers/webglrenderer/Controller.test.d.ts +0 -1
  222. package/dist/types/renderers/webglrenderer/Renderer.test.d.ts +0 -1
  223. package/dist/types/utils/ariaUtils.test.d.ts +0 -1
  224. package/dist/types/utils/canvasManagement.test.d.ts +0 -1
  225. package/dist/types/utils/circularUtils.test.d.ts +0 -1
  226. package/dist/types/utils/colorUtils.test.d.ts +0 -1
  227. package/dist/types/utils/errors.test.d.ts +0 -1
  228. package/dist/types/utils/geometry.test.d.ts +0 -1
  229. package/dist/types/utils/graphObjectUtils.test.d.ts +0 -1
  230. package/dist/types/utils/hittest.d.ts +0 -58
  231. package/dist/types/utils/hittest.test.d.ts +0 -1
  232. package/dist/types/utils/jsDriverResultTransformer.test.d.ts +0 -1
  233. package/dist/types/utils/mouseUtils.test.d.ts +0 -1
  234. package/dist/types/utils/webWorkerUtils.test.d.ts +0 -1
  235. package/dist/types/utils/zoomFunctions.test.d.ts +0 -1
@@ -0,0 +1,88 @@
1
+ # React wrappers
2
+
3
+ When you need this: you use `<InteractiveNvlWrapper>` or `<BasicNvlWrapper>` from `@neo4j-nvl/react` and something does not react to a prop change, a callback sees stale state, or an interaction does not start.
4
+
5
+ Verification tags: **source** = `packages/react/src` in the NVL repository, **types** = shipped `.d.ts`, **runtime** = observed in a running app.
6
+
7
+ ## Which wrapper
8
+
9
+ - `<InteractiveNvlWrapper>`: `<BasicNvlWrapper>` plus every interaction handler, toggled through `mouseEventCallbacks` and `keyboardEventCallbacks`.
10
+ - `<BasicNvlWrapper>`: NVL only. Use it when you wire interactions yourself through the `ref`.
11
+
12
+ Both forward a `ref` to the `NVL` instance (`useRef<NVL>(null)`) and pass unknown props to the container `<div>`. The container is `height: 100%`, so the **parent** needs an explicit height. *source*
13
+
14
+ ## `mouseEventCallbacks` → handler
15
+
16
+ A key set to a function enables the handler and registers the callback; `true` enables the handler with no callback; `false` destroys the handler; omitted means off. *source*
17
+
18
+ | Handler | Keys |
19
+ |---|---|
20
+ | Hover | `onHover` |
21
+ | Click | `onNodeClick`, `onRelationshipClick`, `onCanvasClick`, `onClusterClick`, and the `...DoubleClick` / `...RightClick` variants |
22
+ | Pan | `onPan` |
23
+ | Zoom (wheel) | `onZoomAndPan` |
24
+ | Drag nodes | `onDrag`, `onDragStart`, `onDragEnd` |
25
+ | Draw | `onHoverNodeMargin`, `onDrawStarted`, `onDrawEnded` |
26
+ | Box select | `onBoxStarted`, `onBoxSelect` |
27
+ | Lasso | `onLassoStarted`, `onLassoSelect` |
28
+ | Keyboard (`keyboardEventCallbacks`) | `onKeyDown`, `onKeyUp`, `onNodeFocus`, `onNodeBlur` |
29
+
30
+ There is no `onZoom` key. `{ onZoom: true }` is ignored and wheel zoom stays off. *source*
31
+
32
+ Interaction callbacks are re-registered whenever the function identity changes, so they are **not** subject to the stale-closure problem below. *source*
33
+
34
+ ## `nvlCallbacks` are captured once
35
+
36
+ `BasicNvlWrapper` passes `nvlCallbacks` to the `NVL` constructor and never updates them. A callback that closes over state sees the state from the first render. *source*
37
+
38
+ ```tsx
39
+ const selectedRef = useRef(selected)
40
+ selectedRef.current = selected
41
+
42
+ const nvlCallbacks = useMemo(() => ({
43
+ onLayoutDone: () => console.log('layout done, selected:', selectedRef.current)
44
+ }), [])
45
+ ```
46
+
47
+ ## Which `nvlOptions` update after creation
48
+
49
+ Only these are watched by effects: `layout` (`setLayout`), `layoutOptions` (deep-compared, `setLayoutOptions`), `renderer` (`setRenderer`), `disableWebGL` (`setDisableWebGL`). Everything else (`styling`, `minZoom`, `initialZoom`, `disableTelemetry`, `disableWebWorkers`, ...) is read at construction. *source*
50
+
51
+ Separate props with live effects: `positions` (`setNodePositions`), `zoom` and `pan` (`setZoom` / `setPan` / `setZoomAndPan`). *source*
52
+
53
+ To change a creation-time option, call `nvlRef.current.restart(newOptions, true)` or remount the wrapper with a `key`.
54
+
55
+ ## `nodes` / `rels` diffing
56
+
57
+ On every render the wrapper diffs the new arrays against the previous ones by `id`, then calls `addAndUpdateElementsInGraph` for added and changed elements and `removeNodesWithIds` / `removeRelationshipsWithIds` for removed ones. *source*
58
+
59
+ - Only keys whose value changed are sent, so updates are partial. A key set to `undefined` is sent (and clears the attribute); a key that is omitted is not. *source*
60
+ - Changing `x` / `y` on an existing node does **not** move it; positions are only read on insert. Use the `positions` prop or `setNodePositions`. *source*
61
+ - `pinned` does apply through the diff. *runtime*
62
+ - Keep the arrays referentially stable between renders (`useMemo`) or the diff runs on every render.
63
+
64
+ ## `minimapContainer` must exist first
65
+
66
+ If `nvlOptions.minimapContainer` is present, NVL is not created until it is non-null. With a plain `useRef` the element is `null` on the first render and NVL never starts; hold the element in state via a callback ref. *source*
67
+
68
+ ```tsx
69
+ const [minimapEl, setMinimapEl] = useState<HTMLDivElement | null>(null)
70
+ const nvlOptions = useMemo(() => ({ minimapContainer: minimapEl }), [minimapEl])
71
+
72
+ <div ref={setMinimapEl} style={{ width: 200, height: 150 }} />
73
+ <InteractiveNvlWrapper nvlOptions={nvlOptions} ... />
74
+ ```
75
+
76
+ ## `interactionOptions` replaces the defaults
77
+
78
+ The default is `{ selectOnClick: false, drawShadowOnHover: true, selectOnRelease: false, excludeNodeMargin: true }`. Passing the prop replaces this object, so `interactionOptions={{ selectOnClick: true }}` turns the hover shadow off. Pass every option you want. *source*
79
+
80
+ Keep the object stable (`useMemo`); a new object each render re-runs every interaction effect.
81
+
82
+ ## Selection toggles twice / handlers duplicated
83
+
84
+ Flipping `selectOnClick` or other `interactionOptions` across renders, or registering your own `container.addEventListener('click')` next to the wrapper's `ClickInteraction`, produces double handling. Set the options once and use the wrapper's callbacks.
85
+
86
+ ## Teardown
87
+
88
+ The wrappers call `nvl.destroy()` on unmount and destroy their handlers. Only manual `new NVL(...)` in a `useEffect` needs an explicit `return () => nvl.destroy()`.
@@ -0,0 +1,52 @@
1
+ # Verifying NVL apps
2
+
3
+ When you need this: you want to check from a test, a script or a headless browser that the graph rendered, the layout finished, or nodes are where you expect.
4
+
5
+ Verification tags: **source**, **types**, **runtime** (see `SKILL.md`).
6
+
7
+ ## Window hooks
8
+
9
+ Every NVL instance registers these on `window` (declared in `nvl-window-functions.d.ts`). They are read-only test hooks; `instanceId` is the `nvlOptions.instanceId` you gave (default `'default'`). With several instances and no id, the most recently created one answers. *source*
10
+
11
+ | Hook | Returns |
12
+ |---|---|
13
+ | `__Nvl_dumpNodes(instanceId?)` | `NodeWithClientPosition[]`: every node with `x`, `y` and `clientPosition` |
14
+ | `__Nvl_dumpRelationships(instanceId?)` | `Relationship[]` |
15
+ | `__Nvl_getNodesOnScreen(instanceId?)` | `{ nodes, rels }` currently inside the viewport |
16
+ | `__Nvl_getZoomLevel(instanceId?)` | current zoom |
17
+ | `__Nvl_registerDoneCallback(cb, instanceId)` | registers `cb` for `onLayoutDone`; note the argument order |
18
+
19
+ Playwright example (the pattern used by this repository's build-tool tests): *source*
20
+
21
+ ```typescript
22
+ await expect.poll(() => page.evaluate('window.__Nvl_dumpNodes !== undefined')).toBeTruthy()
23
+ await expect.poll(() => page.evaluate(() => window.__Nvl_dumpNodes().length)).toBe(42)
24
+ await page.evaluate(() => new Promise<void>((resolve) => window.__Nvl_registerDoneCallback(resolve, 'default')))
25
+ ```
26
+
27
+ ## Detecting a settled layout
28
+
29
+ - Preferred: `onLayoutDone` (or `__Nvl_registerDoneCallback`).
30
+ - Alternative: poll `__Nvl_dumpNodes()` and compare positions between two polls.
31
+ - `onLayoutComputing(false)` fires when a computation ends; the force-directed layout may compute again after interactions.
32
+
33
+ ## What a screenshot can and cannot show
34
+
35
+ - The WebGL canvas is not inspectable through the DOM; pixels are the only evidence. Captions are absent with WebGL (see [labels-and-overlays](labels-and-overlays.md)), so a text-based check needs the Canvas renderer or `html` overlays.
36
+ - `getImageDataUrl()` returns the main canvas as PNG for in-process comparisons. *types*
37
+
38
+ ## Headless Chrome and WebGL2
39
+
40
+ Headless Chrome uses software GL by default. The force-directed GPU simulation then runs so slowly that it looks hung. Launch with hardware GL: *runtime*
41
+
42
+ ```
43
+ --use-angle=gl --use-gl=angle --enable-gpu --ignore-gpu-blocklist --disable-gpu-sandbox
44
+ ```
45
+
46
+ Playwright: pass them in `launchOptions.args`. Allow long timeouts for the first layout. If no GPU is available, set `disableWebGL: true` in the test build so NVL uses the Canvas renderer and CPU layouts.
47
+
48
+ ## Checklist
49
+
50
+ - Wait for `__Nvl_dumpNodes` to exist, then for the expected node count, then for `onLayoutDone`.
51
+ - Set `instanceId` when a page has more than one graph.
52
+ - Set `disableTelemetry: true` in test builds.
@@ -0,0 +1,62 @@
1
+ # Vite and other bundlers
2
+
3
+ When you need this: a layout never finishes in development, the console mentions a worker script, or you set up a new project.
4
+
5
+ Verification tags: **source**, **types**, **runtime** (see `SKILL.md`).
6
+
7
+ ## What runs in a worker
8
+
9
+ Only the **hierarchical** layout uses a worker: a `SharedWorker` (`type: 'module'`, name `HierarchicalLayout`) created by `@neo4j-nvl/layout-workers` with `new URL('./HierarchicalLayout.worker.js', import.meta.url)`. The worker imports the CommonJS package `bin-pack`. Force-directed, circular, grid, free and d3Force run on the main thread or the GPU. *source*
10
+
11
+ If the worker constructor throws, NVL logs a warning and falls back to the synchronous implementation automatically. A worker that is created but fails to **load** does not throw, so there is no fallback and the layout never completes. *source*
12
+
13
+ ## Vite dev server
14
+
15
+ With Vite 7.3 the hierarchical layout works in `vite` dev without configuration: Vite discovers `bin-pack` from the worker graph and pre-bundles it. *runtime*
16
+
17
+ **Symptom (reported with older Vite versions and npm-installed packages, not reproduced in this repository):** switching to `hierarchical` fires `onLayoutComputing(true)` and nothing else. The page console is clean; the worker's console (DevTools → Sources → Threads, or `chrome://inspect/#workers`) shows "Failed to fetch a worker script" or a CJS resolution error. `vite build` + `vite preview` works.
18
+
19
+ **Cause:** Vite pre-bundles CommonJS dependencies found from the main module graph. If the worker graph is not scanned, `bin-pack` reaches the worker un-bundled.
20
+
21
+ **Fix:**
22
+
23
+ ```typescript
24
+ // vite.config.ts
25
+ import { defineConfig } from 'vite'
26
+
27
+ export default defineConfig({
28
+ optimizeDeps: { include: ['bin-pack'] }
29
+ })
30
+ ```
31
+
32
+ Restart `vite` after editing `optimizeDeps`; delete `node_modules/.vite` if the change does not take.
33
+
34
+ With pnpm or other strict hoisting, `bin-pack` is a transitive dependency and not resolvable from the app root. Use Vite's nested syntax (documented by Vite, not exercised in this repository):
35
+
36
+ ```typescript
37
+ optimizeDeps: {
38
+ include: ['@neo4j-nvl/base > @neo4j-nvl/layout-workers > bin-pack']
39
+ }
40
+ ```
41
+
42
+ ## Webpack
43
+
44
+ Webpack 5 handles `new SharedWorker(new URL(..., import.meta.url))` natively; no configuration is needed. The repository's build-tool tests cover webpack and Vite production builds. *source*
45
+
46
+ ## Other bundlers
47
+
48
+ Not tested in this repository. Check that the bundler supports `new URL(..., import.meta.url)` in `SharedWorker` constructors and bundles CJS dependencies into worker chunks. If it does not, use `disableWebWorkers`.
49
+
50
+ ## `disableWebWorkers`
51
+
52
+ ```javascript
53
+ new NVL(container, nodes, rels, { disableWebWorkers: true })
54
+ ```
55
+
56
+ Runs the hierarchical layout synchronously on the main thread: same result, blocks the UI for large graphs. Use it when workers are blocked (CSP `worker-src 'none'`, sandboxed iframes) or a bundler cannot be configured. For the Vite dev case prefer `optimizeDeps`. *types, source*
57
+
58
+ ## Telling a worker failure from a slow layout
59
+
60
+ - `onLayoutComputing(true)` followed by nothing for more than a few seconds on a small graph is a failure, not slowness.
61
+ - `window.__Nvl_registerDoneCallback(cb)` never fires (see [verifying-nvl-apps](verifying-nvl-apps.md)).
62
+ - Switch to `disableWebWorkers: true`: if the layout now completes, the worker is the problem.
@@ -1,21 +0,0 @@
1
- /*!
2
- * The buffer module from node.js, for the browser.
3
- *
4
- * @author Feross Aboukhadijeh <https://feross.org>
5
- * @license MIT
6
- */
7
-
8
- /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
9
-
10
- /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
11
-
12
- /*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
13
-
14
- /**
15
- * @license
16
- * Lodash <https://lodash.com/>
17
- * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
18
- * Released under MIT license <https://lodash.com/license>
19
- * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
20
- * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
21
- */
@@ -1,10 +0,0 @@
1
- export declare class D3ForceLayout {
2
- update(): void;
3
- getNodePositions(items: unknown[]): unknown[];
4
- getShouldUpdate(): boolean;
5
- getComputing(): boolean;
6
- destroy(): void;
7
- setOptions(): void;
8
- updateNodes(): void;
9
- terminateUpdate(): void;
10
- }
@@ -1,22 +0,0 @@
1
- export declare const ForceDirectedLayoutType = "forceDirected";
2
- export declare const CoseBilkentType = "coseBilkent";
3
- export declare class ForceCytoLayout {
4
- private readonly physLayout;
5
- private readonly coseBilkentLayout;
6
- private readonly state;
7
- private currentLayoutType;
8
- private enableCytoscape;
9
- private currentLayout;
10
- constructor(config: any);
11
- setOptions(options: any): void;
12
- private getLayout;
13
- private setLayout;
14
- copyLayoutPositions(nodeList: any, prevLayout: any, nextLayout: any): void;
15
- update(refreshPositions?: boolean): void;
16
- getShouldUpdate(): boolean;
17
- getComputing(): boolean;
18
- updateNodes(positionList: any): void;
19
- getNodePositions(data: any): import("../..").Node[];
20
- terminateUpdate(): void;
21
- destroy(): void;
22
- }
@@ -1,33 +0,0 @@
1
- import type { NvlState } from '../../../modules/state/types';
2
- import type { Node, Relationship } from '../../../types/graph-element';
3
- import AnimatedLayout from '../../animatedlayout/AnimatedLayout';
4
- type LayoutData = {
5
- elements: {
6
- group: string;
7
- data: {
8
- id: string;
9
- };
10
- }[];
11
- spacingFactor: number;
12
- };
13
- export declare class CoseBilkentLayout extends AnimatedLayout {
14
- private stateDisposers;
15
- cytoCompleteCallback: () => void;
16
- computing: boolean;
17
- pendingLayoutData: LayoutData;
18
- worker: SharedWorker;
19
- private workersDisabled;
20
- constructor(config: {
21
- state: NvlState;
22
- cytoCompleteCallback?: () => void;
23
- animationCompleteCallback?: () => void;
24
- });
25
- setOptions(): void;
26
- update(refreshPositions?: boolean, updateMobXNodes?: Node[], updateMobXRelationships?: Relationship[]): void;
27
- getShouldUpdate(): boolean;
28
- getComputing(): boolean;
29
- layout(nodes: Node[], relationships: Relationship[]): void;
30
- terminateUpdate(): void;
31
- destroy(): void;
32
- }
33
- export {};
@@ -1,174 +0,0 @@
1
- import type { ForceDirectedOptions, NvlState } from '../../../modules/state/types';
2
- import type { Node, Relationship } from '../../../types/graph-element';
3
- import type { Point } from '../../../utils/geometry';
4
- export declare class PhysLayout {
5
- private physVbo;
6
- private physSmallVbo;
7
- private physProjection;
8
- private physSmallProjection;
9
- private gl;
10
- private useReadpixelWorkaround;
11
- private averageNodeSize;
12
- private shouldUpdate;
13
- private iterationCount;
14
- private lastSpeedValues;
15
- private rollingAvgGraphSpeed;
16
- private nodeVariation;
17
- private nodeCenterPoint;
18
- private peakIterationMultiplier;
19
- private stateDisposers;
20
- private state;
21
- private dpr;
22
- private intelWorkaround;
23
- private simulationStopVelocitySquared;
24
- private gravity;
25
- private force;
26
- private nodeIdToIndex;
27
- private nodeIndexToId;
28
- private flatRelationshipKeys;
29
- private numNodes;
30
- private solarMerger;
31
- private subGraphs;
32
- private nodeSortMap;
33
- private firstUpdate;
34
- private curPhysData;
35
- private apprxRepForceShader;
36
- private levelsClusterTexture;
37
- private levelsFinestIndexTexture;
38
- private initalLevelTexture;
39
- private levelsData;
40
- private collisionDetectionMultiplier;
41
- private physShader;
42
- private physData;
43
- private workaroundData;
44
- private pinData;
45
- private updateData;
46
- private updateShader;
47
- private workaroundShader;
48
- private physPositions;
49
- private springTexture;
50
- private sizeTexture;
51
- private offsetTexture;
52
- private pinTexture;
53
- private addedNodes;
54
- private updateTexture;
55
- private vaoExt;
56
- private physVao;
57
- private physSmallVao;
58
- private updateVao;
59
- private workaroundVao;
60
- constructor(config: ForceDirectedOptions & {
61
- webGLContext: WebGLRenderingContext;
62
- state: NvlState;
63
- });
64
- /**
65
- * Sets the layout options.
66
- * @param options - The object with the options.
67
- * @param initial - Whether this is the first setting of options.
68
- */
69
- setOptions(options?: ForceDirectedOptions, initial?: boolean): void;
70
- /**
71
- * Sets graph data to be used
72
- * @param {{ nodes: Node[]; rels: Relationship[] }} data the graph object
73
- * @returns The top level graph of the subgraphs created by the solar merger.
74
- */
75
- setData(data: {
76
- nodes: Node[];
77
- rels: Relationship[];
78
- }): import("./solarmerger/types").CoarsenedGraph;
79
- /**
80
- * Updates the node's positions for the next step in the physics layout iterations if the layout needs to update
81
- * @param refreshPositions whether the entire layout should be reheated
82
- * @returns Whether the layout should update in the following step.
83
- */
84
- update(refreshPositions?: boolean): boolean;
85
- /**
86
- * Stops the layout
87
- */
88
- terminateUpdate(): void;
89
- /**
90
- * Returns whether the current layout needs to be updated in the next iteration step.
91
- * @returns Whether the layout should update in the following step.
92
- */
93
- getShouldUpdate(): boolean;
94
- /**
95
- * Returns whether the current layout is computing.
96
- * Always returns false because the force-directed layout has no computing step
97
- * @returns Whether the layout is computing.
98
- */
99
- getComputing(): boolean;
100
- /**
101
- * Adds the current x,y coordinates for each node to a given list of nodes.
102
- * @param nodeList - The list of nodes to get positions for.
103
- * @returns The list of nodes containing the x,y coordinates on each node object.
104
- */
105
- getNodePositions(nodeList: Node[]): (Node & Point)[];
106
- /**
107
- * Reheats the layout
108
- * @param fullData - The entire graph object.
109
- */
110
- reheat(fullData: {
111
- nodes: Node[];
112
- rels?: Relationship[];
113
- }): void;
114
- /**
115
- * Updates the existing nodes of a graph with a given list of updates
116
- * @param nodeList - The list of updates.
117
- */
118
- updateNodes(nodeList: Node[]): void;
119
- /**
120
- * Adds and removes nodes from the graph based on given updates
121
- * @param fullData - The entire graph object.
122
- * @param fullData.nodes - The nodes in the graph.
123
- * @param fullData.rels - The relationships in the graph.
124
- * @param nodeChanges - The changes in the graph.
125
- * @param nodeChanges.adds - A list of nodes to be added.
126
- * @param nodeChanges.removes - A list of nodes to be removed.
127
- */
128
- addRemoveData(fullData: {
129
- nodes: Node[];
130
- rels: Relationship[];
131
- }, nodeChanges: {
132
- adds: Record<string, Node>;
133
- removes: Record<string, Node>;
134
- }, relationshipChanges: {
135
- adds: Record<string, Relationship>;
136
- removes: Record<string, Relationship>;
137
- }): import("./solarmerger/types").CoarsenedGraph;
138
- /**
139
- * Destroys the class and all buffers and textures.
140
- */
141
- destroy(): void;
142
- /**
143
- * Takes the new flat key set of relationships and the current relationship changes
144
- * and checks whether removed relationships are still in the new flat key set.
145
- * and whether added relationships were already in the old flat key set.
146
- * @param newFlatKeySet The new flat key set of relationships.
147
- * @param relationshipChanges The changes in the relationships.
148
- * @returns Whether the relationship flat map has changed.
149
- */
150
- private hasRelationshipFlatMapChanged;
151
- private dumpTexture;
152
- private getScaleNumber;
153
- private getBaseLength;
154
- private checkForUpdates;
155
- private getNodePosition;
156
- private getMaxSpeedSquared;
157
- private getMedianSpeedSquared;
158
- private getPhysData;
159
- private newTexture;
160
- private newFramebuffer;
161
- private checkCompatibility;
162
- private printGlStats;
163
- private adjustToGlSize;
164
- private setupSize;
165
- private setupSprings;
166
- private setupPhysics;
167
- private setupPhysicsForNodes;
168
- private setupPhysicsForCoarse;
169
- private setupPinData;
170
- private setupUpdates;
171
- private setupReadpixelWorkaround;
172
- private doReadpixelWorkaround;
173
- private definePhysicsArrays;
174
- }
@@ -1,4 +0,0 @@
1
- export default class GlWrapper {
2
- constructor(gl: RenderingContext);
3
- private wrapFunction;
4
- }
@@ -1,2 +0,0 @@
1
- declare const _default: "precision mediump float;\n\nuniform sampler2D u_physData;\nuniform sampler2D u_connections;\nuniform sampler2D u_connectionOffsets;\nuniform sampler2D u_pinnedNodes;\nuniform sampler2D u_sizeTexture;\nuniform float u_baseLength;\nuniform float u_curIteration;\nuniform float u_iterationMultiplier;\nuniform vec2 u_gravityCenter;\nuniform float u_numNodes;\nuniform float u_gravity;\n\nuniform sampler2D u_clusterData;\nuniform sampler2D u_prevForce;\nuniform float u_collisionMultiplier;\n\n\nfloat DAMP = 0.6;\nfloat COOL = 0.99998;\nfloat TEMP = max(0.02, pow(COOL, u_curIteration));\nfloat TIMESTEP = 1.0 / 30.0;\nfloat VELOCITYDECAY = 0.6;\nfloat accLimitLow = 500000.0;\nfloat accLimitHigh = 750000.0;\nfloat accLimitPosHigh = 10000000.0;\n\nconst float denseNodeThreshold = 1000.0;\nconst float MIN_DISTANCE = 0.00000001;\nconst float MAX_DISTANCE = 1000000000.0;\nconst float MAX_ACCELERATION = 50000.0;\n\nvec4 getTextureData(sampler2D texture, float index, float base) {\n float x = mod(index, base);\n float y = (index - x) / base;\n return texture2D(texture, vec2(x + 0.5, y + 0.5) / base);\n}\n\nbool isNan(float val) {\n return (val < 0.0 || 0.0 < val || val == 0.0) ? false : true;\n}\n\nconst float BIG_NUMBER = 999999999999999999.0;\nbool isInf(float val) {\n return val > BIG_NUMBER || val < -BIG_NUMBER;\n}\n\nvec2 getDelta(vec2 v1, vec2 v2) {\n vec2 delta = v1 - v2;\n float dist = length(delta);\n if (dist < MIN_DISTANCE || isNan(dist)) {\n return vec2(MIN_DISTANCE, MIN_DISTANCE);\n }\n if (dist > MAX_DISTANCE) {\n vec2 normDelta = delta / dist;\n return normDelta * MAX_DISTANCE;\n }\n return delta;\n}\n\nvec4 getOtherNodePosition(float i) {\n return getTextureData(u_physData, i, 256.0);\n}\n\nfloat getCombinedNodeSize(float i, float nodeSize) {\n float otherNodeSize = getTextureData(u_sizeTexture, i, 256.0).a;\n return nodeSize + otherNodeSize;\n}\n\nvec2 getSpringForce(float curConnection, float numConnections, float springFScale, vec4 myPosition, float i) {\n float curSpring = getTextureData(u_connections, curConnection + i, 4096.0).a;\n\n vec4 otherPosition = getTextureData(u_physData, curSpring, 256.0);\n float otherDataPosition = getTextureData(u_connectionOffsets, curSpring, 256.0).a;\n float avgDegree;\n#if INTEL_WORKAROUND\n avgDegree = max(numConnections, 4.0);\n#else\n float otherNumConnections = getTextureData(u_connections, otherDataPosition, 4096.0).a;\n avgDegree = max((otherNumConnections + numConnections * 3.0) / 4.0, 4.0);\n#endif\n\n vec2 delta = getDelta(myPosition.xy, otherPosition.xy);\n float dist = length(delta);\n\n float F = (dist * dist * springFScale) / (u_baseLength * avgDegree);\n if (u_collisionMultiplier > 0.0) {\n F *= u_collisionMultiplier;\n }\n return (-delta / dist) * F;\n}\n\nvec2 getCollisionForce(float combinedNodeSize, float dist, float fScale, vec2 delta) {\n float collisionForce = (combinedNodeSize - dist) / (dist);\n if (u_collisionMultiplier > 0.0) {\n collisionForce *= u_collisionMultiplier;\n }\n return (delta * collisionForce * fScale * combinedNodeSize) / (combinedNodeSize + 1.0);\n}\n\nvec2 getRepulsionForce(float dist, float fScale, vec2 delta) {\n float F = (u_baseLength * u_baseLength * fScale) / (dist);\n return (delta / dist) * F * 0.05;\n}\n\nvoid main(void) {\n float textureSide = 256.0; //#TEXTURE_SIDE#;\n float index = (gl_FragCoord.x - 0.5) + (gl_FragCoord.y - 0.5) * textureSide;\n\n if (index >= u_numNodes) {\n discard;\n }\n\n vec4 clusterData = getTextureData(u_clusterData, index, 256.0);\n\n float clusterIndex = clusterData.x;\n float clusterStartIndex = clusterData.y;\n float clusterSize = clusterData.z;\n float clusterWeight = clusterData.w;\n\n vec4 myPosition = getTextureData(u_physData, index, 256.0);\n vec4 previousForce = getTextureData(u_prevForce, clusterIndex, 256.0);\n\n vec2 acceleration = previousForce.xy;\n\n float isPinned = getTextureData(u_pinnedNodes, index, 256.0).a;\n float nodeSize = getTextureData(u_sizeTexture, index, 256.0).a;\n\n if (isPinned > 0.5) {\n gl_FragColor = vec4(myPosition.xy, 0.0, 0.0);\n return;\n }\n\n float curConnection = getTextureData(u_connectionOffsets, index, 256.0).a;\n float numConnections = getTextureData(u_connections, curConnection, 4096.0).a;\n\n float fScale = 1.0 + sqrt(u_iterationMultiplier);\n float springFScale = fScale;\n\n if (numConnections > denseNodeThreshold) {\n springFScale = sqrt(fScale);\n }\n\n float numOfRels = 0.0;\n\n // Springs\n for (float i = 1.0; i <= 256.0 * 256.0; i++) {\n if (numOfRels >= numConnections) {\n break;\n }\n acceleration += getSpringForce(curConnection, numConnections, springFScale, myPosition, i);\n numOfRels += 1.0;\n }\n\n // Repulsion && collision detection\n if (u_collisionMultiplier > 0.0) {\n float number_of_collisions = 0.0;\n for (float i = 0.0; i < 256.0 * 256.0; i++) {\n if (i >= u_numNodes) {\n break;\n }\n\n if (i == index) {\n continue;\n }\n\n vec4 otherPosition = getOtherNodePosition(i);\n vec2 delta = getDelta(myPosition.xy, otherPosition.xy);\n float dist = length(delta);\n float combinedNodeSize = getCombinedNodeSize(i, nodeSize) * 2.0;\n\n if (dist < combinedNodeSize && number_of_collisions < 40.0) {\n number_of_collisions++;\n acceleration += getCollisionForce(combinedNodeSize, dist, fScale, delta);\n }\n\n if (i >= clusterStartIndex && i < clusterStartIndex + clusterSize) {\n acceleration += getRepulsionForce(dist, fScale, delta);\n }\n }\n } else {\n for (float i = 0.0; i < 256.0 * 256.0; i++) {\n if (i >= clusterStartIndex + clusterSize || i >= u_numNodes) {\n break;\n }\n\n if (i < clusterStartIndex || i == index) {\n continue;\n }\n\n vec4 otherPosition = getOtherNodePosition(i);\n vec2 delta = getDelta(myPosition.xy, otherPosition.xy);\n float dist = length(delta);\n float combinedNodeSize = getCombinedNodeSize(i, nodeSize);\n\n if (dist < combinedNodeSize) {\n acceleration += getCollisionForce(combinedNodeSize, dist, fScale, delta);\n }\n\n acceleration += getRepulsionForce(dist, fScale, delta);\n }\n }\n\n // Gravity\n vec2 delta = getDelta(u_gravityCenter, myPosition.xy);\n float dist = length(delta);\n\n vec2 grav = (delta / dist) * u_gravity * fScale * (dist / 1000.0);\n acceleration += grav;\n\n float accMagnitude = length(acceleration);\n acceleration *= min(MAX_ACCELERATION, accMagnitude) / accMagnitude;\n\n float iterationFrictionThreshold = 1000.0;\n\n if (u_curIteration > iterationFrictionThreshold) {\n float friction = 1.0 + pow((u_curIteration - iterationFrictionThreshold), 2.0) / 100.0;\n acceleration *= 1.0 / friction;\n }\n\n if (u_curIteration == 0.0) {\n gl_FragColor = vec4(myPosition.xy, myPosition.zw);\n } else {\n vec2 prevVelocity = myPosition.zw;\n vec2 currentPos = myPosition.xy;\n vec2 prevPos = currentPos - prevVelocity;\n\n vec2 newPos = currentPos + TEMP * ( DAMP * (prevVelocity) + acceleration * TIMESTEP * TIMESTEP);\n vec2 newVelocity = newPos - currentPos;\n gl_FragColor = vec4(newPos, newVelocity);\n }\n}";
2
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const _default: "precision mediump float;\nuniform sampler2D u_physData;\nuniform sampler2D u_clusterData;\nuniform sampler2D u_finestIndexes;\nuniform sampler2D u_prevForce;\n\nuniform float u_baseLength;\nuniform float u_numNodes;\nuniform float u_iterationMultiplier;\nuniform float u_isTopLevel;\n\nfloat PI = 3.1415926535897932384626433832795;\nfloat TIMESTEP = 1.0 / 30.0;\nfloat VELOCITYDECAY = 1.0;\n\nvec4 getTextureData(sampler2D texture, float index, float base) {\n float x = mod(index, base);\n float y = (index - x) / base;\n return texture2D(texture, vec2(x + 0.5, y + 0.5) / base);\n}\n\nfloat getSquaredLogClusterWeight(float value) {\n return pow(log(value), 2.0);\n}\n\nvoid main(void) {\n float index = (gl_FragCoord.x - 0.5) + (gl_FragCoord.y - 0.5) * 256.0;\n\n if (index >= u_numNodes) {\n discard;\n }\n\n vec4 clusterData = getTextureData(u_clusterData, index, 256.0);\n\n float clusterIndex = clusterData.x;\n float clusterStartIndex = clusterData.y;\n float clusterSize = clusterData.z;\n float clusterArea = pow(clusterSize + u_baseLength * 2.0, 2.0);\n\n float finestIndex = getTextureData(u_finestIndexes, index, 256.0).a;\n vec4 myPosition = getTextureData(u_physData, finestIndex, 256.0);\n vec4 previousForce = getTextureData(u_prevForce, clusterIndex, 256.0);\n float fScale = 1.0 + sqrt(u_iterationMultiplier);\n\n vec2 acceleration = previousForce.xy;\n\n // Repulsion & Collision Detection\n for (float i = 0.0; i < 256.0 * 256.0; i++) {\n if (i >= clusterStartIndex + clusterSize || i >= u_numNodes) {\n break;\n }\n if (i < clusterStartIndex || i == index) {\n continue;\n }\n\n vec4 otherClusterData = getTextureData(u_clusterData, i, 256.0);\n float otherClusterWeight = getSquaredLogClusterWeight(otherClusterData.w);\n\n float otherFinestIndex = getTextureData(u_finestIndexes, i, 256.0).a;\n vec4 otherPosition = getTextureData(u_physData, otherFinestIndex, 256.0);\n\n vec2 delta = myPosition.xy - otherPosition.xy;\n float dist = max(length(delta), 0.0000001);\n float maxDist = 25.0;\n float repulsionForceScale = 0.1;\n\n float F = (clusterArea * fScale) / (dist * dist);\n\n if (u_isTopLevel == 1.0) {\n repulsionForceScale = 0.2;\n }\n\n acceleration += ((delta / sqrt(dist)) * F) * repulsionForceScale * otherClusterWeight;\n\n if (dist < maxDist) {\n float collide = (maxDist - dist) / (dist * dist);\n acceleration += delta * collide * fScale * maxDist / (maxDist + 1.0);\n }\n }\n\n gl_FragColor = vec4(acceleration, vec2(finestIndex, 0));\n}";
2
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const _default: "precision mediump float;\n\nuniform sampler2D u_physData;\nuniform sampler2D u_updateData;\nuniform float u_numNodesNew;\n\nconst float INDEX_FLAG = 999999.0;\n\nvec4 getTextureData(sampler2D texture, float index, float base) {\n float x = mod(index, base);\n float y = (index - x) / base;\n return texture2D(texture, vec2(x + 0.5, y + 0.5) / base);\n}\n\nvoid main(void) {\n float textureSide = 256.0; //#TEXTURE_SIDE#;\n float index = (gl_FragCoord.x - 0.5) + (gl_FragCoord.y - 0.5)*textureSide;\n\n if (index >= u_numNodesNew) {\n discard;\n }\n\n float firstValue = getTextureData(u_updateData, index * 2.0, 256.0).a;\n float secondValue = getTextureData(u_updateData, index * 2.0 + 1.0, 256.0).a;\n\n if (secondValue == INDEX_FLAG) {\n vec4 myPosition = getTextureData(u_physData, firstValue, 256.0);\n gl_FragColor = myPosition;\n } else {\n gl_FragColor = vec4(firstValue, secondValue, 0.0, 0.0);\n }\n}\n";
2
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const _default: "uniform mat4 u_projection;\n\nattribute vec2 a_position;\n//attribute float a_index;\n\n//varying highp float index;\n\nvoid main() {\n// index = a_index;\n gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n}";
2
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const _default: "precision lowp float;\n\nuniform sampler2D u_physData;\nuniform float u_index;\n\nfloat shift_right (float v, float amt) { \n v = floor(v) + 0.5; \n return floor(v / exp2(amt)); \n}\n\nfloat shift_left (float v, float amt) { \n return floor(v * exp2(amt) + 0.5); \n}\n\nfloat mask_last (float v, float bits) { \n return mod(v, shift_left(1.0, bits)); \n}\n\nfloat extract_bits (float num, float from, float to) { \n from = floor(from + 0.5); to = floor(to + 0.5); \n return mask_last(shift_right(num, from), to - from); \n}\n\n// From https://stackoverflow.com/questions/17981163/webgl-read-pixels-from-floating-point-render-target\nvec4 encode_float (float val) { \n if (val == 0.0) return vec4(0, 0, 0, 0); \n float sign = val > 0.0 ? 0.0 : 1.0; \n val = abs(val); \n float exponent = floor(log2(val)); \n float biased_exponent = exponent + 127.0; \n float fraction = ((val / exp2(exponent)) - 1.0) * 8388608.0; \n float t = biased_exponent / 2.0; \n float last_bit_of_biased_exponent = fract(t) * 2.0; \n float remaining_bits_of_biased_exponent = floor(t); \n float byte4 = extract_bits(fraction, 0.0, 8.0) / 255.0; \n float byte3 = extract_bits(fraction, 8.0, 16.0) / 255.0; \n float byte2 = (last_bit_of_biased_exponent * 128.0 + extract_bits(fraction, 16.0, 23.0)) / 255.0; \n float byte1 = (sign * 128.0 + remaining_bits_of_biased_exponent) / 255.0; \n return vec4(byte4, byte3, byte2, byte1); \n}\n\nvoid main(void) {\n vec4 texData = texture2D(u_physData, gl_FragCoord.xy / 255.0);\n float data;\n if (u_index == 0.0) {\n data = texData.x;\n } else if (u_index == 1.0) {\n data = texData.y;\n } else if (u_index == 2.0) {\n data = texData.z;\n } else if (u_index == 3.0) {\n data = texData.w;\n }\n\n gl_FragColor = encode_float(data);\n}\n";
2
- export default _default;
@@ -1,21 +0,0 @@
1
- import type { Node, Relationship } from '../../../../types/graph-element';
2
- import type { CoarsenedGraph, SolarRelationship } from './types';
3
- export default class SolarMerger {
4
- graph: {
5
- nodes: Node[];
6
- relationships: number[][];
7
- idToRel: Record<string, SolarRelationship>;
8
- };
9
- subGraphs: CoarsenedGraph[];
10
- sunMap: Record<string, string>;
11
- relIdMap: string[][];
12
- nodeSortMap?: Record<number, number>;
13
- constructor(inputGraph: {
14
- nodes: Node[];
15
- rels: Relationship[];
16
- }, nodeIdToIndex: Record<string, number>);
17
- private constructGraphObjects;
18
- coarsenTo(targetSize: number): CoarsenedGraph;
19
- coarsenBy(levelToCoarsenBy: number): CoarsenedGraph;
20
- private coarsen;
21
- }
@@ -1,2 +0,0 @@
1
- import type { Point } from '../../../../utils/geometry';
2
- export declare const calculatePositions: (centre: Point, r: number, noOfChildren: number) => any[];
@@ -1,49 +0,0 @@
1
- import type { Node } from '../../../../types/graph-element';
2
- export interface SolarNode extends Omit<Node, 'id' | 'size'> {
3
- id: number;
4
- weight?: number;
5
- finestIndex?: number;
6
- originalId: string;
7
- position?: {
8
- x: number;
9
- y: number;
10
- };
11
- placement?: {
12
- x: number;
13
- y: number;
14
- };
15
- size?: number | (() => number);
16
- }
17
- export interface SolarRelationship {
18
- id: string;
19
- from: string;
20
- to: string;
21
- }
22
- export interface CoarsenedGraph {
23
- nodes: SolarNode[];
24
- relationships: number[][];
25
- idToRel: Record<string, SolarRelationship>;
26
- }
27
- export interface Sun extends SolarNode {
28
- planets: Planet[];
29
- size: () => number;
30
- children: () => Planet[];
31
- previousIndex: number;
32
- }
33
- export interface Planet extends SolarNode {
34
- parent: Sun;
35
- sunId: number;
36
- moons: Moon[];
37
- size: () => number;
38
- children: () => Moon[];
39
- }
40
- export interface Moon extends SolarNode {
41
- parent: Planet;
42
- sunId: number;
43
- size: () => number;
44
- }
45
- export type Celestial = Sun | Planet | Moon;
46
- export declare const isSolarNode: (node: SolarNode | Node) => node is SolarNode;
47
- export declare const isSun: (node: SolarNode | Celestial) => node is Sun;
48
- export declare const isPlanet: (node: SolarNode | Celestial) => node is Planet;
49
- export declare const isMoon: (node: SolarNode | Celestial) => node is Moon;
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};