ngx-vflow 1.7.1 → 1.8.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/esm2022/lib/vflow/components/edge/edge.component.mjs +3 -3
- package/esm2022/lib/vflow/components/vflow/vflow.component.mjs +43 -20
- package/esm2022/lib/vflow/interfaces/intersecting-nodes-options.interface.mjs +2 -0
- package/esm2022/lib/vflow/interfaces/point.interface.mjs +1 -1
- package/esm2022/lib/vflow/services/node-changes.service.mjs +9 -5
- package/esm2022/lib/vflow/services/node-rendering.service.mjs +1 -6
- package/esm2022/lib/vflow/testing-utils/component-mocks/vflow-mock.component.mjs +19 -2
- package/esm2022/lib/vflow/utils/get-overlapping-area.mjs +6 -0
- package/esm2022/lib/vflow/utils/get-space-points.mjs +25 -0
- package/esm2022/lib/vflow/utils/identity-checker/reference-identity-checker.mjs +2 -5
- package/esm2022/lib/vflow/utils/nodes.mjs +25 -1
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/ngx-vflow.mjs +123 -35
- package/fesm2022/ngx-vflow.mjs.map +1 -1
- package/lib/vflow/components/vflow/vflow.component.d.ts +31 -5
- package/lib/vflow/interfaces/intersecting-nodes-options.interface.d.ts +3 -0
- package/lib/vflow/interfaces/point.interface.d.ts +3 -0
- package/lib/vflow/services/node-changes.service.d.ts +1 -5
- package/lib/vflow/testing-utils/component-mocks/vflow-mock.component.d.ts +10 -2
- package/lib/vflow/utils/get-overlapping-area.d.ts +2 -0
- package/lib/vflow/utils/get-space-points.d.ts +10 -0
- package/lib/vflow/utils/nodes.d.ts +3 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @todo handle regular nodes
|
|
3
|
+
*
|
|
4
|
+
* @param point global point in flow coordinates
|
|
5
|
+
* @param groups sorted array of groups
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export function getSpacePoints(point, groups) {
|
|
9
|
+
const result = [];
|
|
10
|
+
for (const group of groups) {
|
|
11
|
+
const { x, y } = group.globalPoint();
|
|
12
|
+
if (point.x >= x && point.x <= x + group.width() && point.y >= y && point.y <= y + group.height()) {
|
|
13
|
+
result.push({
|
|
14
|
+
x: point.x - x,
|
|
15
|
+
y: point.y - y,
|
|
16
|
+
spaceNodeId: group.rawNode.id,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
result.reverse();
|
|
21
|
+
// TODO: spread does not work, because the point is SVGPoint
|
|
22
|
+
result.push({ spaceNodeId: null, x: point.x, y: point.y });
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXNwYWNlLXBvaW50cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL2xpYi92Zmxvdy91dGlscy9nZXQtc3BhY2UtcG9pbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsS0FBWSxFQUFFLE1BQW1CO0lBQzlELE1BQU0sTUFBTSxHQUFpQixFQUFFLENBQUM7SUFFaEMsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUMzQixNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUVyQyxJQUFJLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUUsSUFBSSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUNsRyxNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUNWLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7Z0JBQ2QsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDZCxXQUFXLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO2FBQzlCLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBRWpCLDREQUE0RDtJQUM1RCxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFM0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNwYWNlUG9pbnQsIFBvaW50IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9wb2ludC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTm9kZU1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL25vZGUubW9kZWwnO1xuXG4vKipcbiAqIEB0b2RvIGhhbmRsZSByZWd1bGFyIG5vZGVzXG4gKlxuICogQHBhcmFtIHBvaW50IGdsb2JhbCBwb2ludCBpbiBmbG93IGNvb3JkaW5hdGVzXG4gKiBAcGFyYW0gZ3JvdXBzIHNvcnRlZCBhcnJheSBvZiBncm91cHNcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTcGFjZVBvaW50cyhwb2ludDogUG9pbnQsIGdyb3VwczogTm9kZU1vZGVsW10pOiBTcGFjZVBvaW50W10ge1xuICBjb25zdCByZXN1bHQ6IFNwYWNlUG9pbnRbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgZ3JvdXAgb2YgZ3JvdXBzKSB7XG4gICAgY29uc3QgeyB4LCB5IH0gPSBncm91cC5nbG9iYWxQb2ludCgpO1xuXG4gICAgaWYgKHBvaW50LnggPj0geCAmJiBwb2ludC54IDw9IHggKyBncm91cC53aWR0aCgpICYmIHBvaW50LnkgPj0geSAmJiBwb2ludC55IDw9IHkgKyBncm91cC5oZWlnaHQoKSkge1xuICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICB4OiBwb2ludC54IC0geCxcbiAgICAgICAgeTogcG9pbnQueSAtIHksXG4gICAgICAgIHNwYWNlTm9kZUlkOiBncm91cC5yYXdOb2RlLmlkLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmVzdWx0LnJldmVyc2UoKTtcblxuICAvLyBUT0RPOiBzcHJlYWQgZG9lcyBub3Qgd29yaywgYmVjYXVzZSB0aGUgcG9pbnQgaXMgU1ZHUG9pbnRcbiAgcmVzdWx0LnB1c2goeyBzcGFjZU5vZGVJZDogbnVsbCwgeDogcG9pbnQueCwgeTogcG9pbnQueSB9KTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuIl19
|
|
@@ -8,10 +8,7 @@ export class ReferenceIdentityChecker {
|
|
|
8
8
|
const oldNodesMap = new Map();
|
|
9
9
|
oldNodeModels.forEach((model) => oldNodesMap.set(model.rawNode, model));
|
|
10
10
|
return newNodes.map((newNode) => {
|
|
11
|
-
|
|
12
|
-
return oldNodesMap.get(newNode);
|
|
13
|
-
else
|
|
14
|
-
return new NodeModel(newNode);
|
|
11
|
+
return oldNodesMap.get(newNode) ?? new NodeModel(newNode);
|
|
15
12
|
});
|
|
16
13
|
}
|
|
17
14
|
/**
|
|
@@ -28,4 +25,4 @@ export class ReferenceIdentityChecker {
|
|
|
28
25
|
});
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmZXJlbmNlLWlkZW50aXR5LWNoZWNrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvdXRpbHMvaWRlbnRpdHktY2hlY2tlci9yZWZlcmVuY2UtaWRlbnRpdHktY2hlY2tlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBR3BELE1BQU0sT0FBTyx3QkFBd0I7SUFDbkM7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQWdDLEVBQUUsYUFBMEI7UUFDOUUsTUFBTSxXQUFXLEdBQXVDLElBQUksR0FBRyxFQUFFLENBQUM7UUFDbEUsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFeEUsT0FBTyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDOUIsT0FBTyxXQUFXLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFnQixFQUFFLGFBQTBCO1FBQzlELE1BQU0sV0FBVyxHQUF5QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3BELGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRXJFLE9BQU8sUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzlCLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7Z0JBQUUsT0FBTyxXQUFXLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBRSxDQUFDOztnQkFDMUQsT0FBTyxJQUFJLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5vZGVNb2RlbCB9IGZyb20gJy4uLy4uL21vZGVscy9ub2RlLm1vZGVsJztcbmltcG9ydCB7IER5bmFtaWNOb2RlLCBOb2RlIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ub2RlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBFZGdlTW9kZWwgfSBmcm9tICcuLi8uLi9tb2RlbHMvZWRnZS5tb2RlbCc7XG5pbXBvcnQgeyBFZGdlIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9lZGdlLmludGVyZmFjZSc7XG5cbmV4cG9ydCBjbGFzcyBSZWZlcmVuY2VJZGVudGl0eUNoZWNrZXIge1xuICAvKipcbiAgICogQ3JlYXRlIG5ldyBtb2RlbHMgZm9yIG5ldyBub2RlIHJlZmVyZW5jZXMgYW5kIGtlZXAgb2xkIG1vZGVscyBmb3Igb2xkIG5vZGUgcmVmZXJlbmNlc1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBub2RlcyhuZXdOb2RlczogTm9kZVtdIHwgRHluYW1pY05vZGVbXSwgb2xkTm9kZU1vZGVsczogTm9kZU1vZGVsW10pIHtcbiAgICBjb25zdCBvbGROb2Rlc01hcDogTWFwPE5vZGUgfCBEeW5hbWljTm9kZSwgTm9kZU1vZGVsPiA9IG5ldyBNYXAoKTtcbiAgICBvbGROb2RlTW9kZWxzLmZvckVhY2goKG1vZGVsKSA9PiBvbGROb2Rlc01hcC5zZXQobW9kZWwucmF3Tm9kZSwgbW9kZWwpKTtcblxuICAgIHJldHVybiBuZXdOb2Rlcy5tYXAoKG5ld05vZGUpID0+IHtcbiAgICAgIHJldHVybiBvbGROb2Rlc01hcC5nZXQobmV3Tm9kZSkgPz8gbmV3IE5vZGVNb2RlbChuZXdOb2RlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgbmV3IG1vZGVscyBmb3IgbmV3IGVkZ2UgcmVmZXJlbmNlcyBhbmQga2VlcCBvbGQgbW9kZWxzIGZvciBvbGQgZWRnZSByZWZlcmVuY2VzXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGVkZ2VzKG5ld0VkZ2VzOiBFZGdlW10sIG9sZEVkZ2VNb2RlbHM6IEVkZ2VNb2RlbFtdKTogRWRnZU1vZGVsW10ge1xuICAgIGNvbnN0IG9sZEVkZ2VzTWFwOiBNYXA8RWRnZSwgRWRnZU1vZGVsPiA9IG5ldyBNYXAoKTtcbiAgICBvbGRFZGdlTW9kZWxzLmZvckVhY2goKG1vZGVsKSA9PiBvbGRFZGdlc01hcC5zZXQobW9kZWwuZWRnZSwgbW9kZWwpKTtcblxuICAgIHJldHVybiBuZXdFZGdlcy5tYXAoKG5ld0VkZ2UpID0+IHtcbiAgICAgIGlmIChvbGRFZGdlc01hcC5oYXMobmV3RWRnZSkpIHJldHVybiBvbGRFZGdlc01hcC5nZXQobmV3RWRnZSkhO1xuICAgICAgZWxzZSByZXR1cm4gbmV3IEVkZ2VNb2RlbChuZXdFZGdlKTtcbiAgICB9KTtcbiAgfVxufVxuIl19
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getOverlappingArea } from './get-overlapping-area';
|
|
1
2
|
export function getNodesBounds(nodes) {
|
|
2
3
|
if (nodes.length === 0) {
|
|
3
4
|
return { x: 0, y: 0, width: 0, height: 0 };
|
|
@@ -9,6 +10,21 @@ export function getNodesBounds(nodes) {
|
|
|
9
10
|
});
|
|
10
11
|
return boxToRect(box);
|
|
11
12
|
}
|
|
13
|
+
export function getIntesectingNodes(nodeId, nodes, options) {
|
|
14
|
+
const node = nodes.find((n) => n.rawNode.id === nodeId);
|
|
15
|
+
if (!node)
|
|
16
|
+
return [];
|
|
17
|
+
const nodeRect = nodeToRect(node);
|
|
18
|
+
return nodes.filter((currentNode) => {
|
|
19
|
+
if (currentNode.rawNode.id === nodeId)
|
|
20
|
+
return false;
|
|
21
|
+
const overlappingArea = getOverlappingArea(nodeToRect(currentNode), nodeRect);
|
|
22
|
+
if (options?.partially) {
|
|
23
|
+
return overlappingArea > 0;
|
|
24
|
+
}
|
|
25
|
+
return overlappingArea >= nodeRect.width * nodeRect.height;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
12
28
|
function nodeToBox(node) {
|
|
13
29
|
return {
|
|
14
30
|
x: node.point().x,
|
|
@@ -17,6 +33,14 @@ function nodeToBox(node) {
|
|
|
17
33
|
y2: node.point().y + node.size().height,
|
|
18
34
|
};
|
|
19
35
|
}
|
|
36
|
+
export function nodeToRect(node) {
|
|
37
|
+
return {
|
|
38
|
+
x: node.point().x,
|
|
39
|
+
y: node.point().y,
|
|
40
|
+
width: node.width(),
|
|
41
|
+
height: node.height(),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
20
44
|
function boxToRect({ x, y, x2, y2 }) {
|
|
21
45
|
return {
|
|
22
46
|
x,
|
|
@@ -33,4 +57,4 @@ function getBoundsOfBoxes(box1, box2) {
|
|
|
33
57
|
y2: Math.max(box1.y2, box2.y2),
|
|
34
58
|
};
|
|
35
59
|
}
|
|
36
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdmZsb3ctbGliL3NyYy9saWIvdmZsb3cvdXRpbHMvbm9kZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFNUQsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUFrQjtJQUMvQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdkIsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUM3QyxDQUFDO0lBRUQsSUFBSSxHQUFHLEdBQVEsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBRTFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtRQUNyQixNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsR0FBRyxHQUFHLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2QyxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLENBQUM7QUFFRCxNQUFNLFVBQVUsbUJBQW1CLENBQ2pDLE1BQWMsRUFDZCxLQUFrQixFQUNsQixPQUFrQztJQUVsQyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQztJQUN4RCxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sRUFBRSxDQUFDO0lBRXJCLE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsQyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtRQUNsQyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLE1BQU07WUFBRSxPQUFPLEtBQUssQ0FBQztRQUVwRCxNQUFNLGVBQWUsR0FBRyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFOUUsSUFBSSxPQUFPLEVBQUUsU0FBUyxFQUFFLENBQUM7WUFDdkIsT0FBTyxlQUFlLEdBQUcsQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFFRCxPQUFPLGVBQWUsSUFBSSxRQUFRLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7SUFDN0QsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsSUFBZTtJQUNoQyxPQUFPO1FBQ0wsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2pCLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNqQixFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSztRQUN0QyxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTTtLQUN4QyxDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSxVQUFVLENBQUMsSUFBZTtJQUN4QyxPQUFPO1FBQ0wsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2pCLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNqQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRTtRQUNuQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRTtLQUN0QixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFPO0lBQ3RDLE9BQU87UUFDTCxDQUFDO1FBQ0QsQ0FBQztRQUNELEtBQUssRUFBRSxFQUFFLEdBQUcsQ0FBQztRQUNiLE1BQU0sRUFBRSxFQUFFLEdBQUcsQ0FBQztLQUNmLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxJQUFTLEVBQUUsSUFBUztJQUM1QyxPQUFPO1FBQ0wsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzNCLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUMzQixFQUFFLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDOUIsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO0tBQy9CLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQm94IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ib3gnO1xuaW1wb3J0IHsgSW50ZXJzZWN0aW5nTm9kZXNPcHRpb25zIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9pbnRlcnNlY3Rpbmctbm9kZXMtb3B0aW9ucy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVjdCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVjdCc7XG5pbXBvcnQgeyBOb2RlTW9kZWwgfSBmcm9tICcuLi9tb2RlbHMvbm9kZS5tb2RlbCc7XG5pbXBvcnQgeyBnZXRPdmVybGFwcGluZ0FyZWEgfSBmcm9tICcuL2dldC1vdmVybGFwcGluZy1hcmVhJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5vZGVzQm91bmRzKG5vZGVzOiBOb2RlTW9kZWxbXSk6IFJlY3Qge1xuICBpZiAobm9kZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHsgeDogMCwgeTogMCwgd2lkdGg6IDAsIGhlaWdodDogMCB9O1xuICB9XG5cbiAgbGV0IGJveDogQm94ID0geyB4OiBJbmZpbml0eSwgeTogSW5maW5pdHksIHgyOiAtSW5maW5pdHksIHkyOiAtSW5maW5pdHkgfTtcblxuICBub2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgY29uc3Qgbm9kZUJveCA9IG5vZGVUb0JveChub2RlKTtcbiAgICBib3ggPSBnZXRCb3VuZHNPZkJveGVzKGJveCwgbm9kZUJveCk7XG4gIH0pO1xuXG4gIHJldHVybiBib3hUb1JlY3QoYm94KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEludGVzZWN0aW5nTm9kZXMoXG4gIG5vZGVJZDogc3RyaW5nLFxuICBub2RlczogTm9kZU1vZGVsW10sXG4gIG9wdGlvbnM/OiBJbnRlcnNlY3RpbmdOb2Rlc09wdGlvbnMsXG4pOiBOb2RlTW9kZWxbXSB7XG4gIGNvbnN0IG5vZGUgPSBub2Rlcy5maW5kKChuKSA9PiBuLnJhd05vZGUuaWQgPT09IG5vZGVJZCk7XG4gIGlmICghbm9kZSkgcmV0dXJuIFtdO1xuXG4gIGNvbnN0IG5vZGVSZWN0ID0gbm9kZVRvUmVjdChub2RlKTtcblxuICByZXR1cm4gbm9kZXMuZmlsdGVyKChjdXJyZW50Tm9kZSkgPT4ge1xuICAgIGlmIChjdXJyZW50Tm9kZS5yYXdOb2RlLmlkID09PSBub2RlSWQpIHJldHVybiBmYWxzZTtcblxuICAgIGNvbnN0IG92ZXJsYXBwaW5nQXJlYSA9IGdldE92ZXJsYXBwaW5nQXJlYShub2RlVG9SZWN0KGN1cnJlbnROb2RlKSwgbm9kZVJlY3QpO1xuXG4gICAgaWYgKG9wdGlvbnM/LnBhcnRpYWxseSkge1xuICAgICAgcmV0dXJuIG92ZXJsYXBwaW5nQXJlYSA+IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIG92ZXJsYXBwaW5nQXJlYSA+PSBub2RlUmVjdC53aWR0aCAqIG5vZGVSZWN0LmhlaWdodDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG5vZGVUb0JveChub2RlOiBOb2RlTW9kZWwpOiBCb3gge1xuICByZXR1cm4ge1xuICAgIHg6IG5vZGUucG9pbnQoKS54LFxuICAgIHk6IG5vZGUucG9pbnQoKS55LFxuICAgIHgyOiBub2RlLnBvaW50KCkueCArIG5vZGUuc2l6ZSgpLndpZHRoLFxuICAgIHkyOiBub2RlLnBvaW50KCkueSArIG5vZGUuc2l6ZSgpLmhlaWdodCxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5vZGVUb1JlY3Qobm9kZTogTm9kZU1vZGVsKTogUmVjdCB7XG4gIHJldHVybiB7XG4gICAgeDogbm9kZS5wb2ludCgpLngsXG4gICAgeTogbm9kZS5wb2ludCgpLnksXG4gICAgd2lkdGg6IG5vZGUud2lkdGgoKSxcbiAgICBoZWlnaHQ6IG5vZGUuaGVpZ2h0KCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGJveFRvUmVjdCh7IHgsIHksIHgyLCB5MiB9OiBCb3gpOiBSZWN0IHtcbiAgcmV0dXJuIHtcbiAgICB4LFxuICAgIHksXG4gICAgd2lkdGg6IHgyIC0geCxcbiAgICBoZWlnaHQ6IHkyIC0geSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRzT2ZCb3hlcyhib3gxOiBCb3gsIGJveDI6IEJveCk6IEJveCB7XG4gIHJldHVybiB7XG4gICAgeDogTWF0aC5taW4oYm94MS54LCBib3gyLngpLFxuICAgIHk6IE1hdGgubWluKGJveDEueSwgYm94Mi55KSxcbiAgICB4MjogTWF0aC5tYXgoYm94MS54MiwgYm94Mi54MiksXG4gICAgeTI6IE1hdGgubWF4KGJveDEueTIsIGJveDIueTIpLFxuICB9O1xufVxuIl19
|
package/esm2022/public-api.mjs
CHANGED
|
@@ -12,6 +12,7 @@ export * from './lib/vflow/interfaces/marker.interface';
|
|
|
12
12
|
export * from './lib/vflow/interfaces/component-node-event.interface';
|
|
13
13
|
export * from './lib/vflow/interfaces/fit-view-options.interface';
|
|
14
14
|
export * from './lib/vflow/interfaces/optimization.interface';
|
|
15
|
+
export * from './lib/vflow/interfaces/intersecting-nodes-options.interface';
|
|
15
16
|
// Types
|
|
16
17
|
export * from './lib/vflow/types/node-change.type';
|
|
17
18
|
export * from './lib/vflow/types/edge-change.type';
|
|
@@ -46,4 +47,4 @@ export * from './lib/vflow/testing-utils/directive-mocks/drag-handle-mock.direct
|
|
|
46
47
|
export * from './lib/vflow/testing-utils/directive-mocks/selectable-mock.directive';
|
|
47
48
|
export * from './lib/vflow/testing-utils/directive-mocks/template-mock.directive';
|
|
48
49
|
export * from './lib/vflow/testing-utils/vflow-mocks';
|
|
49
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25neC12Zmxvdy1saWIvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0JBQWtCO0FBQ2xCLGNBQWMsbUJBQW1CLENBQUM7QUFFbEMsYUFBYTtBQUNiLGNBQWMsdUNBQXVDLENBQUM7QUFDdEQsY0FBYyx3Q0FBd0MsQ0FBQztBQUN2RCxjQUFjLHVDQUF1QyxDQUFDO0FBQ3RELGNBQWMsNkNBQTZDLENBQUM7QUFDNUQsY0FBYyw2Q0FBNkMsQ0FBQztBQUM1RCxjQUFjLDZDQUE2QyxDQUFDO0FBQzVELGNBQWMsc0RBQXNELENBQUM7QUFDckUsY0FBYyx5Q0FBeUMsQ0FBQztBQUV4RCxjQUFjLHVEQUF1RCxDQUFDO0FBQ3RFLGNBQWMsbURBQW1ELENBQUM7QUFDbEUsY0FBYywrQ0FBK0MsQ0FBQztBQUM5RCxjQUFjLDZEQUE2RCxDQUFDO0FBRTVFLFFBQVE7QUFDUixjQUFjLG9DQUFvQyxDQUFDO0FBQ25ELGNBQWMsb0NBQW9DLENBQUM7QUFDbkQsY0FBYyxpQ0FBaUMsQ0FBQztBQUNoRCxjQUFjLG1DQUFtQyxDQUFDO0FBQ2xELGNBQWMsd0NBQXdDLENBQUM7QUFDdkQsY0FBYyx3Q0FBd0MsQ0FBQztBQUV2RCxhQUFhO0FBQ2IsY0FBYyw4Q0FBOEMsQ0FBQztBQUM3RCxjQUFjLHVEQUF1RCxDQUFDO0FBQ3RFLGNBQWMsaUVBQWlFLENBQUM7QUFDaEYsY0FBYyxpRkFBaUYsQ0FBQztBQUNoRyxjQUFjLDZEQUE2RCxDQUFDO0FBQzVFLGNBQWMseURBQXlELENBQUM7QUFDeEUsY0FBYyxtRUFBbUUsQ0FBQztBQUNsRixjQUFjLG1GQUFtRixDQUFDO0FBRWxHLGFBQWE7QUFDYixjQUFjLDJDQUEyQyxDQUFDO0FBQzFELGNBQWMsd0RBQXdELENBQUM7QUFDdkUsY0FBYyxxREFBcUQsQ0FBQztBQUNwRSxjQUFjLDZDQUE2QyxDQUFDO0FBQzVELGNBQWMsOENBQThDLENBQUM7QUFFN0QsVUFBVTtBQUNWLGNBQWMscURBQXFELENBQUM7QUFDcEUsY0FBYyxnRUFBZ0UsQ0FBQztBQUMvRSxjQUFjLGlFQUFpRSxDQUFDO0FBQ2hGLGNBQWMsb0VBQW9FLENBQUM7QUFDbkYsY0FBYyxrRUFBa0UsQ0FBQztBQUNqRixjQUFjLHVFQUF1RSxDQUFDO0FBQ3RGLGNBQWMsZ0ZBQWdGLENBQUM7QUFDL0YsY0FBYyxzRUFBc0UsQ0FBQztBQUNyRixjQUFjLHFFQUFxRSxDQUFDO0FBQ3BGLGNBQWMsbUVBQW1FLENBQUM7QUFDbEYsY0FBYyx1Q0FBdUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFN0YW5kYWxvbmUgVXRpbFxuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvdmZsb3cnO1xuXG4vLyBJbnRlcmZhY2VzXG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy9pbnRlcmZhY2VzL25vZGUuaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2ludGVyZmFjZXMvcG9pbnQuaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2ludGVyZmFjZXMvZWRnZS5pbnRlcmZhY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvaW50ZXJmYWNlcy9lZGdlLWxhYmVsLmludGVyZmFjZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy9pbnRlcmZhY2VzL2Nvbm5lY3Rpb24uaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2ludGVyZmFjZXMvY29ubmVjdGlvbi5pbnRlcmZhY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvaW50ZXJmYWNlcy9jb25uZWN0aW9uLXNldHRpbmdzLmludGVyZmFjZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy9pbnRlcmZhY2VzL21hcmtlci5pbnRlcmZhY2UnO1xuZXhwb3J0IHsgVmlld3BvcnRTdGF0ZSB9IGZyb20gJy4vbGliL3ZmbG93L2ludGVyZmFjZXMvdmlld3BvcnQuaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2ludGVyZmFjZXMvY29tcG9uZW50LW5vZGUtZXZlbnQuaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2ludGVyZmFjZXMvZml0LXZpZXctb3B0aW9ucy5pbnRlcmZhY2UnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvaW50ZXJmYWNlcy9vcHRpbWl6YXRpb24uaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2ludGVyZmFjZXMvaW50ZXJzZWN0aW5nLW5vZGVzLW9wdGlvbnMuaW50ZXJmYWNlJztcblxuLy8gVHlwZXNcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3R5cGVzL25vZGUtY2hhbmdlLnR5cGUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvdHlwZXMvZWRnZS1jaGFuZ2UudHlwZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy90eXBlcy9wb3NpdGlvbi50eXBlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3R5cGVzL2JhY2tncm91bmQudHlwZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy90eXBlcy9jb25uZWN0aW9uLW1vZGUudHlwZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy90eXBlcy9rZXlib2FyZC1hY3Rpb24udHlwZSc7XG5cbi8vIENvbXBvbmVudHNcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2NvbXBvbmVudHMvdmZsb3cvdmZsb3cuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3B1YmxpYy1jb21wb25lbnRzL2hhbmRsZS9oYW5kbGUuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3B1YmxpYy1jb21wb25lbnRzL2N1c3RvbS1ub2RlL2N1c3RvbS1ub2RlLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy9wdWJsaWMtY29tcG9uZW50cy9jdXN0b20tZHluYW1pYy1ub2RlL2N1c3RvbS1keW5hbWljLW5vZGUuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3B1YmxpYy1jb21wb25lbnRzL3Jlc2l6YWJsZS9yZXNpemFibGUuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3B1YmxpYy1jb21wb25lbnRzL21pbmltYXAvbWluaW1hcC5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvcHVibGljLWNvbXBvbmVudHMvbm9kZS10b29sYmFyL25vZGUtdG9vbGJhci5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvcHVibGljLWNvbXBvbmVudHMvY3VzdG9tLXRlbXBsYXRlLWVkZ2UvY3VzdG9tLXRlbXBsYXRlLWVkZ2UuY29tcG9uZW50JztcblxuLy8gRGlyZWN0aXZlc1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvZGlyZWN0aXZlcy90ZW1wbGF0ZS5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvZGlyZWN0aXZlcy9jb25uZWN0aW9uLWNvbnRyb2xsZXIuZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2RpcmVjdGl2ZXMvY2hhbmdlcy1jb250cm9sbGVyLmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy9kaXJlY3RpdmVzL3NlbGVjdGFibGUuZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L2RpcmVjdGl2ZXMvZHJhZy1oYW5kbGUuZGlyZWN0aXZlJztcblxuLy8gVGVzdGluZ1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvdGVzdGluZy11dGlscy9wcm92aWRlLWN1c3RvbS1ub2RlLW1vY2tzJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3Rlc3RpbmctdXRpbHMvY29tcG9uZW50LW1vY2tzL3ZmbG93LW1vY2suY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3Rlc3RpbmctdXRpbHMvY29tcG9uZW50LW1vY2tzL2hhbmRsZS1tb2NrLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy90ZXN0aW5nLXV0aWxzL2NvbXBvbmVudC1tb2Nrcy9yZXNpemFibGUtbW9jay5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvdGVzdGluZy11dGlscy9jb21wb25lbnQtbW9ja3MvbWluaW1hcC1tb2NrLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi92Zmxvdy90ZXN0aW5nLXV0aWxzL2NvbXBvbmVudC1tb2Nrcy9ub2RlLXRvb2xiYXItbW9jay5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvdGVzdGluZy11dGlscy9kaXJlY3RpdmUtbW9ja3MvY29ubmVjdGlvbi1jb250cm9sbGVyLW1vY2suZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3Rlc3RpbmctdXRpbHMvZGlyZWN0aXZlLW1vY2tzL2RyYWctaGFuZGxlLW1vY2suZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3ZmbG93L3Rlc3RpbmctdXRpbHMvZGlyZWN0aXZlLW1vY2tzL3NlbGVjdGFibGUtbW9jay5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvdGVzdGluZy11dGlscy9kaXJlY3RpdmUtbW9ja3MvdGVtcGxhdGUtbW9jay5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvdmZsb3cvdGVzdGluZy11dGlscy92Zmxvdy1tb2Nrcyc7XG4iXX0=
|
package/fesm2022/ngx-vflow.mjs
CHANGED
|
@@ -8,6 +8,12 @@ import { drag } from 'd3-drag';
|
|
|
8
8
|
import { __decorate } from 'tslib';
|
|
9
9
|
import { NgTemplateOutlet, NgComponentOutlet, KeyValuePipe } from '@angular/common';
|
|
10
10
|
|
|
11
|
+
const getOverlappingArea = (rectA, rectB) => {
|
|
12
|
+
const xOverlap = Math.max(0, Math.min(rectA.x + rectA.width, rectB.x + rectB.width) - Math.max(rectA.x, rectB.x));
|
|
13
|
+
const yOverlap = Math.max(0, Math.min(rectA.y + rectA.height, rectB.y + rectB.height) - Math.max(rectA.y, rectB.y));
|
|
14
|
+
return Math.ceil(xOverlap * yOverlap);
|
|
15
|
+
};
|
|
16
|
+
|
|
11
17
|
function getNodesBounds(nodes) {
|
|
12
18
|
if (nodes.length === 0) {
|
|
13
19
|
return { x: 0, y: 0, width: 0, height: 0 };
|
|
@@ -19,6 +25,21 @@ function getNodesBounds(nodes) {
|
|
|
19
25
|
});
|
|
20
26
|
return boxToRect(box);
|
|
21
27
|
}
|
|
28
|
+
function getIntesectingNodes(nodeId, nodes, options) {
|
|
29
|
+
const node = nodes.find((n) => n.rawNode.id === nodeId);
|
|
30
|
+
if (!node)
|
|
31
|
+
return [];
|
|
32
|
+
const nodeRect = nodeToRect(node);
|
|
33
|
+
return nodes.filter((currentNode) => {
|
|
34
|
+
if (currentNode.rawNode.id === nodeId)
|
|
35
|
+
return false;
|
|
36
|
+
const overlappingArea = getOverlappingArea(nodeToRect(currentNode), nodeRect);
|
|
37
|
+
if (options?.partially) {
|
|
38
|
+
return overlappingArea > 0;
|
|
39
|
+
}
|
|
40
|
+
return overlappingArea >= nodeRect.width * nodeRect.height;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
22
43
|
function nodeToBox(node) {
|
|
23
44
|
return {
|
|
24
45
|
x: node.point().x,
|
|
@@ -27,6 +48,14 @@ function nodeToBox(node) {
|
|
|
27
48
|
y2: node.point().y + node.size().height,
|
|
28
49
|
};
|
|
29
50
|
}
|
|
51
|
+
function nodeToRect(node) {
|
|
52
|
+
return {
|
|
53
|
+
x: node.point().x,
|
|
54
|
+
y: node.point().y,
|
|
55
|
+
width: node.width(),
|
|
56
|
+
height: node.height(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
30
59
|
function boxToRect({ x, y, x2, y2 }) {
|
|
31
60
|
return {
|
|
32
61
|
x,
|
|
@@ -1440,10 +1469,7 @@ class ReferenceIdentityChecker {
|
|
|
1440
1469
|
const oldNodesMap = new Map();
|
|
1441
1470
|
oldNodeModels.forEach((model) => oldNodesMap.set(model.rawNode, model));
|
|
1442
1471
|
return newNodes.map((newNode) => {
|
|
1443
|
-
|
|
1444
|
-
return oldNodesMap.get(newNode);
|
|
1445
|
-
else
|
|
1446
|
-
return new NodeModel(newNode);
|
|
1472
|
+
return oldNodesMap.get(newNode) ?? new NodeModel(newNode);
|
|
1447
1473
|
});
|
|
1448
1474
|
}
|
|
1449
1475
|
/**
|
|
@@ -1472,10 +1498,14 @@ class NodesChangeService {
|
|
|
1472
1498
|
switchMap((nodes) => merge(...nodes.map((node) => node.point$.pipe(
|
|
1473
1499
|
// skip initial position from signal
|
|
1474
1500
|
skip(1), map(() => node))))), map((changedNode) => {
|
|
1475
|
-
return
|
|
1476
|
-
.
|
|
1477
|
-
|
|
1478
|
-
.
|
|
1501
|
+
return [
|
|
1502
|
+
{ type: 'position', id: changedNode.rawNode.id, point: changedNode.point() },
|
|
1503
|
+
// TODO: emits even if node is not change position
|
|
1504
|
+
...this.entitiesService
|
|
1505
|
+
.nodes()
|
|
1506
|
+
.filter((node) => node !== changedNode && node.selected())
|
|
1507
|
+
.map((node) => ({ type: 'position', id: node.rawNode.id, point: node.point() })),
|
|
1508
|
+
];
|
|
1479
1509
|
}));
|
|
1480
1510
|
this.nodeSizeChange$ = toObservable(this.entitiesService.nodes).pipe(switchMap((nodes) => merge(...nodes.map((node) => node.size$.pipe(skip(1), map(() => node))))), map((changedNode) => [{ type: 'size', id: changedNode.rawNode.id, size: changedNode.size() }]));
|
|
1481
1511
|
this.nodeAddChange$ = toObservable(this.entitiesService.nodes).pipe(pairwise(), map(([oldList, newList]) => newList.filter((node) => !oldList.includes(node))), filter((nodes) => !!nodes.length), map((nodes) => nodes.map((node) => ({ type: 'add', id: node.rawNode.id }))));
|
|
@@ -1711,11 +1741,6 @@ class NodeRenderingService {
|
|
|
1711
1741
|
});
|
|
1712
1742
|
}
|
|
1713
1743
|
pullNode(node) {
|
|
1714
|
-
const isAlreadyOnTop = node.renderOrder() !== 0 && this.maxOrder() === node.renderOrder();
|
|
1715
|
-
// TODO: does not work for group nodes
|
|
1716
|
-
if (isAlreadyOnTop) {
|
|
1717
|
-
return;
|
|
1718
|
-
}
|
|
1719
1744
|
// pull node
|
|
1720
1745
|
node.renderOrder.set(this.maxOrder() + 1);
|
|
1721
1746
|
// pull children
|
|
@@ -2244,14 +2269,14 @@ class EdgeComponent {
|
|
|
2244
2269
|
this.connectionController?.startReconnection(handle, this.model());
|
|
2245
2270
|
}
|
|
2246
2271
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2247
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.visibility": "isReconnecting() ? \"hidden\" : \"visible\"" }, classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().
|
|
2272
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EdgeComponent, isStandalone: true, selector: "g[edge]", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, edgeTemplate: { classPropertyName: "edgeTemplate", publicName: "edgeTemplate", isSignal: true, isRequired: false, transformFunction: null }, edgeLabelHtmlTemplate: { classPropertyName: "edgeLabelHtmlTemplate", publicName: "edgeLabelHtmlTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.visibility": "isReconnecting() ? \"hidden\" : \"visible\"" }, classAttribute: "selectable" }, ngImport: i0, template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\" />\n\n <svg:path class=\"interactive-edge\" [attr.d]=\"model().path().path\" (pointerStart)=\"select(); pull()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().sourceHandle() && model().targetHandle()) {\n @if (model().reconnectable === true || model().reconnectable === 'source') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().sourceHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().sourceHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().targetHandle()!)\" />\n }\n\n @if (model().reconnectable === true || model().reconnectable === 'target') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().targetHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().targetHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().sourceHandle()!)\" />\n }\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}.interactive-edge{fill:none;stroke-width:20;stroke:transparent}.reconnect-handle{fill:transparent;cursor:move}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EdgeLabelComponent, selector: "g[edgeLabel]", inputs: ["model", "edgeModel", "point", "htmlTemplate"] }, { kind: "directive", type: PointerDirective, selector: "[pointerStart], [pointerEnd], [pointerOver], [pointerOut]", outputs: ["pointerOver", "pointerOut", "pointerStart", "pointerEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2248
2273
|
}
|
|
2249
2274
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EdgeComponent, decorators: [{
|
|
2250
2275
|
type: Component,
|
|
2251
2276
|
args: [{ standalone: true, selector: 'g[edge]', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
2252
2277
|
class: 'selectable',
|
|
2253
2278
|
'[style.visibility]': 'isReconnecting() ? "hidden" : "visible"',
|
|
2254
|
-
}, imports: [NgTemplateOutlet, EdgeLabelComponent, PointerDirective], template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().
|
|
2279
|
+
}, imports: [NgTemplateOutlet, EdgeLabelComponent, PointerDirective], template: "@if (model().type === 'default') {\n <svg:path\n class=\"edge\"\n [attr.d]=\"model().path().path\"\n [attr.marker-start]=\"model().markerStartUrl()\"\n [attr.marker-end]=\"model().markerEndUrl()\"\n [class.edge_selected]=\"model().selected()\" />\n\n <svg:path class=\"interactive-edge\" [attr.d]=\"model().path().path\" (pointerStart)=\"select(); pull()\" />\n}\n\n@if (model().type === 'template' && edgeTemplate()) {\n @if (edgeTemplate(); as edgeTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"edgeTemplate\"\n [ngTemplateOutletContext]=\"model().context\"\n [ngTemplateOutletInjector]=\"injector\" />\n }\n}\n\n@if (model().edgeLabels.start; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.start\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.center; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.center\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().edgeLabels.end; as label) {\n <svg:g\n edgeLabel\n [model]=\"label\"\n [point]=\"model().path().points.end\"\n [edgeModel]=\"model()\"\n [htmlTemplate]=\"edgeLabelHtmlTemplate()\" />\n}\n\n@if (model().sourceHandle() && model().targetHandle()) {\n @if (model().reconnectable === true || model().reconnectable === 'source') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().sourceHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().sourceHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().targetHandle()!)\" />\n }\n\n @if (model().reconnectable === true || model().reconnectable === 'target') {\n <svg:circle\n class=\"reconnect-handle\"\n r=\"10\"\n [attr.cx]=\"model().targetHandle()!.pointAbsolute().x\"\n [attr.cy]=\"model().targetHandle()!.pointAbsolute().y\"\n (pointerStart)=\"startReconnection($event, model().sourceHandle()!)\" />\n }\n}\n", styles: [".edge{fill:none;stroke-width:2;stroke:#b1b1b7}.edge_selected{stroke-width:2.5;stroke:#0f4c75}.interactive-edge{fill:none;stroke-width:20;stroke:transparent}.reconnect-handle{fill:transparent;cursor:move}\n"] }]
|
|
2255
2280
|
}] });
|
|
2256
2281
|
|
|
2257
2282
|
class HandleService {
|
|
@@ -3182,6 +3207,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3182
3207
|
args: ['contextmenu']
|
|
3183
3208
|
}] } });
|
|
3184
3209
|
|
|
3210
|
+
/**
|
|
3211
|
+
* @todo handle regular nodes
|
|
3212
|
+
*
|
|
3213
|
+
* @param point global point in flow coordinates
|
|
3214
|
+
* @param groups sorted array of groups
|
|
3215
|
+
* @returns
|
|
3216
|
+
*/
|
|
3217
|
+
function getSpacePoints(point, groups) {
|
|
3218
|
+
const result = [];
|
|
3219
|
+
for (const group of groups) {
|
|
3220
|
+
const { x, y } = group.globalPoint();
|
|
3221
|
+
if (point.x >= x && point.x <= x + group.width() && point.y >= y && point.y <= y + group.height()) {
|
|
3222
|
+
result.push({
|
|
3223
|
+
x: point.x - x,
|
|
3224
|
+
y: point.y - y,
|
|
3225
|
+
spaceNodeId: group.rawNode.id,
|
|
3226
|
+
});
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
result.reverse();
|
|
3230
|
+
// TODO: spread does not work, because the point is SVGPoint
|
|
3231
|
+
result.push({ spaceNodeId: null, x: point.x, y: point.y });
|
|
3232
|
+
return result;
|
|
3233
|
+
}
|
|
3234
|
+
|
|
3185
3235
|
const changesControllerHostDirective = {
|
|
3186
3236
|
directive: ChangesControllerDirective,
|
|
3187
3237
|
outputs: [
|
|
@@ -3366,10 +3416,12 @@ class VflowComponent {
|
|
|
3366
3416
|
* Nodes to render
|
|
3367
3417
|
*/
|
|
3368
3418
|
set nodes(newNodes) {
|
|
3369
|
-
const
|
|
3419
|
+
const models = runInInjectionContext(this.injector, () => ReferenceIdentityChecker.nodes(newNodes, this.flowEntitiesService.nodes()));
|
|
3420
|
+
// TODO: consider calling only fo new nodes
|
|
3370
3421
|
// quick and dirty binding nodes to edges
|
|
3371
|
-
addNodesToEdges(
|
|
3372
|
-
this.flowEntitiesService.nodes.set(
|
|
3422
|
+
addNodesToEdges(models, this.flowEntitiesService.edges());
|
|
3423
|
+
this.flowEntitiesService.nodes.set(models);
|
|
3424
|
+
models.forEach((model) => this.nodeRenderingService.pullNode(model));
|
|
3373
3425
|
}
|
|
3374
3426
|
/**
|
|
3375
3427
|
* Edges to render
|
|
@@ -3380,9 +3432,6 @@ class VflowComponent {
|
|
|
3380
3432
|
addNodesToEdges(this.nodeModels(), newModels);
|
|
3381
3433
|
this.flowEntitiesService.edges.set(newModels);
|
|
3382
3434
|
}
|
|
3383
|
-
ngOnInit() {
|
|
3384
|
-
this.setInitialNodesOrder();
|
|
3385
|
-
}
|
|
3386
3435
|
// #region METHODS_API
|
|
3387
3436
|
/**
|
|
3388
3437
|
* Change viewport to specified state
|
|
@@ -3437,11 +3486,43 @@ class VflowComponent {
|
|
|
3437
3486
|
getDetachedEdges() {
|
|
3438
3487
|
return this.flowEntitiesService.getDetachedEdges().map((e) => e.edge);
|
|
3439
3488
|
}
|
|
3489
|
+
documentPointToFlowPoint(point, options) {
|
|
3490
|
+
const transformedPoint = this.spacePointContext().documentPointToFlowPoint(point);
|
|
3491
|
+
if (options?.spaces) {
|
|
3492
|
+
return getSpacePoints(transformedPoint, this.nodeRenderingService.groups());
|
|
3493
|
+
}
|
|
3494
|
+
return transformedPoint;
|
|
3495
|
+
}
|
|
3440
3496
|
/**
|
|
3441
|
-
*
|
|
3497
|
+
* Gets nodes that intersect with the specified node
|
|
3498
|
+
*
|
|
3499
|
+
* @template T - The type of data associated with the nodes
|
|
3500
|
+
* @param nodeId - The ID of the node to check intersections for
|
|
3501
|
+
* @param options.partially - If true, returns nodes that partially intersect. If false, only returns fully intersecting nodes
|
|
3502
|
+
* @returns An array of nodes that intersect with the specified node
|
|
3503
|
+
*/
|
|
3504
|
+
getIntesectingNodes(nodeId, options = { partially: true }) {
|
|
3505
|
+
return getIntesectingNodes(nodeId, this.nodeModels(), options).map((n) => n.rawNode);
|
|
3506
|
+
}
|
|
3507
|
+
/**
|
|
3508
|
+
* Converts a node's position to the coordinate space of another node
|
|
3509
|
+
*
|
|
3510
|
+
* @param nodeId - The ID of the node whose position should be converted
|
|
3511
|
+
* @param spaceNodeId - The ID of the node that defines the target coordinate space.
|
|
3512
|
+
* If null, returns the position in global coordinates
|
|
3513
|
+
* @returns {Point} The converted position. Returns {x: Infinity, y: Infinity} if either node is not found
|
|
3442
3514
|
*/
|
|
3443
|
-
|
|
3444
|
-
|
|
3515
|
+
toNodeSpace(nodeId, spaceNodeId) {
|
|
3516
|
+
const node = this.nodeModels().find((n) => n.rawNode.id === nodeId);
|
|
3517
|
+
if (!node)
|
|
3518
|
+
return { x: Infinity, y: Infinity };
|
|
3519
|
+
if (spaceNodeId === null) {
|
|
3520
|
+
return node.globalPoint();
|
|
3521
|
+
}
|
|
3522
|
+
const coordinateSpaceNode = this.nodeModels().find((n) => n.rawNode.id === spaceNodeId);
|
|
3523
|
+
if (!coordinateSpaceNode)
|
|
3524
|
+
return { x: Infinity, y: Infinity };
|
|
3525
|
+
return getSpacePoints(node.globalPoint(), [coordinateSpaceNode])[0];
|
|
3445
3526
|
}
|
|
3446
3527
|
// #endregion
|
|
3447
3528
|
trackNodes(idx, { rawNode: node }) {
|
|
@@ -3450,16 +3531,6 @@ class VflowComponent {
|
|
|
3450
3531
|
trackEdges(idx, { edge }) {
|
|
3451
3532
|
return edge;
|
|
3452
3533
|
}
|
|
3453
|
-
setInitialNodesOrder() {
|
|
3454
|
-
this.nodeModels().forEach((model) => {
|
|
3455
|
-
switch (model.rawNode.type) {
|
|
3456
|
-
case 'default-group':
|
|
3457
|
-
case 'template-group': {
|
|
3458
|
-
this.nodeRenderingService.pullNode(model);
|
|
3459
|
-
}
|
|
3460
|
-
}
|
|
3461
|
-
});
|
|
3462
|
-
}
|
|
3463
3534
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VflowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3464
3535
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: VflowComponent, isStandalone: true, selector: "vflow", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: false, isRequired: false, transformFunction: null }, minZoom: { classPropertyName: "minZoom", publicName: "minZoom", isSignal: false, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: false, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: false, isRequired: false, transformFunction: null }, optimization: { classPropertyName: "optimization", publicName: "optimization", isSignal: true, isRequired: false, transformFunction: null }, entitiesSelectable: { classPropertyName: "entitiesSelectable", publicName: "entitiesSelectable", isSignal: false, isRequired: false, transformFunction: null }, keyboardShortcuts: { classPropertyName: "keyboardShortcuts", publicName: "keyboardShortcuts", isSignal: false, isRequired: false, transformFunction: null }, connection: { classPropertyName: "connection", publicName: "connection", isSignal: false, isRequired: false, transformFunction: (settings) => new ConnectionModel(settings) }, snapGrid: { classPropertyName: "snapGrid", publicName: "snapGrid", isSignal: false, isRequired: false, transformFunction: null }, elevateNodesOnSelect: { classPropertyName: "elevateNodesOnSelect", publicName: "elevateNodesOnSelect", isSignal: false, isRequired: false, transformFunction: null }, elevateEdgesOnSelect: { classPropertyName: "elevateEdgesOnSelect", publicName: "elevateEdgesOnSelect", isSignal: false, isRequired: false, transformFunction: null }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: false, isRequired: true, transformFunction: null }, edges: { classPropertyName: "edges", publicName: "edges", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onComponentNodeEvent: "onComponentNodeEvent" }, providers: [
|
|
3465
3536
|
DraggableService,
|
|
@@ -4049,9 +4120,26 @@ class VflowMockComponent {
|
|
|
4049
4120
|
}
|
|
4050
4121
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4051
4122
|
fitView(options) { }
|
|
4052
|
-
documentPointToFlowPoint(point) {
|
|
4123
|
+
documentPointToFlowPoint(point, options) {
|
|
4124
|
+
if (options?.spaces) {
|
|
4125
|
+
return [
|
|
4126
|
+
{
|
|
4127
|
+
nodeId: null,
|
|
4128
|
+
x: point.x,
|
|
4129
|
+
y: point.y,
|
|
4130
|
+
},
|
|
4131
|
+
];
|
|
4132
|
+
}
|
|
4053
4133
|
return point;
|
|
4054
4134
|
}
|
|
4135
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4136
|
+
getIntesectingNodes(nodeId, options) {
|
|
4137
|
+
return [];
|
|
4138
|
+
}
|
|
4139
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4140
|
+
toNodeSpace(nodeId, spaceNodeId) {
|
|
4141
|
+
return { x: 0, y: 0 };
|
|
4142
|
+
}
|
|
4055
4143
|
getNode(id) {
|
|
4056
4144
|
return this.nodes.find((node) => node.id === id);
|
|
4057
4145
|
}
|