I am using msagljs/core directly, and specifically the SplineRouter class. My nodes are being positioned by a graph layout algorithm not in msagljs, but that has other features I need. This layout algorithm, being incremental, can result in layouts where some nodes overlap.
From what I can see, msagljs seems designed to handle these cases gracefully, (including values like OverlapDetected and ContinueOnOverlaps. However, the following test case fails:
test('overlap test', () => {
const g = GeomGraph.mk('graph', Rectangle.mkEmpty());
const as = g.graph.addNode(new Node('a'));
const a = new GeomNode(as);
a.boundaryCurve = CurveFactory.mkRectangleWithRoundedCorners(20, 20, 3, 3, new Point(0, 0))
const bs = g.graph.addNode(new Node('b'));
const b = new GeomNode(bs);
b.boundaryCurve = CurveFactory.mkRectangleWithRoundedCorners(40, 20, 3, 3, new Point(-10, 210))
const es = g.graph.addNode(new Node('e'));
const e = new GeomNode(es);
e.boundaryCurve = CurveFactory.mkRectangleWithRoundedCorners(60, 20, 3, 3, new Point(0, 50))
const fs = g.graph.addNode(new Node('f'));
const f = new GeomNode(fs);
f.boundaryCurve = CurveFactory.mkRectangleWithRoundedCorners(60, 20, 3, 3, new Point(20, 60))
g.setEdge('a', 'b');
const sr = SplineRouter.mk4(g, 2, 4, Math.PI / 6);
sr.run();
SvgDebugWriter.writeGeomGraph('./tmp/overlap_test.svg', g);
})
The two nodes that overlap are e and f. If I remove f I get:
If I add f and remove the edge ab, I get:
But if I add f and edge ab I get an exception thrown:
● overlap test
TypeError: Cannot read properties of undefined (reading 'Ports')
301 | SetLoosePolylinesForAnywherePorts() {
302 | for (const [shape, cpl] of this.shapesToTightLooseCouples) {
> 303 | for (const port of shape.Ports) {
| ^
304 | const isHport = port instanceof HookUpAnywhereFromInsidePort
305 |
306 | if (isHport) {
at SplineRouter.SetLoosePolylinesForAnywherePorts (modules/core/src/routing/splineRouter.ts:303:32)
at SplineRouter.RouteOnRoot (modules/core/src/routing/splineRouter.ts:268:10)
at SplineRouter.run (modules/core/src/routing/splineRouter.ts:212:10)
at Object.<anonymous> (modules/core/test/routing/splineRouter.spec.ts:735:8)
This is because an undefined key is being placed into the SplineRouter.shapesToTightLooseCouples map:
shapesToTightLooseCouples: Map<Shape, TightLooseCouple> = new Map<Shape, TightLooseCouple>()
It's quite problematic to ensure that none of my nodes overlap before calling the edge router, and I don't think throwing an exception here is intended behavior in any case.
I am using msagljs/core directly, and specifically the
SplineRouter
class. My nodes are being positioned by a graph layout algorithm not in msagljs, but that has other features I need. This layout algorithm, being incremental, can result in layouts where some nodes overlap.From what I can see, msagljs seems designed to handle these cases gracefully, (including values like
OverlapDetected
andContinueOnOverlaps
. However, the following test case fails:The two nodes that overlap are
e
andf
. If I removef
I get:If I add
f
and remove the edgeab
, I get:But if I add
f
and edgeab
I get an exception thrown:This is because an
undefined
key is being placed into theSplineRouter.shapesToTightLooseCouples
map:It's quite problematic to ensure that none of my nodes overlap before calling the edge router, and I don't think throwing an exception here is intended behavior in any case.