@graph-render/core 1.0.1

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 (161) hide show
  1. package/.eslintrc.json +6 -0
  2. package/CHANGELOG.md +45 -0
  3. package/dist/edges/collision.d.ts +8 -0
  4. package/dist/edges/collision.d.ts.map +1 -0
  5. package/dist/edges/collision.js +26 -0
  6. package/dist/edges/collision.js.map +1 -0
  7. package/dist/edges/geometry.d.ts +22 -0
  8. package/dist/edges/geometry.d.ts.map +1 -0
  9. package/dist/edges/geometry.js +75 -0
  10. package/dist/edges/geometry.js.map +1 -0
  11. package/dist/edges/index.d.ts +4 -0
  12. package/dist/edges/index.d.ts.map +1 -0
  13. package/dist/edges/index.js +4 -0
  14. package/dist/edges/index.js.map +1 -0
  15. package/dist/edges/pathBuilder.d.ts +11 -0
  16. package/dist/edges/pathBuilder.d.ts.map +1 -0
  17. package/dist/edges/pathBuilder.js +114 -0
  18. package/dist/edges/pathBuilder.js.map +1 -0
  19. package/dist/edges/pathCalculation.d.ts +14 -0
  20. package/dist/edges/pathCalculation.d.ts.map +1 -0
  21. package/dist/edges/pathCalculation.js +47 -0
  22. package/dist/edges/pathCalculation.js.map +1 -0
  23. package/dist/edges/routing.d.ts +6 -0
  24. package/dist/edges/routing.d.ts.map +1 -0
  25. package/dist/edges/routing.js +243 -0
  26. package/dist/edges/routing.js.map +1 -0
  27. package/dist/edges/sideSelection.d.ts +17 -0
  28. package/dist/edges/sideSelection.d.ts.map +1 -0
  29. package/dist/edges/sideSelection.js +45 -0
  30. package/dist/edges/sideSelection.js.map +1 -0
  31. package/dist/index.d.ts +7 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +6 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/layouts/centered.d.ts +6 -0
  36. package/dist/layouts/centered.d.ts.map +1 -0
  37. package/dist/layouts/centered.js +69 -0
  38. package/dist/layouts/centered.js.map +1 -0
  39. package/dist/layouts/compactBracket.d.ts +3 -0
  40. package/dist/layouts/compactBracket.d.ts.map +1 -0
  41. package/dist/layouts/compactBracket.js +7 -0
  42. package/dist/layouts/compactBracket.js.map +1 -0
  43. package/dist/layouts/dag.d.ts +3 -0
  44. package/dist/layouts/dag.d.ts.map +1 -0
  45. package/dist/layouts/dag.js +52 -0
  46. package/dist/layouts/dag.js.map +1 -0
  47. package/dist/layouts/forceDirected.d.ts +3 -0
  48. package/dist/layouts/forceDirected.d.ts.map +1 -0
  49. package/dist/layouts/forceDirected.js +176 -0
  50. package/dist/layouts/forceDirected.js.map +1 -0
  51. package/dist/layouts/grid.d.ts +6 -0
  52. package/dist/layouts/grid.d.ts.map +1 -0
  53. package/dist/layouts/grid.js +34 -0
  54. package/dist/layouts/grid.js.map +1 -0
  55. package/dist/layouts/index.d.ts +12 -0
  56. package/dist/layouts/index.d.ts.map +1 -0
  57. package/dist/layouts/index.js +88 -0
  58. package/dist/layouts/index.js.map +1 -0
  59. package/dist/layouts/orthogonalFlow.d.ts +3 -0
  60. package/dist/layouts/orthogonalFlow.d.ts.map +1 -0
  61. package/dist/layouts/orthogonalFlow.js +81 -0
  62. package/dist/layouts/orthogonalFlow.js.map +1 -0
  63. package/dist/layouts/radialTree.d.ts +3 -0
  64. package/dist/layouts/radialTree.d.ts.map +1 -0
  65. package/dist/layouts/radialTree.js +45 -0
  66. package/dist/layouts/radialTree.js.map +1 -0
  67. package/dist/layouts/tree.d.ts +6 -0
  68. package/dist/layouts/tree.d.ts.map +1 -0
  69. package/dist/layouts/tree.js +19 -0
  70. package/dist/layouts/tree.js.map +1 -0
  71. package/dist/layouts/treeAlignment.d.ts +10 -0
  72. package/dist/layouts/treeAlignment.d.ts.map +1 -0
  73. package/dist/layouts/treeAlignment.js +69 -0
  74. package/dist/layouts/treeAlignment.js.map +1 -0
  75. package/dist/layouts/treePositioning.d.ts +14 -0
  76. package/dist/layouts/treePositioning.d.ts.map +1 -0
  77. package/dist/layouts/treePositioning.js +30 -0
  78. package/dist/layouts/treePositioning.js.map +1 -0
  79. package/dist/layouts/treeTopology.d.ts +29 -0
  80. package/dist/layouts/treeTopology.d.ts.map +1 -0
  81. package/dist/layouts/treeTopology.js +137 -0
  82. package/dist/layouts/treeTopology.js.map +1 -0
  83. package/dist/rendering/defaultRenderers.d.ts +10 -0
  84. package/dist/rendering/defaultRenderers.d.ts.map +1 -0
  85. package/dist/rendering/defaultRenderers.js +85 -0
  86. package/dist/rendering/defaultRenderers.js.map +1 -0
  87. package/dist/rendering/index.d.ts +4 -0
  88. package/dist/rendering/index.d.ts.map +1 -0
  89. package/dist/rendering/index.js +4 -0
  90. package/dist/rendering/index.js.map +1 -0
  91. package/dist/rendering/svg.d.ts +7 -0
  92. package/dist/rendering/svg.d.ts.map +1 -0
  93. package/dist/rendering/svg.js +256 -0
  94. package/dist/rendering/svg.js.map +1 -0
  95. package/dist/rendering/utils.d.ts +5 -0
  96. package/dist/rendering/utils.d.ts.map +1 -0
  97. package/dist/rendering/utils.js +33 -0
  98. package/dist/rendering/utils.js.map +1 -0
  99. package/dist/utils/config.d.ts +36 -0
  100. package/dist/utils/config.d.ts.map +1 -0
  101. package/dist/utils/config.js +115 -0
  102. package/dist/utils/config.js.map +1 -0
  103. package/dist/utils/constants.d.ts +15 -0
  104. package/dist/utils/constants.d.ts.map +1 -0
  105. package/dist/utils/constants.js +19 -0
  106. package/dist/utils/constants.js.map +1 -0
  107. package/dist/utils/graphParser.d.ts +16 -0
  108. package/dist/utils/graphParser.d.ts.map +1 -0
  109. package/dist/utils/graphParser.js +277 -0
  110. package/dist/utils/graphParser.js.map +1 -0
  111. package/dist/utils/graphTraversal.d.ts +13 -0
  112. package/dist/utils/graphTraversal.d.ts.map +1 -0
  113. package/dist/utils/graphTraversal.js +28 -0
  114. package/dist/utils/graphTraversal.js.map +1 -0
  115. package/dist/utils/index.d.ts +8 -0
  116. package/dist/utils/index.d.ts.map +1 -0
  117. package/dist/utils/index.js +7 -0
  118. package/dist/utils/index.js.map +1 -0
  119. package/dist/utils/nodeMetrics.d.ts +8 -0
  120. package/dist/utils/nodeMetrics.d.ts.map +1 -0
  121. package/dist/utils/nodeMetrics.js +12 -0
  122. package/dist/utils/nodeMetrics.js.map +1 -0
  123. package/dist/utils/nodeSizing.d.ts +3 -0
  124. package/dist/utils/nodeSizing.d.ts.map +1 -0
  125. package/dist/utils/nodeSizing.js +77 -0
  126. package/dist/utils/nodeSizing.js.map +1 -0
  127. package/package.json +29 -0
  128. package/project.json +32 -0
  129. package/src/edges/collision.ts +31 -0
  130. package/src/edges/geometry.ts +85 -0
  131. package/src/edges/index.ts +3 -0
  132. package/src/edges/pathBuilder.ts +136 -0
  133. package/src/edges/pathCalculation.ts +69 -0
  134. package/src/edges/routing.ts +459 -0
  135. package/src/edges/sideSelection.ts +67 -0
  136. package/src/index.ts +50 -0
  137. package/src/layouts/centered.ts +114 -0
  138. package/src/layouts/compactBracket.ts +14 -0
  139. package/src/layouts/dag.ts +76 -0
  140. package/src/layouts/forceDirected.ts +224 -0
  141. package/src/layouts/grid.ts +50 -0
  142. package/src/layouts/index.ts +148 -0
  143. package/src/layouts/orthogonalFlow.ts +112 -0
  144. package/src/layouts/radialTree.ts +77 -0
  145. package/src/layouts/tree.ts +35 -0
  146. package/src/layouts/treeAlignment.ts +107 -0
  147. package/src/layouts/treePositioning.ts +55 -0
  148. package/src/layouts/treeTopology.ts +184 -0
  149. package/src/rendering/defaultRenderers.ts +110 -0
  150. package/src/rendering/index.ts +3 -0
  151. package/src/rendering/svg.ts +346 -0
  152. package/src/rendering/utils.ts +41 -0
  153. package/src/utils/config.ts +198 -0
  154. package/src/utils/constants.ts +24 -0
  155. package/src/utils/graphParser.ts +495 -0
  156. package/src/utils/graphTraversal.ts +32 -0
  157. package/src/utils/index.ts +19 -0
  158. package/src/utils/nodeMetrics.ts +23 -0
  159. package/src/utils/nodeSizing.ts +97 -0
  160. package/tsconfig.json +11 -0
  161. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,85 @@
1
+ import { PositionedNode, Point, Size, NodeSide } from '@graph-render/types';
2
+
3
+ /**
4
+ * Calculate the center point of a node
5
+ */
6
+ export const getNodeCenter = (node: PositionedNode, size: Size): Point => {
7
+ return {
8
+ x: node.position.x + size.width / 2,
9
+ y: node.position.y + size.height / 2,
10
+ };
11
+ };
12
+
13
+ /**
14
+ * Get the point at the center of a node's side
15
+ */
16
+ export const getSideCenter = (node: PositionedNode, size: Size, side: NodeSide): Point => {
17
+ const cx = node.position.x + size.width / 2;
18
+ const cy = node.position.y + size.height / 2;
19
+ switch (side) {
20
+ case NodeSide.Left:
21
+ return { x: node.position.x, y: cy };
22
+ case NodeSide.Right:
23
+ return { x: node.position.x + size.width, y: cy };
24
+ case NodeSide.Top:
25
+ return { x: cx, y: node.position.y };
26
+ case NodeSide.Bottom:
27
+ return { x: cx, y: node.position.y + size.height };
28
+ }
29
+ };
30
+
31
+ /**
32
+ * Get anchor point on a node's side with offset and inset
33
+ */
34
+ export const getAnchorPoint = (
35
+ node: PositionedNode,
36
+ size: Size,
37
+ side: NodeSide,
38
+ offset: number,
39
+ inset: number
40
+ ): Point => {
41
+ const cx = node.position.x + size.width / 2;
42
+ const cy = node.position.y + size.height / 2;
43
+ switch (side) {
44
+ case NodeSide.Left:
45
+ return { x: node.position.x - inset, y: cy + offset };
46
+ case NodeSide.Right:
47
+ return { x: node.position.x + size.width + inset, y: cy + offset };
48
+ case NodeSide.Top:
49
+ return { x: cx + offset, y: node.position.y - inset };
50
+ case NodeSide.Bottom:
51
+ return { x: cx + offset, y: node.position.y + size.height + inset };
52
+ }
53
+ };
54
+
55
+ /**
56
+ * Get the normal vector for a given side
57
+ */
58
+ export const getSideNormal = (side: NodeSide): Point => {
59
+ switch (side) {
60
+ case NodeSide.Left:
61
+ return { x: -1, y: 0 };
62
+ case NodeSide.Right:
63
+ return { x: 1, y: 0 };
64
+ case NodeSide.Top:
65
+ return { x: 0, y: -1 };
66
+ case NodeSide.Bottom:
67
+ return { x: 0, y: 1 };
68
+ }
69
+ };
70
+
71
+ /**
72
+ * Get the inward normal vector for a given side
73
+ */
74
+ export const getSideInwardNormal = (side: NodeSide): Point => {
75
+ switch (side) {
76
+ case NodeSide.Left:
77
+ return { x: 1, y: 0 };
78
+ case NodeSide.Right:
79
+ return { x: -1, y: 0 };
80
+ case NodeSide.Top:
81
+ return { x: 0, y: 1 };
82
+ case NodeSide.Bottom:
83
+ return { x: 0, y: -1 };
84
+ }
85
+ };
@@ -0,0 +1,3 @@
1
+ export { routeEdges } from './routing';
2
+ export { buildEdgePath } from './pathBuilder';
3
+ export { segmentIntersectsRect } from './collision';
@@ -0,0 +1,136 @@
1
+ import { PositionedEdge, Point } from '@graph-render/types';
2
+
3
+ /**
4
+ * Build a straight line path from edge points
5
+ */
6
+ const buildStraightPath = (points: Point[]): string => {
7
+ const [start, ...rest] = points;
8
+ return [`M ${start.x} ${start.y}`, ...rest.map((pt) => `L ${pt.x} ${pt.y}`)].join(' ');
9
+ };
10
+
11
+ /**
12
+ * Build a curved path for two-point edges
13
+ */
14
+ const buildTwoPointCurvedPath = (start: Point, end: Point, curveStrength: number): string => {
15
+ if (start.y === end.y) {
16
+ return `M ${start.x} ${start.y} L ${end.x} ${end.y}`;
17
+ }
18
+
19
+ const midX = start.x + (end.x - start.x) * 0.55;
20
+ const dirY = Math.sign(end.y - start.y) || 1;
21
+ const dirX = Math.sign(end.x - start.x) || 1;
22
+ const radiusBase = Math.min(Math.abs(end.x - start.x), Math.abs(end.y - start.y));
23
+ const r = Math.max(4, radiusBase * Math.min(Math.max(curveStrength, 0), 0.45));
24
+
25
+ const p1x = midX - r * dirX;
26
+ const p1y = start.y;
27
+ const p2x = midX;
28
+ const p2y = start.y + r * dirY;
29
+ const p3x = midX;
30
+ const p3y = end.y - r * dirY;
31
+ const p4x = midX + r * dirX;
32
+ const p4y = end.y;
33
+
34
+ return [
35
+ `M ${start.x} ${start.y}`,
36
+ `L ${p1x} ${p1y}`,
37
+ `Q ${midX} ${p1y} ${p2x} ${p2y}`,
38
+ `L ${p3x} ${p3y}`,
39
+ `Q ${midX} ${end.y} ${p4x} ${p4y}`,
40
+ `L ${end.x} ${end.y}`,
41
+ ].join(' ');
42
+ };
43
+
44
+ /**
45
+ * Build a quadratic bezier path for three-point edges
46
+ */
47
+ const buildThreePointPath = (start: Point, control: Point, end: Point): string => {
48
+ return `M ${start.x} ${start.y} Q ${control.x} ${control.y} ${end.x} ${end.y}`;
49
+ };
50
+
51
+ /**
52
+ * Build a cubic bezier path for six-point edges (standard curved edge)
53
+ */
54
+ const buildSixPointPath = (points: Point[]): string => {
55
+ const [start, out, c1, c2, straightIn, end] = points;
56
+ return [
57
+ `M ${start.x} ${start.y}`,
58
+ `L ${out.x} ${out.y}`,
59
+ `C ${c1.x} ${c1.y} ${c2.x} ${c2.y} ${straightIn.x} ${straightIn.y}`,
60
+ `L ${end.x} ${end.y}`,
61
+ ].join(' ');
62
+ };
63
+
64
+ /**
65
+ * Build a path with multiple quadratic curves for variable-length edges
66
+ */
67
+ const buildMultiPointPath = (points: Point[]): string => {
68
+ const [start, ...rest] = points;
69
+ const commands = [`M ${start.x} ${start.y}`];
70
+
71
+ if (rest.length) {
72
+ commands.push(`L ${rest[0].x} ${rest[0].y}`);
73
+ }
74
+
75
+ for (let i = 1; i < rest.length - 1; i += 1) {
76
+ const ctrl = rest[i];
77
+ const next = rest[i + 1];
78
+ const isLastCurve = i === rest.length - 2;
79
+ if (isLastCurve) {
80
+ // FIX: removed the trailing `L rest[last]` that duplicated the Q endpoint.
81
+ // When isLastCurve is true, `next === rest[rest.length - 1]`, so the Q
82
+ // command already terminates at the final point. The extra L produced a
83
+ // zero-length segment that misplaced SVG `marker-end` arrowheads.
84
+ commands.push(`Q ${ctrl.x} ${ctrl.y} ${next.x} ${next.y}`);
85
+ break;
86
+ }
87
+ commands.push(`Q ${ctrl.x} ${ctrl.y} ${next.x} ${next.y}`);
88
+ }
89
+
90
+ if (rest.length === 2) {
91
+ const [ctrl, end] = rest;
92
+ commands.push(`Q ${ctrl.x} ${ctrl.y} ${end.x} ${end.y}`);
93
+ }
94
+
95
+ return commands.join(' ');
96
+ };
97
+
98
+ /**
99
+ * Build an SVG path string from edge points.
100
+ *
101
+ * Returns null (instead of throwing) when the edge has fewer than two points so
102
+ * that a malformed edge from a user-supplied routeEdgesOverride does not crash
103
+ * the React render tree. Both callers (EdgePath and svg.ts) already guard
104
+ * against a falsy return value.
105
+ */
106
+ export const buildEdgePath = (
107
+ edge: PositionedEdge,
108
+ curveEdges: boolean,
109
+ curveStrength: number
110
+ ): string | null => {
111
+ // FIX: was `throw new Error(...)` — returning null lets callers handle
112
+ // the bad edge gracefully without an unhandled exception in render.
113
+ if (edge.points.length < 2) {
114
+ return null;
115
+ }
116
+
117
+ if (!curveEdges) {
118
+ return buildStraightPath(edge.points);
119
+ }
120
+
121
+ if (edge.points.length === 2) {
122
+ const [start, end] = edge.points;
123
+ return buildTwoPointCurvedPath(start, end, curveStrength);
124
+ }
125
+
126
+ if (edge.points.length === 3) {
127
+ const [start, control, end] = edge.points;
128
+ return buildThreePointPath(start, control, end);
129
+ }
130
+
131
+ if (edge.points.length >= 6) {
132
+ return buildSixPointPath(edge.points);
133
+ }
134
+
135
+ return buildMultiPointPath(edge.points);
136
+ };
@@ -0,0 +1,69 @@
1
+ import { Point } from '@graph-render/types';
2
+
3
+ /**
4
+ * Calculate the lead-out distance based on edge configuration
5
+ */
6
+ export const getLeadOutDistance = (straight: boolean, isUndirected: boolean): number => {
7
+ if (straight && !isUndirected) return 28;
8
+ return isUndirected ? 8 : 10;
9
+ };
10
+
11
+ /**
12
+ * Calculate control points for curved edge path
13
+ */
14
+ export const calculateControlPoints = (
15
+ startPoint: Point,
16
+ endPoint: Point,
17
+ sourceNormal: Point,
18
+ targetNormal: Point,
19
+ leadOut: number,
20
+ isUndirected: boolean
21
+ ): Point[] => {
22
+ const outPoint = {
23
+ x: startPoint.x + sourceNormal.x * leadOut,
24
+ y: startPoint.y + sourceNormal.y * leadOut,
25
+ };
26
+
27
+ const endStraight = isUndirected ? 10 : 20;
28
+ const endStraightStart = {
29
+ x: endPoint.x - targetNormal.x * endStraight,
30
+ y: endPoint.y - targetNormal.y * endStraight,
31
+ };
32
+
33
+ const control1 = {
34
+ x: outPoint.x + sourceNormal.x * (leadOut * 3),
35
+ y: outPoint.y + sourceNormal.y * (leadOut * 3),
36
+ };
37
+
38
+ const control2 = {
39
+ x: endStraightStart.x - targetNormal.x * (endStraight * 3),
40
+ y: endStraightStart.y - targetNormal.y * (endStraight * 3),
41
+ };
42
+
43
+ return [startPoint, outPoint, control1, control2, endStraightStart, endPoint];
44
+ };
45
+
46
+ /**
47
+ * Calculate straight path points
48
+ */
49
+ export const calculateStraightPoints = (
50
+ startPoint: Point,
51
+ endPoint: Point,
52
+ sourceNormal: Point,
53
+ targetNormal: Point,
54
+ leadOut: number,
55
+ isUndirected: boolean
56
+ ): Point[] => {
57
+ const outPoint = {
58
+ x: startPoint.x + sourceNormal.x * leadOut,
59
+ y: startPoint.y + sourceNormal.y * leadOut,
60
+ };
61
+
62
+ const endStraight = isUndirected ? 10 : 20;
63
+ const endStraightStart = {
64
+ x: endPoint.x - targetNormal.x * endStraight,
65
+ y: endPoint.y - targetNormal.y * endStraight,
66
+ };
67
+
68
+ return [startPoint, outPoint, endStraightStart, endPoint];
69
+ };