Defer manual canvas edges to Save and restore center-anchor connect.

Keep connect/delete/move as dirty local edits until Save, use straight edges again, and drop Visio side handles so lines attach at the NE center like discovered links.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-08-05 23:48:27 +08:00
parent b4f0e468cb
commit 155cb4e921
7 changed files with 180 additions and 140 deletions

View file

@ -1,14 +1,12 @@
import { BaseEdge, EdgeLabelRenderer, getSmoothStepPath, type EdgeProps } from "@xyflow/react";
import { BaseEdge, EdgeLabelRenderer, getStraightPath, type EdgeProps } from "@xyflow/react";
/** Offset parallel physical links so they do not stack on one line (Visio-like elbows). */
/** Offset parallel physical links so they do not stack on one line. */
export function ParallelEdge({
id,
sourceX,
sourceY,
targetX,
targetY,
sourcePosition,
targetPosition,
style,
markerEnd,
label,
@ -18,20 +16,17 @@ export function ParallelEdge({
}: EdgeProps) {
const index = Number((data as { parallelIndex?: number } | undefined)?.parallelIndex || 0);
const count = Math.max(1, Number((data as { parallelCount?: number } | undefined)?.parallelCount || 1));
const offset = (index - (count - 1) / 2) * 12;
const offset = (index - (count - 1) / 2) * 10;
const dx = targetX - sourceX;
const dy = targetY - sourceY;
const len = Math.hypot(dx, dy) || 1;
const ox = (-dy / len) * offset;
const oy = (dx / len) * offset;
const [path, labelX, labelY] = getSmoothStepPath({
const [path, labelX, labelY] = getStraightPath({
sourceX: sourceX + ox,
sourceY: sourceY + oy,
targetX: targetX + ox,
targetY: targetY + oy,
sourcePosition,
targetPosition,
borderRadius: 8,
});
return (
<>

View file

@ -116,7 +116,7 @@ export function buildLinkDisplayEdges(
const portLabel = formatPortPairLabel(data.source_port || "", data.target_port || "");
out.push({
...e,
type: count > 1 ? "topoParallel" : e.type || "smoothstep",
type: count > 1 ? "topoParallel" : e.type || "straight",
// Never fall back to a stale e.label — it may still contain ports.
label: hidePorts ? undefined : portLabel || undefined,
data,
@ -137,7 +137,7 @@ export function buildLinkDisplayEdges(
const portLabel = formatPortPairLabel(data.source_port || "", data.target_port || "");
out.push({
...e,
type: "smoothstep",
type: "straight",
label: hidePorts ? undefined : portLabel || undefined,
data,
});
@ -162,7 +162,7 @@ export function buildLinkDisplayEdges(
out.push({
...primary,
id: aggregateIdForPair(primary.source, primary.target),
type: "smoothstep",
type: "straight",
label: formatBundleLabel(
list.length,
{ a_port: data.source_port, b_port: data.target_port },