spytial-core 1.4.21 → 1.4.22
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.
|
@@ -91338,9 +91338,6 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91338
91338
|
const bbox2 = hasgetBBox(element2) ? element2.getBBox() : { x: 0, y: 0, width: 0, height: 0 };
|
|
91339
91339
|
return !(bbox2.x > bbox1.x + bbox1.width || bbox2.x + bbox2.width < bbox1.x || bbox2.y > bbox1.y + bbox1.height || bbox2.y + bbox2.height < bbox1.y);
|
|
91340
91340
|
}
|
|
91341
|
-
function hasInnerBounds(target) {
|
|
91342
|
-
return target && typeof target === "object" && "innerBounds" in target;
|
|
91343
|
-
}
|
|
91344
91341
|
var d32, cola, DEFAULT_SCALE_FACTOR, _WebColaCnDGraph, WebColaCnDGraph;
|
|
91345
91342
|
var init_webcola_cnd_graph = __esm({
|
|
91346
91343
|
"src/translators/webcola/webcola-cnd-graph.ts"() {
|
|
@@ -91350,7 +91347,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91350
91347
|
cola = window.cola;
|
|
91351
91348
|
DEFAULT_SCALE_FACTOR = 5;
|
|
91352
91349
|
_WebColaCnDGraph = class _WebColaCnDGraph extends HTMLElement {
|
|
91353
|
-
constructor() {
|
|
91350
|
+
constructor(isInputAllowed = false) {
|
|
91354
91351
|
super();
|
|
91355
91352
|
// Reduced from 5 for performance, but kept at 1 for alignment
|
|
91356
91353
|
/**
|
|
@@ -91383,6 +91380,23 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91383
91380
|
* Input mode state management for edge creation and modification
|
|
91384
91381
|
*/
|
|
91385
91382
|
this.isInputModeActive = false;
|
|
91383
|
+
this.inputModeEnabled = true;
|
|
91384
|
+
this.inputModeListenersAttached = false;
|
|
91385
|
+
this.handleInputModeKeydown = (event) => {
|
|
91386
|
+
if ((event.metaKey || event.ctrlKey) && !this.isInputModeActive) {
|
|
91387
|
+
this.activateInputMode();
|
|
91388
|
+
}
|
|
91389
|
+
};
|
|
91390
|
+
this.handleInputModeKeyup = (event) => {
|
|
91391
|
+
if (!event.metaKey && !event.ctrlKey && this.isInputModeActive) {
|
|
91392
|
+
this.deactivateInputMode();
|
|
91393
|
+
}
|
|
91394
|
+
};
|
|
91395
|
+
this.handleInputModeBlur = () => {
|
|
91396
|
+
if (this.isInputModeActive) {
|
|
91397
|
+
this.deactivateInputMode();
|
|
91398
|
+
}
|
|
91399
|
+
};
|
|
91386
91400
|
this.edgeCreationState = {
|
|
91387
91401
|
isCreating: false,
|
|
91388
91402
|
sourceNode: null,
|
|
@@ -91405,6 +91419,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91405
91419
|
this.initializeDOM();
|
|
91406
91420
|
this.initializeD3();
|
|
91407
91421
|
this.lineFunction = d32.line().x((d) => d.x).y((d) => d.y).curve(d32.curveBasis);
|
|
91422
|
+
this.inputModeEnabled = isInputAllowed;
|
|
91408
91423
|
this.initializeInputModeHandlers();
|
|
91409
91424
|
}
|
|
91410
91425
|
/**
|
|
@@ -91780,21 +91795,27 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
91780
91795
|
* Initialize keyboard event handlers for input mode activation
|
|
91781
91796
|
*/
|
|
91782
91797
|
initializeInputModeHandlers() {
|
|
91783
|
-
|
|
91784
|
-
|
|
91785
|
-
|
|
91786
|
-
|
|
91787
|
-
|
|
91788
|
-
|
|
91789
|
-
|
|
91790
|
-
|
|
91791
|
-
|
|
91792
|
-
|
|
91793
|
-
window.addEventListener("blur",
|
|
91794
|
-
|
|
91795
|
-
|
|
91796
|
-
|
|
91797
|
-
|
|
91798
|
+
if (this.inputModeEnabled) {
|
|
91799
|
+
this.attachInputModeListeners();
|
|
91800
|
+
}
|
|
91801
|
+
}
|
|
91802
|
+
attachInputModeListeners() {
|
|
91803
|
+
if (this.inputModeListenersAttached) {
|
|
91804
|
+
return;
|
|
91805
|
+
}
|
|
91806
|
+
document.addEventListener("keydown", this.handleInputModeKeydown);
|
|
91807
|
+
document.addEventListener("keyup", this.handleInputModeKeyup);
|
|
91808
|
+
window.addEventListener("blur", this.handleInputModeBlur);
|
|
91809
|
+
this.inputModeListenersAttached = true;
|
|
91810
|
+
}
|
|
91811
|
+
detachInputModeListeners() {
|
|
91812
|
+
if (!this.inputModeListenersAttached) {
|
|
91813
|
+
return;
|
|
91814
|
+
}
|
|
91815
|
+
document.removeEventListener("keydown", this.handleInputModeKeydown);
|
|
91816
|
+
document.removeEventListener("keyup", this.handleInputModeKeyup);
|
|
91817
|
+
window.removeEventListener("blur", this.handleInputModeBlur);
|
|
91818
|
+
this.inputModeListenersAttached = false;
|
|
91798
91819
|
}
|
|
91799
91820
|
/**
|
|
91800
91821
|
* Activate input mode for edge creation and modification
|
|
@@ -92996,35 +93017,17 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
92996
93017
|
const targetGroup = potentialGroups.find((group) => group.keyNode === this.getNodeIndex(source));
|
|
92997
93018
|
if (targetGroup) {
|
|
92998
93019
|
target = targetGroup;
|
|
92999
|
-
if (hasInnerBounds(target)) {
|
|
93000
|
-
target.innerBounds = targetGroup.bounds?.inflate(-1 * (targetGroup.padding || 10));
|
|
93001
|
-
}
|
|
93002
|
-
} else {
|
|
93003
|
-
console.log("Target group not found", potentialGroups, this.getNodeIndex(target));
|
|
93004
93020
|
}
|
|
93005
93021
|
} else if (addSourceToGroup) {
|
|
93006
93022
|
const potentialGroups = this.getContainingGroups(this.currentLayout?.groups || [], source);
|
|
93007
93023
|
const sourceGroup = potentialGroups.find((group) => group.keyNode === this.getNodeIndex(target));
|
|
93008
93024
|
if (sourceGroup) {
|
|
93009
93025
|
source = sourceGroup;
|
|
93010
|
-
if (hasInnerBounds(source)) {
|
|
93011
|
-
source.innerBounds = sourceGroup.bounds?.inflate(-1 * (sourceGroup.padding || 10));
|
|
93012
|
-
}
|
|
93013
|
-
} else {
|
|
93014
|
-
console.log("Source group not found", potentialGroups, this.getNodeIndex(source));
|
|
93015
93026
|
}
|
|
93016
|
-
} else {
|
|
93017
|
-
console.log("This is a group edge (on tick), but neither source nor target is a group.", d);
|
|
93018
93027
|
}
|
|
93019
93028
|
}
|
|
93020
|
-
|
|
93021
|
-
|
|
93022
|
-
return this.lineFunction([route.sourceIntersection, route.arrowStart]);
|
|
93023
|
-
}
|
|
93024
|
-
return this.lineFunction([
|
|
93025
|
-
{ x: source.x || 0, y: source.y || 0 },
|
|
93026
|
-
{ x: target.x || 0, y: target.y || 0 }
|
|
93027
|
-
]);
|
|
93029
|
+
const route = this.getStableEdgePath(source, target);
|
|
93030
|
+
return this.lineFunction(route);
|
|
93028
93031
|
}).attr("marker-end", (d) => {
|
|
93029
93032
|
if (this.isAlignmentEdge(d)) return "none";
|
|
93030
93033
|
return "url(#end-arrow)";
|
|
@@ -93660,6 +93663,83 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
93660
93663
|
const closestY = Math.max(y, Math.min(point.y, Y));
|
|
93661
93664
|
return { x: closestX, y: closestY };
|
|
93662
93665
|
}
|
|
93666
|
+
/**
|
|
93667
|
+
* Calculates a stable anchor point on a rectangle's perimeter for edge drawing.
|
|
93668
|
+
* This method produces consistent, jitter-free anchor points by using the
|
|
93669
|
+
* center of the rectangle edge that faces the target point.
|
|
93670
|
+
*
|
|
93671
|
+
* Unlike intersection-based approaches that can jump erratically as rectangles
|
|
93672
|
+
* move, this method selects one of four edge centers (top, bottom, left, right)
|
|
93673
|
+
* based on the dominant direction to the target, producing smooth transitions.
|
|
93674
|
+
*
|
|
93675
|
+
* @param bounds - Rectangle bounds with x, y, X, Y properties (or cx(), cy(), width(), height() methods)
|
|
93676
|
+
* @param targetPoint - The point the edge is connecting to
|
|
93677
|
+
* @returns Stable anchor point on the rectangle's perimeter
|
|
93678
|
+
*/
|
|
93679
|
+
getStableEdgeAnchor(bounds, targetPoint) {
|
|
93680
|
+
if (!bounds) return targetPoint;
|
|
93681
|
+
let cx, cy, halfWidth, halfHeight;
|
|
93682
|
+
if (typeof bounds.cx === "function") {
|
|
93683
|
+
cx = bounds.cx();
|
|
93684
|
+
cy = bounds.cy();
|
|
93685
|
+
halfWidth = bounds.width() / 2;
|
|
93686
|
+
halfHeight = bounds.height() / 2;
|
|
93687
|
+
} else if (bounds.x !== void 0 && bounds.X !== void 0) {
|
|
93688
|
+
cx = (bounds.x + bounds.X) / 2;
|
|
93689
|
+
cy = (bounds.y + bounds.Y) / 2;
|
|
93690
|
+
halfWidth = (bounds.X - bounds.x) / 2;
|
|
93691
|
+
halfHeight = (bounds.Y - bounds.y) / 2;
|
|
93692
|
+
} else {
|
|
93693
|
+
return targetPoint;
|
|
93694
|
+
}
|
|
93695
|
+
const dx = targetPoint.x - cx;
|
|
93696
|
+
const dy = targetPoint.y - cy;
|
|
93697
|
+
const normalizedDx = Math.abs(dx) / halfWidth;
|
|
93698
|
+
const normalizedDy = Math.abs(dy) / halfHeight;
|
|
93699
|
+
if (normalizedDx > normalizedDy) {
|
|
93700
|
+
if (dx > 0) {
|
|
93701
|
+
return { x: cx + halfWidth, y: cy };
|
|
93702
|
+
} else {
|
|
93703
|
+
return { x: cx - halfWidth, y: cy };
|
|
93704
|
+
}
|
|
93705
|
+
} else {
|
|
93706
|
+
if (dy > 0) {
|
|
93707
|
+
return { x: cx, y: cy + halfHeight };
|
|
93708
|
+
} else {
|
|
93709
|
+
return { x: cx, y: cy - halfHeight };
|
|
93710
|
+
}
|
|
93711
|
+
}
|
|
93712
|
+
}
|
|
93713
|
+
/**
|
|
93714
|
+
* Calculates stable edge path points for drawing during tick/drag operations.
|
|
93715
|
+
* This method avoids jitter by using stable anchor points instead of
|
|
93716
|
+
* dynamic intersection calculations.
|
|
93717
|
+
*
|
|
93718
|
+
* @param source - Source node or group with bounds
|
|
93719
|
+
* @param target - Target node or group with bounds
|
|
93720
|
+
* @returns Array of two points for a simple line path
|
|
93721
|
+
*/
|
|
93722
|
+
getStableEdgePath(source, target) {
|
|
93723
|
+
let targetCenter;
|
|
93724
|
+
if (target.bounds && typeof target.bounds.cx === "function") {
|
|
93725
|
+
targetCenter = { x: target.bounds.cx(), y: target.bounds.cy() };
|
|
93726
|
+
} else if (target.bounds) {
|
|
93727
|
+
targetCenter = { x: (target.bounds.x + target.bounds.X) / 2, y: (target.bounds.y + target.bounds.Y) / 2 };
|
|
93728
|
+
} else {
|
|
93729
|
+
targetCenter = { x: target.x || 0, y: target.y || 0 };
|
|
93730
|
+
}
|
|
93731
|
+
let sourceCenter;
|
|
93732
|
+
if (source.bounds && typeof source.bounds.cx === "function") {
|
|
93733
|
+
sourceCenter = { x: source.bounds.cx(), y: source.bounds.cy() };
|
|
93734
|
+
} else if (source.bounds) {
|
|
93735
|
+
sourceCenter = { x: (source.bounds.x + source.bounds.X) / 2, y: (source.bounds.y + source.bounds.Y) / 2 };
|
|
93736
|
+
} else {
|
|
93737
|
+
sourceCenter = { x: source.x || 0, y: source.y || 0 };
|
|
93738
|
+
}
|
|
93739
|
+
const sourceAnchor = source.bounds || source.innerBounds ? this.getStableEdgeAnchor(source.bounds || source.innerBounds, targetCenter) : sourceCenter;
|
|
93740
|
+
const targetAnchor = target.bounds || target.innerBounds ? this.getStableEdgeAnchor(target.bounds || target.innerBounds, sourceCenter) : targetCenter;
|
|
93741
|
+
return [sourceAnchor, targetAnchor];
|
|
93742
|
+
}
|
|
93663
93743
|
/**
|
|
93664
93744
|
* Adjusts a point to lie on the perimeter of a rectangle.
|
|
93665
93745
|
*
|
|
@@ -94720,6 +94800,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
94720
94800
|
* - Temporary UI elements (modals, overlays)
|
|
94721
94801
|
*/
|
|
94722
94802
|
dispose() {
|
|
94803
|
+
this.detachInputModeListeners();
|
|
94723
94804
|
this.deactivateInputMode();
|
|
94724
94805
|
if (this.svg) {
|
|
94725
94806
|
this.svg.on(".zoom", null);
|
|
@@ -95534,7 +95615,7 @@ VVbdfjptxz|~\x80\x82\x84\xA6\xA8W\b
|
|
|
95534
95615
|
init_layoutspec();
|
|
95535
95616
|
exports.StructuredInputGraph = class extends WebColaCnDGraph {
|
|
95536
95617
|
constructor(dataInstance) {
|
|
95537
|
-
super();
|
|
95618
|
+
super(true);
|
|
95538
95619
|
this.evaluator = null;
|
|
95539
95620
|
this.layoutInstance = null;
|
|
95540
95621
|
this.cndSpecString = "";
|