@neo4j-nvl/base 1.1.0 → 1.2.0-090ec876

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 (60) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/base.mjs +1 -1
  3. package/dist/types/index.d.ts +20 -1
  4. package/dist/types/layouts/d3forcelayout/__mocks__/d3ForceLayout.d.ts +10 -0
  5. package/dist/types/layouts/d3forcelayout/constants.d.ts +0 -1
  6. package/dist/types/layouts/d3forcelayout/d3ForceLayout.d.ts +20 -20
  7. package/dist/types/layouts/d3forcelayout/d3ForceLayout.test.d.ts +1 -0
  8. package/dist/types/layouts/d3forcelayout/types.d.ts +5 -6
  9. package/dist/types/layouts/forcedirectedlayout/physlayout/PhysLayout.d.ts +17 -13
  10. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-fragment.d.ts +1 -1
  11. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-repulsive-fragment.d.ts +1 -1
  12. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-update-fragment.d.ts +1 -1
  13. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/sim-vertex.d.ts +1 -1
  14. package/dist/types/layouts/forcedirectedlayout/physlayout/solarmerger/SolarMerger.bench.d.ts +1 -0
  15. package/dist/types/layouts/gridLayout/GridLayout.d.ts +25 -9
  16. package/dist/types/modules/NvlController.d.ts +25 -4
  17. package/dist/types/modules/NvlController.test.d.ts +1 -0
  18. package/dist/types/modules/Shader.d.ts +1 -1
  19. package/dist/types/modules/state/types.d.ts +32 -13
  20. package/dist/types/renderers/domrenderer/BaseRenderer.d.ts +1 -1
  21. package/dist/types/renderers/domrenderer/BaseRenderer.test.d.ts +1 -0
  22. package/dist/types/renderers/domrenderer/canvasrenderer/CanvasRenderer.d.ts +2 -36
  23. package/dist/types/renderers/domrenderer/canvasrenderer/arrowDrawing.d.ts +168 -0
  24. package/dist/types/renderers/domrenderer/canvasrenderer/arrowDrawing.test.d.ts +1 -0
  25. package/dist/types/renderers/domrenderer/canvasrenderer/nodeDrawing.d.ts +109 -0
  26. package/dist/types/renderers/domrenderer/canvasrenderer/nodeDrawing.test.d.ts +1 -0
  27. package/dist/types/renderers/domrenderer/shared/ImageCache.d.ts +3 -2
  28. package/dist/types/renderers/domrenderer/shared/arrows/ArrowBundle.d.ts +18 -2
  29. package/dist/types/renderers/domrenderer/shared/arrows/ArrowBundler.d.ts +10 -0
  30. package/dist/types/renderers/domrenderer/shared/nodes/nodes.d.ts +53 -1
  31. package/dist/types/renderers/domrenderer/shared/util.d.ts +6 -1
  32. package/dist/types/renderers/domrenderer/shared/wordwrap.d.ts +12 -1
  33. package/dist/types/renderers/domrenderer/svgrenderer/SvgRenderer.d.ts +1 -3
  34. package/dist/types/renderers/domrenderer/svgrenderer/arrowDrawing.d.ts +59 -0
  35. package/dist/types/renderers/domrenderer/svgrenderer/arrowDrawing.test.d.ts +1 -0
  36. package/dist/types/renderers/domrenderer/svgrenderer/nodeDrawing.d.ts +16 -0
  37. package/dist/types/renderers/domrenderer/svgrenderer/nodeDrawing.test.d.ts +1 -0
  38. package/dist/types/renderers/domrenderer/svgrenderer/svgUtils.d.ts +33 -141
  39. package/dist/types/renderers/domrenderer/svgrenderer/svgUtils.test.d.ts +1 -0
  40. package/dist/types/renderers/webglrenderer/Renderer.d.ts +1 -2
  41. package/dist/types/renderers/webglrenderer/node-animation-fragment.d.ts +1 -1
  42. package/dist/types/renderers/webglrenderer/node-animation-vertex.d.ts +1 -1
  43. package/dist/types/renderers/webglrenderer/node-fragment-point.d.ts +1 -1
  44. package/dist/types/renderers/webglrenderer/node-vertex-point.d.ts +1 -1
  45. package/dist/types/renderers/webglrenderer/rel-fragment-line.d.ts +1 -1
  46. package/dist/types/renderers/webglrenderer/rel-vertex-line.d.ts +1 -1
  47. package/dist/types/renderers/webglrenderer/viewport-box-fragment.d.ts +1 -1
  48. package/dist/types/renderers/webglrenderer/viewport-box-vertex.d.ts +1 -1
  49. package/dist/types/utils/canvasManagement.d.ts +1 -1
  50. package/dist/types/utils/constants.d.ts +8 -2
  51. package/dist/types/utils/geometry.d.ts +4 -0
  52. package/dist/types/utils/layoutSeeding.d.ts +7 -0
  53. package/dist/types/utils/layoutSeeding.test.d.ts +1 -0
  54. package/dist/types/utils/segmentAnalytics.d.ts +2 -2
  55. package/package.json +8 -6
  56. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-fragment-verlet.d.ts +0 -2
  57. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/multilevel-repulsive-fragment-verlet.d.ts +0 -2
  58. package/dist/types/layouts/forcedirectedlayout/physlayout/shaders/workaround-fragment.d.ts +0 -2
  59. package/dist/types/renderers/domrenderer/canvasrenderer/canvasUtils.d.ts +0 -56
  60. package/dist/types/renderers/domrenderer/shared/nodes/nodeUtils.d.ts +0 -29
@@ -1,48 +1,40 @@
1
- import type { Point } from '../../../utils/geometry';
2
1
  /**
3
- * Applies text styles to an SVG tspan element based on a style string
4
- * @param {SVGTSpanElement} tspanElem - The SVG tspan element to style
5
- * @param {string} styleStr - Comma-separated style string (e.g., "bold,italic")
6
- */
7
- export declare const applySvgTextStyles: (tspanElem: SVGTSpanElement, styleStr: string) => void;
8
- /**
9
- * Builds an SVG path string for a self-referencing loop using quadratic curves
10
- * @param startPoint - The start point of the loop
11
- * @param endPoint - The end point of the loop
12
- * @param apexPoint - The apex (top) point of the loop
13
- * @param control1Point - The first control point
14
- * @param control2Point - The second control point
15
- * @returns SVG path string
2
+ * Creates an SVG image element for an icon
3
+ *
4
+ * @param nodeX - The x-coordinate of the node
5
+ * @param nodeY - The y-coordinate of the node
6
+ * @param iconXPos - The x-position of the icon relative to the node
7
+ * @param iconYPos - The y-position of the icon relative to the node
8
+ * @param iconSize - The size of the icon
9
+ * @param image - The image to use for the icon
10
+ * @param isDisabled - Whether the icon should be disabled
16
11
  */
17
- export declare const buildSelfLoopPath: (startPoint: Point, endPoint: Point, apexPoint: Point, control1Point: Point, control2Point: Point) => string;
18
- /**
19
- * Builds an SVG path string for a polyline with quadratic curves between points
20
- * @param points - Array of points along the path
21
- * @returns SVG path string
22
- */
23
- export declare const buildQuadraticCurvePath: (points: Point[]) => string;
12
+ export declare const createSvgIconElement: (options: {
13
+ nodeX: number;
14
+ nodeY: number;
15
+ iconXPos: number;
16
+ iconYPos: number;
17
+ iconSize: number;
18
+ image: HTMLCanvasElement;
19
+ isDisabled: boolean;
20
+ }) => SVGImageElement;
24
21
  /**
25
- * Converts an array of points to an SVG polyline points attribute string
26
- * @param points - Array of points
27
- * @returns String suitable for SVG polyline points attribute
22
+ * Calculates the SVG transform string for viewport positioning
23
+ *
24
+ * @param width - SVG viewport width
25
+ * @param height - SVG viewport height
26
+ * @param zoom - Zoom level multiplier
27
+ * @param panX - Pan offset in X direction
28
+ * @param panY - Pan offset in Y direction
29
+ * @returns SVG transform string with translate and scale operations
28
30
  */
29
- export declare const pointsToPolylineString: (points: Point[]) => string;
31
+ export declare const calculateSvgTransform: (width: number, height: number, zoom: number, panX: number, panY: number) => string;
30
32
  /**
31
- * Creates an SVG arrowhead polygon element with selection rings
32
- * @param arrowHead - Arrowhead geometry (tip, base1, base2 points)
33
- * @param fillColor - Fill color for the arrowhead
34
- * @param rings - Selection rings configuration
35
- * @param pixelRatio - Device pixel ratio
36
- * @returns Array of SVG polygon elements [rings..., arrowhead]
33
+ * Applies text styles to an SVG tspan element based on a style string
34
+ * @param {SVGTSpanElement} tspanElem - The SVG tspan element to style
35
+ * @param {string} styleStr - Comma-separated style string (e.g., "bold,italic")
37
36
  */
38
- export declare const createArrowHeadWithRings: (arrowHead: {
39
- tip: Point;
40
- base1: Point;
41
- base2: Point;
42
- }, fillColor: string, rings: Array<{
43
- color: string;
44
- width: number;
45
- }>, pixelRatio: number) => SVGPolygonElement[];
37
+ export declare const applySvgTextStyles: (tspanElem: SVGTSpanElement, styleStr: string) => void;
46
38
  /**
47
39
  * Creates an SVG text element with styled spans
48
40
  * @param options - Configuration options for the text element
@@ -66,110 +58,10 @@ export declare const createStyledTextElement: (options: {
66
58
  fontColor: string;
67
59
  textAnchor: string;
68
60
  dominantBaseline: string;
69
- lineSpans: Array<{
61
+ lineSpans: {
70
62
  text: string;
71
63
  style: string;
72
- }>;
64
+ }[];
73
65
  transform?: string;
74
66
  fontWeight?: string;
75
67
  }) => SVGTextElement;
76
- /**
77
- * Creates an SVG path element with selection rings
78
- * @param pathData - SVG path d attribute
79
- * @param strokeColor - Stroke color for the path
80
- * @param strokeWidth - Stroke width for the path
81
- * @param rings - Selection rings configuration
82
- * @param pixelRatio - Device pixel ratio
83
- * @returns Array of SVG path elements [rings..., path]
84
- */
85
- export declare const createPathWithRings: (pathData: string, strokeColor: string, strokeWidth: number, rings: Array<{
86
- color: string;
87
- width: number;
88
- }>, pixelRatio: number) => SVGPathElement[];
89
- /**
90
- * Creates an SVG polyline element with selection rings
91
- * @param points - Polyline points string
92
- * @param strokeColor - Stroke color for the polyline
93
- * @param strokeWidth - Stroke width for the polyline
94
- * @param rings - Selection rings configuration
95
- * @param pixelRatio - Device pixel ratio
96
- * @returns Array of SVG polyline elements [rings..., polyline]
97
- */
98
- export declare const createPolylineWithRings: (points: string, strokeColor: string, strokeWidth: number, rings: Array<{
99
- color: string;
100
- width: number;
101
- }>, pixelRatio: number) => SVGPolylineElement[];
102
- /**
103
- * Calculates arrowhead geometry for relationship endpoints (SVG-specific)
104
- * @param point1 - First point (direction from)
105
- * @param point2 - Second point (direction to)
106
- * @param arrowLength - Length of the arrowhead
107
- * @param arrowWidth - Width of the arrowhead
108
- * @param offsetFactor - Factor to offset the tip (default 1/3)
109
- * @returns Object containing arrowhead points
110
- */
111
- export declare const getArrowheadGeometry: (point1: {
112
- x: number;
113
- y: number;
114
- }, point2: {
115
- x: number;
116
- y: number;
117
- }, arrowLength: number, arrowWidth: number, offsetFactor?: number) => {
118
- tip: {
119
- x: number;
120
- y: number;
121
- };
122
- base1: {
123
- x: number;
124
- y: number;
125
- };
126
- base2: {
127
- x: number;
128
- y: number;
129
- };
130
- angle: number;
131
- };
132
- /**
133
- * Calculates the proper angle for relationship labels to prevent upside-down text (SVG-specific)
134
- * @param angle - The original angle in radians
135
- * @returns The corrected angle in degrees
136
- */
137
- export declare const getCorrectLabelAngle: (angle: number) => number;
138
- /**
139
- * Processes caption data for SVG rendering
140
- * @param captions - Array of caption objects with value and styles
141
- * @param caption - Legacy single caption string
142
- * @returns Object with fullCaption and stylesPerChar array
143
- */
144
- /**
145
- * Groups consecutive characters with the same style into text spans
146
- * @param lineText - The text of the line
147
- * @param stylesPerChar - Array of style arrays for each character
148
- * @param startCharIndex - The starting character index in the overall caption
149
- * @returns Array of text spans with their styles
150
- */
151
- export declare const getGroupedTextSpans: (lineText: string, stylesPerChar: string[][], startCharIndex: number) => {
152
- text: string;
153
- style: string;
154
- }[];
155
- /**
156
- * Creates an SVG image element for node icons
157
- * @param options - Configuration options for the icon element
158
- * @param options.nodeX - X coordinate of the node center
159
- * @param options.nodeY - Y coordinate of the node center
160
- * @param options.iconXPos - X offset from node center to icon position
161
- * @param options.iconYPos - Y offset from node center to icon position
162
- * @param options.iconSize - Size (width and height) of the icon
163
- * @param options.image - The image from cache (HTMLCanvasElement)
164
- * @param options.isDisabled - Whether the node is disabled
165
- * @returns SVG image element
166
- */
167
- export declare const createSvgIconElement: (options: {
168
- nodeX: number;
169
- nodeY: number;
170
- iconXPos: number;
171
- iconYPos: number;
172
- iconSize: number;
173
- image: HTMLCanvasElement;
174
- isDisabled: boolean;
175
- }) => SVGImageElement;
@@ -30,8 +30,7 @@ export default class Renderer {
30
30
  private nodeVao;
31
31
  private relVao;
32
32
  private nodeAnimVao;
33
- private vaoExt;
34
- constructor(gl: WebGLRenderingContext, nodes: DataSet<Node>, rels: DataSet<Relationship>, state: NvlState);
33
+ constructor(gl: WebGL2RenderingContext, nodes: DataSet<Node>, rels: DataSet<Relationship>, state: NvlState);
35
34
  private setShaderUniforms;
36
35
  setData(data: {
37
36
  nodes: Node[];
@@ -1,2 +1,2 @@
1
- declare const _default: "uniform mediump float u_zoom;\nuniform lowp float u_animPos;\nuniform mediump float u_glAdjust;\n\nvarying lowp vec4 color;\nvarying lowp float varNodeSize;\nmediump float circleSize = 0.50;\n\nvoid main(void) {\n\n lowp float dist = distance(gl_PointCoord, vec2(0.5));\n\n if (dist > 0.51) {\n discard;\n }\n else {\n lowp float alpha = 1.0 - smoothstep(circleSize - (1.0 / (varNodeSize * 2.0 * u_zoom * u_glAdjust)), circleSize, dist);\n lowp float pulseAlpha = 0.9 - 0.9 * u_animPos;\n gl_FragColor = vec4(color.xyz, 1.0) * alpha * pulseAlpha;\n }\n}\n";
1
+ declare const _default: "#version 300 es\nprecision lowp float;\n\nuniform mediump float u_zoom;\nuniform lowp float u_animPos;\nuniform mediump float u_glAdjust;\n\nin lowp vec4 color;\nin lowp float varNodeSize;\n\nout vec4 fragColor;\n\nmediump float circleSize = 0.50;\n\nvoid main(void) {\n\n lowp float dist = distance(gl_PointCoord, vec2(0.5));\n\n if (dist > 0.51) {\n discard;\n }\n else {\n lowp float alpha = 1.0 - smoothstep(circleSize - (1.0 / (varNodeSize * 2.0 * u_zoom * u_glAdjust)), circleSize, dist);\n lowp float pulseAlpha = 0.9 - 0.9 * u_animPos;\n fragColor = vec4(color.xyz, 1.0) * alpha * pulseAlpha;\n }\n}\n";
2
2
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: "uniform mat4 u_projection;\nuniform sampler2D u_positions;\nuniform lowp float u_animPos;\nuniform mediump float u_zoom;\nuniform mediump float u_glAdjust;\n\nattribute float a_size;\nattribute lowp vec2 a_index;\nattribute lowp vec4 a_color;\nattribute lowp float a_active;\n\nvarying lowp float varNodeSize;\nvarying lowp vec4 color;\n\nvoid main(void) {\n vec4 data = texture2D(u_positions, a_index);\n\n gl_Position = u_projection * vec4(data.xy, 0.0, 1.0);\n\n float nodeSize = a_size * u_zoom * u_glAdjust;\n nodeSize = nodeSize * (0.4 / 0.5); // Remove extra space added for shadow and selection ring\n\n gl_PointSize = a_active > 0.5\n ? nodeSize + 0.88 * nodeSize * u_animPos\n : 0.0;\n\n color = a_color;\n varNodeSize = a_size;\n}";
1
+ declare const _default: "#version 300 es\nuniform mat4 u_projection;\nuniform sampler2D u_positions;\nuniform lowp float u_animPos;\nuniform mediump float u_zoom;\nuniform mediump float u_glAdjust;\n\nin float a_size;\nin lowp vec2 a_index;\nin lowp vec4 a_color;\nin lowp float a_active;\n\nout lowp float varNodeSize;\nout lowp vec4 color;\n\nvoid main(void) {\n vec4 data = texture(u_positions, a_index);\n\n gl_Position = u_projection * vec4(data.xy, 0.0, 1.0);\n\n float nodeSize = a_size * u_zoom * u_glAdjust;\n nodeSize = nodeSize * (0.4 / 0.5); // Remove extra space added for shadow and selection ring\n\n gl_PointSize = a_active > 0.5\n ? nodeSize + 0.88 * nodeSize * u_animPos\n : 0.0;\n\n color = a_color;\n varNodeSize = a_size;\n}";
2
2
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: "uniform mediump float u_zoom;\nuniform mediump float u_glAdjust;\n\nvarying lowp vec4 color;\nvarying lowp float drawDefaultBorder;\nvarying lowp vec3 nodeBorderColor;\nvarying lowp vec3 selectedBorderColor;\nvarying lowp vec3 selectedInnerBorderColor;\nvarying lowp vec3 shadowColor;\nvarying lowp float selected;\nvarying lowp float hovered;\nvarying lowp float varNodeSize;\n\nmediump float circleSize = 0.40;\nmediump float defaultBoderSize = 0.42;\nmediump float innerSelectedRingSize = 0.43;\nmediump float outerSelectedRingSize = 0.47;\nmediump float shadowSize = 0.51;\n\nlowp float getShadowAlpha(lowp float size, lowp float dist) {\n return (1.0 - smoothstep(size, shadowSize, dist)) * 0.25;\n}\n\nlowp float getCircleAlpha(lowp float ringSize, lowp float nodeSize, lowp float dist) {\n return color.w - smoothstep(ringSize - nodeSize, ringSize, dist);\n}\n\nvoid main() {\n lowp float dist = distance(gl_PointCoord, vec2(0.5));\n\n if (dist > 0.51) {\n discard;\n }\n else {\n lowp float nodeSize = 1.0 / varNodeSize;\n lowp float nodeAlpha = getCircleAlpha(circleSize, nodeSize, dist);\n lowp float borderAlpha = getCircleAlpha(defaultBoderSize, nodeSize, dist);\n lowp float ringAlpha = getCircleAlpha(innerSelectedRingSize, nodeSize, dist);\n lowp vec3 finalColor = color.xyz;\n lowp float finalAlpha = nodeAlpha;\n\n if (selected > 0.0) {\n lowp float shadowAlpha = getShadowAlpha(outerSelectedRingSize, dist);\n lowp float ringAlpha2 = getCircleAlpha(outerSelectedRingSize, nodeSize, dist);\n\n if (drawDefaultBorder > 0.0) {\n finalColor = mix(nodeBorderColor, finalColor, nodeAlpha);\n finalColor = mix(selectedInnerBorderColor, finalColor, borderAlpha);\n finalColor = mix(selectedBorderColor, finalColor, ringAlpha);\n finalColor = mix(shadowColor, finalColor, ringAlpha2);\n finalAlpha = max(shadowAlpha, max(nodeAlpha, max(borderAlpha, ringAlpha2)));\n } else {\n finalColor = mix(selectedInnerBorderColor, finalColor, nodeAlpha);\n finalColor = mix(selectedBorderColor, finalColor, ringAlpha);\n finalColor = mix(shadowColor, finalColor, ringAlpha2);\n finalAlpha = max(shadowAlpha, max(nodeAlpha, max(ringAlpha, ringAlpha2)));\n }\n } else if (hovered > 0.0) {\n if (drawDefaultBorder > 0.0) {\n lowp float shadowAlpha = getShadowAlpha(defaultBoderSize, dist);\n \n finalColor = mix(nodeBorderColor, finalColor, nodeAlpha);\n finalColor = mix(shadowColor, finalColor, borderAlpha);\n finalAlpha = max(shadowAlpha, max(nodeAlpha, ringAlpha));\n } else {\n lowp float shadowAlpha = getShadowAlpha(circleSize, dist);\n\n finalColor = mix(shadowColor, finalColor, nodeAlpha);\n finalAlpha = max(shadowAlpha, nodeAlpha);\n }\n } else {\n if (drawDefaultBorder > 0.0) {\n finalColor = mix(nodeBorderColor, finalColor, nodeAlpha);\n finalAlpha = borderAlpha;\n }\n }\n gl_FragColor = vec4(finalColor, 1.0) * finalAlpha;\n }\n}\n";
1
+ declare const _default: "#version 300 es\nprecision lowp float;\n\nuniform mediump float u_zoom;\nuniform mediump float u_glAdjust;\n\nin lowp vec4 color;\nin lowp float drawDefaultBorder;\nin lowp vec3 nodeBorderColor;\nin lowp vec3 selectedBorderColor;\nin lowp vec3 selectedInnerBorderColor;\nin lowp vec3 shadowColor;\nin lowp float selected;\nin lowp float hovered;\nin lowp float varNodeSize;\n\nout vec4 fragColor;\n\nmediump float circleSize = 0.40;\nmediump float defaultBoderSize = 0.42;\nmediump float innerSelectedRingSize = 0.43;\nmediump float outerSelectedRingSize = 0.47;\nmediump float shadowSize = 0.51;\n\nlowp float getShadowAlpha(lowp float size, lowp float dist) {\n return (1.0 - smoothstep(size, shadowSize, dist)) * 0.25;\n}\n\nlowp float getCircleAlpha(lowp float ringSize, lowp float nodeSize, lowp float dist) {\n return color.w - smoothstep(ringSize - nodeSize, ringSize, dist);\n}\n\nvoid main() {\n lowp float dist = distance(gl_PointCoord, vec2(0.5));\n\n if (dist > 0.51) {\n discard;\n }\n else {\n lowp float nodeSize = 1.0 / varNodeSize;\n lowp float nodeAlpha = getCircleAlpha(circleSize, nodeSize, dist);\n lowp float borderAlpha = getCircleAlpha(defaultBoderSize, nodeSize, dist);\n lowp float ringAlpha = getCircleAlpha(innerSelectedRingSize, nodeSize, dist);\n lowp vec3 finalColor = color.xyz;\n lowp float finalAlpha = nodeAlpha;\n\n if (selected > 0.0) {\n lowp float shadowAlpha = getShadowAlpha(outerSelectedRingSize, dist);\n lowp float ringAlpha2 = getCircleAlpha(outerSelectedRingSize, nodeSize, dist);\n\n if (drawDefaultBorder > 0.0) {\n finalColor = mix(nodeBorderColor, finalColor, nodeAlpha);\n finalColor = mix(selectedInnerBorderColor, finalColor, borderAlpha);\n finalColor = mix(selectedBorderColor, finalColor, ringAlpha);\n finalColor = mix(shadowColor, finalColor, ringAlpha2);\n finalAlpha = max(shadowAlpha, max(nodeAlpha, max(borderAlpha, ringAlpha2)));\n } else {\n finalColor = mix(selectedInnerBorderColor, finalColor, nodeAlpha);\n finalColor = mix(selectedBorderColor, finalColor, ringAlpha);\n finalColor = mix(shadowColor, finalColor, ringAlpha2);\n finalAlpha = max(shadowAlpha, max(nodeAlpha, max(ringAlpha, ringAlpha2)));\n }\n } else if (hovered > 0.0) {\n if (drawDefaultBorder > 0.0) {\n lowp float shadowAlpha = getShadowAlpha(defaultBoderSize, dist);\n \n finalColor = mix(nodeBorderColor, finalColor, nodeAlpha);\n finalColor = mix(shadowColor, finalColor, borderAlpha);\n finalAlpha = max(shadowAlpha, max(nodeAlpha, ringAlpha));\n } else {\n lowp float shadowAlpha = getShadowAlpha(circleSize, dist);\n\n finalColor = mix(shadowColor, finalColor, nodeAlpha);\n finalAlpha = max(shadowAlpha, nodeAlpha);\n }\n } else {\n if (drawDefaultBorder > 0.0) {\n finalColor = mix(nodeBorderColor, finalColor, nodeAlpha);\n finalAlpha = borderAlpha;\n }\n }\n fragColor = vec4(finalColor, 1.0) * finalAlpha;\n }\n}\n";
2
2
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: "uniform mat4 u_projection;\nuniform sampler2D u_positions;\nuniform mediump float u_zoom;\nuniform mediump float u_glAdjust;\nuniform lowp vec3 u_nodeBorderColor;\nuniform lowp vec3 u_selectedBorderColor;\nuniform lowp vec3 u_selectedInnerBorderColor;\nuniform lowp vec3 u_shadowColor;\nuniform lowp float u_drawDefaultBorder;\n\nattribute float a_size;\nattribute lowp vec2 a_index;\nattribute lowp vec4 a_color;\nattribute lowp float a_selected;\nattribute lowp float a_hovered;\n\nvarying lowp float window;\nvarying lowp vec4 color;\nvarying lowp float selected;\nvarying lowp float hovered;\nvarying lowp float varNodeSize;\nvarying lowp vec3 nodeBorderColor;\nvarying lowp vec3 selectedBorderColor;\nvarying lowp vec3 selectedInnerBorderColor;\nvarying lowp vec3 shadowColor;\nvarying lowp float drawDefaultBorder;\n\nlowp float MinNodeSize = 5.0;\n\nvoid main(void) {\n vec4 data = texture2D(u_positions, a_index);\n gl_Position = u_projection * vec4(data.xy, 0.0, 1.0);\n\n lowp float nodeSize = a_size * u_zoom * u_glAdjust;\n if (nodeSize < MinNodeSize) {\n gl_PointSize = MinNodeSize;\n varNodeSize = MinNodeSize;\n } else {\n gl_PointSize = nodeSize;\n varNodeSize = nodeSize;\n }\n\n color = a_color;\n selected = a_selected;\n hovered = a_hovered;\n nodeBorderColor = u_nodeBorderColor;\n selectedBorderColor = u_selectedBorderColor;\n selectedInnerBorderColor = u_selectedInnerBorderColor;\n shadowColor = u_shadowColor;\n drawDefaultBorder = u_drawDefaultBorder;\n}";
1
+ declare const _default: "#version 300 es\nuniform mat4 u_projection;\nuniform sampler2D u_positions;\nuniform mediump float u_zoom;\nuniform mediump float u_glAdjust;\nuniform lowp vec3 u_nodeBorderColor;\nuniform lowp vec3 u_selectedBorderColor;\nuniform lowp vec3 u_selectedInnerBorderColor;\nuniform lowp vec3 u_shadowColor;\nuniform lowp float u_drawDefaultBorder;\n\nin float a_size;\nin lowp vec2 a_index;\nin lowp vec4 a_color;\nin lowp float a_selected;\nin lowp float a_hovered;\n\nout lowp vec4 color;\nout lowp float selected;\nout lowp float hovered;\nout lowp float varNodeSize;\nout lowp vec3 nodeBorderColor;\nout lowp vec3 selectedBorderColor;\nout lowp vec3 selectedInnerBorderColor;\nout lowp vec3 shadowColor;\nout lowp float drawDefaultBorder;\n\nlowp float MinNodeSize = 5.0;\n\nvoid main(void) {\n vec4 data = texture(u_positions, a_index);\n gl_Position = u_projection * vec4(data.xy, 0.0, 1.0);\n\n lowp float nodeSize = a_size * u_zoom * u_glAdjust;\n if (nodeSize < MinNodeSize) {\n gl_PointSize = MinNodeSize;\n varNodeSize = MinNodeSize;\n } else {\n gl_PointSize = nodeSize;\n varNodeSize = nodeSize;\n }\n\n color = a_color;\n selected = a_selected;\n hovered = a_hovered;\n nodeBorderColor = u_nodeBorderColor;\n selectedBorderColor = u_selectedBorderColor;\n selectedInnerBorderColor = u_selectedInnerBorderColor;\n shadowColor = u_shadowColor;\n drawDefaultBorder = u_drawDefaultBorder;\n}";
2
2
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: "varying lowp vec4 color;\n\nvoid main(void) {\n gl_FragColor = vec4(color.xyz, 1.0) * color.w;\n}\n";
1
+ declare const _default: "#version 300 es\nprecision lowp float;\n\nin lowp vec4 color;\n\nout vec4 fragColor;\n\nvoid main(void) {\n fragColor = vec4(color.xyz, 1.0) * color.w;\n}\n";
2
2
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: "uniform mat4 u_projection;\nuniform sampler2D u_positions;\nuniform mediump float u_glAdjust;\n\nattribute vec2 a_from;\nattribute vec2 a_to;\nattribute lowp vec4 a_color;\nattribute lowp float a_triside;\nattribute float a_width;\n\nvarying lowp vec4 color;\n\nvoid main(void) {\n vec4 from = texture2D(u_positions, a_from);\n vec4 to = texture2D(u_positions, a_to);\n vec2 direction = normalize(to.xy - from.xy);\n direction = vec2(-direction.y, direction.x);\n\n float width = a_width * u_glAdjust * 0.5;\n\n if (a_triside == 0.0) {\n from.y += (width / 2.0) * direction.y;\n from.x += (width / 2.0) * direction.x;\n } else {\n from.y -= (width / 2.0) * direction.y;\n from.x -= (width / 2.0) * direction.x;\n }\n\n color = a_color;\n gl_Position = u_projection * vec4(from.xy, 0.0, 1.0);\n}\n";
1
+ declare const _default: "#version 300 es\nuniform mat4 u_projection;\nuniform sampler2D u_positions;\nuniform mediump float u_glAdjust;\n\nin vec2 a_from;\nin vec2 a_to;\nin lowp vec4 a_color;\nin lowp float a_triside;\nin float a_width;\n\nout lowp vec4 color;\n\nvoid main(void) {\n vec4 from = texture(u_positions, a_from);\n vec4 to = texture(u_positions, a_to);\n vec2 direction = normalize(to.xy - from.xy);\n direction = vec2(-direction.y, direction.x);\n\n float width = a_width * u_glAdjust * 0.5;\n\n if (a_triside == 0.0) {\n from.y += (width / 2.0) * direction.y;\n from.x += (width / 2.0) * direction.x;\n } else {\n from.y -= (width / 2.0) * direction.y;\n from.x -= (width / 2.0) * direction.x;\n }\n\n color = a_color;\n gl_Position = u_projection * vec4(from.xy, 0.0, 1.0);\n}\n";
2
2
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: "\nvarying lowp vec4 minimapViewportBoxColor;\n\nvoid main(void) {\n gl_FragColor = minimapViewportBoxColor;\n}\n";
1
+ declare const _default: "#version 300 es\nprecision lowp float;\n\nin lowp vec4 minimapViewportBoxColor;\n\nout vec4 fragColor;\n\nvoid main(void) {\n fragColor = minimapViewportBoxColor;\n}\n";
2
2
  export default _default;
@@ -1,2 +1,2 @@
1
- declare const _default: "\nattribute vec2 coordinates;\nuniform mat4 u_projection;\nuniform lowp vec4 u_minimapViewportBoxColor;\n\nvarying lowp vec4 minimapViewportBoxColor;\n\nvoid main(void) {\n gl_Position = u_projection * vec4(coordinates, 0.0, 1.0);\n minimapViewportBoxColor = u_minimapViewportBoxColor;\n}\n";
1
+ declare const _default: "#version 300 es\nin vec2 coordinates;\nuniform mat4 u_projection;\nuniform lowp vec4 u_minimapViewportBoxColor;\n\nout lowp vec4 minimapViewportBoxColor;\n\nvoid main(void) {\n gl_Position = u_projection * vec4(coordinates, 0.0, 1.0);\n minimapViewportBoxColor = u_minimapViewportBoxColor;\n}\n";
2
2
  export default _default;
@@ -13,7 +13,7 @@ export declare const createCanvasForScreenshot: (fullWidth: number, fullHeight:
13
13
  export declare const createCanvasForRenderer: (parent?: HTMLElement, onContextLostCallback?: (e: WebGLContextEvent) => void) => HTMLCanvasElement;
14
14
  export declare const removeCanvas: (canvas: HTMLCanvasElement) => void;
15
15
  export declare const getCanvas2DContext: (canvas: HTMLCanvasElement) => CanvasRenderingContext2D;
16
- export declare const getWebGLContext: (canvas: HTMLCanvasElement) => WebGLRenderingContext;
16
+ export declare const getWebGLContext: (canvas: HTMLCanvasElement) => WebGL2RenderingContext | null;
17
17
  export declare const removeWebGLContext: (webGLCtx: WebGLRenderingContext) => void;
18
18
  export declare const checkWebGLAvailability: (canvas?: HTMLCanvasElement) => boolean;
19
19
  /**
@@ -3,9 +3,13 @@ export declare const SpringTextureSize = 4096;
3
3
  export declare const MaxIndexBuffer = 65536;
4
4
  export declare const MinRelLength = 100;
5
5
  export declare const Gravity = 25;
6
- export declare const SimulationStopVelocity = 100;
7
- export declare const VerletSimulationStopVelocity = 0.25;
6
+ export declare const SimulationStopVelocity = 0.25;
8
7
  export declare const MappingEnd = 999999;
8
+ export declare const LayoutStepIntervalMs = 13;
9
+ export declare const DefaultMaxFps = 30;
10
+ export declare const DefaultMinFps = 3;
11
+ export declare const MinAllowedFps = 1;
12
+ export declare const MaxAllowedFps = 120;
9
13
  export declare const ActiveAnimDuration = 1000;
10
14
  export declare const DefaultNodeSize = 25;
11
15
  export declare const DefaultNodeColor = "#FFDF81";
@@ -40,4 +44,6 @@ export declare const GlAdjust: number;
40
44
  */
41
45
  export declare const getDevicePixelRatio: () => number;
42
46
  export declare const HtmlCaptionMinWidthThreshold = 5;
47
+ /** Min on-screen icon size (px) before we skip drawing; avoids unreadable bitmaps when zoomed out. */
48
+ export declare const MinNodeIconScreenPx = 10;
43
49
  export declare const allowedWrappers: string[];
@@ -9,6 +9,10 @@ export interface Point {
9
9
  y: number;
10
10
  }
11
11
  export declare const isPointDefined: (point: Point | Node) => boolean;
12
+ /**
13
+ * Returns true when value is a finite number (not NaN or Infinity).
14
+ */
15
+ export declare const isValidFiniteNumber: (value: unknown) => value is number;
12
16
  /**
13
17
  * This function checks if the coordinates are defined.
14
18
  * @param from - The {@link Node} the edge starts from.
@@ -0,0 +1,7 @@
1
+ import type { Point } from './geometry';
2
+ export type SeedingMethod = 'box' | 'circle';
3
+ export declare const getCircleSeedRadius: (nodeCount: number, seedSpacing: number) => number;
4
+ export declare const getBoxStartSize: (nodeCount: number) => number;
5
+ export declare const getCirclePositionsForNodeCount: (nodeCount: number, center: Point, radius: number) => Point[];
6
+ export declare const getBoxPositionsForNodeCount: (nodeCount: number, center: Point) => Point[];
7
+ export declare const getSeedPositions: (nodeCount: number, seedingMethod: SeedingMethod, center?: Point) => Point[];
@@ -0,0 +1 @@
1
+ export {};
@@ -24,7 +24,7 @@ export declare abstract class AnalyticsFunction {
24
24
  /**
25
25
  * Get/fetch unique segment Id from the localstorage.
26
26
  */
27
- abstract getSegmentTrackingId(): Record<string, unknown>;
27
+ abstract getSegmentTrackingId(): string;
28
28
  /**
29
29
  * Track arbitrary event.
30
30
  */
@@ -44,7 +44,7 @@ export declare class SegmentAnalytics implements AnalyticsFunction {
44
44
  }): Promise<void>;
45
45
  identify(): void;
46
46
  loadSavedSegmentId(): string;
47
- getSegmentTrackingId(): any;
47
+ getSegmentTrackingId(): string;
48
48
  saveTrackingId(segmentId: string): void;
49
49
  private ready;
50
50
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neo4j-nvl/base",
3
- "version": "1.1.0",
3
+ "version": "1.2.0-090ec876",
4
4
  "license": "SEE LICENSE IN 'LICENSE.txt'",
5
5
  "homepage": "https://neo4j.com/docs/nvl/current/",
6
6
  "description": "Base library for the Neo4j Visualization Library",
@@ -23,25 +23,26 @@
23
23
  "build:dev": "yarn global:tsc && webpack --mode development",
24
24
  "watch": "concurrently 'tsc -w' 'webpack -w --mode development' -k -n 'tsc,webpack' -c 'cyan,magenta'",
25
25
  "test": "yarn global:jest",
26
+ "test:perf": "yarn global:jest --testPathPattern='.bench.' --testPathIgnorePatterns=",
26
27
  "eslint": "yarn global:eslint ./src/",
27
28
  "coverage": "yarn test --coverage --silent",
28
29
  "prepack": "cp ../../LICENSE.txt ./ && cp ../../CHANGELOG.md ./",
29
30
  "postpack": "rm LICENSE.txt && rm CHANGELOG.md"
30
31
  },
31
32
  "dependencies": {
32
- "@neo4j-nvl/layout-workers": "1.1.0",
33
+ "@neo4j-nvl/layout-workers": "1.2.0-090ec876",
33
34
  "@segment/analytics-next": "1.81.1",
34
35
  "color-string": "1.9.1",
35
36
  "d3-force": "3.0.0",
36
37
  "gl-matrix": "3.4.4",
37
38
  "glsl-inject-defines": "1.0.3",
38
- "lodash": "4.17.23",
39
+ "lodash": "4.18.1",
39
40
  "loglevel": "1.9.2",
40
41
  "mobx": "3.6.2",
41
42
  "node-pid-controller": "1.0.1",
42
43
  "resizelistener": "1.1.0",
43
44
  "tinycolor2": "1.6.0",
44
- "uuid": "8.3.2"
45
+ "uuid": "14.0.0"
45
46
  },
46
47
  "devDependencies": {
47
48
  "@babel/core": "7.28.5",
@@ -53,10 +54,11 @@
53
54
  "babel-loader": "8.4.1",
54
55
  "copy-webpack-plugin": "11.0.0",
55
56
  "neo4j-driver": "5.28.2",
56
- "webpack": "5.103.0",
57
+ "webpack": "5.104.1",
57
58
  "webpack-cli": "5.1.4"
58
59
  },
59
60
  "peerDependencies": {
60
61
  "neo4j-driver": "*"
61
- }
62
+ },
63
+ "stableVersion": "1.2.0"
62
64
  }
@@ -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 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,56 +0,0 @@
1
- import type { Point } from '../../../utils/geometry';
2
- import type { TextSegment } from '../shared/types';
3
- /**
4
- * The parameters for drawing an arrowhead.
5
- */
6
- type ArrowHeadParameters = {
7
- headPosition: Point;
8
- headAngle: number;
9
- headHeight: number;
10
- headChinHeight: number;
11
- headWidth: number;
12
- };
13
- /**
14
- * Creates an arrowhead shape using a polygon.
15
- * @param ctx - The canvas context to draw on.
16
- * @param headLineWidth - The width of the arrowhead's outline.
17
- * @param color - The color of the arrowhead.
18
- * @param arrowHeadParameters - The parameters for the arrowhead.
19
- * @param fill - Whether or not to fill the triangle.
20
- * @param stroke - Whether or not to stroke the triangle.
21
- */
22
- export declare const drawArrowHead: (ctx: CanvasRenderingContext2D, headLineWidth: number, color: string, arrowHeadParameters: ArrowHeadParameters, fill?: boolean, stroke?: boolean) => void;
23
- /**
24
- * Draws borders around a node with a given array of border styles
25
- * @param ctx - The canvas context.
26
- * @param x - The x coordinate of the node.
27
- * @param y - The y coordinate of the node.
28
- * @param innerRadius - The inner radius of the node without any border.
29
- * @param borderStyles - An array of border styles.
30
- * @internal
31
- * @hidden
32
- */
33
- export declare const drawCircleBand: (ctx: CanvasRenderingContext2D, x: number, y: number, innerRadius: number, borderStyles: {
34
- width: number;
35
- color: string;
36
- }[]) => void;
37
- /**
38
- * Fill a circle band with a gradient from a certain color to transparent
39
- * @param ctx - The canvas context.
40
- * @param x - The x coordinate of the node.
41
- * @param y - The y coordinate of the node.
42
- * @param color - The color of the gradient.
43
- * @param radius - The inner radius of the node without any border.
44
- * @param blur - The blur radius of the gradient.
45
- * @param maxOpacity - The maximum opacity of the gradient.
46
- */
47
- export declare const drawGradientCircleBand: (ctx: CanvasRenderingContext2D, x: number, y: number, color: string, radius: number, blur: number, maxOpacity?: number) => void;
48
- /**
49
- * Draw a circle shape with a solid color
50
- */
51
- export declare const drawSolidCircle: (ctx: CanvasRenderingContext2D, x: number, y: number, color: string, size: number) => void;
52
- /**
53
- * Prints the caption for a node
54
- */
55
- export declare const drawNodeCaption: (ctx: CanvasRenderingContext2D, lines: TextSegment[], stylesPerChar: string[][], initialYPos: number, fontSize: number, fontFace: string, lineDistance: number, x: number, y: number, ellipsisWidth: number) => void;
56
- export {};
@@ -1,29 +0,0 @@
1
- import type { Node } from '../../../../types/graph-element';
2
- import type { TextSegment } from '../types';
3
- /**
4
- * Returns the caption font size that should be used
5
- * for the given info level and node diameter.
6
- * @param infoLevel {number} - The info level.
7
- * @param nodeRadius {number} - The radius of the node.
8
- * @param captionSize {number} - The size of the caption.
9
- * @returns {number} - The font size.
10
- */
11
- export declare const infoLevelToFontSize: (infoLevel: number, nodeRadius?: number, captionSize?: number, hasIcon?: boolean) => number;
12
- /**
13
- * Prepares node caption data for rendering (works for both Canvas and SVG)
14
- * @param node - The node to prepare caption data for
15
- * @param zoomLevel - Current zoom level
16
- * @param ctx - Canvas context for text measurement (optional for SVG, will create one if not provided)
17
- * @returns Caption rendering data including lines, styles, positioning, and font info
18
- */
19
- export declare function prepareNodeCaptionData(node: Node, zoomLevel: number, ctx?: CanvasRenderingContext2D): {
20
- lines: TextSegment[];
21
- stylesPerChar: string[][];
22
- fullCaption: string;
23
- fontSize: number;
24
- fontFace: string;
25
- fontColor: string;
26
- yPos: number;
27
- maxNoLines: number;
28
- hasContent: boolean;
29
- };