polly-graph 0.1.15 → 0.1.16
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/dist/index.cjs +127 -91
- package/dist/index.css +14 -0
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +127 -91
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4761,7 +4761,18 @@ function getShortenedSourcePoint(link, style) {
|
|
|
4761
4761
|
const dx = targetX - sourceX;
|
|
4762
4762
|
const dy = targetY - sourceY;
|
|
4763
4763
|
const distance = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
4764
|
-
|
|
4764
|
+
let sourceRadius = source.style?.radius ?? 12;
|
|
4765
|
+
if (typeof document !== "undefined") {
|
|
4766
|
+
const circles = Array.from(document.querySelectorAll("circle"));
|
|
4767
|
+
for (const circle of circles) {
|
|
4768
|
+
const boundData = circle.__data__;
|
|
4769
|
+
if (boundData && boundData.id === source.id) {
|
|
4770
|
+
const currentRadius = parseFloat(circle.getAttribute("r") || "12");
|
|
4771
|
+
sourceRadius = currentRadius;
|
|
4772
|
+
break;
|
|
4773
|
+
}
|
|
4774
|
+
}
|
|
4775
|
+
}
|
|
4765
4776
|
const sourceStrokeWidth = source.style?.strokeWidth ?? 1.5;
|
|
4766
4777
|
const linkStrokeCompensation = style.strokeWidth / 2;
|
|
4767
4778
|
const nodeStrokeOffset = sourceStrokeWidth / 2;
|
|
@@ -4782,7 +4793,18 @@ function getShortenedTargetPoint(link, style) {
|
|
|
4782
4793
|
const dx = targetX - sourceX;
|
|
4783
4794
|
const dy = targetY - sourceY;
|
|
4784
4795
|
const distance = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
4785
|
-
|
|
4796
|
+
let targetRadius = target.style?.radius ?? 12;
|
|
4797
|
+
if (typeof document !== "undefined") {
|
|
4798
|
+
const circles = Array.from(document.querySelectorAll("circle"));
|
|
4799
|
+
for (const circle of circles) {
|
|
4800
|
+
const boundData = circle.__data__;
|
|
4801
|
+
if (boundData && boundData.id === target.id) {
|
|
4802
|
+
const currentRadius = parseFloat(circle.getAttribute("r") || "12");
|
|
4803
|
+
targetRadius = currentRadius;
|
|
4804
|
+
break;
|
|
4805
|
+
}
|
|
4806
|
+
}
|
|
4807
|
+
}
|
|
4786
4808
|
const targetStrokeWidth = target.style?.strokeWidth ?? 1.5;
|
|
4787
4809
|
const arrowLength = style.arrow.enabled ? style.arrow.size * 2 : 0;
|
|
4788
4810
|
const linkStrokeCompensation = style.strokeWidth / 2;
|
|
@@ -5407,48 +5429,38 @@ function createNodeHover(nodeSelection, hoverStyle, options) {
|
|
|
5407
5429
|
const svgElement = firstNode.ownerSVGElement;
|
|
5408
5430
|
if (!svgElement) return;
|
|
5409
5431
|
const root2 = select_default2(svgElement);
|
|
5432
|
+
const elevatedElements = /* @__PURE__ */ new Set();
|
|
5410
5433
|
function clearAllHoverLayers() {
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
}
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
nodeLabelsLayer.appendChild(hoverNodeLabelsLayer.firstChild);
|
|
5423
|
-
}
|
|
5424
|
-
}
|
|
5425
|
-
const hoverLinksLayer = root2.select('[data-layer="hover-links"]').node();
|
|
5426
|
-
const linksLayer = root2.select('[data-layer="links"]').node();
|
|
5427
|
-
if (hoverLinksLayer && linksLayer) {
|
|
5428
|
-
while (hoverLinksLayer.firstChild) {
|
|
5429
|
-
const linkElement = hoverLinksLayer.firstChild;
|
|
5430
|
-
linksLayer.appendChild(linkElement);
|
|
5431
|
-
const event = new MouseEvent("mouseleave", {
|
|
5432
|
-
bubbles: true,
|
|
5433
|
-
cancelable: false,
|
|
5434
|
-
view: window
|
|
5435
|
-
});
|
|
5436
|
-
linkElement.dispatchEvent(event);
|
|
5437
|
-
}
|
|
5438
|
-
}
|
|
5439
|
-
const hoverLinkLabelsLayer = root2.select('[data-layer="hover-link-labels"]').node();
|
|
5440
|
-
const linkLabelsLayer = root2.select('[data-layer="link-labels"]').node();
|
|
5441
|
-
if (hoverLinkLabelsLayer && linkLabelsLayer) {
|
|
5442
|
-
while (hoverLinkLabelsLayer.firstChild) {
|
|
5443
|
-
const labelElement = hoverLinkLabelsLayer.firstChild;
|
|
5444
|
-
const labelData = labelElement.__data__;
|
|
5445
|
-
if (labelData && labelData.style.label.visibility === "hover" && !labelElement.classList.contains("label-selection-pinned")) {
|
|
5446
|
-
labelElement.style.opacity = "0";
|
|
5447
|
-
labelElement.style.pointerEvents = "none";
|
|
5434
|
+
elevatedElements.forEach((element) => {
|
|
5435
|
+
element.classList.remove("pg-hover-elevated");
|
|
5436
|
+
element.style.removeProperty("filter");
|
|
5437
|
+
if (element.tagName === "circle") {
|
|
5438
|
+
element.removeAttribute("data-hover-elevated");
|
|
5439
|
+
}
|
|
5440
|
+
if (element.classList.contains("link-label")) {
|
|
5441
|
+
const labelData = element.__data__;
|
|
5442
|
+
if (labelData && labelData.style.label.visibility === "hover" && !element.classList.contains("label-selection-pinned")) {
|
|
5443
|
+
element.style.opacity = "0";
|
|
5444
|
+
element.style.pointerEvents = "none";
|
|
5448
5445
|
}
|
|
5449
|
-
linkLabelsLayer.appendChild(labelElement);
|
|
5450
5446
|
}
|
|
5451
|
-
}
|
|
5447
|
+
});
|
|
5448
|
+
elevatedElements.clear();
|
|
5449
|
+
root2.selectAll("line[data-hover-elevated]").each(function() {
|
|
5450
|
+
const linkElement = this;
|
|
5451
|
+
linkElement.removeAttribute("data-hover-elevated");
|
|
5452
|
+
const event = new MouseEvent("mouseleave", {
|
|
5453
|
+
bubbles: true,
|
|
5454
|
+
cancelable: false,
|
|
5455
|
+
view: window
|
|
5456
|
+
});
|
|
5457
|
+
linkElement.dispatchEvent(event);
|
|
5458
|
+
});
|
|
5459
|
+
}
|
|
5460
|
+
function elevateElement(element) {
|
|
5461
|
+
element.classList.add("pg-hover-elevated");
|
|
5462
|
+
element.style.filter = "drop-shadow(0 2px 4px rgba(0,0,0,0.15))";
|
|
5463
|
+
elevatedElements.add(element);
|
|
5452
5464
|
}
|
|
5453
5465
|
nodeSelection.on("mouseenter.links", function(_event, hoveredNode) {
|
|
5454
5466
|
const hoveredNodeElement = this;
|
|
@@ -5459,16 +5471,11 @@ function createNodeHover(nodeSelection, hoverStyle, options) {
|
|
|
5459
5471
|
return;
|
|
5460
5472
|
}
|
|
5461
5473
|
clearAllHoverLayers();
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
hoverNodesLayer.appendChild(hoveredNodeElement);
|
|
5465
|
-
}
|
|
5474
|
+
elevateElement(hoveredNodeElement);
|
|
5475
|
+
hoveredNodeElement.setAttribute("data-hover-elevated", "true");
|
|
5466
5476
|
root2.selectAll("text").filter((d) => d.id === hoveredNode.id).each(function() {
|
|
5467
5477
|
const labelElement = this;
|
|
5468
|
-
|
|
5469
|
-
if (hoverNodeLabelsLayer) {
|
|
5470
|
-
hoverNodeLabelsLayer.appendChild(labelElement);
|
|
5471
|
-
}
|
|
5478
|
+
elevateElement(labelElement);
|
|
5472
5479
|
});
|
|
5473
5480
|
const connectedLinks = root2.selectAll("line:not(.link-hit-area)").filter((renderableLink) => {
|
|
5474
5481
|
const source = renderableLink.link.source;
|
|
@@ -5477,10 +5484,8 @@ function createNodeHover(nodeSelection, hoverStyle, options) {
|
|
|
5477
5484
|
});
|
|
5478
5485
|
connectedLinks.each(function(_renderableLink) {
|
|
5479
5486
|
const linkElement = this;
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
hoverLinksLayer.appendChild(linkElement);
|
|
5483
|
-
}
|
|
5487
|
+
elevateElement(linkElement);
|
|
5488
|
+
linkElement.setAttribute("data-hover-elevated", "true");
|
|
5484
5489
|
const event = new MouseEvent("mouseenter", {
|
|
5485
5490
|
bubbles: true,
|
|
5486
5491
|
cancelable: false,
|
|
@@ -5494,13 +5499,10 @@ function createNodeHover(nodeSelection, hoverStyle, options) {
|
|
|
5494
5499
|
return source.id === hoveredNode.id || target.id === hoveredNode.id;
|
|
5495
5500
|
}).each(function(item) {
|
|
5496
5501
|
const labelElement = this;
|
|
5497
|
-
|
|
5498
|
-
if (
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
labelElement.style.opacity = "1";
|
|
5502
|
-
labelElement.style.pointerEvents = "auto";
|
|
5503
|
-
}
|
|
5502
|
+
elevateElement(labelElement);
|
|
5503
|
+
if (item.style.label.visibility === "hover") {
|
|
5504
|
+
labelElement.style.opacity = "1";
|
|
5505
|
+
labelElement.style.pointerEvents = "auto";
|
|
5504
5506
|
}
|
|
5505
5507
|
});
|
|
5506
5508
|
}).on("mouseleave.links", function(_event, _hoveredNode) {
|
|
@@ -5882,11 +5884,15 @@ function updateHitAreaDimensions(rectElement, item, root2) {
|
|
|
5882
5884
|
const source = item.link.source;
|
|
5883
5885
|
const target = item.link.target;
|
|
5884
5886
|
if (!source.x || !source.y || !target.x || !target.y) return;
|
|
5887
|
+
const dx = target.x - source.x;
|
|
5888
|
+
const dy = target.y - source.y;
|
|
5889
|
+
const linkLength = Math.sqrt(dx * dx + dy * dy);
|
|
5890
|
+
const angle = Math.atan2(dy, dx);
|
|
5885
5891
|
const midX = (source.x + target.x) / 2;
|
|
5886
5892
|
const midY = (source.y + target.y) / 2;
|
|
5887
|
-
const
|
|
5888
|
-
let
|
|
5889
|
-
let
|
|
5893
|
+
const thickness = Math.max((item.style.strokeWidth || 2) * 4, item.style.arrow.size * 2, 20);
|
|
5894
|
+
let length = linkLength + item.style.arrow.size * 2;
|
|
5895
|
+
let width = thickness;
|
|
5890
5896
|
if (item.link.label) {
|
|
5891
5897
|
const labelElement = root2.select('[data-layer="link-labels"]').selectAll(".link-label").filter((labelItem) => labelItem.link === item.link).node();
|
|
5892
5898
|
if (labelElement) {
|
|
@@ -5897,23 +5903,27 @@ function updateHitAreaDimensions(rectElement, item, root2) {
|
|
|
5897
5903
|
const bbox = textElement.getBBox();
|
|
5898
5904
|
const labelWidth = bbox.width + item.style.label.paddingX * 2;
|
|
5899
5905
|
const labelHeight = bbox.height + item.style.label.paddingY * 2;
|
|
5900
|
-
width = Math.max(width,
|
|
5901
|
-
|
|
5906
|
+
width = Math.max(width, labelHeight + 10);
|
|
5907
|
+
length = Math.max(length, labelWidth + 20);
|
|
5902
5908
|
}
|
|
5903
5909
|
} catch {
|
|
5904
5910
|
const text = item.link.label ?? "";
|
|
5905
5911
|
const fontSize = item.style.label.fontSize;
|
|
5906
|
-
const estimatedWidth = text.length * fontSize * 0.6 + item.style.label.paddingX * 2 +
|
|
5912
|
+
const estimatedWidth = text.length * fontSize * 0.6 + item.style.label.paddingX * 2 + 20;
|
|
5907
5913
|
const estimatedHeight = fontSize + item.style.label.paddingY * 2 + 10;
|
|
5908
|
-
width = Math.max(width,
|
|
5909
|
-
|
|
5914
|
+
width = Math.max(width, estimatedHeight);
|
|
5915
|
+
length = Math.max(length, estimatedWidth);
|
|
5910
5916
|
}
|
|
5911
5917
|
}
|
|
5912
5918
|
}
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
rectElement.setAttribute("width", String(
|
|
5916
|
-
rectElement.setAttribute("height", String(
|
|
5919
|
+
const rectX = midX - length / 2;
|
|
5920
|
+
const rectY = midY - width / 2;
|
|
5921
|
+
rectElement.setAttribute("width", String(length));
|
|
5922
|
+
rectElement.setAttribute("height", String(width));
|
|
5923
|
+
rectElement.setAttribute("x", String(rectX));
|
|
5924
|
+
rectElement.setAttribute("y", String(rectY));
|
|
5925
|
+
const degrees2 = angle * 180 / Math.PI;
|
|
5926
|
+
rectElement.setAttribute("transform", `rotate(${degrees2}, ${midX}, ${midY})`);
|
|
5917
5927
|
}
|
|
5918
5928
|
|
|
5919
5929
|
// src/utils/get-link-target-point.ts
|
|
@@ -6152,7 +6162,10 @@ var SelectionManager = class {
|
|
|
6152
6162
|
if (style.stroke !== void 0) nodeElement.style.stroke = style.stroke;
|
|
6153
6163
|
if (style.strokeWidth !== void 0) nodeElement.style.strokeWidth = String(style.strokeWidth);
|
|
6154
6164
|
if (style.opacity !== void 0) nodeElement.style.opacity = String(style.opacity);
|
|
6155
|
-
if (style.radius !== void 0)
|
|
6165
|
+
if (style.radius !== void 0) {
|
|
6166
|
+
nodeElement.setAttribute("r", String(style.radius));
|
|
6167
|
+
this.updateConnectedLinkPositions(nodeData);
|
|
6168
|
+
}
|
|
6156
6169
|
}
|
|
6157
6170
|
this.root.selectAll(".link-label").filter((item) => {
|
|
6158
6171
|
if (item.style.label.visibility !== "hover") return false;
|
|
@@ -6209,6 +6222,7 @@ var SelectionManager = class {
|
|
|
6209
6222
|
element.style.opacity = "";
|
|
6210
6223
|
const originalRadius = data.style?.radius ?? 8;
|
|
6211
6224
|
element.setAttribute("r", String(originalRadius));
|
|
6225
|
+
this.updateConnectedLinkPositions(data);
|
|
6212
6226
|
delete element.dataset.selected;
|
|
6213
6227
|
this.root.selectAll(".link-label.label-selection-pinned").classed("label-selection-pinned", false).interrupt().transition().duration(200).style("opacity", 0).style("pointer-events", "none");
|
|
6214
6228
|
this.state.selectedNode = null;
|
|
@@ -6221,7 +6235,7 @@ var SelectionManager = class {
|
|
|
6221
6235
|
if (!this.state.selectedLink) return;
|
|
6222
6236
|
const { element, data, originalMarker } = this.state.selectedLink;
|
|
6223
6237
|
this.layers.links.appendChild(element);
|
|
6224
|
-
this.root.selectAll(".link-label").filter((item) => item.link === data).each((
|
|
6238
|
+
this.root.selectAll(".link-label").filter((item) => item.link === data).each((_, i, nodes) => {
|
|
6225
6239
|
const element2 = nodes[i];
|
|
6226
6240
|
if (element2) {
|
|
6227
6241
|
this.layers.linkLabels.appendChild(element2);
|
|
@@ -6291,13 +6305,13 @@ var SelectionManager = class {
|
|
|
6291
6305
|
const target = d.link.target;
|
|
6292
6306
|
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6293
6307
|
});
|
|
6294
|
-
connectedLinks.each((
|
|
6308
|
+
connectedLinks.each((_, i, nodes) => {
|
|
6295
6309
|
const element = nodes[i];
|
|
6296
6310
|
if (element) {
|
|
6297
6311
|
this.layers.selectionLayer.links.appendChild(element);
|
|
6298
6312
|
}
|
|
6299
6313
|
});
|
|
6300
|
-
this.root.selectAll("text").filter((d) => d.id === nodeData.id).each((
|
|
6314
|
+
this.root.selectAll("text").filter((d) => d.id === nodeData.id).each((_, i, nodes) => {
|
|
6301
6315
|
const element = nodes[i];
|
|
6302
6316
|
if (element) {
|
|
6303
6317
|
this.layers.selectionLayer.nodeLabels.appendChild(element);
|
|
@@ -6307,7 +6321,7 @@ var SelectionManager = class {
|
|
|
6307
6321
|
const source = item.link.source;
|
|
6308
6322
|
const target = item.link.target;
|
|
6309
6323
|
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6310
|
-
}).each((
|
|
6324
|
+
}).each((_, i, nodes) => {
|
|
6311
6325
|
const element = nodes[i];
|
|
6312
6326
|
if (element) {
|
|
6313
6327
|
this.layers.selectionLayer.linkLabels.appendChild(element);
|
|
@@ -6319,7 +6333,7 @@ var SelectionManager = class {
|
|
|
6319
6333
|
*/
|
|
6320
6334
|
bringLinkToFront(linkElement, renderableLink) {
|
|
6321
6335
|
this.layers.selectionLayer.links.appendChild(linkElement);
|
|
6322
|
-
this.root.selectAll(".link-label").filter((item) => item.link === renderableLink.link).each((
|
|
6336
|
+
this.root.selectAll(".link-label").filter((item) => item.link === renderableLink.link).each((_, i, nodes) => {
|
|
6323
6337
|
const element = nodes[i];
|
|
6324
6338
|
if (element) {
|
|
6325
6339
|
this.layers.selectionLayer.linkLabels.appendChild(element);
|
|
@@ -6330,7 +6344,7 @@ var SelectionManager = class {
|
|
|
6330
6344
|
* Restore elements back to their original layers
|
|
6331
6345
|
*/
|
|
6332
6346
|
restoreSelectedElements(nodeData) {
|
|
6333
|
-
this.root.selectAll("circle").filter((d) => d.id === nodeData.id).each((
|
|
6347
|
+
this.root.selectAll("circle").filter((d) => d.id === nodeData.id).each((_, i, nodes) => {
|
|
6334
6348
|
const element = nodes[i];
|
|
6335
6349
|
if (element) {
|
|
6336
6350
|
this.layers.nodes.appendChild(element);
|
|
@@ -6340,13 +6354,13 @@ var SelectionManager = class {
|
|
|
6340
6354
|
const source = d.link.source;
|
|
6341
6355
|
const target = d.link.target;
|
|
6342
6356
|
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6343
|
-
}).each((
|
|
6357
|
+
}).each((_, i, nodes) => {
|
|
6344
6358
|
const element = nodes[i];
|
|
6345
6359
|
if (element) {
|
|
6346
6360
|
this.layers.links.appendChild(element);
|
|
6347
6361
|
}
|
|
6348
6362
|
});
|
|
6349
|
-
this.root.selectAll("text").filter((d) => d.id === nodeData.id).each((
|
|
6363
|
+
this.root.selectAll("text").filter((d) => d.id === nodeData.id).each((_, i, nodes) => {
|
|
6350
6364
|
const element = nodes[i];
|
|
6351
6365
|
if (element) {
|
|
6352
6366
|
this.layers.nodeLabels.appendChild(element);
|
|
@@ -6356,22 +6370,13 @@ var SelectionManager = class {
|
|
|
6356
6370
|
const source = item.link.source;
|
|
6357
6371
|
const target = item.link.target;
|
|
6358
6372
|
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6359
|
-
}).each((
|
|
6373
|
+
}).each((_, i, nodes) => {
|
|
6360
6374
|
const element = nodes[i];
|
|
6361
6375
|
if (element) {
|
|
6362
6376
|
this.layers.linkLabels.appendChild(element);
|
|
6363
6377
|
}
|
|
6364
6378
|
});
|
|
6365
6379
|
}
|
|
6366
|
-
/**
|
|
6367
|
-
* Utility method to bring any SVG element to front using appendChild
|
|
6368
|
-
* Based on the reference implementation pattern
|
|
6369
|
-
*/
|
|
6370
|
-
bringElementToFront(element) {
|
|
6371
|
-
if (element.parentNode) {
|
|
6372
|
-
element.parentNode.appendChild(element);
|
|
6373
|
-
}
|
|
6374
|
-
}
|
|
6375
6380
|
/**
|
|
6376
6381
|
* Clear hover state to prevent conflicts with selection
|
|
6377
6382
|
* Similar to the clearAllHoverLayers function in create-node-hover.ts
|
|
@@ -6419,6 +6424,25 @@ var SelectionManager = class {
|
|
|
6419
6424
|
}
|
|
6420
6425
|
}
|
|
6421
6426
|
}
|
|
6427
|
+
/**
|
|
6428
|
+
* Immediately update positions of links connected to the specified node
|
|
6429
|
+
* This ensures arrowheads reposition correctly when node radius changes
|
|
6430
|
+
*/
|
|
6431
|
+
updateConnectedLinkPositions(nodeData) {
|
|
6432
|
+
this.root.selectAll("line:not(.link-hit-area)").filter((renderableLink) => {
|
|
6433
|
+
const source = renderableLink.link.source;
|
|
6434
|
+
const target = renderableLink.link.target;
|
|
6435
|
+
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6436
|
+
}).each(function(item) {
|
|
6437
|
+
const linkElement = this;
|
|
6438
|
+
const sourcePoint = getShortenedSourcePoint(item.link, item.style);
|
|
6439
|
+
const targetPoint = getShortenedTargetPoint(item.link, item.style);
|
|
6440
|
+
linkElement.setAttribute("x1", String(sourcePoint.x));
|
|
6441
|
+
linkElement.setAttribute("y1", String(sourcePoint.y));
|
|
6442
|
+
linkElement.setAttribute("x2", String(targetPoint.x));
|
|
6443
|
+
linkElement.setAttribute("y2", String(targetPoint.y));
|
|
6444
|
+
});
|
|
6445
|
+
}
|
|
6422
6446
|
/**
|
|
6423
6447
|
* Clean up resources
|
|
6424
6448
|
*/
|
|
@@ -6585,6 +6609,13 @@ var InteractionManager = class {
|
|
|
6585
6609
|
const nodeElement = event.currentTarget;
|
|
6586
6610
|
this.manager.selectionManager?.selectNode(nodeElement, node);
|
|
6587
6611
|
});
|
|
6612
|
+
selections.linkSelection.on("click.select", (event, renderableLinkData) => {
|
|
6613
|
+
event.stopPropagation();
|
|
6614
|
+
const linkElement = event.currentTarget;
|
|
6615
|
+
if (this.manager.selectionManager) {
|
|
6616
|
+
this.manager.selectionManager.selectLink(linkElement, renderableLinkData, event);
|
|
6617
|
+
}
|
|
6618
|
+
});
|
|
6588
6619
|
selections.linkLabelSelection.on("click.select", (event, renderableLinkLabel) => {
|
|
6589
6620
|
event.stopPropagation();
|
|
6590
6621
|
const correspondingLink = selections.linkSelection.filter((d) => d.link === renderableLinkLabel.link).node();
|
|
@@ -6630,12 +6661,17 @@ var InteractionManager = class {
|
|
|
6630
6661
|
const target = item.link.target;
|
|
6631
6662
|
if (!source.x || !source.y || !target.x || !target.y) return;
|
|
6632
6663
|
const rectElement = this;
|
|
6664
|
+
const dx = target.x - source.x;
|
|
6665
|
+
const dy = target.y - source.y;
|
|
6666
|
+
const angle = Math.atan2(dy, dx);
|
|
6633
6667
|
const midX = (source.x + target.x) / 2;
|
|
6634
6668
|
const midY = (source.y + target.y) / 2;
|
|
6635
6669
|
const width = parseFloat(rectElement.getAttribute("width") || "20");
|
|
6636
6670
|
const height = parseFloat(rectElement.getAttribute("height") || "20");
|
|
6637
6671
|
rectElement.setAttribute("x", String(midX - width / 2));
|
|
6638
6672
|
rectElement.setAttribute("y", String(midY - height / 2));
|
|
6673
|
+
const degrees2 = angle * 180 / Math.PI;
|
|
6674
|
+
rectElement.setAttribute("transform", `rotate(${degrees2}, ${midX}, ${midY})`);
|
|
6639
6675
|
});
|
|
6640
6676
|
});
|
|
6641
6677
|
}
|
package/dist/index.css
CHANGED
|
@@ -320,5 +320,19 @@
|
|
|
320
320
|
cursor: pointer;
|
|
321
321
|
transition: stroke-opacity 0.2s ease;
|
|
322
322
|
}
|
|
323
|
+
.pg-hover-elevated {
|
|
324
|
+
paint-order: fill stroke markers;
|
|
325
|
+
transition: filter 0.15s ease-in-out;
|
|
326
|
+
}
|
|
327
|
+
.pg-hover-elevated.pg-layer-nodes circle,
|
|
328
|
+
.pg-hover-elevated[data-hover-elevated] {
|
|
329
|
+
paint-order: stroke fill markers;
|
|
330
|
+
}
|
|
331
|
+
svg .pg-hover-elevated {
|
|
332
|
+
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.15));
|
|
333
|
+
}
|
|
334
|
+
[data-hover-elevated=true] {
|
|
335
|
+
opacity: 1 !important;
|
|
336
|
+
}
|
|
323
337
|
|
|
324
338
|
/* src/styles/main.css */
|
package/dist/index.d.cts
CHANGED
|
@@ -616,16 +616,16 @@ declare class SelectionManager {
|
|
|
616
616
|
* Restore elements back to their original layers
|
|
617
617
|
*/
|
|
618
618
|
private restoreSelectedElements;
|
|
619
|
-
/**
|
|
620
|
-
* Utility method to bring any SVG element to front using appendChild
|
|
621
|
-
* Based on the reference implementation pattern
|
|
622
|
-
*/
|
|
623
|
-
private bringElementToFront;
|
|
624
619
|
/**
|
|
625
620
|
* Clear hover state to prevent conflicts with selection
|
|
626
621
|
* Similar to the clearAllHoverLayers function in create-node-hover.ts
|
|
627
622
|
*/
|
|
628
623
|
private clearHoverState;
|
|
624
|
+
/**
|
|
625
|
+
* Immediately update positions of links connected to the specified node
|
|
626
|
+
* This ensures arrowheads reposition correctly when node radius changes
|
|
627
|
+
*/
|
|
628
|
+
private updateConnectedLinkPositions;
|
|
629
629
|
/**
|
|
630
630
|
* Clean up resources
|
|
631
631
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -616,16 +616,16 @@ declare class SelectionManager {
|
|
|
616
616
|
* Restore elements back to their original layers
|
|
617
617
|
*/
|
|
618
618
|
private restoreSelectedElements;
|
|
619
|
-
/**
|
|
620
|
-
* Utility method to bring any SVG element to front using appendChild
|
|
621
|
-
* Based on the reference implementation pattern
|
|
622
|
-
*/
|
|
623
|
-
private bringElementToFront;
|
|
624
619
|
/**
|
|
625
620
|
* Clear hover state to prevent conflicts with selection
|
|
626
621
|
* Similar to the clearAllHoverLayers function in create-node-hover.ts
|
|
627
622
|
*/
|
|
628
623
|
private clearHoverState;
|
|
624
|
+
/**
|
|
625
|
+
* Immediately update positions of links connected to the specified node
|
|
626
|
+
* This ensures arrowheads reposition correctly when node radius changes
|
|
627
|
+
*/
|
|
628
|
+
private updateConnectedLinkPositions;
|
|
629
629
|
/**
|
|
630
630
|
* Clean up resources
|
|
631
631
|
*/
|
package/dist/index.js
CHANGED
|
@@ -4729,7 +4729,18 @@ function getShortenedSourcePoint(link, style) {
|
|
|
4729
4729
|
const dx = targetX - sourceX;
|
|
4730
4730
|
const dy = targetY - sourceY;
|
|
4731
4731
|
const distance = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
4732
|
-
|
|
4732
|
+
let sourceRadius = source.style?.radius ?? 12;
|
|
4733
|
+
if (typeof document !== "undefined") {
|
|
4734
|
+
const circles = Array.from(document.querySelectorAll("circle"));
|
|
4735
|
+
for (const circle of circles) {
|
|
4736
|
+
const boundData = circle.__data__;
|
|
4737
|
+
if (boundData && boundData.id === source.id) {
|
|
4738
|
+
const currentRadius = parseFloat(circle.getAttribute("r") || "12");
|
|
4739
|
+
sourceRadius = currentRadius;
|
|
4740
|
+
break;
|
|
4741
|
+
}
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4733
4744
|
const sourceStrokeWidth = source.style?.strokeWidth ?? 1.5;
|
|
4734
4745
|
const linkStrokeCompensation = style.strokeWidth / 2;
|
|
4735
4746
|
const nodeStrokeOffset = sourceStrokeWidth / 2;
|
|
@@ -4750,7 +4761,18 @@ function getShortenedTargetPoint(link, style) {
|
|
|
4750
4761
|
const dx = targetX - sourceX;
|
|
4751
4762
|
const dy = targetY - sourceY;
|
|
4752
4763
|
const distance = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
4753
|
-
|
|
4764
|
+
let targetRadius = target.style?.radius ?? 12;
|
|
4765
|
+
if (typeof document !== "undefined") {
|
|
4766
|
+
const circles = Array.from(document.querySelectorAll("circle"));
|
|
4767
|
+
for (const circle of circles) {
|
|
4768
|
+
const boundData = circle.__data__;
|
|
4769
|
+
if (boundData && boundData.id === target.id) {
|
|
4770
|
+
const currentRadius = parseFloat(circle.getAttribute("r") || "12");
|
|
4771
|
+
targetRadius = currentRadius;
|
|
4772
|
+
break;
|
|
4773
|
+
}
|
|
4774
|
+
}
|
|
4775
|
+
}
|
|
4754
4776
|
const targetStrokeWidth = target.style?.strokeWidth ?? 1.5;
|
|
4755
4777
|
const arrowLength = style.arrow.enabled ? style.arrow.size * 2 : 0;
|
|
4756
4778
|
const linkStrokeCompensation = style.strokeWidth / 2;
|
|
@@ -5375,48 +5397,38 @@ function createNodeHover(nodeSelection, hoverStyle, options) {
|
|
|
5375
5397
|
const svgElement = firstNode.ownerSVGElement;
|
|
5376
5398
|
if (!svgElement) return;
|
|
5377
5399
|
const root2 = select_default2(svgElement);
|
|
5400
|
+
const elevatedElements = /* @__PURE__ */ new Set();
|
|
5378
5401
|
function clearAllHoverLayers() {
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
}
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
nodeLabelsLayer.appendChild(hoverNodeLabelsLayer.firstChild);
|
|
5391
|
-
}
|
|
5392
|
-
}
|
|
5393
|
-
const hoverLinksLayer = root2.select('[data-layer="hover-links"]').node();
|
|
5394
|
-
const linksLayer = root2.select('[data-layer="links"]').node();
|
|
5395
|
-
if (hoverLinksLayer && linksLayer) {
|
|
5396
|
-
while (hoverLinksLayer.firstChild) {
|
|
5397
|
-
const linkElement = hoverLinksLayer.firstChild;
|
|
5398
|
-
linksLayer.appendChild(linkElement);
|
|
5399
|
-
const event = new MouseEvent("mouseleave", {
|
|
5400
|
-
bubbles: true,
|
|
5401
|
-
cancelable: false,
|
|
5402
|
-
view: window
|
|
5403
|
-
});
|
|
5404
|
-
linkElement.dispatchEvent(event);
|
|
5405
|
-
}
|
|
5406
|
-
}
|
|
5407
|
-
const hoverLinkLabelsLayer = root2.select('[data-layer="hover-link-labels"]').node();
|
|
5408
|
-
const linkLabelsLayer = root2.select('[data-layer="link-labels"]').node();
|
|
5409
|
-
if (hoverLinkLabelsLayer && linkLabelsLayer) {
|
|
5410
|
-
while (hoverLinkLabelsLayer.firstChild) {
|
|
5411
|
-
const labelElement = hoverLinkLabelsLayer.firstChild;
|
|
5412
|
-
const labelData = labelElement.__data__;
|
|
5413
|
-
if (labelData && labelData.style.label.visibility === "hover" && !labelElement.classList.contains("label-selection-pinned")) {
|
|
5414
|
-
labelElement.style.opacity = "0";
|
|
5415
|
-
labelElement.style.pointerEvents = "none";
|
|
5402
|
+
elevatedElements.forEach((element) => {
|
|
5403
|
+
element.classList.remove("pg-hover-elevated");
|
|
5404
|
+
element.style.removeProperty("filter");
|
|
5405
|
+
if (element.tagName === "circle") {
|
|
5406
|
+
element.removeAttribute("data-hover-elevated");
|
|
5407
|
+
}
|
|
5408
|
+
if (element.classList.contains("link-label")) {
|
|
5409
|
+
const labelData = element.__data__;
|
|
5410
|
+
if (labelData && labelData.style.label.visibility === "hover" && !element.classList.contains("label-selection-pinned")) {
|
|
5411
|
+
element.style.opacity = "0";
|
|
5412
|
+
element.style.pointerEvents = "none";
|
|
5416
5413
|
}
|
|
5417
|
-
linkLabelsLayer.appendChild(labelElement);
|
|
5418
5414
|
}
|
|
5419
|
-
}
|
|
5415
|
+
});
|
|
5416
|
+
elevatedElements.clear();
|
|
5417
|
+
root2.selectAll("line[data-hover-elevated]").each(function() {
|
|
5418
|
+
const linkElement = this;
|
|
5419
|
+
linkElement.removeAttribute("data-hover-elevated");
|
|
5420
|
+
const event = new MouseEvent("mouseleave", {
|
|
5421
|
+
bubbles: true,
|
|
5422
|
+
cancelable: false,
|
|
5423
|
+
view: window
|
|
5424
|
+
});
|
|
5425
|
+
linkElement.dispatchEvent(event);
|
|
5426
|
+
});
|
|
5427
|
+
}
|
|
5428
|
+
function elevateElement(element) {
|
|
5429
|
+
element.classList.add("pg-hover-elevated");
|
|
5430
|
+
element.style.filter = "drop-shadow(0 2px 4px rgba(0,0,0,0.15))";
|
|
5431
|
+
elevatedElements.add(element);
|
|
5420
5432
|
}
|
|
5421
5433
|
nodeSelection.on("mouseenter.links", function(_event, hoveredNode) {
|
|
5422
5434
|
const hoveredNodeElement = this;
|
|
@@ -5427,16 +5439,11 @@ function createNodeHover(nodeSelection, hoverStyle, options) {
|
|
|
5427
5439
|
return;
|
|
5428
5440
|
}
|
|
5429
5441
|
clearAllHoverLayers();
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
hoverNodesLayer.appendChild(hoveredNodeElement);
|
|
5433
|
-
}
|
|
5442
|
+
elevateElement(hoveredNodeElement);
|
|
5443
|
+
hoveredNodeElement.setAttribute("data-hover-elevated", "true");
|
|
5434
5444
|
root2.selectAll("text").filter((d) => d.id === hoveredNode.id).each(function() {
|
|
5435
5445
|
const labelElement = this;
|
|
5436
|
-
|
|
5437
|
-
if (hoverNodeLabelsLayer) {
|
|
5438
|
-
hoverNodeLabelsLayer.appendChild(labelElement);
|
|
5439
|
-
}
|
|
5446
|
+
elevateElement(labelElement);
|
|
5440
5447
|
});
|
|
5441
5448
|
const connectedLinks = root2.selectAll("line:not(.link-hit-area)").filter((renderableLink) => {
|
|
5442
5449
|
const source = renderableLink.link.source;
|
|
@@ -5445,10 +5452,8 @@ function createNodeHover(nodeSelection, hoverStyle, options) {
|
|
|
5445
5452
|
});
|
|
5446
5453
|
connectedLinks.each(function(_renderableLink) {
|
|
5447
5454
|
const linkElement = this;
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
hoverLinksLayer.appendChild(linkElement);
|
|
5451
|
-
}
|
|
5455
|
+
elevateElement(linkElement);
|
|
5456
|
+
linkElement.setAttribute("data-hover-elevated", "true");
|
|
5452
5457
|
const event = new MouseEvent("mouseenter", {
|
|
5453
5458
|
bubbles: true,
|
|
5454
5459
|
cancelable: false,
|
|
@@ -5462,13 +5467,10 @@ function createNodeHover(nodeSelection, hoverStyle, options) {
|
|
|
5462
5467
|
return source.id === hoveredNode.id || target.id === hoveredNode.id;
|
|
5463
5468
|
}).each(function(item) {
|
|
5464
5469
|
const labelElement = this;
|
|
5465
|
-
|
|
5466
|
-
if (
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
labelElement.style.opacity = "1";
|
|
5470
|
-
labelElement.style.pointerEvents = "auto";
|
|
5471
|
-
}
|
|
5470
|
+
elevateElement(labelElement);
|
|
5471
|
+
if (item.style.label.visibility === "hover") {
|
|
5472
|
+
labelElement.style.opacity = "1";
|
|
5473
|
+
labelElement.style.pointerEvents = "auto";
|
|
5472
5474
|
}
|
|
5473
5475
|
});
|
|
5474
5476
|
}).on("mouseleave.links", function(_event, _hoveredNode) {
|
|
@@ -5850,11 +5852,15 @@ function updateHitAreaDimensions(rectElement, item, root2) {
|
|
|
5850
5852
|
const source = item.link.source;
|
|
5851
5853
|
const target = item.link.target;
|
|
5852
5854
|
if (!source.x || !source.y || !target.x || !target.y) return;
|
|
5855
|
+
const dx = target.x - source.x;
|
|
5856
|
+
const dy = target.y - source.y;
|
|
5857
|
+
const linkLength = Math.sqrt(dx * dx + dy * dy);
|
|
5858
|
+
const angle = Math.atan2(dy, dx);
|
|
5853
5859
|
const midX = (source.x + target.x) / 2;
|
|
5854
5860
|
const midY = (source.y + target.y) / 2;
|
|
5855
|
-
const
|
|
5856
|
-
let
|
|
5857
|
-
let
|
|
5861
|
+
const thickness = Math.max((item.style.strokeWidth || 2) * 4, item.style.arrow.size * 2, 20);
|
|
5862
|
+
let length = linkLength + item.style.arrow.size * 2;
|
|
5863
|
+
let width = thickness;
|
|
5858
5864
|
if (item.link.label) {
|
|
5859
5865
|
const labelElement = root2.select('[data-layer="link-labels"]').selectAll(".link-label").filter((labelItem) => labelItem.link === item.link).node();
|
|
5860
5866
|
if (labelElement) {
|
|
@@ -5865,23 +5871,27 @@ function updateHitAreaDimensions(rectElement, item, root2) {
|
|
|
5865
5871
|
const bbox = textElement.getBBox();
|
|
5866
5872
|
const labelWidth = bbox.width + item.style.label.paddingX * 2;
|
|
5867
5873
|
const labelHeight = bbox.height + item.style.label.paddingY * 2;
|
|
5868
|
-
width = Math.max(width,
|
|
5869
|
-
|
|
5874
|
+
width = Math.max(width, labelHeight + 10);
|
|
5875
|
+
length = Math.max(length, labelWidth + 20);
|
|
5870
5876
|
}
|
|
5871
5877
|
} catch {
|
|
5872
5878
|
const text = item.link.label ?? "";
|
|
5873
5879
|
const fontSize = item.style.label.fontSize;
|
|
5874
|
-
const estimatedWidth = text.length * fontSize * 0.6 + item.style.label.paddingX * 2 +
|
|
5880
|
+
const estimatedWidth = text.length * fontSize * 0.6 + item.style.label.paddingX * 2 + 20;
|
|
5875
5881
|
const estimatedHeight = fontSize + item.style.label.paddingY * 2 + 10;
|
|
5876
|
-
width = Math.max(width,
|
|
5877
|
-
|
|
5882
|
+
width = Math.max(width, estimatedHeight);
|
|
5883
|
+
length = Math.max(length, estimatedWidth);
|
|
5878
5884
|
}
|
|
5879
5885
|
}
|
|
5880
5886
|
}
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
rectElement.setAttribute("width", String(
|
|
5884
|
-
rectElement.setAttribute("height", String(
|
|
5887
|
+
const rectX = midX - length / 2;
|
|
5888
|
+
const rectY = midY - width / 2;
|
|
5889
|
+
rectElement.setAttribute("width", String(length));
|
|
5890
|
+
rectElement.setAttribute("height", String(width));
|
|
5891
|
+
rectElement.setAttribute("x", String(rectX));
|
|
5892
|
+
rectElement.setAttribute("y", String(rectY));
|
|
5893
|
+
const degrees2 = angle * 180 / Math.PI;
|
|
5894
|
+
rectElement.setAttribute("transform", `rotate(${degrees2}, ${midX}, ${midY})`);
|
|
5885
5895
|
}
|
|
5886
5896
|
|
|
5887
5897
|
// src/utils/get-link-target-point.ts
|
|
@@ -6120,7 +6130,10 @@ var SelectionManager = class {
|
|
|
6120
6130
|
if (style.stroke !== void 0) nodeElement.style.stroke = style.stroke;
|
|
6121
6131
|
if (style.strokeWidth !== void 0) nodeElement.style.strokeWidth = String(style.strokeWidth);
|
|
6122
6132
|
if (style.opacity !== void 0) nodeElement.style.opacity = String(style.opacity);
|
|
6123
|
-
if (style.radius !== void 0)
|
|
6133
|
+
if (style.radius !== void 0) {
|
|
6134
|
+
nodeElement.setAttribute("r", String(style.radius));
|
|
6135
|
+
this.updateConnectedLinkPositions(nodeData);
|
|
6136
|
+
}
|
|
6124
6137
|
}
|
|
6125
6138
|
this.root.selectAll(".link-label").filter((item) => {
|
|
6126
6139
|
if (item.style.label.visibility !== "hover") return false;
|
|
@@ -6177,6 +6190,7 @@ var SelectionManager = class {
|
|
|
6177
6190
|
element.style.opacity = "";
|
|
6178
6191
|
const originalRadius = data.style?.radius ?? 8;
|
|
6179
6192
|
element.setAttribute("r", String(originalRadius));
|
|
6193
|
+
this.updateConnectedLinkPositions(data);
|
|
6180
6194
|
delete element.dataset.selected;
|
|
6181
6195
|
this.root.selectAll(".link-label.label-selection-pinned").classed("label-selection-pinned", false).interrupt().transition().duration(200).style("opacity", 0).style("pointer-events", "none");
|
|
6182
6196
|
this.state.selectedNode = null;
|
|
@@ -6189,7 +6203,7 @@ var SelectionManager = class {
|
|
|
6189
6203
|
if (!this.state.selectedLink) return;
|
|
6190
6204
|
const { element, data, originalMarker } = this.state.selectedLink;
|
|
6191
6205
|
this.layers.links.appendChild(element);
|
|
6192
|
-
this.root.selectAll(".link-label").filter((item) => item.link === data).each((
|
|
6206
|
+
this.root.selectAll(".link-label").filter((item) => item.link === data).each((_, i, nodes) => {
|
|
6193
6207
|
const element2 = nodes[i];
|
|
6194
6208
|
if (element2) {
|
|
6195
6209
|
this.layers.linkLabels.appendChild(element2);
|
|
@@ -6259,13 +6273,13 @@ var SelectionManager = class {
|
|
|
6259
6273
|
const target = d.link.target;
|
|
6260
6274
|
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6261
6275
|
});
|
|
6262
|
-
connectedLinks.each((
|
|
6276
|
+
connectedLinks.each((_, i, nodes) => {
|
|
6263
6277
|
const element = nodes[i];
|
|
6264
6278
|
if (element) {
|
|
6265
6279
|
this.layers.selectionLayer.links.appendChild(element);
|
|
6266
6280
|
}
|
|
6267
6281
|
});
|
|
6268
|
-
this.root.selectAll("text").filter((d) => d.id === nodeData.id).each((
|
|
6282
|
+
this.root.selectAll("text").filter((d) => d.id === nodeData.id).each((_, i, nodes) => {
|
|
6269
6283
|
const element = nodes[i];
|
|
6270
6284
|
if (element) {
|
|
6271
6285
|
this.layers.selectionLayer.nodeLabels.appendChild(element);
|
|
@@ -6275,7 +6289,7 @@ var SelectionManager = class {
|
|
|
6275
6289
|
const source = item.link.source;
|
|
6276
6290
|
const target = item.link.target;
|
|
6277
6291
|
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6278
|
-
}).each((
|
|
6292
|
+
}).each((_, i, nodes) => {
|
|
6279
6293
|
const element = nodes[i];
|
|
6280
6294
|
if (element) {
|
|
6281
6295
|
this.layers.selectionLayer.linkLabels.appendChild(element);
|
|
@@ -6287,7 +6301,7 @@ var SelectionManager = class {
|
|
|
6287
6301
|
*/
|
|
6288
6302
|
bringLinkToFront(linkElement, renderableLink) {
|
|
6289
6303
|
this.layers.selectionLayer.links.appendChild(linkElement);
|
|
6290
|
-
this.root.selectAll(".link-label").filter((item) => item.link === renderableLink.link).each((
|
|
6304
|
+
this.root.selectAll(".link-label").filter((item) => item.link === renderableLink.link).each((_, i, nodes) => {
|
|
6291
6305
|
const element = nodes[i];
|
|
6292
6306
|
if (element) {
|
|
6293
6307
|
this.layers.selectionLayer.linkLabels.appendChild(element);
|
|
@@ -6298,7 +6312,7 @@ var SelectionManager = class {
|
|
|
6298
6312
|
* Restore elements back to their original layers
|
|
6299
6313
|
*/
|
|
6300
6314
|
restoreSelectedElements(nodeData) {
|
|
6301
|
-
this.root.selectAll("circle").filter((d) => d.id === nodeData.id).each((
|
|
6315
|
+
this.root.selectAll("circle").filter((d) => d.id === nodeData.id).each((_, i, nodes) => {
|
|
6302
6316
|
const element = nodes[i];
|
|
6303
6317
|
if (element) {
|
|
6304
6318
|
this.layers.nodes.appendChild(element);
|
|
@@ -6308,13 +6322,13 @@ var SelectionManager = class {
|
|
|
6308
6322
|
const source = d.link.source;
|
|
6309
6323
|
const target = d.link.target;
|
|
6310
6324
|
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6311
|
-
}).each((
|
|
6325
|
+
}).each((_, i, nodes) => {
|
|
6312
6326
|
const element = nodes[i];
|
|
6313
6327
|
if (element) {
|
|
6314
6328
|
this.layers.links.appendChild(element);
|
|
6315
6329
|
}
|
|
6316
6330
|
});
|
|
6317
|
-
this.root.selectAll("text").filter((d) => d.id === nodeData.id).each((
|
|
6331
|
+
this.root.selectAll("text").filter((d) => d.id === nodeData.id).each((_, i, nodes) => {
|
|
6318
6332
|
const element = nodes[i];
|
|
6319
6333
|
if (element) {
|
|
6320
6334
|
this.layers.nodeLabels.appendChild(element);
|
|
@@ -6324,22 +6338,13 @@ var SelectionManager = class {
|
|
|
6324
6338
|
const source = item.link.source;
|
|
6325
6339
|
const target = item.link.target;
|
|
6326
6340
|
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6327
|
-
}).each((
|
|
6341
|
+
}).each((_, i, nodes) => {
|
|
6328
6342
|
const element = nodes[i];
|
|
6329
6343
|
if (element) {
|
|
6330
6344
|
this.layers.linkLabels.appendChild(element);
|
|
6331
6345
|
}
|
|
6332
6346
|
});
|
|
6333
6347
|
}
|
|
6334
|
-
/**
|
|
6335
|
-
* Utility method to bring any SVG element to front using appendChild
|
|
6336
|
-
* Based on the reference implementation pattern
|
|
6337
|
-
*/
|
|
6338
|
-
bringElementToFront(element) {
|
|
6339
|
-
if (element.parentNode) {
|
|
6340
|
-
element.parentNode.appendChild(element);
|
|
6341
|
-
}
|
|
6342
|
-
}
|
|
6343
6348
|
/**
|
|
6344
6349
|
* Clear hover state to prevent conflicts with selection
|
|
6345
6350
|
* Similar to the clearAllHoverLayers function in create-node-hover.ts
|
|
@@ -6387,6 +6392,25 @@ var SelectionManager = class {
|
|
|
6387
6392
|
}
|
|
6388
6393
|
}
|
|
6389
6394
|
}
|
|
6395
|
+
/**
|
|
6396
|
+
* Immediately update positions of links connected to the specified node
|
|
6397
|
+
* This ensures arrowheads reposition correctly when node radius changes
|
|
6398
|
+
*/
|
|
6399
|
+
updateConnectedLinkPositions(nodeData) {
|
|
6400
|
+
this.root.selectAll("line:not(.link-hit-area)").filter((renderableLink) => {
|
|
6401
|
+
const source = renderableLink.link.source;
|
|
6402
|
+
const target = renderableLink.link.target;
|
|
6403
|
+
return source.id === nodeData.id || target.id === nodeData.id;
|
|
6404
|
+
}).each(function(item) {
|
|
6405
|
+
const linkElement = this;
|
|
6406
|
+
const sourcePoint = getShortenedSourcePoint(item.link, item.style);
|
|
6407
|
+
const targetPoint = getShortenedTargetPoint(item.link, item.style);
|
|
6408
|
+
linkElement.setAttribute("x1", String(sourcePoint.x));
|
|
6409
|
+
linkElement.setAttribute("y1", String(sourcePoint.y));
|
|
6410
|
+
linkElement.setAttribute("x2", String(targetPoint.x));
|
|
6411
|
+
linkElement.setAttribute("y2", String(targetPoint.y));
|
|
6412
|
+
});
|
|
6413
|
+
}
|
|
6390
6414
|
/**
|
|
6391
6415
|
* Clean up resources
|
|
6392
6416
|
*/
|
|
@@ -6553,6 +6577,13 @@ var InteractionManager = class {
|
|
|
6553
6577
|
const nodeElement = event.currentTarget;
|
|
6554
6578
|
this.manager.selectionManager?.selectNode(nodeElement, node);
|
|
6555
6579
|
});
|
|
6580
|
+
selections.linkSelection.on("click.select", (event, renderableLinkData) => {
|
|
6581
|
+
event.stopPropagation();
|
|
6582
|
+
const linkElement = event.currentTarget;
|
|
6583
|
+
if (this.manager.selectionManager) {
|
|
6584
|
+
this.manager.selectionManager.selectLink(linkElement, renderableLinkData, event);
|
|
6585
|
+
}
|
|
6586
|
+
});
|
|
6556
6587
|
selections.linkLabelSelection.on("click.select", (event, renderableLinkLabel) => {
|
|
6557
6588
|
event.stopPropagation();
|
|
6558
6589
|
const correspondingLink = selections.linkSelection.filter((d) => d.link === renderableLinkLabel.link).node();
|
|
@@ -6598,12 +6629,17 @@ var InteractionManager = class {
|
|
|
6598
6629
|
const target = item.link.target;
|
|
6599
6630
|
if (!source.x || !source.y || !target.x || !target.y) return;
|
|
6600
6631
|
const rectElement = this;
|
|
6632
|
+
const dx = target.x - source.x;
|
|
6633
|
+
const dy = target.y - source.y;
|
|
6634
|
+
const angle = Math.atan2(dy, dx);
|
|
6601
6635
|
const midX = (source.x + target.x) / 2;
|
|
6602
6636
|
const midY = (source.y + target.y) / 2;
|
|
6603
6637
|
const width = parseFloat(rectElement.getAttribute("width") || "20");
|
|
6604
6638
|
const height = parseFloat(rectElement.getAttribute("height") || "20");
|
|
6605
6639
|
rectElement.setAttribute("x", String(midX - width / 2));
|
|
6606
6640
|
rectElement.setAttribute("y", String(midY - height / 2));
|
|
6641
|
+
const degrees2 = angle * 180 / Math.PI;
|
|
6642
|
+
rectElement.setAttribute("transform", `rotate(${degrees2}, ${midX}, ${midY})`);
|
|
6607
6643
|
});
|
|
6608
6644
|
});
|
|
6609
6645
|
}
|
package/package.json
CHANGED