@joshrp/react-flow-smart-edge 4.0.2
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/LICENSE +21 -0
- package/README.md +355 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.mjs +409 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +108 -0
- package/src/SmartBezierEdge/index.tsx +26 -0
- package/src/SmartEdge/index.tsx +92 -0
- package/src/SmartStepEdge/index.tsx +29 -0
- package/src/SmartStraightEdge/index.tsx +29 -0
- package/src/functions/createGrid.ts +81 -0
- package/src/functions/drawSvgPath.ts +72 -0
- package/src/functions/generatePath.ts +60 -0
- package/src/functions/getBoundingBoxes.ts +138 -0
- package/src/functions/guaranteeWalkablePath.ts +38 -0
- package/src/functions/index.ts +7 -0
- package/src/functions/pointConversion.ts +49 -0
- package/src/functions/utils.ts +15 -0
- package/src/getSmartEdge/index.ts +160 -0
- package/src/index.tsx +18 -0
- package/src/internal/SmartEdgeDebug.tsx +43 -0
- package/src/internal/SmartEdgeDebugOverlay.tsx +24 -0
- package/src/internal/useSmartEdgeDebug.ts +26 -0
- package/src/pathfinding/aStar.ts +134 -0
- package/src/pathfinding/grid.ts +141 -0
- package/src/pathfinding/types.ts +3 -0
- package/src/stories/CustomLabel.tsx +94 -0
- package/src/stories/DummyData.ts +194 -0
- package/src/stories/GraphWrapper.tsx +23 -0
- package/src/stories/SmartEdge.stories.tsx +67 -0
- package/src/vite-env.d.ts +1 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import { jsx as A } from "react/jsx-runtime";
|
|
2
|
+
import { BezierEdge as _, BaseEdge as K, useNodes as X, StraightEdge as O, StepEdge as V } from "@xyflow/react";
|
|
3
|
+
import { createContext as tt, useContext as et } from "react";
|
|
4
|
+
const nt = (t, e, n) => {
|
|
5
|
+
const o = new Array(e);
|
|
6
|
+
for (let s = 0; s < e; s++) {
|
|
7
|
+
const r = new Array(t);
|
|
8
|
+
for (let l = 0; l < t; l++) {
|
|
9
|
+
const x = !!(n ? n[s]?.[l] : void 0), h = n ? !x : !0;
|
|
10
|
+
r[l] = { x: l, y: s, walkable: h };
|
|
11
|
+
}
|
|
12
|
+
o[s] = r;
|
|
13
|
+
}
|
|
14
|
+
return o;
|
|
15
|
+
}, v = (t, e, n, o) => n >= 0 && n < t && o >= 0 && o < e, R = (t, e, n) => {
|
|
16
|
+
const o = nt(t, e, n), s = (h, i) => o[i][h], r = (h, i) => v(t, e, h, i) && o[i][h].walkable;
|
|
17
|
+
return {
|
|
18
|
+
width: t,
|
|
19
|
+
height: e,
|
|
20
|
+
nodes: o,
|
|
21
|
+
getNodeAt: s,
|
|
22
|
+
isWalkableAt: r,
|
|
23
|
+
setWalkableAt: (h, i, a) => {
|
|
24
|
+
v(t, e, h, i) && (o[i][h].walkable = a);
|
|
25
|
+
},
|
|
26
|
+
getNeighbors: (h, i) => {
|
|
27
|
+
const a = h.x, c = h.y, g = [], m = r(a, c - 1), E = r(a + 1, c), S = r(a, c + 1), M = r(a - 1, c);
|
|
28
|
+
m && g.push(s(a, c - 1)), E && g.push(s(a + 1, c)), S && g.push(s(a, c + 1)), M && g.push(s(a - 1, c));
|
|
29
|
+
const w = r(a + 1, c - 1), d = r(a + 1, c + 1), f = r(a - 1, c + 1), y = r(a - 1, c - 1);
|
|
30
|
+
return i === "Never" || (w && g.push(s(a + 1, c - 1)), d && g.push(s(a + 1, c + 1)), f && g.push(s(a - 1, c + 1)), y && g.push(s(a - 1, c - 1))), g;
|
|
31
|
+
},
|
|
32
|
+
isInside: (h, i) => v(t, e, h, i),
|
|
33
|
+
clone: () => {
|
|
34
|
+
const h = o.map(
|
|
35
|
+
(i) => i.map((a) => a.walkable ? 0 : 1)
|
|
36
|
+
);
|
|
37
|
+
return R(t, e, h);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}, $ = (t, e) => {
|
|
41
|
+
switch (e) {
|
|
42
|
+
case "top":
|
|
43
|
+
return { x: t.x, y: t.y - 1 };
|
|
44
|
+
case "bottom":
|
|
45
|
+
return { x: t.x, y: t.y + 1 };
|
|
46
|
+
case "left":
|
|
47
|
+
return { x: t.x - 1, y: t.y };
|
|
48
|
+
case "right":
|
|
49
|
+
return { x: t.x + 1, y: t.y };
|
|
50
|
+
}
|
|
51
|
+
}, W = (t, e, n) => {
|
|
52
|
+
let o = t.getNodeAt(e.x, e.y);
|
|
53
|
+
for (; !o.walkable; ) {
|
|
54
|
+
t.setWalkableAt(o.x, o.y, !0);
|
|
55
|
+
const s = $(o, n);
|
|
56
|
+
o = t.getNodeAt(s.x, s.y);
|
|
57
|
+
}
|
|
58
|
+
}, P = (t, e, n, o) => {
|
|
59
|
+
const s = (t.x - e) / o + 1, r = (t.y - n) / o + 1;
|
|
60
|
+
return { x: s, y: r };
|
|
61
|
+
}, Y = (t, e, n, o) => {
|
|
62
|
+
const s = (t.x - 1) * o + e, r = (t.y - 1) * o + n;
|
|
63
|
+
return { x: s, y: r };
|
|
64
|
+
}, B = (t, e = 10) => Math.round(t / e) * e, k = (t, e = 10) => Math.floor(t / e) * e, N = (t, e = 10) => Math.ceil(t / e) * e, D = (t, e = 0) => {
|
|
65
|
+
let n = Math.max(Math.round(t), e);
|
|
66
|
+
return n = Number.isInteger(n) ? n : e, n = n >= e ? n : e, n;
|
|
67
|
+
}, ot = (t, e, n, o, s = 2) => {
|
|
68
|
+
const { xMin: r, yMin: l, width: u, height: x } = t, h = N(u, s) / s + 1, i = N(x, s) / s + 1, a = R(h, i);
|
|
69
|
+
e.forEach((w) => {
|
|
70
|
+
const d = P(w.topLeft, r, l, s), f = P(w.bottomRight, r, l, s);
|
|
71
|
+
for (let y = d.x; y < f.x; y++)
|
|
72
|
+
for (let p = d.y; p < f.y; p++)
|
|
73
|
+
a.setWalkableAt(y, p, !1);
|
|
74
|
+
});
|
|
75
|
+
const c = P(
|
|
76
|
+
{
|
|
77
|
+
x: B(n.x, s),
|
|
78
|
+
y: B(n.y, s)
|
|
79
|
+
},
|
|
80
|
+
r,
|
|
81
|
+
l,
|
|
82
|
+
s
|
|
83
|
+
), g = P(
|
|
84
|
+
{
|
|
85
|
+
x: B(o.x, s),
|
|
86
|
+
y: B(o.y, s)
|
|
87
|
+
},
|
|
88
|
+
r,
|
|
89
|
+
l,
|
|
90
|
+
s
|
|
91
|
+
), m = a.getNodeAt(c.x, c.y);
|
|
92
|
+
W(a, m, n.position);
|
|
93
|
+
const E = a.getNodeAt(g.x, g.y);
|
|
94
|
+
W(a, E, o.position);
|
|
95
|
+
const S = $(m, n.position), M = $(E, o.position);
|
|
96
|
+
return { grid: a, start: S, end: M };
|
|
97
|
+
}, T = (t, e, n) => {
|
|
98
|
+
let o = `M ${String(t.x)}, ${String(t.y)} `;
|
|
99
|
+
return n.forEach((s) => {
|
|
100
|
+
const [r, l] = s;
|
|
101
|
+
o += `L ${String(r)}, ${String(l)} `;
|
|
102
|
+
}), o += `L ${String(e.x)}, ${String(e.y)} `, o;
|
|
103
|
+
}, z = (t, e, n) => {
|
|
104
|
+
const o = [[t.x, t.y], ...n, [e.x, e.y]];
|
|
105
|
+
return st(o);
|
|
106
|
+
}, st = (t) => {
|
|
107
|
+
let o = t[0];
|
|
108
|
+
const s = t[0];
|
|
109
|
+
let r = `M${String(s[0])},${String(s[1])}M`;
|
|
110
|
+
for (const u of t) {
|
|
111
|
+
const x = rt(o[0], o[1], u[0], u[1]);
|
|
112
|
+
r += ` ${String(x[0])},${String(x[1])}`, r += `Q${String(u[0])},${String(u[1])}`, o = u;
|
|
113
|
+
}
|
|
114
|
+
const l = t[t.length - 1];
|
|
115
|
+
return r += ` ${String(l[0])},${String(l[1])}`, r;
|
|
116
|
+
}, rt = (t, e, n, o) => {
|
|
117
|
+
const s = (t - n) / 2 + n, r = (e - o) / 2 + o;
|
|
118
|
+
return [s, r];
|
|
119
|
+
}, at = (t, e) => t + e, ct = (t, e) => {
|
|
120
|
+
const n = Math.SQRT2 - 1;
|
|
121
|
+
return t < e ? n * t + e : n * e + t;
|
|
122
|
+
}, it = (t) => {
|
|
123
|
+
const e = [];
|
|
124
|
+
let n = t;
|
|
125
|
+
for (; n; )
|
|
126
|
+
e.push([n.x, n.y]), n = n.parent;
|
|
127
|
+
return e.reverse();
|
|
128
|
+
}, lt = (t) => t === "Never" ? at : ct, ht = (t) => {
|
|
129
|
+
let e = 0;
|
|
130
|
+
for (let n = 1; n < t.length; n++)
|
|
131
|
+
(t[n].estimatedTotalCost ?? 1 / 0) < (t[e].estimatedTotalCost ?? 1 / 0) && (e = n);
|
|
132
|
+
return t.splice(e, 1)[0];
|
|
133
|
+
}, xt = (t, e, n, o, s, r) => {
|
|
134
|
+
if (t.closed) return;
|
|
135
|
+
const l = Math.abs(t.x - e.x), u = Math.abs(t.y - e.y), x = (e.costFromStart ?? 0) + (l === 0 || u === 0 ? 1 : Math.SQRT2);
|
|
136
|
+
(!t.opened || x < (t.costFromStart ?? 1 / 0)) && (t.costFromStart = x, t.heuristicCostToGoal = t.heuristicCostToGoal ?? r * s(Math.abs(t.x - n.x), Math.abs(t.y - n.y)), t.estimatedTotalCost = (t.costFromStart ?? 0) + (t.heuristicCostToGoal ?? 0), t.parent = e, t.opened || (t.opened = !0, o.push(t)));
|
|
137
|
+
}, U = (t = {}) => {
|
|
138
|
+
const e = t.diagonalMovement ?? "Never", n = t.heuristic ?? lt(e), o = t.weight ?? 1;
|
|
139
|
+
return { findPath: (r, l, u, x, h) => {
|
|
140
|
+
const i = h.getNodeAt(r, l), a = h.getNodeAt(u, x), c = [];
|
|
141
|
+
for (i.costFromStart = 0, i.heuristicCostToGoal = 0, i.estimatedTotalCost = 0, i.opened = !0, c.push(i); c.length > 0; ) {
|
|
142
|
+
const g = ht(c);
|
|
143
|
+
if (g.closed = !0, g === a)
|
|
144
|
+
return it(a);
|
|
145
|
+
const m = h.getNeighbors(g, e);
|
|
146
|
+
for (const E of m)
|
|
147
|
+
xt(E, g, a, c, n, o);
|
|
148
|
+
}
|
|
149
|
+
return [];
|
|
150
|
+
} };
|
|
151
|
+
}, F = (t, e, n) => {
|
|
152
|
+
try {
|
|
153
|
+
const s = U({
|
|
154
|
+
diagonalMovement: "Always"
|
|
155
|
+
}).findPath(e.x, e.y, n.x, n.y, t);
|
|
156
|
+
if (s.length === 0)
|
|
157
|
+
throw new Error("No path found");
|
|
158
|
+
return s;
|
|
159
|
+
} catch (o) {
|
|
160
|
+
throw o instanceof Error ? o : new Error(`Unknown error: ${String(o)}`);
|
|
161
|
+
}
|
|
162
|
+
}, gt = (t, e, n) => {
|
|
163
|
+
try {
|
|
164
|
+
const s = U({
|
|
165
|
+
diagonalMovement: "Never"
|
|
166
|
+
}).findPath(e.x, e.y, n.x, n.y, t);
|
|
167
|
+
if (s.length === 0)
|
|
168
|
+
throw new Error("No path found");
|
|
169
|
+
return s;
|
|
170
|
+
} catch (o) {
|
|
171
|
+
throw o instanceof Error ? o : new Error(`Unknown error: ${String(o)}`);
|
|
172
|
+
}
|
|
173
|
+
}, ft = (t, e = 2, n = 2) => {
|
|
174
|
+
let o = Number.MIN_SAFE_INTEGER, s = Number.MIN_SAFE_INTEGER, r = Number.MAX_SAFE_INTEGER, l = Number.MAX_SAFE_INTEGER;
|
|
175
|
+
const u = t.map((S) => {
|
|
176
|
+
const M = Math.max(S.measured?.width ?? 0, 1), w = Math.max(S.measured?.height ?? 0, 1), d = {
|
|
177
|
+
x: S.position.x,
|
|
178
|
+
y: S.position.y
|
|
179
|
+
}, f = {
|
|
180
|
+
x: d.x - e,
|
|
181
|
+
y: d.y - e
|
|
182
|
+
}, y = {
|
|
183
|
+
x: d.x - e,
|
|
184
|
+
y: d.y + w + e
|
|
185
|
+
}, p = {
|
|
186
|
+
x: d.x + M + e,
|
|
187
|
+
y: d.y - e
|
|
188
|
+
}, b = {
|
|
189
|
+
x: d.x + M + e,
|
|
190
|
+
y: d.y + w + e
|
|
191
|
+
};
|
|
192
|
+
return n > 0 && (f.x = k(f.x, n), f.y = k(f.y, n), y.x = k(y.x, n), y.y = N(y.y, n), p.x = N(p.x, n), p.y = k(p.y, n), b.x = N(b.x, n), b.y = N(b.y, n)), f.y < l && (l = f.y), f.x < r && (r = f.x), b.y > s && (s = b.y), b.x > o && (o = b.x), {
|
|
193
|
+
id: S.id,
|
|
194
|
+
width: M,
|
|
195
|
+
height: w,
|
|
196
|
+
topLeft: f,
|
|
197
|
+
bottomLeft: y,
|
|
198
|
+
topRight: p,
|
|
199
|
+
bottomRight: b
|
|
200
|
+
};
|
|
201
|
+
}), x = e * 2;
|
|
202
|
+
o = N(o + x, n), s = N(s + x, n), r = k(r - x, n), l = k(l - x, n);
|
|
203
|
+
const h = {
|
|
204
|
+
x: r,
|
|
205
|
+
y: l
|
|
206
|
+
}, i = {
|
|
207
|
+
x: r,
|
|
208
|
+
y: s
|
|
209
|
+
}, a = {
|
|
210
|
+
x: o,
|
|
211
|
+
y: l
|
|
212
|
+
}, c = {
|
|
213
|
+
x: o,
|
|
214
|
+
y: s
|
|
215
|
+
}, g = Math.abs(h.x - a.x), m = Math.abs(h.y - i.y);
|
|
216
|
+
return { nodeBoxes: u, graphBox: {
|
|
217
|
+
topLeft: h,
|
|
218
|
+
bottomLeft: i,
|
|
219
|
+
topRight: a,
|
|
220
|
+
bottomRight: c,
|
|
221
|
+
width: g,
|
|
222
|
+
height: m,
|
|
223
|
+
xMax: o,
|
|
224
|
+
yMax: s,
|
|
225
|
+
xMin: r,
|
|
226
|
+
yMin: l
|
|
227
|
+
} };
|
|
228
|
+
}, ut = ({
|
|
229
|
+
options: t = {},
|
|
230
|
+
nodes: e = [],
|
|
231
|
+
sourceX: n,
|
|
232
|
+
sourceY: o,
|
|
233
|
+
targetX: s,
|
|
234
|
+
targetY: r,
|
|
235
|
+
sourcePosition: l,
|
|
236
|
+
targetPosition: u
|
|
237
|
+
}) => {
|
|
238
|
+
try {
|
|
239
|
+
const {
|
|
240
|
+
drawEdge: x = z,
|
|
241
|
+
generatePath: h = F
|
|
242
|
+
} = t;
|
|
243
|
+
let { gridRatio: i = 10, nodePadding: a = 10 } = t;
|
|
244
|
+
i = D(i), a = D(a);
|
|
245
|
+
const { graphBox: c, nodeBoxes: g } = ft(
|
|
246
|
+
e,
|
|
247
|
+
a,
|
|
248
|
+
i
|
|
249
|
+
);
|
|
250
|
+
t.debug?.enabled && t.debug.setGraphBox && t.debug.setGraphBox({
|
|
251
|
+
x: c.topLeft.x,
|
|
252
|
+
y: c.topLeft.y,
|
|
253
|
+
width: c.width,
|
|
254
|
+
height: c.height
|
|
255
|
+
});
|
|
256
|
+
const m = {
|
|
257
|
+
x: n,
|
|
258
|
+
y: o,
|
|
259
|
+
position: l
|
|
260
|
+
}, E = {
|
|
261
|
+
x: s,
|
|
262
|
+
y: r,
|
|
263
|
+
position: u
|
|
264
|
+
}, { grid: S, start: M, end: w } = ot(
|
|
265
|
+
c,
|
|
266
|
+
g,
|
|
267
|
+
m,
|
|
268
|
+
E,
|
|
269
|
+
i
|
|
270
|
+
), f = h(S, M, w), y = f.map((q) => {
|
|
271
|
+
const [H, J] = q, L = Y(
|
|
272
|
+
{ x: H, y: J },
|
|
273
|
+
c.xMin,
|
|
274
|
+
c.yMin,
|
|
275
|
+
i
|
|
276
|
+
);
|
|
277
|
+
return [L.x, L.y];
|
|
278
|
+
}), p = x(m, E, y), b = Math.floor(f.length / 2), C = f[b], [G, Q] = C, { x: Z, y: j } = Y(
|
|
279
|
+
{ x: G, y: Q },
|
|
280
|
+
c.xMin,
|
|
281
|
+
c.yMin,
|
|
282
|
+
i
|
|
283
|
+
);
|
|
284
|
+
return { svgPathString: p, edgeCenterX: Z, edgeCenterY: j };
|
|
285
|
+
} catch (x) {
|
|
286
|
+
return x instanceof Error ? x : new Error(`Unknown error: ${String(x)}`);
|
|
287
|
+
}
|
|
288
|
+
}, yt = tt({
|
|
289
|
+
enabled: !1,
|
|
290
|
+
graphBox: null,
|
|
291
|
+
setGraphBox: () => {
|
|
292
|
+
}
|
|
293
|
+
}), dt = () => et(yt);
|
|
294
|
+
function I({
|
|
295
|
+
nodes: t,
|
|
296
|
+
options: e,
|
|
297
|
+
...n
|
|
298
|
+
}) {
|
|
299
|
+
const { enabled: o, setGraphBox: s } = dt(), {
|
|
300
|
+
sourceX: r,
|
|
301
|
+
sourceY: l,
|
|
302
|
+
sourcePosition: u,
|
|
303
|
+
targetX: x,
|
|
304
|
+
targetY: h,
|
|
305
|
+
targetPosition: i,
|
|
306
|
+
style: a,
|
|
307
|
+
label: c,
|
|
308
|
+
labelStyle: g,
|
|
309
|
+
labelShowBg: m,
|
|
310
|
+
labelBgStyle: E,
|
|
311
|
+
labelBgPadding: S,
|
|
312
|
+
labelBgBorderRadius: M,
|
|
313
|
+
markerEnd: w,
|
|
314
|
+
markerStart: d,
|
|
315
|
+
interactionWidth: f
|
|
316
|
+
} = n, y = ut({
|
|
317
|
+
sourcePosition: u,
|
|
318
|
+
targetPosition: i,
|
|
319
|
+
sourceX: r,
|
|
320
|
+
sourceY: l,
|
|
321
|
+
targetX: x,
|
|
322
|
+
targetY: h,
|
|
323
|
+
options: {
|
|
324
|
+
...e,
|
|
325
|
+
debug: { enabled: o, setGraphBox: s }
|
|
326
|
+
},
|
|
327
|
+
nodes: t
|
|
328
|
+
}), p = e.fallback ?? _;
|
|
329
|
+
if (y instanceof Error)
|
|
330
|
+
return o && console.error(y), /* @__PURE__ */ A(p, { ...n });
|
|
331
|
+
const { edgeCenterX: b, edgeCenterY: C, svgPathString: G } = y;
|
|
332
|
+
return /* @__PURE__ */ A(
|
|
333
|
+
K,
|
|
334
|
+
{
|
|
335
|
+
path: G,
|
|
336
|
+
labelX: b,
|
|
337
|
+
labelY: C,
|
|
338
|
+
label: c,
|
|
339
|
+
labelStyle: g,
|
|
340
|
+
labelShowBg: m,
|
|
341
|
+
labelBgStyle: E,
|
|
342
|
+
labelBgPadding: S,
|
|
343
|
+
labelBgBorderRadius: M,
|
|
344
|
+
style: a,
|
|
345
|
+
markerStart: d,
|
|
346
|
+
markerEnd: w,
|
|
347
|
+
interactionWidth: f
|
|
348
|
+
}
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
const mt = {
|
|
352
|
+
drawEdge: z,
|
|
353
|
+
generatePath: F,
|
|
354
|
+
fallback: _
|
|
355
|
+
};
|
|
356
|
+
function Mt(t) {
|
|
357
|
+
const e = X();
|
|
358
|
+
return /* @__PURE__ */ A(
|
|
359
|
+
I,
|
|
360
|
+
{
|
|
361
|
+
...t,
|
|
362
|
+
options: mt,
|
|
363
|
+
nodes: e
|
|
364
|
+
}
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
const St = {
|
|
368
|
+
drawEdge: T,
|
|
369
|
+
generatePath: F,
|
|
370
|
+
fallback: O
|
|
371
|
+
};
|
|
372
|
+
function Nt(t) {
|
|
373
|
+
const e = X();
|
|
374
|
+
return /* @__PURE__ */ A(
|
|
375
|
+
I,
|
|
376
|
+
{
|
|
377
|
+
...t,
|
|
378
|
+
options: St,
|
|
379
|
+
nodes: e
|
|
380
|
+
}
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
const pt = {
|
|
384
|
+
drawEdge: T,
|
|
385
|
+
generatePath: gt,
|
|
386
|
+
fallback: V
|
|
387
|
+
};
|
|
388
|
+
function kt(t) {
|
|
389
|
+
const e = X();
|
|
390
|
+
return /* @__PURE__ */ A(
|
|
391
|
+
I,
|
|
392
|
+
{
|
|
393
|
+
...t,
|
|
394
|
+
options: pt,
|
|
395
|
+
nodes: e
|
|
396
|
+
}
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
export {
|
|
400
|
+
Mt as SmartBezierEdge,
|
|
401
|
+
kt as SmartStepEdge,
|
|
402
|
+
Nt as SmartStraightEdge,
|
|
403
|
+
ut as getSmartEdge,
|
|
404
|
+
F as pathfindingAStarDiagonal,
|
|
405
|
+
gt as pathfindingAStarNoDiagonal,
|
|
406
|
+
z as svgDrawSmoothLinePath,
|
|
407
|
+
T as svgDrawStraightLinePath
|
|
408
|
+
};
|
|
409
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/pathfinding/grid.ts","../src/functions/guaranteeWalkablePath.ts","../src/functions/pointConversion.ts","../src/functions/utils.ts","../src/functions/createGrid.ts","../src/functions/drawSvgPath.ts","../src/pathfinding/aStar.ts","../src/functions/generatePath.ts","../src/functions/getBoundingBoxes.ts","../src/getSmartEdge/index.ts","../src/internal/useSmartEdgeDebug.ts","../src/SmartEdge/index.tsx","../src/SmartBezierEdge/index.tsx","../src/SmartStraightEdge/index.tsx","../src/SmartStepEdge/index.tsx"],"sourcesContent":["// Based on https://github.com/qiao/PathFinding.js\nimport type { DiagonalMovement } from \"./types.ts\";\n\n// A modern, typed, functional replacement for PathFinding.js Grid\n// Provides the same runtime API shape used by finders/utilities:\n// - width, height, nodes[][]\n// - getNodeAt, isWalkableAt, setWalkableAt, getNeighbors, clone\n\nexport interface GridNode {\n x: number;\n y: number;\n walkable: boolean;\n // A* search metadata (set during pathfinding)\n costFromStart?: number;\n heuristicCostToGoal?: number;\n estimatedTotalCost?: number;\n opened?: boolean;\n closed?: boolean;\n parent?: GridNode;\n}\n\nexport interface Grid {\n width: number;\n height: number;\n nodes: GridNode[][]; // nodes[row][col] i.e., nodes[y][x]\n\n getNodeAt: (x: number, y: number) => GridNode;\n isWalkableAt: (x: number, y: number) => boolean;\n setWalkableAt: (x: number, y: number, walkable: boolean) => void;\n getNeighbors: (\n node: GridNode,\n diagonalMovement: DiagonalMovement,\n ) => GridNode[];\n isInside: (x: number, y: number) => boolean;\n clone: () => Grid;\n}\n\nconst createNodes = (\n width: number,\n height: number,\n matrix?: (number | boolean)[][],\n): GridNode[][] => {\n const rows: GridNode[][] = new Array<GridNode[]>(height);\n for (let y = 0; y < height; y++) {\n const row: GridNode[] = new Array<GridNode>(width);\n for (let x = 0; x < width; x++) {\n // PathFinding.js semantics: a truthy matrix cell means non-walkable\n // (e.g., 1 indicates obstacle). Falsy (0) means walkable.\n const cell = matrix ? matrix[y]?.[x] : undefined;\n const isBlocked = !!cell;\n const walkable = matrix ? !isBlocked : true;\n row[x] = { x, y, walkable };\n }\n rows[y] = row;\n }\n return rows;\n};\n\nconst withinBounds = (width: number, height: number, x: number, y: number) =>\n x >= 0 && x < width && y >= 0 && y < height;\n\n/**\n * Create a grid with the given width/height. Optionally accepts a matrix\n * of booleans/numbers indicating obstacles (truthy = blocked, falsy/0 = walkable).\n */\nexport const createGrid = (\n width: number,\n height: number,\n matrix?: (number | boolean)[][],\n): Grid => {\n const nodes = createNodes(width, height, matrix);\n\n const getNodeAt = (x: number, y: number): GridNode => nodes[y][x];\n\n const isWalkableAt = (x: number, y: number): boolean =>\n withinBounds(width, height, x, y) && nodes[y][x].walkable;\n\n const setWalkableAt = (x: number, y: number, walkable: boolean): void => {\n if (!withinBounds(width, height, x, y)) return;\n nodes[y][x].walkable = walkable;\n };\n\n // Diagonal movement policy using string literal union values:\n // \"Always\", \"Never\", \"IfAtMostOneObstacle\", \"OnlyWhenNoObstacles\"\n const getNeighbors = (\n node: GridNode,\n diagonalMovement: import(\"./types.ts\").DiagonalMovement,\n ): GridNode[] => {\n const x = node.x;\n const y = node.y;\n const neighbors: GridNode[] = [];\n\n // ↑, →, ↓, ←\n const s0 = isWalkableAt(x, y - 1);\n const s1 = isWalkableAt(x + 1, y);\n const s2 = isWalkableAt(x, y + 1);\n const s3 = isWalkableAt(x - 1, y);\n\n if (s0) neighbors.push(getNodeAt(x, y - 1));\n if (s1) neighbors.push(getNodeAt(x + 1, y));\n if (s2) neighbors.push(getNodeAt(x, y + 1));\n if (s3) neighbors.push(getNodeAt(x - 1, y));\n\n // Diagonals: ↗, ↘, ↙, ↖\n const d0Walkable = isWalkableAt(x + 1, y - 1);\n const d1Walkable = isWalkableAt(x + 1, y + 1);\n const d2Walkable = isWalkableAt(x - 1, y + 1);\n const d3Walkable = isWalkableAt(x - 1, y - 1);\n\n if (diagonalMovement === \"Never\") {\n return neighbors;\n }\n\n // default: \"Always\"\n if (d0Walkable) neighbors.push(getNodeAt(x + 1, y - 1));\n if (d1Walkable) neighbors.push(getNodeAt(x + 1, y + 1));\n if (d2Walkable) neighbors.push(getNodeAt(x - 1, y + 1));\n if (d3Walkable) neighbors.push(getNodeAt(x - 1, y - 1));\n return neighbors;\n };\n\n const clone = (): Grid => {\n // Recreate the original matrix semantics: truthy = blocked\n const clonedMatrix: number[][] = nodes.map((row) =>\n row.map((node) => (node.walkable ? 0 : 1)),\n );\n return createGrid(width, height, clonedMatrix);\n };\n\n return {\n width,\n height,\n nodes,\n getNodeAt,\n isWalkableAt,\n setWalkableAt,\n getNeighbors,\n isInside: (x: number, y: number) => withinBounds(width, height, x, y),\n clone,\n };\n};\n","import type { Grid } from \"../pathfinding/grid\";\nimport type { Position, XYPosition } from \"@xyflow/react\";\n\ntype Direction = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport const getNextPointFromPosition = (\n point: XYPosition,\n position: Direction,\n): XYPosition => {\n switch (position) {\n case \"top\":\n return { x: point.x, y: point.y - 1 };\n case \"bottom\":\n return { x: point.x, y: point.y + 1 };\n case \"left\":\n return { x: point.x - 1, y: point.y };\n case \"right\":\n return { x: point.x + 1, y: point.y };\n }\n};\n\n/**\n * Guarantee that the path is walkable, even if the point is inside a non\n * walkable area, by adding a walkable path in the direction of the point's\n * Position.\n */\nexport const guaranteeWalkablePath = (\n grid: Grid,\n point: XYPosition,\n position: Position,\n) => {\n let node = grid.getNodeAt(point.x, point.y);\n while (!node.walkable) {\n grid.setWalkableAt(node.x, node.y, true);\n const next = getNextPointFromPosition(node, position);\n node = grid.getNodeAt(next.x, next.y);\n }\n};\n","import type { XYPosition } from \"@xyflow/react\";\n\n/**\n * Each bounding box is a collection of X/Y points in a graph, and we\n * need to convert them to \"occupied\" cells in a 2D grid representation.\n *\n * The top most position of the grid (grid[0][0]) needs to be equivalent\n * to the top most point in the graph (the graph.topLeft point).\n *\n * Since the top most point can have X/Y values different than zero,\n * and each cell in a grid represents a 10x10 pixel area in the grid (or a\n * gridRatio area), there's need to be a conversion between a point in a graph\n * to a point in the grid.\n *\n * We do this conversion by dividing a graph point X/Y values by the grid ratio,\n * and \"shifting\" their values up or down, depending on the values of the top\n * most point in the graph. The top most point in the graph will have the\n * smallest values for X and Y.\n *\n * We avoid setting nodes in the border of the grid (x=0 or y=0), so there's\n * always a \"walkable\" area around the grid.\n */\nexport const graphToGridPoint = (\n graphPoint: XYPosition,\n smallestX: number,\n smallestY: number,\n gridRatio: number,\n): XYPosition => {\n // Affine transform: translate by top-left, scale by grid size, then offset border (1 cell)\n const x = (graphPoint.x - smallestX) / gridRatio + 1;\n const y = (graphPoint.y - smallestY) / gridRatio + 1;\n return { x, y };\n};\n\n/**\n * Converts a grid point back to a graph point, using the reverse logic of\n * graphToGridPoint.\n */\nexport const gridToGraphPoint = (\n gridPoint: XYPosition,\n smallestX: number,\n smallestY: number,\n gridRatio: number,\n): XYPosition => {\n // Inverse affine transform: remove border, scale by grid size, then translate by top-left\n const x = (gridPoint.x - 1) * gridRatio + smallestX;\n const y = (gridPoint.y - 1) * gridRatio + smallestY;\n return { x, y };\n};\n","export const round = (x: number, multiple = 10) =>\n Math.round(x / multiple) * multiple;\n\nexport const roundDown = (x: number, multiple = 10) =>\n Math.floor(x / multiple) * multiple;\n\nexport const roundUp = (x: number, multiple = 10) =>\n Math.ceil(x / multiple) * multiple;\n\nexport const toInteger = (value: number, min = 0) => {\n let result = Math.max(Math.round(value), min);\n result = Number.isInteger(result) ? result : min;\n result = result >= min ? result : min;\n return result;\n};\n","import { createGrid as createLocalGrid } from \"../pathfinding/grid\";\nimport type { Grid } from \"../pathfinding/grid\";\nimport {\n guaranteeWalkablePath,\n getNextPointFromPosition,\n} from \"./guaranteeWalkablePath\";\nimport { graphToGridPoint } from \"./pointConversion\";\nimport { round, roundUp } from \"./utils\";\nimport type { NodeBoundingBox, GraphBoundingBox } from \"./getBoundingBoxes\";\nimport type { Position } from \"@xyflow/react\";\n\nexport interface PointInfo {\n x: number;\n y: number;\n position: Position;\n}\n\nexport const createGrid = (\n graph: GraphBoundingBox,\n nodes: NodeBoundingBox[],\n source: PointInfo,\n target: PointInfo,\n gridRatio = 2,\n) => {\n const { xMin, yMin, width, height } = graph;\n\n // Create a grid representation of the graph box, where each cell is\n // equivalent to 10x10 pixels (or the grid ratio) on the graph. We'll use\n // this simplified grid to do pathfinding.\n const mapColumns = roundUp(width, gridRatio) / gridRatio + 1;\n const mapRows = roundUp(height, gridRatio) / gridRatio + 1;\n const grid: Grid = createLocalGrid(mapColumns, mapRows);\n\n // Update the grid representation with the space the nodes take up\n nodes.forEach((node) => {\n const nodeStart = graphToGridPoint(node.topLeft, xMin, yMin, gridRatio);\n const nodeEnd = graphToGridPoint(node.bottomRight, xMin, yMin, gridRatio);\n\n for (let x = nodeStart.x; x < nodeEnd.x; x++) {\n for (let y = nodeStart.y; y < nodeEnd.y; y++) {\n grid.setWalkableAt(x, y, false);\n }\n }\n });\n\n // Convert the starting and ending graph points to grid points\n const startGrid = graphToGridPoint(\n {\n x: round(source.x, gridRatio),\n y: round(source.y, gridRatio),\n },\n xMin,\n yMin,\n gridRatio,\n );\n\n const endGrid = graphToGridPoint(\n {\n x: round(target.x, gridRatio),\n y: round(target.y, gridRatio),\n },\n xMin,\n yMin,\n gridRatio,\n );\n\n // Guarantee a walkable path between the start and end points, even if the\n // source or target where covered by another node or by padding\n const startingNode = grid.getNodeAt(startGrid.x, startGrid.y);\n guaranteeWalkablePath(grid, startingNode, source.position);\n\n const endingNode = grid.getNodeAt(endGrid.x, endGrid.y);\n guaranteeWalkablePath(grid, endingNode, target.position);\n\n // Use the next closest points as the start and end points, so\n // pathfinding does not start too close to the nodes\n const start = getNextPointFromPosition(startingNode, source.position);\n const end = getNextPointFromPosition(endingNode, target.position);\n\n return { grid, start, end };\n};\n","import type { XYPosition } from \"@xyflow/react\";\n\n/**\n * Takes source and target {x, y} points, together with an array of number\n * tuples [x, y] representing the points along the path, and returns a string\n * to be used as the SVG path.\n */\nexport type SVGDrawFunction = (\n source: XYPosition,\n target: XYPosition,\n path: number[][],\n) => string;\n\n/**\n * Draws a SVG path from a list of points, using straight lines.\n */\nexport const svgDrawStraightLinePath: SVGDrawFunction = (\n source,\n target,\n path,\n) => {\n let svgPathString = `M ${String(source.x)}, ${String(source.y)} `;\n\n path.forEach((point) => {\n const [x, y] = point;\n svgPathString += `L ${String(x)}, ${String(y)} `;\n });\n\n svgPathString += `L ${String(target.x)}, ${String(target.y)} `;\n\n return svgPathString;\n};\n\n/**\n * Draws a SVG path from a list of points, using rounded lines.\n */\nexport const svgDrawSmoothLinePath: SVGDrawFunction = (\n source,\n target,\n path,\n) => {\n const points = [[source.x, source.y], ...path, [target.x, target.y]];\n return quadraticBezierCurve(points);\n};\n\nconst quadraticBezierCurve = (points: number[][]) => {\n const X = 0;\n const Y = 1;\n let point = points[0];\n\n const first = points[0];\n let svgPath = `M${String(first[X])},${String(first[Y])}M`;\n\n for (const next of points) {\n const midPoint = getMidPoint(point[X], point[Y], next[X], next[Y]);\n\n svgPath += ` ${String(midPoint[X])},${String(midPoint[Y])}`;\n svgPath += `Q${String(next[X])},${String(next[Y])}`;\n point = next;\n }\n\n const last = points[points.length - 1];\n svgPath += ` ${String(last[0])},${String(last[1])}`;\n\n return svgPath;\n};\n\nconst getMidPoint = (Ax: number, Ay: number, Bx: number, By: number) => {\n const Zx = (Ax - Bx) / 2 + Bx;\n const Zy = (Ay - By) / 2 + By;\n return [Zx, Zy];\n};\n","// Based on https://github.com/qiao/PathFinding.js\n\nimport type { Grid, GridNode } from \"./grid\";\nimport type { DiagonalMovement } from \"./types.ts\";\n\nexport interface AStarOptions {\n diagonalMovement?: DiagonalMovement;\n heuristic?: (dx: number, dy: number) => number;\n weight?: number;\n}\n\nconst manhattan = (dx: number, dy: number): number => dx + dy;\n\nconst octile = (dx: number, dy: number): number => {\n const F = Math.SQRT2 - 1;\n return dx < dy ? F * dx + dy : F * dy + dx;\n};\n\nconst reconstructPath = (endNode: GridNode): number[][] => {\n const path: number[][] = [];\n let node: GridNode | undefined = endNode;\n\n while (node) {\n path.push([node.x, node.y]);\n node = node.parent;\n }\n\n return path.reverse();\n};\n\nconst getHeuristic = (\n diagonalMovement: DiagonalMovement,\n): ((dx: number, dy: number) => number) => {\n if (diagonalMovement === \"Never\") return manhattan;\n return octile;\n};\n\nconst selectNodeWithLowestEstimatedTotalCost = (\n openList: GridNode[],\n): GridNode => {\n let bestIdx = 0;\n\n for (let i = 1; i < openList.length; i++) {\n if (\n (openList[i].estimatedTotalCost ?? Infinity) <\n (openList[bestIdx].estimatedTotalCost ?? Infinity)\n ) {\n bestIdx = i;\n }\n }\n\n return openList.splice(bestIdx, 1)[0];\n};\n\nconst processNeighbor = (\n neighbor: GridNode,\n current: GridNode,\n end: GridNode,\n openList: GridNode[],\n heuristic: (dx: number, dy: number) => number,\n weight: number,\n): void => {\n if (neighbor.closed) return;\n\n const dx = Math.abs(neighbor.x - current.x);\n const dy = Math.abs(neighbor.y - current.y);\n\n const tentativeG =\n (current.costFromStart ?? 0) + (dx === 0 || dy === 0 ? 1 : Math.SQRT2);\n\n if (!neighbor.opened || tentativeG < (neighbor.costFromStart ?? Infinity)) {\n neighbor.costFromStart = tentativeG;\n\n neighbor.heuristicCostToGoal =\n neighbor.heuristicCostToGoal ??\n weight *\n heuristic(Math.abs(neighbor.x - end.x), Math.abs(neighbor.y - end.y));\n\n neighbor.estimatedTotalCost =\n (neighbor.costFromStart ?? 0) + (neighbor.heuristicCostToGoal ?? 0);\n\n neighbor.parent = current;\n\n if (!neighbor.opened) {\n neighbor.opened = true;\n openList.push(neighbor);\n }\n }\n};\n\nexport const createAStarFinder = (opts: AStarOptions = {}) => {\n const diagonalMovement: DiagonalMovement = opts.diagonalMovement ?? \"Never\";\n const heuristic = opts.heuristic ?? getHeuristic(diagonalMovement);\n const weight = opts.weight ?? 1;\n\n const findPath = (\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n grid: Grid,\n ): number[][] => {\n const start = grid.getNodeAt(startX, startY);\n const end = grid.getNodeAt(endX, endY);\n\n // Open list implemented as a simple array with linear min search for clarity\n const openList: GridNode[] = [];\n\n start.costFromStart = 0;\n start.heuristicCostToGoal = 0;\n start.estimatedTotalCost = 0;\n start.opened = true;\n openList.push(start);\n\n while (openList.length > 0) {\n const node = selectNodeWithLowestEstimatedTotalCost(openList);\n node.closed = true;\n\n if (node === end) {\n return reconstructPath(end);\n }\n\n const neighbors = grid.getNeighbors(node, diagonalMovement);\n for (const neighbor of neighbors) {\n processNeighbor(neighbor, node, end, openList, heuristic, weight);\n }\n }\n\n // no path found\n return [];\n };\n\n return { findPath };\n};\n","import { createAStarFinder } from \"../pathfinding/aStar\";\nimport type { Grid } from \"../pathfinding/grid\";\nimport type { XYPosition } from \"@xyflow/react\";\n\n/**\n * Takes source and target {x, y} points, together with an grid representation\n * of the graph, and returns an array of number tuples [x, y], representing\n * the full path from source to target.\n */\nexport type PathFindingFunction = (\n grid: Grid,\n start: XYPosition,\n end: XYPosition,\n) => number[][];\n\nexport const pathfindingAStarDiagonal: PathFindingFunction = (\n grid,\n start,\n end,\n) => {\n try {\n const finder = createAStarFinder({\n diagonalMovement: \"Always\",\n });\n const fullPath = finder.findPath(start.x, start.y, end.x, end.y, grid);\n\n if (fullPath.length === 0) {\n throw new Error(\"No path found\");\n }\n return fullPath;\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`Unknown error: ${String(error)}`);\n }\n};\n\nexport const pathfindingAStarNoDiagonal: PathFindingFunction = (\n grid,\n start,\n end,\n) => {\n try {\n const finder = createAStarFinder({\n diagonalMovement: \"Never\",\n });\n const fullPath = finder.findPath(start.x, start.y, end.x, end.y, grid);\n\n if (fullPath.length === 0) {\n throw new Error(\"No path found\");\n }\n return fullPath;\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`Unknown error: ${String(error)}`);\n }\n};\n","import { roundUp, roundDown } from \"./utils\";\nimport type { Node, XYPosition } from \"@xyflow/react\";\n\nexport interface NodeBoundingBox {\n id: string;\n width: number;\n height: number;\n topLeft: XYPosition;\n bottomLeft: XYPosition;\n topRight: XYPosition;\n bottomRight: XYPosition;\n}\n\nexport interface GraphBoundingBox {\n width: number;\n height: number;\n topLeft: XYPosition;\n bottomLeft: XYPosition;\n topRight: XYPosition;\n bottomRight: XYPosition;\n xMax: number;\n yMax: number;\n xMin: number;\n yMin: number;\n}\n\n/**\n * Get the bounding box of all nodes and the graph itself, as X/Y coordinates\n * of all corner points.\n */\nexport const getBoundingBoxes = (\n nodes: Node[],\n nodePadding = 2,\n roundTo = 2,\n) => {\n let xMax = Number.MIN_SAFE_INTEGER;\n let yMax = Number.MIN_SAFE_INTEGER;\n let xMin = Number.MAX_SAFE_INTEGER;\n let yMin = Number.MAX_SAFE_INTEGER;\n\n const nodeBoxes: NodeBoundingBox[] = nodes.map((node) => {\n const width = Math.max(node.measured?.width ?? 0, 1);\n const height = Math.max(node.measured?.height ?? 0, 1);\n\n const position: XYPosition = {\n x: node.position.x,\n y: node.position.y,\n };\n\n const topLeft: XYPosition = {\n x: position.x - nodePadding,\n y: position.y - nodePadding,\n };\n const bottomLeft: XYPosition = {\n x: position.x - nodePadding,\n y: position.y + height + nodePadding,\n };\n const topRight: XYPosition = {\n x: position.x + width + nodePadding,\n y: position.y - nodePadding,\n };\n const bottomRight: XYPosition = {\n x: position.x + width + nodePadding,\n y: position.y + height + nodePadding,\n };\n\n if (roundTo > 0) {\n topLeft.x = roundDown(topLeft.x, roundTo);\n topLeft.y = roundDown(topLeft.y, roundTo);\n bottomLeft.x = roundDown(bottomLeft.x, roundTo);\n bottomLeft.y = roundUp(bottomLeft.y, roundTo);\n topRight.x = roundUp(topRight.x, roundTo);\n topRight.y = roundDown(topRight.y, roundTo);\n bottomRight.x = roundUp(bottomRight.x, roundTo);\n bottomRight.y = roundUp(bottomRight.y, roundTo);\n }\n\n if (topLeft.y < yMin) yMin = topLeft.y;\n if (topLeft.x < xMin) xMin = topLeft.x;\n if (bottomRight.y > yMax) yMax = bottomRight.y;\n if (bottomRight.x > xMax) xMax = bottomRight.x;\n\n return {\n id: node.id,\n width,\n height,\n topLeft,\n bottomLeft,\n topRight,\n bottomRight,\n };\n });\n\n const graphPadding = nodePadding * 2;\n\n xMax = roundUp(xMax + graphPadding, roundTo);\n yMax = roundUp(yMax + graphPadding, roundTo);\n xMin = roundDown(xMin - graphPadding, roundTo);\n yMin = roundDown(yMin - graphPadding, roundTo);\n\n const topLeft: XYPosition = {\n x: xMin,\n y: yMin,\n };\n\n const bottomLeft: XYPosition = {\n x: xMin,\n y: yMax,\n };\n\n const topRight: XYPosition = {\n x: xMax,\n y: yMin,\n };\n\n const bottomRight: XYPosition = {\n x: xMax,\n y: yMax,\n };\n\n const width = Math.abs(topLeft.x - topRight.x);\n const height = Math.abs(topLeft.y - bottomLeft.y);\n\n const graphBox: GraphBoundingBox = {\n topLeft,\n bottomLeft,\n topRight,\n bottomRight,\n width,\n height,\n xMax,\n yMax,\n xMin,\n yMin,\n };\n\n return { nodeBoxes, graphBox };\n};\n","import {\n createGrid,\n getBoundingBoxes,\n gridToGraphPoint,\n pathfindingAStarDiagonal,\n svgDrawSmoothLinePath,\n toInteger,\n} from \"../functions\";\nimport type {\n PointInfo,\n PathFindingFunction,\n SVGDrawFunction,\n} from \"../functions\";\nimport type { Node, EdgeProps } from \"@xyflow/react\";\n\nexport type EdgeParams = Pick<\n EdgeProps,\n | \"sourceX\"\n | \"sourceY\"\n | \"targetX\"\n | \"targetY\"\n | \"sourcePosition\"\n | \"targetPosition\"\n>;\n\nexport interface GetSmartEdgeOptions {\n gridRatio?: number;\n nodePadding?: number;\n drawEdge?: SVGDrawFunction;\n generatePath?: PathFindingFunction;\n // Internal-only debug hook. Not intended for public consumption.\n debug?: {\n enabled?: boolean;\n setGraphBox?: (box: {\n x: number;\n y: number;\n width: number;\n height: number;\n }) => void;\n };\n}\n\nexport type GetSmartEdgeParams<\n NodeDataType extends Record<string, unknown> = Record<string, unknown>,\n> = EdgeParams & {\n options?: GetSmartEdgeOptions;\n nodes: Node<NodeDataType>[];\n};\n\nexport interface GetSmartEdgeReturn {\n svgPathString: string;\n edgeCenterX: number;\n edgeCenterY: number;\n}\n\nexport const getSmartEdge = <\n NodeDataType extends Record<string, unknown> = Record<string, unknown>,\n>({\n options = {},\n nodes = [],\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n}: GetSmartEdgeParams<NodeDataType>): GetSmartEdgeReturn | Error => {\n try {\n const {\n drawEdge = svgDrawSmoothLinePath,\n generatePath = pathfindingAStarDiagonal,\n } = options;\n\n let { gridRatio = 10, nodePadding = 10 } = options;\n gridRatio = toInteger(gridRatio);\n nodePadding = toInteger(nodePadding);\n\n // We use the node's information to generate bounding boxes for them\n // and the graph\n const { graphBox, nodeBoxes } = getBoundingBoxes(\n nodes,\n nodePadding,\n gridRatio,\n );\n\n // Internal: publish computed bounding box for debugging visualization\n if (options.debug?.enabled && options.debug.setGraphBox) {\n options.debug.setGraphBox({\n x: graphBox.topLeft.x,\n y: graphBox.topLeft.y,\n width: graphBox.width,\n height: graphBox.height,\n });\n }\n\n const source: PointInfo = {\n x: sourceX,\n y: sourceY,\n position: sourcePosition,\n };\n\n const target: PointInfo = {\n x: targetX,\n y: targetY,\n position: targetPosition,\n };\n\n // With this information, we can create a 2D grid representation of\n // our graph, that tells us where in the graph there is a \"free\" space or not\n const { grid, start, end } = createGrid(\n graphBox,\n nodeBoxes,\n source,\n target,\n gridRatio,\n );\n\n // We then can use the grid representation to do pathfinding\n const generatePathResult = generatePath(grid, start, end);\n\n const fullPath = generatePathResult;\n\n // Here we convert the grid path to a sequence of graph coordinates.\n const graphPath = fullPath.map((gridPoint) => {\n const [x, y] = gridPoint;\n const graphPoint = gridToGraphPoint(\n { x, y },\n graphBox.xMin,\n graphBox.yMin,\n gridRatio,\n );\n return [graphPoint.x, graphPoint.y];\n });\n\n // Finally, we can use the graph path to draw the edge\n const svgPathString = drawEdge(source, target, graphPath);\n\n // Compute the edge's middle point using the full path, so users can use\n // it to position their custom labels\n const index = Math.floor(fullPath.length / 2);\n const middlePoint = fullPath[index];\n const [middleX, middleY] = middlePoint;\n const { x: edgeCenterX, y: edgeCenterY } = gridToGraphPoint(\n { x: middleX, y: middleY },\n graphBox.xMin,\n graphBox.yMin,\n gridRatio,\n );\n\n return { svgPathString, edgeCenterX, edgeCenterY };\n } catch (error) {\n if (error instanceof Error) {\n return error;\n } else {\n return new Error(`Unknown error: ${String(error)}`);\n }\n }\n};\n\nexport type GetSmartEdgeFunction = typeof getSmartEdge;\n","import { createContext, useContext } from \"react\";\n\nexport type SmartEdgeGraphBox = {\n x: number;\n y: number;\n width: number;\n height: number;\n} | null;\n\nexport interface SmartEdgeDebugContextValue {\n enabled: boolean;\n graphBox: SmartEdgeGraphBox;\n setGraphBox: (next: SmartEdgeGraphBox) => void;\n}\n\nexport const SmartEdgeDebugContext = createContext<SmartEdgeDebugContextValue>({\n enabled: false,\n graphBox: null,\n setGraphBox: () => {\n // Do nothing\n },\n});\n\nexport const useSmartEdgeDebug = (): SmartEdgeDebugContextValue => {\n return useContext(SmartEdgeDebugContext);\n};\n","import { BezierEdge, BaseEdge } from \"@xyflow/react\";\nimport type { ComponentType } from \"react\";\nimport { getSmartEdge } from \"../getSmartEdge\";\nimport { useSmartEdgeDebug } from \"../internal/useSmartEdgeDebug\";\nimport type { GetSmartEdgeOptions } from \"../getSmartEdge\";\nimport type { EdgeProps, Node, Edge } from \"@xyflow/react\";\n\nexport type SmartEdgeOptions = GetSmartEdgeOptions & {\n fallback?: ComponentType<EdgeProps<Edge>>;\n};\n\nexport interface SmartEdgeProps<\n EdgeType extends Edge = Edge,\n NodeType extends Node = Node,\n> extends EdgeProps<EdgeType> {\n nodes: NodeType[];\n options: SmartEdgeOptions;\n}\n\nexport function SmartEdge<\n EdgeType extends Edge = Edge,\n NodeType extends Node = Node,\n>({\n nodes,\n options,\n ...edgeProps\n}: Readonly<SmartEdgeProps<EdgeType, NodeType>>) {\n const { enabled: isDebugEnabled, setGraphBox } = useSmartEdgeDebug();\n const {\n sourceX,\n sourceY,\n sourcePosition,\n targetX,\n targetY,\n targetPosition,\n style,\n label,\n labelStyle,\n labelShowBg,\n labelBgStyle,\n labelBgPadding,\n labelBgBorderRadius,\n markerEnd,\n markerStart,\n interactionWidth,\n } = edgeProps;\n\n const smartResponse = getSmartEdge({\n sourcePosition,\n targetPosition,\n sourceX,\n sourceY,\n targetX,\n targetY,\n options: {\n ...options,\n debug: { enabled: isDebugEnabled, setGraphBox },\n } as GetSmartEdgeOptions,\n nodes,\n });\n\n const FallbackEdge = options.fallback ?? BezierEdge;\n\n if (smartResponse instanceof Error) {\n if (isDebugEnabled) {\n console.error(smartResponse);\n }\n return <FallbackEdge {...edgeProps} />;\n }\n\n const { edgeCenterX, edgeCenterY, svgPathString } = smartResponse;\n\n return (\n <BaseEdge\n path={svgPathString}\n labelX={edgeCenterX}\n labelY={edgeCenterY}\n label={label}\n labelStyle={labelStyle}\n labelShowBg={labelShowBg}\n labelBgStyle={labelBgStyle}\n labelBgPadding={labelBgPadding}\n labelBgBorderRadius={labelBgBorderRadius}\n style={style}\n markerStart={markerStart}\n markerEnd={markerEnd}\n interactionWidth={interactionWidth}\n />\n );\n}\n\nexport type SmartEdgeFunction = typeof SmartEdge;\n","import { useNodes, BezierEdge } from \"@xyflow/react\";\nimport { SmartEdge } from \"../SmartEdge\";\nimport { svgDrawSmoothLinePath, pathfindingAStarDiagonal } from \"../functions\";\nimport type { SmartEdgeOptions } from \"../SmartEdge\";\nimport type { EdgeProps, Edge, Node } from \"@xyflow/react\";\n\nconst BezierConfiguration: SmartEdgeOptions = {\n drawEdge: svgDrawSmoothLinePath,\n generatePath: pathfindingAStarDiagonal,\n fallback: BezierEdge,\n};\n\nexport function SmartBezierEdge<\n EdgeType extends Edge = Edge,\n NodeType extends Node = Node,\n>(props: EdgeProps<EdgeType>) {\n const nodes = useNodes<NodeType>();\n\n return (\n <SmartEdge<EdgeType, NodeType>\n {...props}\n options={BezierConfiguration}\n nodes={nodes}\n />\n );\n}\n","import { useNodes, StraightEdge } from \"@xyflow/react\";\nimport { SmartEdge } from \"../SmartEdge\";\nimport {\n svgDrawStraightLinePath,\n pathfindingAStarDiagonal,\n} from \"../functions\";\nimport type { SmartEdgeOptions } from \"../SmartEdge\";\nimport type { Edge, EdgeProps, Node } from \"@xyflow/react\";\n\nconst StraightConfiguration: SmartEdgeOptions = {\n drawEdge: svgDrawStraightLinePath,\n generatePath: pathfindingAStarDiagonal,\n fallback: StraightEdge,\n};\n\nexport function SmartStraightEdge<\n EdgeType extends Edge = Edge,\n NodeType extends Node = Node,\n>(props: EdgeProps<EdgeType>) {\n const nodes = useNodes<NodeType>();\n\n return (\n <SmartEdge<EdgeType, NodeType>\n {...props}\n options={StraightConfiguration}\n nodes={nodes}\n />\n );\n}\n","import { useNodes, StepEdge } from \"@xyflow/react\";\nimport { SmartEdge } from \"../SmartEdge\";\nimport {\n svgDrawStraightLinePath,\n pathfindingAStarNoDiagonal,\n} from \"../functions\";\nimport type { SmartEdgeOptions } from \"../SmartEdge\";\nimport type { Edge, EdgeProps, Node } from \"@xyflow/react\";\n\nconst StepConfiguration: SmartEdgeOptions = {\n drawEdge: svgDrawStraightLinePath,\n generatePath: pathfindingAStarNoDiagonal,\n fallback: StepEdge,\n};\n\nexport function SmartStepEdge<\n EdgeType extends Edge = Edge,\n NodeType extends Node = Node,\n>(props: EdgeProps<EdgeType>) {\n const nodes = useNodes<NodeType>();\n\n return (\n <SmartEdge<EdgeType, NodeType>\n {...props}\n options={StepConfiguration}\n nodes={nodes}\n />\n );\n}\n"],"names":["createNodes","width","height","matrix","rows","y","row","x","isBlocked","walkable","withinBounds","createGrid","nodes","getNodeAt","isWalkableAt","node","diagonalMovement","neighbors","s0","s1","s2","s3","d0Walkable","d1Walkable","d2Walkable","d3Walkable","clonedMatrix","getNextPointFromPosition","point","position","guaranteeWalkablePath","grid","next","graphToGridPoint","graphPoint","smallestX","smallestY","gridRatio","gridToGraphPoint","gridPoint","round","multiple","roundDown","roundUp","toInteger","value","min","result","graph","source","target","xMin","yMin","mapColumns","mapRows","createLocalGrid","nodeStart","nodeEnd","startGrid","endGrid","startingNode","endingNode","start","end","svgDrawStraightLinePath","path","svgPathString","svgDrawSmoothLinePath","points","quadraticBezierCurve","first","svgPath","midPoint","getMidPoint","last","Ax","Ay","Bx","By","Zx","Zy","manhattan","dx","dy","octile","F","reconstructPath","endNode","getHeuristic","selectNodeWithLowestEstimatedTotalCost","openList","bestIdx","i","processNeighbor","neighbor","current","heuristic","weight","tentativeG","createAStarFinder","opts","startX","startY","endX","endY","pathfindingAStarDiagonal","fullPath","error","pathfindingAStarNoDiagonal","getBoundingBoxes","nodePadding","roundTo","xMax","yMax","nodeBoxes","topLeft","bottomLeft","topRight","bottomRight","graphPadding","getSmartEdge","options","sourceX","sourceY","targetX","targetY","sourcePosition","targetPosition","drawEdge","generatePath","graphBox","graphPath","index","middlePoint","middleX","middleY","edgeCenterX","edgeCenterY","SmartEdgeDebugContext","createContext","useSmartEdgeDebug","useContext","SmartEdge","edgeProps","isDebugEnabled","setGraphBox","style","label","labelStyle","labelShowBg","labelBgStyle","labelBgPadding","labelBgBorderRadius","markerEnd","markerStart","interactionWidth","smartResponse","FallbackEdge","BezierEdge","jsx","BaseEdge","BezierConfiguration","SmartBezierEdge","props","useNodes","StraightConfiguration","StraightEdge","SmartStraightEdge","StepConfiguration","StepEdge","SmartStepEdge"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@joshrp/react-flow-smart-edge",
|
|
3
|
+
"version": "4.0.2",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Custom React Flow Edge that never intersects with other nodes",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"react",
|
|
8
|
+
"typescript",
|
|
9
|
+
"graph",
|
|
10
|
+
"flow",
|
|
11
|
+
"flowchart",
|
|
12
|
+
"smart",
|
|
13
|
+
"edge",
|
|
14
|
+
"pathfinding",
|
|
15
|
+
"react-flow-smart-edge"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://joshrp.github.io/react-flow-smart-edge/",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/joshrp/react-flow-smart-edge/issues"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/joshrp/react-flow-smart-edge.git"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"author": "Tiso Alvarez Puccinelli",
|
|
27
|
+
"type": "module",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.mjs",
|
|
32
|
+
"require": "./dist/index.cjs"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"main": "dist/index.cjs",
|
|
36
|
+
"module": "dist/index.mjs",
|
|
37
|
+
"types": "dist/index.d.ts",
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"src"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "npm run build-component && npm run build-storybook",
|
|
44
|
+
"build-component": "vite build",
|
|
45
|
+
"build-storybook": "storybook build",
|
|
46
|
+
"check": "npm run typecheck && npm run spellcheck && npm run eslint && npm run prettier",
|
|
47
|
+
"deploy-storybook": "npm run build-storybook && npm run gh-pages",
|
|
48
|
+
"dev": "vite",
|
|
49
|
+
"eslint": "eslint .",
|
|
50
|
+
"eslint-fix": "eslint . --fix",
|
|
51
|
+
"fix": "npm run eslint-fix && npm run prettier-write",
|
|
52
|
+
"gh-pages": "gh-pages -d storybook-static",
|
|
53
|
+
"install-chromium": "npx playwright install chromium --with-deps",
|
|
54
|
+
"prettier": "prettier --check .",
|
|
55
|
+
"prettier-write": "prettier --write .",
|
|
56
|
+
"preview": "vite preview",
|
|
57
|
+
"release": "dotenv release-it",
|
|
58
|
+
"spellcheck": "cspell lint --no-progress .",
|
|
59
|
+
"storybook": "storybook dev -p 6006",
|
|
60
|
+
"test": "npm run test-storybook",
|
|
61
|
+
"test-storybook": "vitest run --project=storybook",
|
|
62
|
+
"typecheck": "tsc --noEmit --project tsconfig.app.json"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@chromatic-com/storybook": "4.1.1",
|
|
66
|
+
"@eslint-react/eslint-plugin": "1.52.6",
|
|
67
|
+
"@eslint/js": "9.33.0",
|
|
68
|
+
"@storybook/addon-docs": "9.1.2",
|
|
69
|
+
"@storybook/addon-vitest": "9.1.2",
|
|
70
|
+
"@storybook/react-vite": "9.1.2",
|
|
71
|
+
"@storybook/testing-library": "0.2.2",
|
|
72
|
+
"@types/node": "24.3.0",
|
|
73
|
+
"@types/react": "19.1.10",
|
|
74
|
+
"@types/react-dom": "19.1.7",
|
|
75
|
+
"@vitejs/plugin-react-swc": "4.0.1",
|
|
76
|
+
"@vitest/browser": "3.2.4",
|
|
77
|
+
"@vitest/coverage-v8": "3.2.4",
|
|
78
|
+
"@xyflow/react": "12.8.4",
|
|
79
|
+
"cspell": "9.2.0",
|
|
80
|
+
"dotenv-cli": "10.0.0",
|
|
81
|
+
"eslint": "9.33.0",
|
|
82
|
+
"eslint-config-prettier": "10.1.8",
|
|
83
|
+
"eslint-plugin-prettier": "5.5.4",
|
|
84
|
+
"eslint-plugin-react-hooks": "5.2.0",
|
|
85
|
+
"eslint-plugin-react-refresh": "0.4.20",
|
|
86
|
+
"eslint-plugin-sonarjs": "3.0.4",
|
|
87
|
+
"eslint-plugin-storybook": "9.1.2",
|
|
88
|
+
"gh-pages": "6.3.0",
|
|
89
|
+
"globals": "16.3.0",
|
|
90
|
+
"playwright": "1.55.0",
|
|
91
|
+
"prettier": "3.6.2",
|
|
92
|
+
"react": "19.1.1",
|
|
93
|
+
"react-dom": "19.1.1",
|
|
94
|
+
"release-it": "19.0.4",
|
|
95
|
+
"storybook": "9.1.2",
|
|
96
|
+
"typescript": "5.9.2",
|
|
97
|
+
"typescript-eslint": "8.40.0",
|
|
98
|
+
"vite": "7.1.3",
|
|
99
|
+
"vite-plugin-dts": "4.5.4",
|
|
100
|
+
"vitest": "3.2.4"
|
|
101
|
+
},
|
|
102
|
+
"peerDependencies": {
|
|
103
|
+
"@xyflow/react": ">=12",
|
|
104
|
+
"react": ">=18",
|
|
105
|
+
"react-dom": ">=18",
|
|
106
|
+
"typescript": ">=5"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useNodes, BezierEdge } from "@xyflow/react";
|
|
2
|
+
import { SmartEdge } from "../SmartEdge";
|
|
3
|
+
import { svgDrawSmoothLinePath, pathfindingAStarDiagonal } from "../functions";
|
|
4
|
+
import type { SmartEdgeOptions } from "../SmartEdge";
|
|
5
|
+
import type { EdgeProps, Edge, Node } from "@xyflow/react";
|
|
6
|
+
|
|
7
|
+
const BezierConfiguration: SmartEdgeOptions = {
|
|
8
|
+
drawEdge: svgDrawSmoothLinePath,
|
|
9
|
+
generatePath: pathfindingAStarDiagonal,
|
|
10
|
+
fallback: BezierEdge,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function SmartBezierEdge<
|
|
14
|
+
EdgeType extends Edge = Edge,
|
|
15
|
+
NodeType extends Node = Node,
|
|
16
|
+
>(props: EdgeProps<EdgeType>) {
|
|
17
|
+
const nodes = useNodes<NodeType>();
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<SmartEdge<EdgeType, NodeType>
|
|
21
|
+
{...props}
|
|
22
|
+
options={BezierConfiguration}
|
|
23
|
+
nodes={nodes}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|