@neo4j-nvl/base 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/base.mjs +1 -1
  3. package/dist/types/index.d.ts +25 -11
  4. package/dist/types/layouts/circularLayout/CircularLayout.d.ts +18 -0
  5. package/dist/types/layouts/forcedirectedlayout/ForceCytoLayout.d.ts +1 -1
  6. package/dist/types/layouts/forcedirectedlayout/physlayout/PhysLayout.d.ts +8 -3
  7. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-fragment-verlet.d.ts +1 -1
  8. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/SolarMerger.d.ts +17 -39
  9. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/types.d.ts +49 -0
  10. package/dist/types/modules/NvlController.d.ts +6 -2
  11. package/dist/types/modules/state/types.d.ts +30 -9
  12. package/dist/types/modules/state/utils.d.ts +2 -2
  13. package/dist/types/renderers/domrenderer/BaseRenderer.d.ts +75 -0
  14. package/dist/types/renderers/domrenderer/canvasrenderer/CanvasRenderer.d.ts +120 -0
  15. package/dist/types/renderers/{canvasrenderer/util.d.ts → domrenderer/canvasrenderer/canvasUtils.d.ts} +2 -14
  16. package/dist/types/renderers/domrenderer/shared/ImageCache.d.ts +16 -0
  17. package/dist/types/renderers/{canvasrenderer → domrenderer/shared}/arrows/ArrowBundle.d.ts +2 -2
  18. package/dist/types/renderers/{canvasrenderer → domrenderer/shared}/arrows/ArrowBundler.d.ts +1 -1
  19. package/dist/types/renderers/domrenderer/shared/arrows/arrows.d.ts +175 -0
  20. package/dist/types/renderers/domrenderer/shared/nodes/nodeUtils.d.ts +29 -0
  21. package/dist/types/renderers/domrenderer/shared/nodes/nodes.d.ts +58 -0
  22. package/dist/types/renderers/{canvasrenderer → domrenderer/shared}/types.d.ts +2 -2
  23. package/dist/types/renderers/domrenderer/shared/util.d.ts +11 -0
  24. package/dist/types/renderers/{canvasrenderer → domrenderer/shared}/vectorUtils.d.ts +1 -1
  25. package/dist/types/renderers/{canvasrenderer → domrenderer/shared}/wordwrap.d.ts +10 -0
  26. package/dist/types/renderers/domrenderer/shared/wordwrap.test.d.ts +1 -0
  27. package/dist/types/renderers/domrenderer/svgrenderer/SvgRenderer.d.ts +22 -0
  28. package/dist/types/renderers/domrenderer/svgrenderer/SvgRenderer.test.d.ts +1 -0
  29. package/dist/types/renderers/domrenderer/svgrenderer/svgUtils.d.ts +175 -0
  30. package/dist/types/renderers/webglrenderer/Renderer.d.ts +5 -1
  31. package/dist/types/renderers/webglrenderer/Renderer.test.d.ts +1 -0
  32. package/dist/types/types/graph-element.d.ts +1 -1
  33. package/dist/types/utils/canvasManagement.d.ts +16 -1
  34. package/dist/types/utils/circularUtils.d.ts +3 -0
  35. package/dist/types/utils/circularUtils.test.d.ts +1 -0
  36. package/dist/types/utils/constants.d.ts +4 -1
  37. package/dist/types/utils/geometry.d.ts +2 -1
  38. package/dist/types/utils/graphObjectUtils.d.ts +2 -2
  39. package/dist/types/utils/jsDriverResultTransformer.d.ts +1 -1
  40. package/package.json +23 -23
  41. package/dist/types/modules/performance.d.ts +0 -93
  42. package/dist/types/renderers/canvasrenderer/CanvasRenderer.d.ts +0 -93
  43. package/dist/types/renderers/canvasrenderer/ImageCache.d.ts +0 -11
  44. package/dist/types/renderers/canvasrenderer/arrows/arrows.d.ts +0 -55
  45. package/dist/types/renderers/canvasrenderer/nodes/nodes.d.ts +0 -59
  46. /package/dist/types/{renderers/canvasrenderer/Animation.test.d.ts → layouts/d3forcelayout/circularLayout.test.d.ts} +0 -0
  47. /package/dist/types/renderers/{canvasrenderer → domrenderer/canvasrenderer}/Animation.d.ts +0 -0
  48. /package/dist/types/renderers/{canvasrenderer/CanvasRenderer.test.d.ts → domrenderer/canvasrenderer/Animation.test.d.ts} +0 -0
  49. /package/dist/types/renderers/{canvasrenderer → domrenderer/canvasrenderer}/AnimationHandler.d.ts +0 -0
  50. /package/dist/types/renderers/{canvasrenderer/ImageCache.test.d.ts → domrenderer/canvasrenderer/CanvasRenderer.test.d.ts} +0 -0
  51. /package/dist/types/renderers/{canvasrenderer/arrows/ArrowBundle.test.d.ts → domrenderer/shared/ImageCache.test.d.ts} +0 -0
  52. /package/dist/types/renderers/{canvasrenderer/arrows/ArrowBundler.test.d.ts → domrenderer/shared/arrows/ArrowBundle.test.d.ts} +0 -0
  53. /package/dist/types/renderers/{canvasrenderer/arrows/arrows.test.d.ts → domrenderer/shared/arrows/ArrowBundler.test.d.ts} +0 -0
  54. /package/dist/types/renderers/{canvasrenderer/nodes/nodes.test.d.ts → domrenderer/shared/arrows/arrows.test.d.ts} +0 -0
  55. /package/dist/types/renderers/{canvasrenderer → domrenderer/shared}/arrows/constants.d.ts +0 -0
  56. /package/dist/types/renderers/{canvasrenderer/util.test.d.ts → domrenderer/shared/nodes/nodes.test.d.ts} +0 -0
  57. /package/dist/types/renderers/{canvasrenderer/wordwrap.test.d.ts → domrenderer/shared/util.test.d.ts} +0 -0
@@ -1,8 +1,8 @@
1
1
  import type { ExternalCallbacks } from './modules/ExternalCallbackHandler';
2
- import type { ForceDirectedOptions, HierarchicalOptions, Layout, LayoutOptions, NvlOptions, NvlState, Renderer, ZoomOptions } from './modules/state/types';
3
- import { CanvasRendererType, ForceDirectedLayoutType, FreeLayoutType, GridLayoutType, HierarchicalLayoutType, WebGLRendererType, d3ForceLayoutType } from './modules/state/types';
4
- import type { StyledCaption } from './renderers/canvasrenderer/types';
5
- import { drawCircleBand } from './renderers/canvasrenderer/util';
2
+ import type { CircularOptions, ForceDirectedOptions, HierarchicalOptions, Renderer as InternalRenderer, Layout, LayoutOptions, NvlOptions, NvlState, ZoomOptions } from './modules/state/types';
3
+ import { CanvasRendererType, CircularLayoutType, ForceDirectedLayoutType, FreeLayoutType, GridLayoutType, HierarchicalLayoutType, SvgRendererType, WebGLRendererType, d3ForceLayoutType } from './modules/state/types';
4
+ import { drawCircleBand } from './renderers/domrenderer/canvasrenderer/canvasUtils';
5
+ import type { StyledCaption } from './renderers/domrenderer/shared/types';
6
6
  import type { Node, PartialNode, PartialRelationship, Relationship } from './types/graph-element';
7
7
  import { CompatibilityError } from './utils/errors';
8
8
  import type { Point } from './utils/geometry';
@@ -38,11 +38,6 @@ interface NvlMouseEvent extends MouseEvent {
38
38
  */
39
39
  declare class NVL {
40
40
  #private;
41
- /**
42
- * @internal
43
- * @hidden
44
- */
45
- readonly performance: any;
46
41
  /**
47
42
  * Creates a new NVL instance.
48
43
  * @param frame - The DOM element to display the graph in.
@@ -274,6 +269,17 @@ declare class NVL {
274
269
  filename?: string;
275
270
  backgroundColor?: string;
276
271
  }): void;
272
+ /**
273
+ * Saves the entire graph visualization as an SVG file to the client.
274
+ * @param options - Options for the SVG export
275
+ * @param options.filename - The filename of the SVG file.
276
+ * @param options.backgroundColor - The background color of the SVG file.
277
+ * @experimental
278
+ */
279
+ saveToSvg(options?: {
280
+ filename?: string;
281
+ backgroundColor?: string;
282
+ }): void;
277
283
  /**
278
284
  * Returns the current view of the graph visualization canvas as a data URL.
279
285
  * @param options - The options for the image.
@@ -295,6 +301,10 @@ declare class NVL {
295
301
  filename?: string;
296
302
  backgroundColor?: string;
297
303
  }): void;
304
+ getZoomLimits(): {
305
+ minZoom: number;
306
+ maxZoom: number;
307
+ };
298
308
  /**
299
309
  * Sets the zoom of the viewport to a specific value.
300
310
  * @param zoomValue - The desired zoom level.
@@ -381,6 +391,10 @@ declare class NVL {
381
391
  declare const colorMapperFunctions: {
382
392
  textColorForBackground: (color: string) => string;
383
393
  };
394
+ /**
395
+ * The different types of renderers available
396
+ */
397
+ type Renderer = Exclude<InternalRenderer, typeof SvgRendererType>;
384
398
  export default NVL;
385
- export type { NvlOptions, Renderer, Node, Relationship, PartialNode, PartialRelationship, Layout, LayoutOptions, ForceDirectedOptions, HierarchicalOptions, ExternalCallbacks, HitTargets, HitTargetNode, HitTargetRelationship, Point, NvlMouseEvent, ZoomOptions, StyledCaption, WebGLRendererType, CanvasRendererType };
386
- export { NVL, colorMapperFunctions, CompatibilityError, ForceDirectedLayoutType, HierarchicalLayoutType, GridLayoutType, FreeLayoutType, d3ForceLayoutType, drawCircleBand, nvlResultTransformer, getZoomTargetForNodePositions };
399
+ export type { NvlOptions, Renderer, Node, Relationship, PartialNode, PartialRelationship, Layout, LayoutOptions, ForceDirectedOptions, HierarchicalOptions, CircularOptions, ExternalCallbacks, HitTargets, HitTargetNode, HitTargetRelationship, Point, NvlMouseEvent, ZoomOptions, StyledCaption, WebGLRendererType, CanvasRendererType };
400
+ export { NVL, colorMapperFunctions, CompatibilityError, ForceDirectedLayoutType, HierarchicalLayoutType, GridLayoutType, FreeLayoutType, d3ForceLayoutType, CircularLayoutType, drawCircleBand, nvlResultTransformer, getZoomTargetForNodePositions };
@@ -0,0 +1,18 @@
1
+ import type { CircularOptions, LayoutOptions, NvlState } from '../../modules/state/types';
2
+ import AnimatedLayout from '../animatedlayout/AnimatedLayout';
3
+ type CircularLayoutConfig = {
4
+ state: NvlState;
5
+ } & CircularOptions;
6
+ export declare class CircularLayout extends AnimatedLayout {
7
+ private stateDisposers;
8
+ private sortFunction;
9
+ constructor(config: CircularLayoutConfig);
10
+ setOptions(options?: LayoutOptions): void;
11
+ update(refreshPositions?: boolean): void;
12
+ getShouldUpdate(): boolean;
13
+ getComputing(): boolean;
14
+ private layout;
15
+ terminateUpdate(): void;
16
+ destroy(): void;
17
+ }
18
+ export {};
@@ -16,7 +16,7 @@ export declare class ForceCytoLayout {
16
16
  getShouldUpdate(): boolean;
17
17
  getComputing(): boolean;
18
18
  updateNodes(positionList: any): void;
19
- getNodePositions(data: any): import("../../types/graph-element").Node[];
19
+ getNodePositions(data: any): import("../..").Node[];
20
20
  terminateUpdate(): void;
21
21
  destroy(): void;
22
22
  }
@@ -52,9 +52,14 @@ export declare class PhysLayout {
52
52
  private pinTexture;
53
53
  private addedNodes;
54
54
  private updateTexture;
55
+ private vaoExt;
56
+ private physVao;
57
+ private physSmallVao;
58
+ private updateVao;
59
+ private workaroundVao;
55
60
  enableVerlet: boolean;
56
61
  constructor(config: ForceDirectedOptions & {
57
- webGLContext: WebGL2RenderingContext;
62
+ webGLContext: WebGLRenderingContext;
58
63
  state: NvlState;
59
64
  });
60
65
  /**
@@ -71,7 +76,7 @@ export declare class PhysLayout {
71
76
  setData(data: {
72
77
  nodes: Node[];
73
78
  rels: Relationship[];
74
- }): any;
79
+ }): import("./solarmerger/types").CoarsenedGraph;
75
80
  /**
76
81
  * Updates the node's positions for the next step in the physics layout iterations if the layout needs to update
77
82
  * @param refreshPositions whether the entire layout should be reheated
@@ -130,7 +135,7 @@ export declare class PhysLayout {
130
135
  }, relationshipChanges: {
131
136
  adds: Record<string, Relationship>;
132
137
  removes: Record<string, Relationship>;
133
- }): any;
138
+ }): import("./solarmerger/types").CoarsenedGraph;
134
139
  /**
135
140
  * Destroys the class and all buffers and textures.
136
141
  */
@@ -1,2 +1,2 @@
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;\n acceleration += grav * smoothstep(0.0, 500.0, dist);\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}";
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
2
  export default _default;
@@ -1,43 +1,21 @@
1
+ import type { Node, Relationship } from '../../../../types/graph-element';
2
+ import type { CoarsenedGraph, SolarRelationship } from './types';
1
3
  export default class SolarMerger {
2
- constructor(graph: any, nodeIdToIndex: any);
3
4
  graph: {
4
- nodes: any[];
5
- relationships: any[];
6
- idToRel: {};
7
- };
8
- subGraphs: any[];
9
- sunMap: {};
10
- constructGraphObjects(graph: any, nodeIdToIndex: any): {
11
- nodes: any[];
12
- relationships: any[];
13
- idToRel: {};
14
- };
15
- relIdMap: any[];
16
- coarsenTo(targetSize: any): {
17
- nodes: any[];
18
- relationships: any[];
19
- idToRel: {};
20
- };
21
- nodeSortMap: {};
22
- coarsenBy(levelToCoarsenBy: any): {
23
- nodes: any[];
24
- relationships: any[];
25
- idToRel: {};
26
- };
27
- coarsen({ nodes, relationships }: {
28
- nodes: any;
29
- relationships: any;
30
- }, firstIteration: any): {
31
- output: {
32
- nodes: {
33
- id: any;
34
- }[];
35
- relationships: any[];
36
- };
37
- sortedInput: {
38
- nodes: any[];
39
- relationships: any[];
40
- };
41
- nodeSortMap: {};
5
+ nodes: Node[];
6
+ relationships: number[][];
7
+ idToRel: Record<string, SolarRelationship>;
42
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;
43
21
  }
@@ -0,0 +1,49 @@
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;
@@ -27,12 +27,15 @@ export default class NvlController {
27
27
  private readonly gridLayout;
28
28
  private readonly freeLayout;
29
29
  private readonly d3ForceLayout;
30
+ private readonly circularLayout;
30
31
  private readonly forceLayout;
31
32
  private readonly canvasRenderer;
33
+ private readonly svgRenderer;
32
34
  private readonly glCanvas;
33
35
  private canvasRect;
34
36
  private readonly glMinimapCanvas;
35
37
  private readonly c2dCanvas;
38
+ private readonly svg;
36
39
  private isInRenderSwitchAnimation;
37
40
  private justSwitchedRenderer;
38
41
  private justSwitchedLayout;
@@ -104,8 +107,8 @@ export default class NvlController {
104
107
  isDestroyed(): boolean;
105
108
  destroy(): void;
106
109
  callIfRegistered(...args: any[]): void;
107
- getCanvasRelsAt(point: Point): import("../utils/hittest").HitTargetRelationship[];
108
- getCanvasNodesAt(point: Point, hitNodeMarginWidth?: number): import("../utils/hittest").HitTargetNode[];
110
+ getCanvasRelsAt(point: Point): import("..").HitTargetRelationship[];
111
+ getCanvasNodesAt(point: Point, hitNodeMarginWidth?: number): import("..").HitTargetNode[];
109
112
  private getLayout;
110
113
  setLayout(layoutType: Layout): void;
111
114
  setLayoutOptions(options: LayoutOptions): void;
@@ -113,6 +116,7 @@ export default class NvlController {
113
116
  private initiateFileDownload;
114
117
  private updateLayoutAndPositions;
115
118
  saveToFile(options: SaveToFileOptions): void;
119
+ saveToSvg(options?: SaveToFileOptions): Promise<void>;
116
120
  getImageDataURL(options: SaveToFileOptions): string;
117
121
  private prepareLargeFileForDownload;
118
122
  private createCanvasAndRenderImage;
@@ -1,5 +1,6 @@
1
1
  import type { LogLevelDesc } from 'loglevel';
2
- import type { WaypointPath } from '../../renderers/canvasrenderer/types';
2
+ import type { WaypointPath } from '../../renderers/domrenderer/shared/types';
3
+ import type { Node } from '../../types/graph-element';
3
4
  import type { ExternalCallbacks } from '../ExternalCallbackHandler';
4
5
  import type { NodeDataSet, RelationshipDataSet } from '../dataset';
5
6
  type RingStyle = {
@@ -67,6 +68,15 @@ export interface HierarchicalOptions {
67
68
  packing?: 'bin' | 'stack';
68
69
  }
69
70
  export declare const isHierarchicalLayoutOptions: (options: LayoutOptions) => options is HierarchicalOptions;
71
+ /**
72
+ * The options for the circular layout.
73
+ */
74
+ export interface CircularOptions {
75
+ /**
76
+ * Function which should return the sorted nodes.
77
+ */
78
+ sortFunction?: (nodes: Node[]) => Node[];
79
+ }
70
80
  /**
71
81
  * NVL's main force directed layout.
72
82
  */
@@ -87,6 +97,11 @@ export declare const FreeLayoutType = "free";
87
97
  * The commonly used d3-force layout.
88
98
  */
89
99
  export declare const d3ForceLayoutType = "d3Force";
100
+ /**
101
+ * A basic circular layout.
102
+ * @experimental
103
+ */
104
+ export declare const CircularLayoutType = "circular";
90
105
  /**
91
106
  * A WebGL renderer that uses the GPU for rendering.
92
107
  *
@@ -103,18 +118,26 @@ export declare const WebGLRendererType = "webgl";
103
118
  * but supports captions and arrowheads.
104
119
  */
105
120
  export declare const CanvasRendererType = "canvas";
121
+ /**
122
+ * A renderer using SVG.
123
+ *
124
+ * @experimental
125
+ * @remarks
126
+ * This renderer is experimental.
127
+ */
128
+ export declare const SvgRendererType = "svg";
106
129
  /**
107
130
  * The different types of layouts available
108
131
  */
109
- export type Layout = typeof ForceDirectedLayoutType | typeof HierarchicalLayoutType | typeof GridLayoutType | typeof FreeLayoutType | typeof d3ForceLayoutType;
132
+ export type Layout = typeof ForceDirectedLayoutType | typeof HierarchicalLayoutType | typeof GridLayoutType | typeof FreeLayoutType | typeof d3ForceLayoutType | typeof CircularLayoutType;
110
133
  /**
111
134
  * The options for the layout.
112
135
  */
113
- export type LayoutOptions = ForceDirectedOptions | HierarchicalOptions;
136
+ export type LayoutOptions = ForceDirectedOptions | HierarchicalOptions | CircularOptions;
114
137
  /**
115
138
  * The different types of renderers available
116
139
  */
117
- export type Renderer = typeof WebGLRendererType | typeof CanvasRendererType;
140
+ export type Renderer = typeof WebGLRendererType | typeof CanvasRendererType | typeof SvgRendererType;
118
141
  /** Configurations for a NVL instance */
119
142
  export interface NvlOptions {
120
143
  /**
@@ -149,7 +172,7 @@ export interface NvlOptions {
149
172
  * @remarks When using a React ref, make sure the attached element is rendered before the NVL instance is created.
150
173
  * Otherwise, the minimap will not be displayed.
151
174
  */
152
- minimapContainer?: HTMLElement;
175
+ minimapContainer?: HTMLElement | null;
153
176
  /** Configuration for the current layout */
154
177
  layoutOptions?: LayoutOptions;
155
178
  /** X-coordinate for panning of the current viewport */
@@ -160,10 +183,9 @@ export interface NvlOptions {
160
183
  initialZoom?: number;
161
184
  /**
162
185
  * What renderer to use
163
- * Possible values are 'webgl' or 'canvas'
164
- * @defaultValue 'webgl'
186
+ * @defaultValue 'canvas'
165
187
  * WebGL renderer uses GPU and has better performance.
166
- * Captions and arrowheads are only displayed when using the canvas renderer.
188
+ * Captions and arrowheads are only displayed when using the canvas or svg renderer.
167
189
  */
168
190
  renderer?: Renderer;
169
191
  /**
@@ -258,7 +280,6 @@ export interface NvlState {
258
280
  fitNodeIds: string[];
259
281
  resetZoom: boolean;
260
282
  forceWebGL: boolean;
261
- webGLVisible: boolean;
262
283
  renderer: Renderer;
263
284
  disableWebGL: boolean;
264
285
  disableWebWorkers: boolean;
@@ -1,4 +1,4 @@
1
- import type { StyledCaption } from '../../renderers/canvasrenderer/types';
1
+ import type { StyledCaption } from '../../renderers/domrenderer/shared/types';
2
2
  import type { Node, Relationship } from '../../types/graph-element';
3
3
  import type { NvlOptions } from './types';
4
4
  /**
@@ -6,7 +6,7 @@ import type { NvlOptions } from './types';
6
6
  * If both caption and captions are provided, captions takes precedence.
7
7
  */
8
8
  export declare const processCaptions: (item: Partial<Node | Relationship>) => StyledCaption[];
9
- export declare const processColorStyles: (styling: NvlOptions['styling']) => {
9
+ export declare const processColorStyles: (styling: NvlOptions["styling"]) => {
10
10
  nodeBorderStyles: {
11
11
  default: {
12
12
  rings?: {
@@ -0,0 +1,75 @@
1
+ import type { Channel, DataSet } from '../../modules/dataset';
2
+ import type { NvlState } from '../../modules/state/types';
3
+ import type { Node } from '../../types/graph-element';
4
+ import ImageCache from './shared/ImageCache';
5
+ import ArrowBundler from './shared/arrows/ArrowBundler';
6
+ import type { RelationshipToRender } from './shared/types';
7
+ export type RendererOptions = {
8
+ relationshipThreshold?: number;
9
+ };
10
+ /**
11
+ * Base class for renderers (Canvas and SVG) that provides common functionality
12
+ */
13
+ export default abstract class BaseRenderer {
14
+ arrowBundler: ArrowBundler;
15
+ protected state: NvlState;
16
+ protected relationshipThreshold: number;
17
+ protected stateDisposers: NvlState['reaction'][];
18
+ protected needsRun: boolean;
19
+ protected imageCache: ImageCache;
20
+ protected nodeVersion: number;
21
+ protected relVersion: number;
22
+ protected waypointVersion: number;
23
+ protected channelId: string;
24
+ protected activeNodes: Set<string>;
25
+ constructor(state: NvlState, channelId: string, options?: RendererOptions);
26
+ /**
27
+ * Gets relationships to render, sorted by their rendering order
28
+ * @param showCaptions - Whether to show relationship captions
29
+ * @param zoom - Current zoom level (optional, used for threshold checking)
30
+ * @param clientWidth - Width of the rendering area
31
+ * @param clientHeight - Height of the rendering area
32
+ * @returns Array of relationships to render, sorted (disabled, normal, selected)
33
+ */
34
+ protected getRelationshipsToRender(showCaptions: boolean, zoom?: number, clientWidth?: number, clientHeight?: number): RelationshipToRender[];
35
+ /**
36
+ * Gets nodes to render, sorted by their rendering order
37
+ * @param positionArray - Array of nodes with positions
38
+ * @param clientWidth - Width of the rendering area
39
+ * @param clientHeight - Height of the rendering area
40
+ * @returns Array of nodes to render, sorted (disabled, normal, selected)
41
+ */
42
+ protected getNodesToRender(positionArray: Node[], clientWidth?: number, clientHeight?: number): Node[];
43
+ /**
44
+ * Processes updates in nodes and relationships.
45
+ */
46
+ processUpdates(): void;
47
+ /**
48
+ * Processes node channel updates to track activated nodes.
49
+ * Adds or removes node IDs from the activeNodes set based on their activated state.
50
+ * @param channel - The node channel with adds, removes, and updates
51
+ * @param fullData - The full node dataset
52
+ */
53
+ protected processNodeChannelUpdates(channel: Channel<Node>, fullData: DataSet<Node>): void;
54
+ /**
55
+ * Checks if a bounding box is off screen
56
+ * @param boundingBox - The bounding box to check
57
+ * @param clientWidth - Width of the rendering area
58
+ * @param clientHeight - Height of the rendering area
59
+ * @returns Whether the bounding box is off screen
60
+ */
61
+ protected isBoundingBoxOffScreen(boundingBox: DOMRect, clientWidth: number, clientHeight: number): boolean;
62
+ /**
63
+ * Checks if the renderer needs to run.
64
+ * @returns Whether the renderer needs to run.
65
+ */
66
+ needsToRun(): boolean;
67
+ /**
68
+ * Returns a promise that resolves when all images in the cache have finished loading.
69
+ */
70
+ waitForImages(): Promise<void>;
71
+ /**
72
+ * Cleans up the renderer by disposing state reactions and removing channels.
73
+ */
74
+ destroy(): void;
75
+ }
@@ -0,0 +1,120 @@
1
+ import type { NvlState } from '../../../modules/state/types';
2
+ import type { Node } from '../../../types/graph-element';
3
+ import type { Point } from '../../../utils/geometry';
4
+ import type { HitTargetNode, HitTargetRelationship } from '../../../utils/hittest';
5
+ import BaseRenderer, { RendererOptions } from '../BaseRenderer';
6
+ export default class CanvasRenderer extends BaseRenderer {
7
+ private canvas;
8
+ private context;
9
+ private animationHandler;
10
+ private ellipsisWidth;
11
+ private disableArrowShadow;
12
+ /**
13
+ * Creates a new CanvasRenderer.
14
+ * @param canvas {HTMLCanvasElement} - The canvas to render on.
15
+ * @param context {CanvasRenderingContext2D} - The canvas context.
16
+ * @param state {NvlState} - The state.
17
+ * @param options {RendererOptions} - The visualization options.
18
+ */
19
+ constructor(canvas: HTMLCanvasElement, context: CanvasRenderingContext2D | null, state: NvlState, options?: RendererOptions);
20
+ /**
21
+ * Checks if the renderer needs to run.
22
+ * @returns Whether the renderer needs to run.
23
+ */
24
+ needsToRun(): boolean;
25
+ /**
26
+ * Override processUpdates to add Canvas-specific shadow handling
27
+ */
28
+ processUpdates(): void;
29
+ /**
30
+ * Draws a single node on the canvas with all its visual elements (circle, icons, captions, etc.)
31
+ * @param ctx - The canvas rendering context
32
+ * @param node - The node to draw
33
+ * @param imageCache - The image cache for icons
34
+ * @param animationHandler - The animation handler for transitions
35
+ * @param nodeBorderStyles - The border styles for nodes
36
+ * @param disabledItemStyles - The styles for disabled items
37
+ * @param defaultNodeColor - The default node color
38
+ * @param ellipsisWidth - The width of the ellipsis character
39
+ * @param zoomLevel - The current zoom level
40
+ */
41
+ private drawNode;
42
+ /**
43
+ * Helper method to enable shadow on canvas context
44
+ */
45
+ private enableShadow;
46
+ /**
47
+ * Helper method to disable shadow on canvas context
48
+ */
49
+ private disableShadow;
50
+ /**
51
+ * Draws line segments on canvas (straight or curved)
52
+ */
53
+ private drawSegments;
54
+ /**
55
+ * Draws a self-referencing loop on canvas
56
+ */
57
+ private drawLoop;
58
+ /**
59
+ * Draws a label for a relationship
60
+ */
61
+ private drawLabel;
62
+ /**
63
+ * Renders a waypoint arrow (relationship between two different nodes)
64
+ */
65
+ private renderWaypointArrow;
66
+ /**
67
+ * Renders a self-referencing arrow (relationship from node to itself)
68
+ */
69
+ private renderSelfArrow;
70
+ /**
71
+ * Main arrow rendering method that delegates to waypoint or self-arrow rendering
72
+ */
73
+ private renderArrow;
74
+ /**
75
+ * Draws the nodes and relationships to their positions on the canvas.
76
+ * @param positionArray {Node[]} - The array of nodes to draw
77
+ * @param options {any} - The options for the render
78
+ */
79
+ render(positionArray: Node[], options?: {
80
+ canvas?: HTMLCanvasElement;
81
+ context?: CanvasRenderingContext2D;
82
+ backgroundColor?: string;
83
+ ignoreAnimations?: boolean;
84
+ showCaptions?: boolean;
85
+ }): void;
86
+ private renderNodes;
87
+ private renderRelationships;
88
+ /**
89
+ * Returns the nodes at the pointer position
90
+ * @param pointer - The position of the pointer.
91
+ * @returns The nodes at the pointer position.
92
+ * @todo Sort nodes by distance descending
93
+ */
94
+ getNodesAt(pointer: Point, hitNodeMarginWidth?: number): HitTargetNode[];
95
+ /**
96
+ * Returns the relationships at the pointer position
97
+ * @param pointer - The position of the pointer.
98
+ * @returns The relationships at the pointer position.
99
+ * @todo: sort relationships by distance descending
100
+ */
101
+ getRelsAt(pointer: Point): HitTargetRelationship[];
102
+ /**
103
+ * Returns an array of styles for the rings of a node.
104
+ * It takes the node as an argument, and an optional array of size animations.
105
+ * If the node is selected, it returns the selectedStyle.rings array.
106
+ * If the node is not selected, it returns an array containing only one object with
107
+ * a width of 0 and an empty color.
108
+ * @param node - The node to get the ring styles for.
109
+ * @param animationHandler - The animation handler.
110
+ * @param nodeBorderStyles - The node border styles.
111
+ * @returns An array of ring styles.
112
+ */
113
+ private getRingStyles;
114
+ /**
115
+ * Handles zoom and pan on the canvas.
116
+ * @param context {CanvasRenderingContext2D} - The canvas context
117
+ * @param canvas {HTMLCanvasElement} - The canvas
118
+ */
119
+ private zoomAndPan;
120
+ }
@@ -1,11 +1,5 @@
1
- import type { Point } from '../../utils/geometry';
2
- import type { TextSegment } from './types';
3
- export declare const fontThresholds: [number, number][];
4
- /**
5
- * This function takes color in hex format or rgb() or rgba() format and overrides the opacity. Returns rgba() string.
6
- * @param color - * @param opacity - * @returns rgba() string with the given opacity.
7
- */
8
- export declare const overrideOpacity: (color: string, opacity: number) => string;
1
+ import type { Point } from '../../../utils/geometry';
2
+ import type { TextSegment } from '../shared/types';
9
3
  /**
10
4
  * The parameters for drawing an arrowhead.
11
5
  */
@@ -40,7 +34,6 @@ export declare const drawCircleBand: (ctx: CanvasRenderingContext2D, x: number,
40
34
  width: number;
41
35
  color: string;
42
36
  }[]) => void;
43
- export declare const drawCircle: (ctx: CanvasRenderingContext2D, x: number, y: number, r: number) => void;
44
37
  /**
45
38
  * Fill a circle band with a gradient from a certain color to transparent
46
39
  * @param ctx - The canvas context.
@@ -56,11 +49,6 @@ export declare const drawGradientCircleBand: (ctx: CanvasRenderingContext2D, x:
56
49
  * Draw a circle shape with a solid color
57
50
  */
58
51
  export declare const drawSolidCircle: (ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number) => void;
59
- export declare function getIndividualInfoLevels(r: number, zoomLevel: number): {
60
- nodeInfoLevel: number;
61
- fontInfoLevel: number;
62
- iconInfoLevel: number;
63
- };
64
52
  /**
65
53
  * Prints the caption for a node
66
54
  */