@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.
- package/.eslintrc.json +6 -0
- package/CHANGELOG.md +45 -0
- package/dist/edges/collision.d.ts +8 -0
- package/dist/edges/collision.d.ts.map +1 -0
- package/dist/edges/collision.js +26 -0
- package/dist/edges/collision.js.map +1 -0
- package/dist/edges/geometry.d.ts +22 -0
- package/dist/edges/geometry.d.ts.map +1 -0
- package/dist/edges/geometry.js +75 -0
- package/dist/edges/geometry.js.map +1 -0
- package/dist/edges/index.d.ts +4 -0
- package/dist/edges/index.d.ts.map +1 -0
- package/dist/edges/index.js +4 -0
- package/dist/edges/index.js.map +1 -0
- package/dist/edges/pathBuilder.d.ts +11 -0
- package/dist/edges/pathBuilder.d.ts.map +1 -0
- package/dist/edges/pathBuilder.js +114 -0
- package/dist/edges/pathBuilder.js.map +1 -0
- package/dist/edges/pathCalculation.d.ts +14 -0
- package/dist/edges/pathCalculation.d.ts.map +1 -0
- package/dist/edges/pathCalculation.js +47 -0
- package/dist/edges/pathCalculation.js.map +1 -0
- package/dist/edges/routing.d.ts +6 -0
- package/dist/edges/routing.d.ts.map +1 -0
- package/dist/edges/routing.js +243 -0
- package/dist/edges/routing.js.map +1 -0
- package/dist/edges/sideSelection.d.ts +17 -0
- package/dist/edges/sideSelection.d.ts.map +1 -0
- package/dist/edges/sideSelection.js +45 -0
- package/dist/edges/sideSelection.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts/centered.d.ts +6 -0
- package/dist/layouts/centered.d.ts.map +1 -0
- package/dist/layouts/centered.js +69 -0
- package/dist/layouts/centered.js.map +1 -0
- package/dist/layouts/compactBracket.d.ts +3 -0
- package/dist/layouts/compactBracket.d.ts.map +1 -0
- package/dist/layouts/compactBracket.js +7 -0
- package/dist/layouts/compactBracket.js.map +1 -0
- package/dist/layouts/dag.d.ts +3 -0
- package/dist/layouts/dag.d.ts.map +1 -0
- package/dist/layouts/dag.js +52 -0
- package/dist/layouts/dag.js.map +1 -0
- package/dist/layouts/forceDirected.d.ts +3 -0
- package/dist/layouts/forceDirected.d.ts.map +1 -0
- package/dist/layouts/forceDirected.js +176 -0
- package/dist/layouts/forceDirected.js.map +1 -0
- package/dist/layouts/grid.d.ts +6 -0
- package/dist/layouts/grid.d.ts.map +1 -0
- package/dist/layouts/grid.js +34 -0
- package/dist/layouts/grid.js.map +1 -0
- package/dist/layouts/index.d.ts +12 -0
- package/dist/layouts/index.d.ts.map +1 -0
- package/dist/layouts/index.js +88 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/layouts/orthogonalFlow.d.ts +3 -0
- package/dist/layouts/orthogonalFlow.d.ts.map +1 -0
- package/dist/layouts/orthogonalFlow.js +81 -0
- package/dist/layouts/orthogonalFlow.js.map +1 -0
- package/dist/layouts/radialTree.d.ts +3 -0
- package/dist/layouts/radialTree.d.ts.map +1 -0
- package/dist/layouts/radialTree.js +45 -0
- package/dist/layouts/radialTree.js.map +1 -0
- package/dist/layouts/tree.d.ts +6 -0
- package/dist/layouts/tree.d.ts.map +1 -0
- package/dist/layouts/tree.js +19 -0
- package/dist/layouts/tree.js.map +1 -0
- package/dist/layouts/treeAlignment.d.ts +10 -0
- package/dist/layouts/treeAlignment.d.ts.map +1 -0
- package/dist/layouts/treeAlignment.js +69 -0
- package/dist/layouts/treeAlignment.js.map +1 -0
- package/dist/layouts/treePositioning.d.ts +14 -0
- package/dist/layouts/treePositioning.d.ts.map +1 -0
- package/dist/layouts/treePositioning.js +30 -0
- package/dist/layouts/treePositioning.js.map +1 -0
- package/dist/layouts/treeTopology.d.ts +29 -0
- package/dist/layouts/treeTopology.d.ts.map +1 -0
- package/dist/layouts/treeTopology.js +137 -0
- package/dist/layouts/treeTopology.js.map +1 -0
- package/dist/rendering/defaultRenderers.d.ts +10 -0
- package/dist/rendering/defaultRenderers.d.ts.map +1 -0
- package/dist/rendering/defaultRenderers.js +85 -0
- package/dist/rendering/defaultRenderers.js.map +1 -0
- package/dist/rendering/index.d.ts +4 -0
- package/dist/rendering/index.d.ts.map +1 -0
- package/dist/rendering/index.js +4 -0
- package/dist/rendering/index.js.map +1 -0
- package/dist/rendering/svg.d.ts +7 -0
- package/dist/rendering/svg.d.ts.map +1 -0
- package/dist/rendering/svg.js +256 -0
- package/dist/rendering/svg.js.map +1 -0
- package/dist/rendering/utils.d.ts +5 -0
- package/dist/rendering/utils.d.ts.map +1 -0
- package/dist/rendering/utils.js +33 -0
- package/dist/rendering/utils.js.map +1 -0
- package/dist/utils/config.d.ts +36 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +115 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/constants.d.ts +15 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +19 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/graphParser.d.ts +16 -0
- package/dist/utils/graphParser.d.ts.map +1 -0
- package/dist/utils/graphParser.js +277 -0
- package/dist/utils/graphParser.js.map +1 -0
- package/dist/utils/graphTraversal.d.ts +13 -0
- package/dist/utils/graphTraversal.d.ts.map +1 -0
- package/dist/utils/graphTraversal.js +28 -0
- package/dist/utils/graphTraversal.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/nodeMetrics.d.ts +8 -0
- package/dist/utils/nodeMetrics.d.ts.map +1 -0
- package/dist/utils/nodeMetrics.js +12 -0
- package/dist/utils/nodeMetrics.js.map +1 -0
- package/dist/utils/nodeSizing.d.ts +3 -0
- package/dist/utils/nodeSizing.d.ts.map +1 -0
- package/dist/utils/nodeSizing.js +77 -0
- package/dist/utils/nodeSizing.js.map +1 -0
- package/package.json +29 -0
- package/project.json +32 -0
- package/src/edges/collision.ts +31 -0
- package/src/edges/geometry.ts +85 -0
- package/src/edges/index.ts +3 -0
- package/src/edges/pathBuilder.ts +136 -0
- package/src/edges/pathCalculation.ts +69 -0
- package/src/edges/routing.ts +459 -0
- package/src/edges/sideSelection.ts +67 -0
- package/src/index.ts +50 -0
- package/src/layouts/centered.ts +114 -0
- package/src/layouts/compactBracket.ts +14 -0
- package/src/layouts/dag.ts +76 -0
- package/src/layouts/forceDirected.ts +224 -0
- package/src/layouts/grid.ts +50 -0
- package/src/layouts/index.ts +148 -0
- package/src/layouts/orthogonalFlow.ts +112 -0
- package/src/layouts/radialTree.ts +77 -0
- package/src/layouts/tree.ts +35 -0
- package/src/layouts/treeAlignment.ts +107 -0
- package/src/layouts/treePositioning.ts +55 -0
- package/src/layouts/treeTopology.ts +184 -0
- package/src/rendering/defaultRenderers.ts +110 -0
- package/src/rendering/index.ts +3 -0
- package/src/rendering/svg.ts +346 -0
- package/src/rendering/utils.ts +41 -0
- package/src/utils/config.ts +198 -0
- package/src/utils/constants.ts +24 -0
- package/src/utils/graphParser.ts +495 -0
- package/src/utils/graphTraversal.ts +32 -0
- package/src/utils/index.ts +19 -0
- package/src/utils/nodeMetrics.ts +23 -0
- package/src/utils/nodeSizing.ts +97 -0
- package/tsconfig.json +11 -0
- 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,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
|
+
};
|