From 5cfbbd3dee30d2119a654f9ee63d2888cb397489 Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Wed, 8 Jan 2025 18:43:45 +0530 Subject: [PATCH 01/13] Verticle and horizontal lines achieved(#2170) --- frontend/src/components/views/Graph.svelte | 125 +++++++++++++-------- 1 file changed, 79 insertions(+), 46 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index bfa6592113..6604175e9f 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -100,7 +100,7 @@ const pathString = buildWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn); const dataType = (outputPort.getAttribute("data-datatype") as FrontendGraphDataType) || "General"; - const thick = verticalIn && verticalOut; + const thick = (verticalIn && verticalOut) || (verticalOut && !verticalIn); return { pathString, dataType, thick, dashed }; } @@ -137,7 +137,6 @@ if (!nodesContainer) return []; const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; - const containerBounds = nodesContainer.getBoundingClientRect(); const outX = verticalOut ? outputBounds.x + outputBounds.width / 2 : outputBounds.x + outputBounds.width - 1; @@ -149,55 +148,89 @@ const inY = verticalIn ? inputBounds.y + inputBounds.height - VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : inputBounds.y + inputBounds.height / 2; const inConnectorX = (inX - containerBounds.x) / $nodeGraph.transform.scale; const inConnectorY = (inY - containerBounds.y) / $nodeGraph.transform.scale; - const horizontalGap = Math.abs(outConnectorX - inConnectorX); - const verticalGap = Math.abs(outConnectorY - inConnectorY); - - // TODO: Finish this commented out code replacement for the code below it based on this diagram: - // // Straight: stacking lines which are always straight, or a straight horizontal wire between two aligned nodes - // if ((verticalOut && verticalIn) || (!verticalOut && !verticalIn && verticalGap === 0)) { - // return [ - // { x: outConnectorX, y: outConnectorY }, - // { x: inConnectorX, y: inConnectorY }, - // ]; - // } - - // // L-shape bend - // if (verticalOut !== verticalIn) { - // } - - const curveLength = 24; - const curveFalloffRate = curveLength * Math.PI * 2; - - const horizontalCurveAmount = -(2 ** ((-10 * horizontalGap) / curveFalloffRate)) + 1; - const verticalCurveAmount = -(2 ** ((-10 * verticalGap) / curveFalloffRate)) + 1; - const horizontalCurve = horizontalCurveAmount * curveLength; - const verticalCurve = verticalCurveAmount * curveLength; - - return [ - { x: outConnectorX, y: outConnectorY }, - { x: verticalOut ? outConnectorX : outConnectorX + horizontalCurve, y: verticalOut ? outConnectorY - verticalCurve : outConnectorY }, - { x: verticalIn ? inConnectorX : inConnectorX - horizontalCurve, y: verticalIn ? inConnectorY + verticalCurve : inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + + // Handle straight lines + if ((verticalOut && verticalIn && outConnectorX === inConnectorX) || (!verticalOut && !verticalIn && outConnectorY === inConnectorY)) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + + // Handle L-shaped paths + if ((verticalOut && !verticalIn && outConnectorX === inConnectorX) || (!verticalOut && verticalIn && outConnectorY === inConnectorY)) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + + // Handle standard right-angle paths + if (verticalOut) { + // Start vertical, then horizontal + + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else if (verticalIn) { + // Start horizontal, then vertical + + return [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX, y: outConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + // Both horizontal - use horizontal middle point + + const midX = (outConnectorX + inConnectorX) / 2; + return [ + { x: outConnectorX, y: outConnectorY }, + { x: midX, y: outConnectorY }, + { x: midX, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } } function buildWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { const locations = buildWirePathLocations(outputBounds, inputBounds, verticalOut, verticalIn); if (locations.length === 0) return "[error]"; - const SMOOTHING = 0.5; - const delta01 = { x: (locations[1].x - locations[0].x) * SMOOTHING, y: (locations[1].y - locations[0].y) * SMOOTHING }; - const delta23 = { x: (locations[3].x - locations[2].x) * SMOOTHING, y: (locations[3].y - locations[2].y) * SMOOTHING }; - return ` - M${locations[0].x},${locations[0].y} - L${locations[1].x},${locations[1].y} - C${locations[1].x + delta01.x},${locations[1].y + delta01.y} - ${locations[2].x - delta23.x},${locations[2].y - delta23.y} - ${locations[2].x},${locations[2].y} - L${locations[3].x},${locations[3].y} - ` - .split("\n") - .map((line) => line.trim()) - .join(" "); + + if (locations.length === 2) { + return `M${locations[0].x},${locations[0].y} L${locations[1].x},${locations[1].y}`; + } + + const CORNER_RADIUS = 10; + + // Create path with rounded corners + let path = `M${locations[0].x},${locations[0].y}`; + + for (let i = 1; i < locations.length - 1; i++) { + const prev = locations[i - 1]; + const curr = locations[i]; + const next = locations[i + 1]; + + // Calculate corner points + const isVertical = curr.x === prev.x; + const cornerStart = { + x: curr.x + (isVertical ? 0 : prev.x < curr.x ? -CORNER_RADIUS : CORNER_RADIUS), + y: curr.y + (isVertical ? (prev.y < curr.y ? -CORNER_RADIUS : CORNER_RADIUS) : 0), + }; + const cornerEnd = { + x: curr.x + (isVertical ? (next.x < curr.x ? -CORNER_RADIUS : CORNER_RADIUS) : 0), + y: curr.y + (isVertical ? 0 : next.y < curr.y ? -CORNER_RADIUS : CORNER_RADIUS), + }; + + // Add line to corner start, quadratic curve for corner, then continue to next point + path += ` L${cornerStart.x},${cornerStart.y}`; + path += ` Q${curr.x},${curr.y} ${cornerEnd.x},${cornerEnd.y}`; + } + + path += ` L${locations[locations.length - 1].x},${locations[locations.length - 1].y}`; + return path; } function toggleLayerDisplay(displayAsLayer: boolean, toggleId: bigint) { From 3504f9d3f4788426a180081dfa2505beff231f44 Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Fri, 10 Jan 2025 12:33:56 +0530 Subject: [PATCH 02/13] vertical lines alligned with grid dots --- frontend/src/components/views/Graph.svelte | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 6604175e9f..4cb11740c5 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -100,8 +100,7 @@ const pathString = buildWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn); const dataType = (outputPort.getAttribute("data-datatype") as FrontendGraphDataType) || "General"; - const thick = (verticalIn && verticalOut) || (verticalOut && !verticalIn); - + const thick = verticalIn && verticalOut; return { pathString, dataType, thick, dashed }; } @@ -136,6 +135,8 @@ function buildWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { if (!nodesContainer) return []; + const lineWidth = 2; + const halfLineWidth = lineWidth / 2; const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; const containerBounds = nodesContainer.getBoundingClientRect(); @@ -188,8 +189,8 @@ const midX = (outConnectorX + inConnectorX) / 2; return [ { x: outConnectorX, y: outConnectorY }, - { x: midX, y: outConnectorY }, - { x: midX, y: inConnectorY }, + { x: midX - halfLineWidth, y: outConnectorY }, + { x: midX - halfLineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } From 32db4a9c108c2d18e8954c1f7856f298bb0ba716 Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Fri, 10 Jan 2025 13:44:58 +0530 Subject: [PATCH 03/13] fixed vertical lines positioning --- frontend/src/components/views/Graph.svelte | 27 +++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 4cb11740c5..6194be04a6 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -185,14 +185,25 @@ ]; } else { // Both horizontal - use horizontal middle point - - const midX = (outConnectorX + inConnectorX) / 2; - return [ - { x: outConnectorX, y: outConnectorY }, - { x: midX - halfLineWidth, y: outConnectorY }, - { x: midX - halfLineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + if (outConnectorX > inConnectorX) { + const midY = (inConnectorY + outConnectorY) / 2; + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: midY }, + { x: inConnectorX - gridSpacing, y: midY }, + { x: inConnectorX - gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + const midX = (outConnectorX + inConnectorX) / 2 + (((outConnectorX + inConnectorX) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: midX - halfLineWidth, y: outConnectorY }, + { x: midX - halfLineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } } } From d7744dcdf44c96a048eb85a8e15bc42011c67f79 Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Fri, 10 Jan 2025 14:06:28 +0530 Subject: [PATCH 04/13] Deals with cases 5 and 6 --- frontend/src/components/views/Graph.svelte | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 6194be04a6..588154d975 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -186,21 +186,21 @@ } else { // Both horizontal - use horizontal middle point if (outConnectorX > inConnectorX) { - const midY = (inConnectorY + outConnectorY) / 2; + const midY = (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: midY }, - { x: inConnectorX - gridSpacing, y: midY }, - { x: inConnectorX - gridSpacing, y: inConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: midY }, + { x: inConnectorX - gridSpacing + lineWidth, y: midY }, + { x: inConnectorX - gridSpacing + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } else { const midX = (outConnectorX + inConnectorX) / 2 + (((outConnectorX + inConnectorX) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, - { x: midX - halfLineWidth, y: outConnectorY }, - { x: midX - halfLineWidth, y: inConnectorY }, + { x: midX - lineWidth, y: outConnectorY }, + { x: midX - lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } From c576ab775ef5ad5e0c7c063dc7e7a62c0448efd5 Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Sun, 12 Jan 2025 21:41:35 +0530 Subject: [PATCH 05/13] Fixed case 5 and other problematic zones --- frontend/src/components/views/Graph.svelte | 59 +++++++++++++++++++--- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 588154d975..b98a55017f 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -135,6 +135,7 @@ function buildWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { if (!nodesContainer) return []; + const scale = $nodeGraph.transform.scale; // Get the current scale const lineWidth = 2; const halfLineWidth = lineWidth / 2; const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; @@ -142,13 +143,13 @@ const outX = verticalOut ? outputBounds.x + outputBounds.width / 2 : outputBounds.x + outputBounds.width - 1; const outY = verticalOut ? outputBounds.y + VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : outputBounds.y + outputBounds.height / 2; - const outConnectorX = (outX - containerBounds.x) / $nodeGraph.transform.scale; - const outConnectorY = (outY - containerBounds.y) / $nodeGraph.transform.scale; + const outConnectorX = Math.round((outX - containerBounds.x) / scale); // Adjust for scale + const outConnectorY = Math.round((outY - containerBounds.y) / scale); // Adjust for scale const inX = verticalIn ? inputBounds.x + inputBounds.width / 2 : inputBounds.x + 1; const inY = verticalIn ? inputBounds.y + inputBounds.height - VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : inputBounds.y + inputBounds.height / 2; - const inConnectorX = (inX - containerBounds.x) / $nodeGraph.transform.scale; - const inConnectorY = (inY - containerBounds.y) / $nodeGraph.transform.scale; + const inConnectorX = Math.round((inX - containerBounds.x) / scale); // Adjust for scale + const inConnectorY = Math.round((inY - containerBounds.y) / scale); // Adjust for scale // Handle straight lines if ((verticalOut && verticalIn && outConnectorX === inConnectorX) || (!verticalOut && !verticalIn && outConnectorY === inConnectorY)) { @@ -167,7 +168,7 @@ } // Handle standard right-angle paths - if (verticalOut) { + if (verticalOut && inConnectorX > outConnectorX) { // Start vertical, then horizontal return [ @@ -175,6 +176,15 @@ { x: outConnectorX, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; + } else if (verticalOut && inConnectorX <= outConnectorX) { + const midY = (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: midY + 5.5 * lineWidth }, + { x: inConnectorX - gridSpacing + lineWidth, y: midY + 5.5 * lineWidth }, + { x: inConnectorX - gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; } else if (verticalIn) { // Start horizontal, then vertical @@ -185,7 +195,35 @@ ]; } else { // Both horizontal - use horizontal middle point - if (outConnectorX > inConnectorX) { + // Whwn outConnector point is one of the two closest diagonally opposite points. + if (0 <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= gridSpacing && inConnectorY - outConnectorY >= -1 * gridSpacing && inConnectorY - outConnectorY <= gridSpacing) { + return [ + { x: outConnectorX - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX - 2 * lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + + // When inConnector point lies on the horizontal line above and below the outConnector point. + else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= gridSpacing && outConnectorX > inConnectorX) { + if (inConnectorY < outConnectorY) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: inConnectorY - gridSpacing }, + { x: inConnectorX - gridSpacing, y: inConnectorY - gridSpacing }, + { x: inConnectorX - gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: inConnectorY + gridSpacing }, + { x: inConnectorX - gridSpacing, y: inConnectorY + gridSpacing }, + { x: inConnectorX - gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } else if (outConnectorX > inConnectorX - gridSpacing) { const midY = (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, @@ -195,6 +233,15 @@ { x: inConnectorX - gridSpacing + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; + } + // when inConnector point lies on the vertical grid line two units to the right of outConnector point. + else if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; } else { const midX = (outConnectorX + inConnectorX) / 2 + (((outConnectorX + inConnectorX) / 2) % gridSpacing); return [ From 15dbeb6161353df2cb1f120cc6acb67b749d2ca8 Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Thu, 16 Jan 2025 05:05:01 +0530 Subject: [PATCH 06/13] edge cases solved --- frontend/src/components/views/Graph.svelte | 407 +++++++++++++++++++-- 1 file changed, 371 insertions(+), 36 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index b98a55017f..a89e62ff5c 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -153,10 +153,22 @@ // Handle straight lines if ((verticalOut && verticalIn && outConnectorX === inConnectorX) || (!verticalOut && !verticalIn && outConnectorY === inConnectorY)) { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + if (!verticalOut && !verticalIn && outConnectorY === inConnectorY && outConnectorX > inConnectorX) { + // outConnector point and inConnector point lying on the same horizontal grid line and outConnector lies to the right of inconnector. + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } } // Handle L-shaped paths @@ -168,34 +180,351 @@ } // Handle standard right-angle paths + // Start vertical, then horizontal + if (verticalOut && inConnectorX > outConnectorX) { - // Start vertical, then horizontal + //outConnector point lies to the left of inConnector point. - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + if (outConnectorY < inConnectorY) { + // outConnector point lies above inConnector point. + if (-4 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX < -3 * gridSpacing) { + //3 units above inConnector point. + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else if (-3 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= -1 * gridSpacing) { + if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing }, + { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: outConnectorX + gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + gridSpacing + lineWidth, y: inConnectorY }, + + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } else if (-1 * gridSpacing < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { + if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, + { x: outConnectorX + gridSpacing, y: outConnectorY + 4 * lineWidth }, + + { x: inConnectorX + lineWidth, y: inConnectorY }, + ]; + } else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, + + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing }, + { x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing }, + { x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } else { + const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: midX + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: midX + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } else { + // outConnector point lies below inConnector point. + if (-1 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { + if (0 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, + { x: outConnectorX - gridSpacing, y: outConnectorY + 4 * lineWidth }, + { x: outConnectorX - gridSpacing, y: inConnectorY }, + + { x: inConnectorX, y: inConnectorY }, + ]; + } + + const midY = (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: midY }, + { x: inConnectorX - 2 * gridSpacing, y: midY }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } } else if (verticalOut && inConnectorX <= outConnectorX) { - const midY = (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing); - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: midY + 5.5 * lineWidth }, - { x: inConnectorX - gridSpacing + lineWidth, y: midY + 5.5 * lineWidth }, - { x: inConnectorX - gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + //outConnector point lies to the right of inConnector point. + + if (outConnectorY < inConnectorY) { + // outConnector point lies above inConnector point. + + /*return [ + { x: outConnectorX, y: outConnectorY }, + { x: 36, y: 36 }, + { x: inConnectorX, y: inConnectorY }, + ];*/ + if (-2 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else if (-1 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, + + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + + if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: midX + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: midX + lineWidth, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } else { + //outConnector point lies below inConnector point. + if (outConnectorY - inConnectorY <= gridSpacing) { + //outConnector point lies on the horizontal grid line 1 unit below the inConnector Point + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY + 6 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing, y: outConnectorY + 6 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: midX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: midX, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } else if (1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { + // outConnector point lies on the horizontal grid line 2 units below outConnector point. + + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY + 5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + + { x: inConnectorX, y: inConnectorY }, + ]; + } else if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: midX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: midX, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } + + if (outConnectorY - inConnectorY <= 4 * gridSpacing) { + //0 to 4 units below the outConnector Point + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + const midY = (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: midY }, + { x: inConnectorX - 2 * gridSpacing, y: midY }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } } else if (verticalIn) { // Start horizontal, then vertical - return [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX, y: outConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + if (outConnectorY > inConnectorY) { + // when outConnector lies below inConnector + if (outConnectorX < inConnectorX) { + // outConnectorX lies to the left of inConnectorX + + return [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX, y: outConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + // outConnectorX lies to the right of inConnectorX. + if (outConnectorY - inConnectorY <= gridSpacing) { + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= gridSpacing) { + // outConnector point directly below inConnector point + + return [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX + gridSpacing, y: outConnectorY }, + { x: inConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX, y: outConnectorY - gridSpacing }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + // outConnector point lies below inConnector point and strictly to the right of inConnector Point. + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing + 6.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing + 6.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } else { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX, y: outConnectorY - gridSpacing }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } + } else { + //outConnectorY lies on or above the inConnectorY point. + if (-6 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { + // edge case + if (-1 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX - 4 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + return [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX + 8 * gridSpacing, y: outConnectorY }, + { x: inConnectorX + 8 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + + { x: inConnectorX, y: inConnectorY }, + ]; + } + } else if (4 * gridSpacing < inConnectorX - outConnectorX) { + // left of edge case + const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: midX - 2 * lineWidth, y: outConnectorY }, + { x: midX - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY }, + ]; + } else if (6 * gridSpacing > inConnectorX - outConnectorX) { + // right of edge case + + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + } } else { // Both horizontal - use horizontal middle point - // Whwn outConnector point is one of the two closest diagonally opposite points. + // When inConnector point is one of the two closest diagonally opposite points. if (0 <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= gridSpacing && inConnectorY - outConnectorY >= -1 * gridSpacing && inConnectorY - outConnectorY <= gridSpacing) { return [ { x: outConnectorX - 2 * lineWidth, y: outConnectorY }, @@ -204,46 +533,52 @@ ]; } - // When inConnector point lies on the horizontal line above and below the outConnector point. + // When inConnector point lies on the horizontal line 1 unit above and below the outConnector point. else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= gridSpacing && outConnectorX > inConnectorX) { if (inConnectorY < outConnectorY) { + //horizontal line above outConnectorY return [ { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: inConnectorY - gridSpacing }, - { x: inConnectorX - gridSpacing, y: inConnectorY - gridSpacing }, - { x: inConnectorX - gridSpacing, y: inConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: inConnectorY - gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } else { + // horizontal line below outConnectorY return [ { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: inConnectorY + gridSpacing }, - { x: inConnectorX - gridSpacing, y: inConnectorY + gridSpacing }, - { x: inConnectorX - gridSpacing, y: inConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } } else if (outConnectorX > inConnectorX - gridSpacing) { + // outConnector point to the right of inConnector point const midY = (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, { x: outConnectorX + gridSpacing - 2 * lineWidth, y: midY }, - { x: inConnectorX - gridSpacing + lineWidth, y: midY }, - { x: inConnectorX - gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: midY }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } // when inConnector point lies on the vertical grid line two units to the right of outConnector point. else if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) { return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY }, + { x: outConnectorX - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX - 2 * lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, ]; } else { const midX = (outConnectorX + inConnectorX) / 2 + (((outConnectorX + inConnectorX) / 2) % gridSpacing); + return [ { x: outConnectorX, y: outConnectorY }, { x: midX - lineWidth, y: outConnectorY }, From 651fdb97ee1be379cc57216233eaeded7c7c76ca Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Thu, 16 Jan 2025 09:06:25 +0530 Subject: [PATCH 07/13] edge cases fixed: HorizontalOut & HorizontalIn --- frontend/src/components/views/Graph.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index a89e62ff5c..691fa30194 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -571,9 +571,9 @@ // when inConnector point lies on the vertical grid line two units to the right of outConnector point. else if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) { return [ - { x: outConnectorX - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX - 2 * lineWidth, y: inConnectorY }, - + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } else { From ab5fa9284c03c55e3172772e7e2793980ad0eb4f Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Thu, 16 Jan 2025 15:11:18 +0530 Subject: [PATCH 08/13] added comments --- frontend/src/components/views/Graph.svelte | 60 ++++++++++++---------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 691fa30194..6f351d9c9f 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -137,7 +137,7 @@ const scale = $nodeGraph.transform.scale; // Get the current scale const lineWidth = 2; - const halfLineWidth = lineWidth / 2; + const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; const containerBounds = nodesContainer.getBoundingClientRect(); @@ -154,7 +154,7 @@ // Handle straight lines if ((verticalOut && verticalIn && outConnectorX === inConnectorX) || (!verticalOut && !verticalIn && outConnectorY === inConnectorY)) { if (!verticalOut && !verticalIn && outConnectorY === inConnectorY && outConnectorX > inConnectorX) { - // outConnector point and inConnector point lying on the same horizontal grid line and outConnector lies to the right of inconnector. + // outConnector point and inConnector point lying on the same horizontal grid line and outConnector point lies to the right of inConnector point. return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX + gridSpacing, y: outConnectorY }, @@ -180,15 +180,16 @@ } // Handle standard right-angle paths - // Start vertical, then horizontal + // Start vertical, then horizontal if (verticalOut && inConnectorX > outConnectorX) { //outConnector point lies to the left of inConnector point. if (outConnectorY < inConnectorY) { // outConnector point lies above inConnector point. if (-4 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX < -3 * gridSpacing) { - //3 units above inConnector point. + //outConnector point lies on the vertical grid line 4 units to the left of inConnector point point. + return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, @@ -196,7 +197,9 @@ { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; - } else if (-3 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= -1 * gridSpacing) { + } + if (-3 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= -1 * gridSpacing) { + // outConnector point lying on vertical grid lines 3 and 2 units to the left of inConnector point. if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { return [ { x: outConnectorX, y: outConnectorY }, @@ -226,7 +229,9 @@ ]; } } else if (-1 * gridSpacing < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { + // outConnector point lying on vertical grid line 1 units to the left of inConnector point. if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { + // outConnector point lying on horizontal grid line 1 unit above inConnector point. return [ { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, { x: outConnectorX + gridSpacing, y: outConnectorY + 4 * lineWidth }, @@ -234,9 +239,9 @@ { x: inConnectorX + lineWidth, y: inConnectorY }, ]; } else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { + // outConnector point lying on the same horizontal grid line as inConnector point. return [ { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, ]; } else { @@ -263,24 +268,25 @@ } else { // outConnector point lies below inConnector point. if (-1 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { + // outConnector point lying on vertical grid line 1 unit to the left of inConnector point. if (0 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { + //outConnector point lying on the horizontal grid lines 1 and 2 units below the inConnector point. return [ { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, { x: outConnectorX - gridSpacing, y: outConnectorY + 4 * lineWidth }, { x: outConnectorX - gridSpacing, y: inConnectorY }, - + { x: inConnectorX, y: inConnectorY }, + ]; + } else { + const midY = (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); + return [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: midY }, + { x: inConnectorX - 2 * gridSpacing, y: midY }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } - - const midY = (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: midY }, - { x: inConnectorX - 2 * gridSpacing, y: midY }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; } else { return [ { x: outConnectorX, y: outConnectorY }, @@ -293,14 +299,10 @@ //outConnector point lies to the right of inConnector point. if (outConnectorY < inConnectorY) { - // outConnector point lies above inConnector point. + // outConnector point lying on any horizontal grid line above inConnector point. - /*return [ - { x: outConnectorX, y: outConnectorY }, - { x: 36, y: 36 }, - { x: inConnectorX, y: inConnectorY }, - ];*/ if (-2 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { + // outConnector point lying on horizontal grid line 1 unit above inConnector point. return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, @@ -310,6 +312,7 @@ { x: inConnectorX, y: inConnectorY }, ]; } else if (-1 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { + // outConnector point lying on the same horizontal grid line as inConnector point. return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, @@ -318,9 +321,8 @@ { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; - } - - if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) { + } else if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) { + // outConnector point lying on vertical grid lines 1 and 2 units to the right of inConnector point. return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, @@ -479,7 +481,8 @@ } else { //outConnectorY lies on or above the inConnectorY point. if (-6 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { - // edge case + // edge case: outConnector point lying on vertical grid lines ranging from 4 units to left to 5 units to right of inConnector point. + if (-1 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { return [ { x: outConnectorX, y: outConnectorY }, @@ -501,7 +504,7 @@ ]; } } else if (4 * gridSpacing < inConnectorX - outConnectorX) { - // left of edge case + // left of edge case: outConnector point lying on vertical grid lines more than 4 units to left of inConnector point. const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, @@ -511,7 +514,7 @@ { x: inConnectorX, y: inConnectorY }, ]; } else if (6 * gridSpacing > inConnectorX - outConnectorX) { - // right of edge case + // right of edge case: outConnector point lying on the vertical grid lines more than 5 units to right of inConnector point. return [ { x: outConnectorX, y: outConnectorY }, @@ -587,6 +590,7 @@ ]; } } + return []; } function buildWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { From 2faa45a265a0d0cdb0d9b761b148f7e877f4b512 Mon Sep 17 00:00:00 2001 From: Stargazer1010 Date: Thu, 30 Jan 2025 12:40:24 +0530 Subject: [PATCH 09/13] Changed midX and midY --- frontend/src/components/views/Graph.svelte | 55 ++++++++++------------ 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 6f351d9c9f..5aa3063990 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -151,6 +151,13 @@ const inConnectorX = Math.round((inX - containerBounds.x) / scale); // Adjust for scale const inConnectorY = Math.round((inY - containerBounds.y) / scale); // Adjust for scale + function calculateMidX() { + return (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); + } + function calculateMidY() { + return (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); + } + // Handle straight lines if ((verticalOut && verticalIn && outConnectorX === inConnectorX) || (!verticalOut && !verticalIn && outConnectorY === inConnectorY)) { if (!verticalOut && !verticalIn && outConnectorY === inConnectorY && outConnectorX > inConnectorX) { @@ -235,7 +242,6 @@ return [ { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, { x: outConnectorX + gridSpacing, y: outConnectorY + 4 * lineWidth }, - { x: inConnectorX + lineWidth, y: inConnectorY }, ]; } else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { @@ -256,12 +262,11 @@ ]; } } else { - const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: midX + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: midX + lineWidth, y: inConnectorY }, + { x: calculateMidX() + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX() + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } @@ -278,11 +283,10 @@ { x: inConnectorX, y: inConnectorY }, ]; } else { - const midY = (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: midY }, - { x: inConnectorX - 2 * gridSpacing, y: midY }, + { x: outConnectorX, y: calculateMidY() }, + { x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }, { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; @@ -306,7 +310,6 @@ return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, @@ -316,7 +319,6 @@ return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, @@ -333,12 +335,11 @@ { x: inConnectorX, y: inConnectorY }, ]; } else { - const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: midX + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: midX + lineWidth, y: inConnectorY - 2 * gridSpacing }, + { x: calculateMidX() + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX() + lineWidth, y: inConnectorY - 2 * gridSpacing }, { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, @@ -366,12 +367,11 @@ { x: inConnectorX, y: inConnectorY }, ]; } else { - const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: midX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: midX, y: inConnectorY + 2 * gridSpacing }, + { x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }, { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, @@ -385,7 +385,6 @@ { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY + 5 * lineWidth }, { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, ]; } else if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { @@ -399,12 +398,11 @@ { x: inConnectorX, y: inConnectorY }, ]; } else { - const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: midX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: midX, y: inConnectorY + 2 * gridSpacing }, + { x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }, { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, @@ -422,11 +420,10 @@ { x: inConnectorX, y: inConnectorY }, ]; } else { - const midY = (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: midY }, - { x: inConnectorX - 2 * gridSpacing, y: midY }, + { x: outConnectorX, y: calculateMidY() }, + { x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }, { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; @@ -499,17 +496,16 @@ { x: inConnectorX + 8 * gridSpacing, y: outConnectorY }, { x: inConnectorX + 8 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, ]; } } else if (4 * gridSpacing < inConnectorX - outConnectorX) { // left of edge case: outConnector point lying on vertical grid lines more than 4 units to left of inConnector point. - const midX = (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); + return [ { x: outConnectorX, y: outConnectorY }, - { x: midX - 2 * lineWidth, y: outConnectorY }, - { x: midX - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: calculateMidX() - 2 * lineWidth, y: outConnectorY }, + { x: calculateMidX() - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, { x: inConnectorX, y: inConnectorY }, ]; @@ -562,6 +558,7 @@ } else if (outConnectorX > inConnectorX - gridSpacing) { // outConnector point to the right of inConnector point const midY = (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing); + return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, @@ -580,12 +577,10 @@ { x: inConnectorX, y: inConnectorY }, ]; } else { - const midX = (outConnectorX + inConnectorX) / 2 + (((outConnectorX + inConnectorX) / 2) % gridSpacing); - return [ { x: outConnectorX, y: outConnectorY }, - { x: midX - lineWidth, y: outConnectorY }, - { x: midX - lineWidth, y: inConnectorY }, + { x: calculateMidX() - lineWidth, y: outConnectorY }, + { x: calculateMidX() - lineWidth, y: inConnectorY }, { x: inConnectorX, y: inConnectorY }, ]; } From d7dbee0d26fe8078b4d0efd7c11c0aead3f4f26e Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Wed, 12 Feb 2025 18:08:01 -0800 Subject: [PATCH 10/13] Clean up if/else statements --- frontend/src/components/views/Graph.svelte | 853 +++++++++++---------- 1 file changed, 468 insertions(+), 385 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 9159563fb3..a20551ff10 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -166,6 +166,7 @@ const pathString = buildWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn); const dataType = (outputPort.getAttribute("data-datatype") as FrontendGraphDataType) || "General"; const thick = verticalIn && verticalOut; + return { pathString, dataType, thick, dashed }; } @@ -200,7 +201,8 @@ function buildWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { if (!nodesContainer) return []; - const scale = $nodeGraph.transform.scale; // Get the current scale + // Get the current scale + const scale = $nodeGraph.transform.scale; const lineWidth = 2; const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; @@ -208,293 +210,440 @@ const outX = verticalOut ? outputBounds.x + outputBounds.width / 2 : outputBounds.x + outputBounds.width - 1; const outY = verticalOut ? outputBounds.y + VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : outputBounds.y + outputBounds.height / 2; - const outConnectorX = Math.round((outX - containerBounds.x) / scale); // Adjust for scale - const outConnectorY = Math.round((outY - containerBounds.y) / scale); // Adjust for scale + + // Adjust for scale + const outConnectorX = Math.round((outX - containerBounds.x) / scale); + const outConnectorY = Math.round((outY - containerBounds.y) / scale); const inX = verticalIn ? inputBounds.x + inputBounds.width / 2 : inputBounds.x + 1; const inY = verticalIn ? inputBounds.y + inputBounds.height - VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : inputBounds.y + inputBounds.height / 2; - const inConnectorX = Math.round((inX - containerBounds.x) / scale); // Adjust for scale - const inConnectorY = Math.round((inY - containerBounds.y) / scale); // Adjust for scale - function calculateMidX() { - return (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); - } - function calculateMidY() { - return (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); - } + // Adjust for scale + const inConnectorX = Math.round((inX - containerBounds.x) / scale); + const inConnectorY = Math.round((inY - containerBounds.y) / scale); + + const calculateMidX = () => (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); + const calculateMidY = () => (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); + + const scenarios = [ + // 0 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 1 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 2 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 3 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing }, + { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: outConnectorX + gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 4 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 5 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 6 + () => [ + { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, + { x: outConnectorX + gridSpacing, y: outConnectorY + 4 * lineWidth }, + { x: inConnectorX + lineWidth, y: inConnectorY }, + ], + // 7 + () => [ + { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, + { x: inConnectorX, y: inConnectorY }, + ], + // 8 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing }, + { x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing }, + { x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 9 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX() + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX() + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 10 + () => [ + { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, + { x: outConnectorX - gridSpacing, y: outConnectorY + 4 * lineWidth }, + { x: outConnectorX - gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 11 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: calculateMidY() }, + { x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 12 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 13 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 14 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 15 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 16 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX() + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX() + lineWidth, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 17 + () => [ + { x: outConnectorX, y: outConnectorY + 6 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing, y: outConnectorY + 6 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 18 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 19 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 20 + () => [ + { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY + 5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 21 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 22 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 23 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 24 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX, y: calculateMidY() }, + { x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 25 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX, y: outConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 26 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: inConnectorX + gridSpacing, y: outConnectorY }, + { x: inConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX, y: outConnectorY - gridSpacing }, + { x: inConnectorX, y: inConnectorY }, + ], + // 27 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing + 6.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing + 6.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY }, + ], + // 28 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX, y: outConnectorY - gridSpacing }, + { x: inConnectorX, y: inConnectorY }, + ], + // 29 + () => [ + { x: outConnectorX - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX - 2 * lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 30 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: inConnectorY - gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 31 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY }, + { x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + gridSpacing }, + { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 32 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing) }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing) }, + { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 33 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + // 34 + () => [ + { x: outConnectorX, y: outConnectorY }, + { x: calculateMidX() - lineWidth, y: outConnectorY }, + { x: calculateMidX() - lineWidth, y: inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ], + ]; // Handle straight lines if ((verticalOut && verticalIn && outConnectorX === inConnectorX) || (!verticalOut && !verticalIn && outConnectorY === inConnectorY)) { + // outConnector point and inConnector point lying on the same horizontal grid line and outConnector point lies to the right of inConnector point. if (!verticalOut && !verticalIn && outConnectorY === inConnectorY && outConnectorX > inConnectorX) { - // outConnector point and inConnector point lying on the same horizontal grid line and outConnector point lies to the right of inConnector point. - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + return scenarios[0](); } + + return scenarios[1](); } // Handle L-shaped paths if ((verticalOut && !verticalIn && outConnectorX === inConnectorX) || (!verticalOut && verticalIn && outConnectorY === inConnectorY)) { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + return scenarios[1](); } // Handle standard right-angle paths // Start vertical, then horizontal if (verticalOut && inConnectorX > outConnectorX) { - //outConnector point lies to the left of inConnector point. + // outConnector point lies to the left of inConnector point. if (outConnectorY < inConnectorY) { // outConnector point lies above inConnector point. if (-4 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX < -3 * gridSpacing) { - //outConnector point lies on the vertical grid line 4 units to the left of inConnector point point. + // outConnector point lies on the vertical grid line 4 units to the left of inConnector point point. - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + return scenarios[2](); } + if (-3 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= -1 * gridSpacing) { // outConnector point lying on vertical grid lines 3 and 2 units to the left of inConnector point. if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing }, - { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: outConnectorX + gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + gridSpacing + lineWidth, y: inConnectorY }, - - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + return scenarios[3](); } - } else if (-1 * gridSpacing < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { + + if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { + return scenarios[4](); + } + + return scenarios[5](); + } + + if (-1 * gridSpacing < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { // outConnector point lying on vertical grid line 1 units to the left of inConnector point. if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { // outConnector point lying on horizontal grid line 1 unit above inConnector point. - return [ - { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, - { x: outConnectorX + gridSpacing, y: outConnectorY + 4 * lineWidth }, - { x: inConnectorX + lineWidth, y: inConnectorY }, - ]; - } else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { + return scenarios[6](); + } + + if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { // outConnector point lying on the same horizontal grid line as inConnector point. - return [ - { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing }, - { x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing }, - { x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + return scenarios[7](); } - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX() + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX() + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + + return scenarios[8](); } - } else { - // outConnector point lies below inConnector point. - if (-1 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { - // outConnector point lying on vertical grid line 1 unit to the left of inConnector point. - if (0 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { - //outConnector point lying on the horizontal grid lines 1 and 2 units below the inConnector point. - return [ - { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, - { x: outConnectorX - gridSpacing, y: outConnectorY + 4 * lineWidth }, - { x: outConnectorX - gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: calculateMidY() }, - { x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + + return scenarios[9](); + } + + // outConnector point lies below inConnector point. + if (-1 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { + // outConnector point lying on vertical grid line 1 unit to the left of inConnector point. + if (0 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { + // outConnector point lying on the horizontal grid lines 1 and 2 units below the inConnector point. + return scenarios[10](); } + + return scenarios[11](); } - } else if (verticalOut && inConnectorX <= outConnectorX) { - //outConnector point lies to the right of inConnector point. + + return scenarios[12](); + } + + if (verticalOut && inConnectorX <= outConnectorX) { + // outConnector point lies to the right of inConnector point. if (outConnectorY < inConnectorY) { // outConnector point lying on any horizontal grid line above inConnector point. if (-2 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { // outConnector point lying on horizontal grid line 1 unit above inConnector point. - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else if (-1 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { + return scenarios[13](); + } + + if (-1 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { // outConnector point lying on the same horizontal grid line as inConnector point. - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) { + return scenarios[14](); + } + + if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) { // outConnector point lying on vertical grid lines 1 and 2 units to the right of inConnector point. - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX() + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX() + lineWidth, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + return scenarios[15](); } - } else { - //outConnector point lies below inConnector point. - if (outConnectorY - inConnectorY <= gridSpacing) { - //outConnector point lies on the horizontal grid line 1 unit below the inConnector Point - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) { - return [ - { x: outConnectorX, y: outConnectorY + 6 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing, y: outConnectorY + 6 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } - } else if (1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { - // outConnector point lies on the horizontal grid line 2 units below outConnector point. - - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) { - return [ - { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY + 5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } + + return scenarios[16](); + } + + // outConnector point lies below inConnector point. + if (outConnectorY - inConnectorY <= gridSpacing) { + // outConnector point lies on the horizontal grid line 1 unit below the inConnector Point + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) { + return scenarios[17](); } - if (outConnectorY - inConnectorY <= 4 * gridSpacing) { - //0 to 4 units below the outConnector Point - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: calculateMidY() }, - { x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { + return scenarios[18](); } + + return scenarios[19](); } - } else if (verticalIn) { + + if (1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { + // outConnector point lies on the horizontal grid line 2 units below outConnector point. + + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) { + return scenarios[20](); + } + + if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { + return scenarios[21](); + } + + return scenarios[22](); + } + + if (outConnectorY - inConnectorY <= 4 * gridSpacing) { + // 0 to 4 units below the outConnector Point + return scenarios[23](); + } + + return scenarios[24](); + } + + if (verticalIn) { // Start horizontal, then vertical if (outConnectorY > inConnectorY) { @@ -502,164 +651,109 @@ if (outConnectorX < inConnectorX) { // outConnectorX lies to the left of inConnectorX - return [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX, y: outConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - // outConnectorX lies to the right of inConnectorX. - if (outConnectorY - inConnectorY <= gridSpacing) { - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= gridSpacing) { - // outConnector point directly below inConnector point - - return [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX + gridSpacing, y: outConnectorY }, - { x: inConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX, y: outConnectorY - gridSpacing }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - // outConnector point lies below inConnector point and strictly to the right of inConnector Point. - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing + 6.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing + 6.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; - } - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX, y: outConnectorY - gridSpacing }, - { x: inConnectorX, y: inConnectorY }, - ]; - } + return scenarios[25](); } - } else { - //outConnectorY lies on or above the inConnectorY point. - if (-6 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { - // edge case: outConnector point lying on vertical grid lines ranging from 4 units to left to 5 units to right of inConnector point. - - if (-1 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX - 4 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX + 8 * gridSpacing, y: outConnectorY }, - { x: inConnectorX + 8 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; - } - } else if (4 * gridSpacing < inConnectorX - outConnectorX) { - // left of edge case: outConnector point lying on vertical grid lines more than 4 units to left of inConnector point. - return [ - { x: outConnectorX, y: outConnectorY }, - { x: calculateMidX() - 2 * lineWidth, y: outConnectorY }, - { x: calculateMidX() - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else if (6 * gridSpacing > inConnectorX - outConnectorX) { - // right of edge case: outConnector point lying on the vertical grid lines more than 5 units to right of inConnector point. + // outConnectorX lies to the right of inConnectorX. + if (outConnectorY - inConnectorY <= gridSpacing) { + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= gridSpacing) { + // outConnector point directly below inConnector point - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; + return scenarios[26](); + } + + // outConnector point lies below inConnector point and strictly to the right of inConnector Point. + return scenarios[27](); } - } - } else { - // Both horizontal - use horizontal middle point - // When inConnector point is one of the two closest diagonally opposite points. - if (0 <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= gridSpacing && inConnectorY - outConnectorY >= -1 * gridSpacing && inConnectorY - outConnectorY <= gridSpacing) { - return [ - { x: outConnectorX - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX - 2 * lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; + + return scenarios[28](); } - // When inConnector point lies on the horizontal line 1 unit above and below the outConnector point. - else if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= gridSpacing && outConnectorX > inConnectorX) { - if (inConnectorY < outConnectorY) { - //horizontal line above outConnectorY - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: inConnectorY - gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ]; - } else { - // horizontal line below outConnectorY + // outConnectorY lies on or above the inConnectorY point. + if (-6 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { + // edge case: outConnector point lying on vertical grid lines ranging from 4 units to left to 5 units to right of inConnector point. + + if (-1 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { return [ { x: outConnectorX, y: outConnectorY }, { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, + { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing }, + { x: inConnectorX - 4 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, { x: inConnectorX, y: inConnectorY }, ]; } - } else if (outConnectorX > inConnectorX - gridSpacing) { - // outConnector point to the right of inConnector point - const midY = (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing); return [ { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: midY }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: midY }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, + { x: inConnectorX + 8 * gridSpacing, y: outConnectorY }, + { x: inConnectorX + 8 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, { x: inConnectorX, y: inConnectorY }, ]; } - // when inConnector point lies on the vertical grid line two units to the right of outConnector point. - else if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) { + + if (4 * gridSpacing < inConnectorX - outConnectorX) { + // left of edge case: outConnector point lying on vertical grid lines more than 4 units to left of inConnector point. + return [ { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY }, + { x: calculateMidX() - 2 * lineWidth, y: outConnectorY }, + { x: calculateMidX() - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, { x: inConnectorX, y: inConnectorY }, ]; - } else { + } + + if (6 * gridSpacing > inConnectorX - outConnectorX) { + // right of edge case: outConnector point lying on the vertical grid lines more than 5 units to right of inConnector point. + return [ { x: outConnectorX, y: outConnectorY }, - { x: calculateMidX() - lineWidth, y: outConnectorY }, - { x: calculateMidX() - lineWidth, y: inConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, + { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, + { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, { x: inConnectorX, y: inConnectorY }, ]; } } - return []; + + // Both horizontal - use horizontal middle point + // When inConnector point is one of the two closest diagonally opposite points. + if (0 <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= gridSpacing && inConnectorY - outConnectorY >= -1 * gridSpacing && inConnectorY - outConnectorY <= gridSpacing) { + return scenarios[29](); + } + + // When inConnector point lies on the horizontal line 1 unit above and below the outConnector point. + if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= gridSpacing && outConnectorX > inConnectorX) { + if (inConnectorY < outConnectorY) { + // horizontal line above outConnectorY + return scenarios[30](); + } + + // horizontal line below outConnectorY + return scenarios[31](); + } + + if (outConnectorX > inConnectorX - gridSpacing) { + // outConnector point to the right of inConnector point + + return scenarios[32](); + } + + // When inConnector point lies on the vertical grid line two units to the right of outConnector point. + if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) { + return scenarios[33](); + } + + return scenarios[34](); } function buildWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { const locations = buildWirePathLocations(outputBounds, inputBounds, verticalOut, verticalIn); if (locations.length === 0) return "[error]"; - - if (locations.length === 2) { - return `M${locations[0].x},${locations[0].y} L${locations[1].x},${locations[1].y}`; - } + if (locations.length === 2) return `M${locations[0].x},${locations[0].y} L${locations[1].x},${locations[1].y}`; const CORNER_RADIUS = 10; @@ -761,31 +855,20 @@ } function outputConnectedToText(output: FrontendGraphOutput): string { - if (output.connectedTo.length === 0) { - return "Connected to nothing"; - } else { - return output.connectedTo - .map((inputConnector) => { - if ((inputConnector as Node).nodeId === undefined) { - return `Connected to export index ${inputConnector.index}`; - } else { - return `Connected to ${(inputConnector as Node).nodeId}, port index ${inputConnector.index}`; - } - }) - .join("\n"); - } + if (output.connectedTo.length === 0) return "Connected to nothing"; + + return output.connectedTo + .map((inputConnector) => { + if ((inputConnector as Node).nodeId === undefined) return `Connected to export index ${inputConnector.index}`; + return `Connected to ${(inputConnector as Node).nodeId}, port index ${inputConnector.index}`; + }) + .join("\n"); } function inputConnectedToText(input: FrontendGraphInput): string { - if (input.connectedTo === undefined) { - return "Connected to nothing"; - } else { - if ((input.connectedTo as Node).nodeId === undefined) { - return `Connected to import index ${input.connectedTo.index}`; - } else { - return `Connected to ${(input.connectedTo as Node).nodeId}, port index ${input.connectedTo.index}`; - } - } + if (input.connectedTo === undefined) return "Connected to nothing"; + if ((input.connectedTo as Node).nodeId === undefined) return `Connected to import index ${input.connectedTo.index}`; + return `Connected to ${(input.connectedTo as Node).nodeId}, port index ${input.connectedTo.index}`; } function primaryOutputConnectedToLayer(node: FrontendNode): boolean { From 121b34d24f7ad41f96fd4a47a0a0ce7bb376f734 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Wed, 12 Feb 2025 18:15:25 -0800 Subject: [PATCH 11/13] Consolidate code --- frontend/src/components/views/Graph.svelte | 649 ++++++--------------- 1 file changed, 191 insertions(+), 458 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index a20551ff10..cdf9e80877 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -201,553 +201,286 @@ function buildWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { if (!nodesContainer) return []; - // Get the current scale - const scale = $nodeGraph.transform.scale; - const lineWidth = 2; - const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; - const containerBounds = nodesContainer.getBoundingClientRect(); - - const outX = verticalOut ? outputBounds.x + outputBounds.width / 2 : outputBounds.x + outputBounds.width - 1; - const outY = verticalOut ? outputBounds.y + VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : outputBounds.y + outputBounds.height / 2; - - // Adjust for scale - const outConnectorX = Math.round((outX - containerBounds.x) / scale); - const outConnectorY = Math.round((outY - containerBounds.y) / scale); + const LINE_WIDTH = 2; + // Calculate coordinates for input and output connectors const inX = verticalIn ? inputBounds.x + inputBounds.width / 2 : inputBounds.x + 1; const inY = verticalIn ? inputBounds.y + inputBounds.height - VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : inputBounds.y + inputBounds.height / 2; + const outX = verticalOut ? outputBounds.x + outputBounds.width / 2 : outputBounds.x + outputBounds.width - 1; + const outY = verticalOut ? outputBounds.y + VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : outputBounds.y + outputBounds.height / 2; // Adjust for scale + const containerBounds = nodesContainer.getBoundingClientRect(); + const scale = $nodeGraph.transform.scale; const inConnectorX = Math.round((inX - containerBounds.x) / scale); const inConnectorY = Math.round((inY - containerBounds.y) / scale); + const outConnectorX = Math.round((outX - containerBounds.x) / scale); + const outConnectorY = Math.round((outY - containerBounds.y) / scale); + // Helper functions for calculating coordinates const calculateMidX = () => (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); const calculateMidY = () => (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); - const scenarios = [ - // 0 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 1 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 2 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 3 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing }, - { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: outConnectorX + gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 4 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 5 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 6 - () => [ - { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, - { x: outConnectorX + gridSpacing, y: outConnectorY + 4 * lineWidth }, - { x: inConnectorX + lineWidth, y: inConnectorY }, - ], - // 7 - () => [ - { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ], - // 8 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing }, - { x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing }, - { x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 9 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX() + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX() + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 10 - () => [ - { x: outConnectorX, y: outConnectorY + 4 * lineWidth }, - { x: outConnectorX - gridSpacing, y: outConnectorY + 4 * lineWidth }, - { x: outConnectorX - gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 11 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: calculateMidY() }, - { x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 12 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 13 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 14 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - 2 * gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 15 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 16 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX() + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX() + lineWidth, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY - 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 17 - () => [ - { x: outConnectorX, y: outConnectorY + 6 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing, y: outConnectorY + 6 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 18 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 19 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 20 - () => [ - { x: outConnectorX, y: outConnectorY + 5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY + 5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 21 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 22 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 23 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: outConnectorY - gridSpacing + 5.5 * lineWidth }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 24 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX, y: calculateMidY() }, - { x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 25 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX, y: outConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 26 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX + gridSpacing, y: outConnectorY }, - { x: inConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX, y: outConnectorY - gridSpacing }, - { x: inConnectorX, y: inConnectorY }, - ], - // 27 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing + 6.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing + 6.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ], - // 28 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX, y: outConnectorY - gridSpacing }, - { x: inConnectorX, y: inConnectorY }, - ], - // 29 - () => [ - { x: outConnectorX - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX - 2 * lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 30 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: inConnectorY - gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY - gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 31 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY + gridSpacing }, - { x: inConnectorX - 2 * gridSpacing, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 32 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing) }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing) }, - { x: inConnectorX - 2 * gridSpacing + lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 33 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - // 34 - () => [ - { x: outConnectorX, y: outConnectorY }, - { x: calculateMidX() - lineWidth, y: outConnectorY }, - { x: calculateMidX() - lineWidth, y: inConnectorY }, - { x: inConnectorX, y: inConnectorY }, - ], - ]; + // Calculate coordinates for each end/corner of the wire path + const coord0 = () => ({ x: outConnectorX, y: outConnectorY }); + const coord1 = () => ({ x: outConnectorX + gridSpacing, y: outConnectorY }); + const coord2 = () => ({ x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }); + const coord3 = () => ({ x: inConnectorX - 2 * gridSpacing, y: outConnectorY - gridSpacing }); + const coord4 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY }); + const coord5 = () => ({ x: inConnectorX, y: inConnectorY }); + const coord6 = () => ({ x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); + const coord7 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); + const coord8 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: inConnectorY }); + const coord9 = () => ({ x: outConnectorX, y: outConnectorY - gridSpacing }); + const coord10 = () => ({ x: outConnectorX + gridSpacing, y: inConnectorY }); + const coord11 = () => ({ x: outConnectorX + gridSpacing + LINE_WIDTH, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); + const coord12 = () => ({ x: outConnectorX + gridSpacing + LINE_WIDTH, y: inConnectorY }); + const coord13 = () => ({ x: outConnectorX + 2 * gridSpacing + LINE_WIDTH, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); + const coord14 = () => ({ x: outConnectorX + 2 * gridSpacing + LINE_WIDTH, y: inConnectorY - 2 * gridSpacing }); + const coord15 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }); + const coord16 = () => ({ x: outConnectorX, y: outConnectorY + 4 * LINE_WIDTH }); + const coord17 = () => ({ x: outConnectorX + gridSpacing, y: outConnectorY + 4 * LINE_WIDTH }); + const coord18 = () => ({ x: inConnectorX + LINE_WIDTH, y: inConnectorY }); + const coord19 = () => ({ x: outConnectorX, y: outConnectorY + 5 * LINE_WIDTH }); + const coord20 = () => ({ x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing }); + const coord21 = () => ({ x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }); + const coord22 = () => ({ x: calculateMidX() + LINE_WIDTH, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); + const coord23 = () => ({ x: calculateMidX() + LINE_WIDTH, y: inConnectorY }); + const coord24 = () => ({ x: outConnectorX - gridSpacing, y: outConnectorY + 4 * LINE_WIDTH }); + const coord25 = () => ({ x: outConnectorX - gridSpacing, y: inConnectorY }); + const coord26 = () => ({ x: outConnectorX, y: calculateMidY() }); + const coord27 = () => ({ x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }); + const coord28 = () => ({ x: outConnectorX, y: inConnectorY }); + const coord29 = () => ({ x: outConnectorX, y: outConnectorY - 2 * gridSpacing + 5.5 * LINE_WIDTH }); + const coord30 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: outConnectorY - 2 * gridSpacing + 5.5 * LINE_WIDTH }); + const coord31 = () => ({ x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); + const coord32 = () => ({ x: calculateMidX() + LINE_WIDTH, y: inConnectorY - 2 * gridSpacing }); + const coord33 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: inConnectorY - 2 * gridSpacing }); + const coord34 = () => ({ x: outConnectorX, y: outConnectorY + 6 * LINE_WIDTH }); + const coord35 = () => ({ x: inConnectorX - 2 * gridSpacing, y: outConnectorY + 6 * LINE_WIDTH }); + const coord36 = () => ({ x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); + const coord37 = () => ({ x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }); + const coord38 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }); + const coord39 = () => ({ x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); + const coord40 = () => ({ x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }); + const coord41 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: outConnectorY + 5 * LINE_WIDTH }); + const coord42 = () => ({ x: inConnectorX, y: outConnectorY }); + const coord43 = () => ({ x: inConnectorX + gridSpacing, y: outConnectorY }); + const coord44 = () => ({ x: inConnectorX + gridSpacing, y: outConnectorY - gridSpacing }); + const coord45 = () => ({ x: inConnectorX, y: outConnectorY - gridSpacing }); + const coord46 = () => ({ x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing + 6.5 * LINE_WIDTH }); + const coord47 = () => ({ x: inConnectorX, y: inConnectorY + gridSpacing + 6.5 * LINE_WIDTH }); + const coord48 = () => ({ x: inConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing }); + const coord49 = () => ({ x: inConnectorX - 4 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); + const coord50 = () => ({ x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); + const coord51 = () => ({ x: inConnectorX + 8 * gridSpacing, y: outConnectorY }); + const coord52 = () => ({ x: inConnectorX + 8 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); + const coord53 = () => ({ x: calculateMidX() - 2 * LINE_WIDTH, y: outConnectorY }); + const coord54 = () => ({ x: calculateMidX() - 2 * LINE_WIDTH, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); + const coord55 = () => ({ x: outConnectorX + gridSpacing - 2 * LINE_WIDTH, y: outConnectorY }); + const coord56 = () => ({ x: outConnectorX + gridSpacing - 2 * LINE_WIDTH, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); + const coord57 = () => ({ x: outConnectorX - 2 * LINE_WIDTH, y: outConnectorY }); + const coord58 = () => ({ x: outConnectorX - 2 * LINE_WIDTH, y: inConnectorY }); + const coord59 = () => ({ x: outConnectorX + gridSpacing, y: inConnectorY - gridSpacing }); + const coord60 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY - gridSpacing }); + const coord61 = () => ({ x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing }); + const coord62 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY + gridSpacing }); + const coord63 = () => ({ x: outConnectorX + gridSpacing - 2 * LINE_WIDTH, y: (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing) }); + const coord64 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing) }); + const coord65 = () => ({ x: outConnectorX + gridSpacing - 2 * LINE_WIDTH, y: inConnectorY }); + const coord66 = () => ({ x: calculateMidX() - LINE_WIDTH, y: outConnectorY }); + const coord67 = () => ({ x: calculateMidX() - LINE_WIDTH, y: inConnectorY }); + + // Define wire path shapes + const shape0 = () => [coord0(), coord1(), coord2(), coord3(), coord4(), coord5()]; + const shape1 = () => [coord0(), coord5()]; + const shape2 = () => [coord0(), coord6(), coord7(), coord8(), coord5()]; + const shape3 = () => [coord0(), coord9(), coord2(), coord10(), coord5()]; + const shape4 = () => [coord0(), coord6(), coord11(), coord12(), coord5()]; + const shape5 = () => [coord0(), coord6(), coord13(), coord14(), coord15(), coord4(), coord5()]; + const shape6 = () => [coord16(), coord17(), coord18()]; + const shape7 = () => [coord19(), coord5()]; + const shape8 = () => [coord0(), coord9(), coord20(), coord21(), coord15(), coord4(), coord5()]; + const shape9 = () => [coord0(), coord6(), coord22(), coord23(), coord5()]; + const shape10 = () => [coord16(), coord24(), coord25(), coord5()]; + const shape11 = () => [coord0(), coord26(), coord27(), coord4(), coord5()]; + const shape12 = () => [coord0(), coord28(), coord5()]; + const shape13 = () => [coord0(), coord29(), coord30(), coord8(), coord5()]; + const shape14 = () => [coord0(), coord6(), coord31(), coord21(), coord15(), coord4(), coord5()]; + const shape15 = () => [coord0(), coord6(), coord22(), coord32(), coord33(), coord8(), coord5()]; + const shape16 = () => [coord34(), coord35(), coord4(), coord5()]; + const shape17 = () => [coord0(), coord6(), coord36(), coord37(), coord38(), coord4(), coord5()]; + const shape18 = () => [coord0(), coord6(), coord39(), coord40(), coord38(), coord4(), coord5()]; + const shape19 = () => [coord19(), coord41(), coord8(), coord5()]; + const shape20 = () => [coord0(), coord42(), coord5()]; + const shape21 = () => [coord0(), coord43(), coord44(), coord45(), coord5()]; + const shape22 = () => [coord0(), coord1(), coord46(), coord47(), coord5()]; + const shape23 = () => [coord0(), coord1(), coord2(), coord45(), coord5()]; + const shape24 = () => [coord0(), coord1(), coord2(), coord48(), coord49(), coord50(), coord5()]; + const shape25 = () => [coord0(), coord51(), coord52(), coord50(), coord5()]; + const shape26 = () => [coord0(), coord53(), coord54(), coord50(), coord5()]; + const shape27 = () => [coord0(), coord55(), coord56(), coord50(), coord5()]; + const shape28 = () => [coord57(), coord58(), coord5()]; + const shape29 = () => [coord0(), coord1(), coord59(), coord60(), coord4(), coord5()]; + const shape30 = () => [coord0(), coord1(), coord61(), coord62(), coord4(), coord5()]; + const shape31 = () => [coord0(), coord55(), coord63(), coord64(), coord8(), coord5()]; + const shape32 = () => [coord0(), coord55(), coord65(), coord5()]; + const shape33 = () => [coord0(), coord66(), coord67(), coord5()]; // Handle straight lines if ((verticalOut && verticalIn && outConnectorX === inConnectorX) || (!verticalOut && !verticalIn && outConnectorY === inConnectorY)) { - // outConnector point and inConnector point lying on the same horizontal grid line and outConnector point lies to the right of inConnector point. - if (!verticalOut && !verticalIn && outConnectorY === inConnectorY && outConnectorX > inConnectorX) { - return scenarios[0](); - } + // `outConnector` point and `inConnector` point lying on the same horizontal grid line and `outConnector` point lies to the right of `inConnector` point + if (!verticalOut && !verticalIn && outConnectorY === inConnectorY && outConnectorX > inConnectorX) return shape0(); - return scenarios[1](); + return shape1(); } // Handle L-shaped paths - if ((verticalOut && !verticalIn && outConnectorX === inConnectorX) || (!verticalOut && verticalIn && outConnectorY === inConnectorY)) { - return scenarios[1](); - } + if ((verticalOut && !verticalIn && outConnectorX === inConnectorX) || (!verticalOut && verticalIn && outConnectorY === inConnectorY)) return shape1(); // Handle standard right-angle paths - // Start vertical, then horizontal - if (verticalOut && inConnectorX > outConnectorX) { - // outConnector point lies to the left of inConnector point. + // `outConnector` point lies to the left of `inConnector` point + if (verticalOut && inConnectorX > outConnectorX) { + // `outConnector` point lies above `inConnector` point if (outConnectorY < inConnectorY) { - // outConnector point lies above inConnector point. - if (-4 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX < -3 * gridSpacing) { - // outConnector point lies on the vertical grid line 4 units to the left of inConnector point point. - - return scenarios[2](); - } + // `outConnector` point lies on the vertical grid line 4 units to the left of `inConnector` point point + if (-4 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX < -3 * gridSpacing) return shape2(); + // `outConnector` point lying on vertical grid lines 3 and 2 units to the left of `inConnector` point if (-3 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= -1 * gridSpacing) { - // outConnector point lying on vertical grid lines 3 and 2 units to the left of inConnector point. - if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { - return scenarios[3](); - } + if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return shape3(); - if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { - return scenarios[4](); - } + if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return shape4(); - return scenarios[5](); + return shape5(); } + // `outConnector` point lying on vertical grid line 1 units to the left of `inConnector` point if (-1 * gridSpacing < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { - // outConnector point lying on vertical grid line 1 units to the left of inConnector point. - if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { - // outConnector point lying on horizontal grid line 1 unit above inConnector point. - return scenarios[6](); - } + // `outConnector` point lying on horizontal grid line 1 unit above `inConnector` point + if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return shape6(); - if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { - // outConnector point lying on the same horizontal grid line as inConnector point. - return scenarios[7](); - } + // `outConnector` point lying on the same horizontal grid line as `inConnector` point + if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return shape7(); - return scenarios[8](); + return shape8(); } - return scenarios[9](); + return shape9(); } - // outConnector point lies below inConnector point. + // `outConnector` point lies below `inConnector` point + // `outConnector` point lying on vertical grid line 1 unit to the left of `inConnector` point if (-1 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { - // outConnector point lying on vertical grid line 1 unit to the left of inConnector point. - if (0 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { - // outConnector point lying on the horizontal grid lines 1 and 2 units below the inConnector point. - return scenarios[10](); - } + // `outConnector` point lying on the horizontal grid lines 1 and 2 units below the `inConnector` point + if (0 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) shape10(); - return scenarios[11](); + return shape11(); } - return scenarios[12](); + return shape12(); } + // `outConnector` point lies to the right of `inConnector` point if (verticalOut && inConnectorX <= outConnectorX) { - // outConnector point lies to the right of inConnector point. - + // `outConnector` point lying on any horizontal grid line above `inConnector` point if (outConnectorY < inConnectorY) { - // outConnector point lying on any horizontal grid line above inConnector point. + // `outConnector` point lying on horizontal grid line 1 unit above `inConnector` point + if (-2 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return shape2(); - if (-2 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) { - // outConnector point lying on horizontal grid line 1 unit above inConnector point. - return scenarios[13](); - } + // `outConnector` point lying on the same horizontal grid line as `inConnector` point + if (-1 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return shape13(); - if (-1 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) { - // outConnector point lying on the same horizontal grid line as inConnector point. - return scenarios[14](); - } + // `outConnector` point lying on vertical grid lines 1 and 2 units to the right of `inConnector` point + if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) return shape14(); - if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) { - // outConnector point lying on vertical grid lines 1 and 2 units to the right of inConnector point. - return scenarios[15](); - } - - return scenarios[16](); + return shape15(); } - // outConnector point lies below inConnector point. + // `outConnector` point lies below `inConnector` point if (outConnectorY - inConnectorY <= gridSpacing) { - // outConnector point lies on the horizontal grid line 1 unit below the inConnector Point - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) { - return scenarios[17](); - } + // `outConnector` point lies on the horizontal grid line 1 unit below the `inConnector` Point + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) return shape16(); - if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { - return scenarios[18](); - } + if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) return shape17(); - return scenarios[19](); + return shape18(); } + // `outConnector` point lies on the horizontal grid line 2 units below `outConnector` point if (1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { - // outConnector point lies on the horizontal grid line 2 units below outConnector point. - - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) { - return scenarios[20](); - } + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) return shape19(); - if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) { - return scenarios[21](); - } + if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) return shape17(); - return scenarios[22](); + return shape18(); } - if (outConnectorY - inConnectorY <= 4 * gridSpacing) { - // 0 to 4 units below the outConnector Point - return scenarios[23](); - } + // 0 to 4 units below the `outConnector` Point + if (outConnectorY - inConnectorY <= 4 * gridSpacing) return shape2(); - return scenarios[24](); + return shape11(); } + // Start horizontal, then vertical if (verticalIn) { - // Start horizontal, then vertical - + // when `outConnector` lies below `inConnector` if (outConnectorY > inConnectorY) { - // when outConnector lies below inConnector - if (outConnectorX < inConnectorX) { - // outConnectorX lies to the left of inConnectorX + // `outConnectorX` lies to the left of `inConnectorX` + if (outConnectorX < inConnectorX) return shape20(); - return scenarios[25](); - } - - // outConnectorX lies to the right of inConnectorX. + // `outConnectorX` lies to the right of `inConnectorX` if (outConnectorY - inConnectorY <= gridSpacing) { - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= gridSpacing) { - // outConnector point directly below inConnector point - - return scenarios[26](); - } + // `outConnector` point directly below `inConnector` point + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= gridSpacing) return shape21(); - // outConnector point lies below inConnector point and strictly to the right of inConnector Point. - return scenarios[27](); + // `outConnector` point lies below `inConnector` point and strictly to the right of `inConnector` point + return shape22(); } - return scenarios[28](); + return shape23(); } - // outConnectorY lies on or above the inConnectorY point. + // `outConnectorY` lies on or above the `inConnectorY` point if (-6 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { - // edge case: outConnector point lying on vertical grid lines ranging from 4 units to left to 5 units to right of inConnector point. - - if (-1 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY }, - { x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing }, - { x: inConnectorX - 4 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; - } + // edge case: `outConnector` point lying on vertical grid lines ranging from 4 units to left to 5 units to right of `inConnector` point + if (-1 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) return shape24(); - return [ - { x: outConnectorX, y: outConnectorY }, - { x: inConnectorX + 8 * gridSpacing, y: outConnectorY }, - { x: inConnectorX + 8 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; + return shape25(); } - if (4 * gridSpacing < inConnectorX - outConnectorX) { - // left of edge case: outConnector point lying on vertical grid lines more than 4 units to left of inConnector point. - - return [ - { x: outConnectorX, y: outConnectorY }, - { x: calculateMidX() - 2 * lineWidth, y: outConnectorY }, - { x: calculateMidX() - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; - } + // left of edge case: `outConnector` point lying on vertical grid lines more than 4 units to left of `inConnector` point + if (4 * gridSpacing < inConnectorX - outConnectorX) return shape26(); - if (6 * gridSpacing > inConnectorX - outConnectorX) { - // right of edge case: outConnector point lying on the vertical grid lines more than 5 units to right of inConnector point. - - return [ - { x: outConnectorX, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: outConnectorY }, - { x: outConnectorX + gridSpacing - 2 * lineWidth, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * lineWidth }, - { x: inConnectorX, y: inConnectorY }, - ]; - } + // right of edge case: `outConnector` point lying on the vertical grid lines more than 5 units to right of `inConnector` point + if (6 * gridSpacing > inConnectorX - outConnectorX) return shape27(); } // Both horizontal - use horizontal middle point - // When inConnector point is one of the two closest diagonally opposite points. + // When `inConnector` point is one of the two closest diagonally opposite points if (0 <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= gridSpacing && inConnectorY - outConnectorY >= -1 * gridSpacing && inConnectorY - outConnectorY <= gridSpacing) { - return scenarios[29](); + return shape28(); } - // When inConnector point lies on the horizontal line 1 unit above and below the outConnector point. + // When `inConnector` point lies on the horizontal line 1 unit above and below the `outConnector` point if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= gridSpacing && outConnectorX > inConnectorX) { - if (inConnectorY < outConnectorY) { - // horizontal line above outConnectorY - return scenarios[30](); - } + // Horizontal line above `outConnectorY` + if (inConnectorY < outConnectorY) return shape29(); - // horizontal line below outConnectorY - return scenarios[31](); + // Horizontal line below `outConnectorY` + return shape30(); } - if (outConnectorX > inConnectorX - gridSpacing) { - // outConnector point to the right of inConnector point + // `outConnector` point to the right of `inConnector` point + if (outConnectorX > inConnectorX - gridSpacing) return shape31(); - return scenarios[32](); - } - - // When inConnector point lies on the vertical grid line two units to the right of outConnector point. - if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) { - return scenarios[33](); - } + // When `inConnector` point lies on the vertical grid line two units to the right of `outConnector` point + if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) return shape32(); - return scenarios[34](); + return shape33(); } function buildWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { From dce08de7cf41959f33c00eb967e27cdb2a78a3e0 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Wed, 12 Feb 2025 21:39:22 -0800 Subject: [PATCH 12/13] Consolidate further --- frontend/src/components/views/Graph.svelte | 251 ++++++++------------- 1 file changed, 97 insertions(+), 154 deletions(-) diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index cdf9e80877..8ae281f8ab 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -220,124 +220,63 @@ // Helper functions for calculating coordinates const calculateMidX = () => (inConnectorX + outConnectorX) / 2 + (((inConnectorX + outConnectorX) / 2) % gridSpacing); - const calculateMidY = () => (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); - - // Calculate coordinates for each end/corner of the wire path - const coord0 = () => ({ x: outConnectorX, y: outConnectorY }); - const coord1 = () => ({ x: outConnectorX + gridSpacing, y: outConnectorY }); - const coord2 = () => ({ x: outConnectorX + gridSpacing, y: outConnectorY - gridSpacing }); - const coord3 = () => ({ x: inConnectorX - 2 * gridSpacing, y: outConnectorY - gridSpacing }); - const coord4 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY }); - const coord5 = () => ({ x: inConnectorX, y: inConnectorY }); - const coord6 = () => ({ x: outConnectorX, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); - const coord7 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); - const coord8 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: inConnectorY }); - const coord9 = () => ({ x: outConnectorX, y: outConnectorY - gridSpacing }); - const coord10 = () => ({ x: outConnectorX + gridSpacing, y: inConnectorY }); - const coord11 = () => ({ x: outConnectorX + gridSpacing + LINE_WIDTH, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); - const coord12 = () => ({ x: outConnectorX + gridSpacing + LINE_WIDTH, y: inConnectorY }); - const coord13 = () => ({ x: outConnectorX + 2 * gridSpacing + LINE_WIDTH, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); - const coord14 = () => ({ x: outConnectorX + 2 * gridSpacing + LINE_WIDTH, y: inConnectorY - 2 * gridSpacing }); - const coord15 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }); - const coord16 = () => ({ x: outConnectorX, y: outConnectorY + 4 * LINE_WIDTH }); - const coord17 = () => ({ x: outConnectorX + gridSpacing, y: outConnectorY + 4 * LINE_WIDTH }); - const coord18 = () => ({ x: inConnectorX + LINE_WIDTH, y: inConnectorY }); - const coord19 = () => ({ x: outConnectorX, y: outConnectorY + 5 * LINE_WIDTH }); - const coord20 = () => ({ x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing }); - const coord21 = () => ({ x: outConnectorX + 2 * gridSpacing, y: inConnectorY - 2 * gridSpacing }); - const coord22 = () => ({ x: calculateMidX() + LINE_WIDTH, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); - const coord23 = () => ({ x: calculateMidX() + LINE_WIDTH, y: inConnectorY }); - const coord24 = () => ({ x: outConnectorX - gridSpacing, y: outConnectorY + 4 * LINE_WIDTH }); - const coord25 = () => ({ x: outConnectorX - gridSpacing, y: inConnectorY }); - const coord26 = () => ({ x: outConnectorX, y: calculateMidY() }); - const coord27 = () => ({ x: inConnectorX - 2 * gridSpacing, y: calculateMidY() }); - const coord28 = () => ({ x: outConnectorX, y: inConnectorY }); - const coord29 = () => ({ x: outConnectorX, y: outConnectorY - 2 * gridSpacing + 5.5 * LINE_WIDTH }); - const coord30 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: outConnectorY - 2 * gridSpacing + 5.5 * LINE_WIDTH }); - const coord31 = () => ({ x: outConnectorX + 2 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); - const coord32 = () => ({ x: calculateMidX() + LINE_WIDTH, y: inConnectorY - 2 * gridSpacing }); - const coord33 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: inConnectorY - 2 * gridSpacing }); - const coord34 = () => ({ x: outConnectorX, y: outConnectorY + 6 * LINE_WIDTH }); - const coord35 = () => ({ x: inConnectorX - 2 * gridSpacing, y: outConnectorY + 6 * LINE_WIDTH }); - const coord36 = () => ({ x: outConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); - const coord37 = () => ({ x: outConnectorX - 4 * gridSpacing, y: inConnectorY + 2 * gridSpacing }); - const coord38 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY + 2 * gridSpacing }); - const coord39 = () => ({ x: calculateMidX(), y: outConnectorY - gridSpacing + 5.5 * LINE_WIDTH }); - const coord40 = () => ({ x: calculateMidX(), y: inConnectorY + 2 * gridSpacing }); - const coord41 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: outConnectorY + 5 * LINE_WIDTH }); - const coord42 = () => ({ x: inConnectorX, y: outConnectorY }); - const coord43 = () => ({ x: inConnectorX + gridSpacing, y: outConnectorY }); - const coord44 = () => ({ x: inConnectorX + gridSpacing, y: outConnectorY - gridSpacing }); - const coord45 = () => ({ x: inConnectorX, y: outConnectorY - gridSpacing }); - const coord46 = () => ({ x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing + 6.5 * LINE_WIDTH }); - const coord47 = () => ({ x: inConnectorX, y: inConnectorY + gridSpacing + 6.5 * LINE_WIDTH }); - const coord48 = () => ({ x: inConnectorX - 4 * gridSpacing, y: outConnectorY - gridSpacing }); - const coord49 = () => ({ x: inConnectorX - 4 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); - const coord50 = () => ({ x: inConnectorX, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); - const coord51 = () => ({ x: inConnectorX + 8 * gridSpacing, y: outConnectorY }); - const coord52 = () => ({ x: inConnectorX + 8 * gridSpacing, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); - const coord53 = () => ({ x: calculateMidX() - 2 * LINE_WIDTH, y: outConnectorY }); - const coord54 = () => ({ x: calculateMidX() - 2 * LINE_WIDTH, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); - const coord55 = () => ({ x: outConnectorX + gridSpacing - 2 * LINE_WIDTH, y: outConnectorY }); - const coord56 = () => ({ x: outConnectorX + gridSpacing - 2 * LINE_WIDTH, y: inConnectorY + gridSpacing - 5.5 * LINE_WIDTH }); - const coord57 = () => ({ x: outConnectorX - 2 * LINE_WIDTH, y: outConnectorY }); - const coord58 = () => ({ x: outConnectorX - 2 * LINE_WIDTH, y: inConnectorY }); - const coord59 = () => ({ x: outConnectorX + gridSpacing, y: inConnectorY - gridSpacing }); - const coord60 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY - gridSpacing }); - const coord61 = () => ({ x: outConnectorX + gridSpacing, y: inConnectorY + gridSpacing }); - const coord62 = () => ({ x: inConnectorX - 2 * gridSpacing, y: inConnectorY + gridSpacing }); - const coord63 = () => ({ x: outConnectorX + gridSpacing - 2 * LINE_WIDTH, y: (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing) }); - const coord64 = () => ({ x: inConnectorX - 2 * gridSpacing + LINE_WIDTH, y: (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing) }); - const coord65 = () => ({ x: outConnectorX + gridSpacing - 2 * LINE_WIDTH, y: inConnectorY }); - const coord66 = () => ({ x: calculateMidX() - LINE_WIDTH, y: outConnectorY }); - const coord67 = () => ({ x: calculateMidX() - LINE_WIDTH, y: inConnectorY }); - - // Define wire path shapes - const shape0 = () => [coord0(), coord1(), coord2(), coord3(), coord4(), coord5()]; - const shape1 = () => [coord0(), coord5()]; - const shape2 = () => [coord0(), coord6(), coord7(), coord8(), coord5()]; - const shape3 = () => [coord0(), coord9(), coord2(), coord10(), coord5()]; - const shape4 = () => [coord0(), coord6(), coord11(), coord12(), coord5()]; - const shape5 = () => [coord0(), coord6(), coord13(), coord14(), coord15(), coord4(), coord5()]; - const shape6 = () => [coord16(), coord17(), coord18()]; - const shape7 = () => [coord19(), coord5()]; - const shape8 = () => [coord0(), coord9(), coord20(), coord21(), coord15(), coord4(), coord5()]; - const shape9 = () => [coord0(), coord6(), coord22(), coord23(), coord5()]; - const shape10 = () => [coord16(), coord24(), coord25(), coord5()]; - const shape11 = () => [coord0(), coord26(), coord27(), coord4(), coord5()]; - const shape12 = () => [coord0(), coord28(), coord5()]; - const shape13 = () => [coord0(), coord29(), coord30(), coord8(), coord5()]; - const shape14 = () => [coord0(), coord6(), coord31(), coord21(), coord15(), coord4(), coord5()]; - const shape15 = () => [coord0(), coord6(), coord22(), coord32(), coord33(), coord8(), coord5()]; - const shape16 = () => [coord34(), coord35(), coord4(), coord5()]; - const shape17 = () => [coord0(), coord6(), coord36(), coord37(), coord38(), coord4(), coord5()]; - const shape18 = () => [coord0(), coord6(), coord39(), coord40(), coord38(), coord4(), coord5()]; - const shape19 = () => [coord19(), coord41(), coord8(), coord5()]; - const shape20 = () => [coord0(), coord42(), coord5()]; - const shape21 = () => [coord0(), coord43(), coord44(), coord45(), coord5()]; - const shape22 = () => [coord0(), coord1(), coord46(), coord47(), coord5()]; - const shape23 = () => [coord0(), coord1(), coord2(), coord45(), coord5()]; - const shape24 = () => [coord0(), coord1(), coord2(), coord48(), coord49(), coord50(), coord5()]; - const shape25 = () => [coord0(), coord51(), coord52(), coord50(), coord5()]; - const shape26 = () => [coord0(), coord53(), coord54(), coord50(), coord5()]; - const shape27 = () => [coord0(), coord55(), coord56(), coord50(), coord5()]; - const shape28 = () => [coord57(), coord58(), coord5()]; - const shape29 = () => [coord0(), coord1(), coord59(), coord60(), coord4(), coord5()]; - const shape30 = () => [coord0(), coord1(), coord61(), coord62(), coord4(), coord5()]; - const shape31 = () => [coord0(), coord55(), coord63(), coord64(), coord8(), coord5()]; - const shape32 = () => [coord0(), coord55(), coord65(), coord5()]; - const shape33 = () => [coord0(), coord66(), coord67(), coord5()]; + const calculateMidY = () => (inConnectorY + outConnectorY) / 2 + (((inConnectorY + outConnectorY) / 2) % gridSpacing); + const calculateMidYAlternate = () => (inConnectorY + outConnectorY) / 2 - (((inConnectorY + outConnectorY) / 2) % gridSpacing); + + // Define X coordinate calculations + const x1 = () => outConnectorX; + const x2 = () => outConnectorX + gridSpacing; + const x3 = () => inConnectorX - 2 * gridSpacing; + const x4 = () => inConnectorX; + const x5 = () => inConnectorX - 2 * gridSpacing + LINE_WIDTH; + const x6 = () => outConnectorX + gridSpacing + LINE_WIDTH; + const x7 = () => outConnectorX + 2 * gridSpacing + LINE_WIDTH; + const x8 = () => inConnectorX + LINE_WIDTH; + const x9 = () => outConnectorX + 2 * gridSpacing; + const x10 = () => calculateMidX() + LINE_WIDTH; + const x11 = () => outConnectorX - gridSpacing; + const x12 = () => outConnectorX - 4 * gridSpacing; + const x13 = () => calculateMidX(); + const x14 = () => inConnectorX + gridSpacing; + const x15 = () => inConnectorX - 4 * gridSpacing; + const x16 = () => inConnectorX + 8 * gridSpacing; + const x17 = () => calculateMidX() - 2 * LINE_WIDTH; + const x18 = () => outConnectorX + gridSpacing - 2 * LINE_WIDTH; + const x19 = () => outConnectorX - 2 * LINE_WIDTH; + const x20 = () => calculateMidX() - LINE_WIDTH; + + // Define Y coordinate calculations + const y1 = () => outConnectorY; + const y2 = () => outConnectorY - gridSpacing; + const y3 = () => inConnectorY; + const y4 = () => outConnectorY - gridSpacing + 5.5 * LINE_WIDTH; + const y5 = () => inConnectorY - 2 * gridSpacing; + const y6 = () => outConnectorY + 4 * LINE_WIDTH; + const y7 = () => outConnectorY + 5 * LINE_WIDTH; + const y8 = () => outConnectorY - 2 * gridSpacing + 5.5 * LINE_WIDTH; + const y9 = () => outConnectorY + 6 * LINE_WIDTH; + const y10 = () => inConnectorY + 2 * gridSpacing; + const y111 = () => inConnectorY + gridSpacing + 6.5 * LINE_WIDTH; + const y12 = () => inConnectorY + gridSpacing - 5.5 * LINE_WIDTH; + const y13 = () => inConnectorY - gridSpacing; + const y14 = () => inConnectorY + gridSpacing; + const y15 = () => calculateMidY(); + const y16 = () => calculateMidYAlternate(); + + // Helper function for constructing coordinate pairs + const construct = (...coords: [() => number, () => number][]) => coords.map(([x, y]) => ({ x: x(), y: y() })); + + // Define wire path shapes that get used more than once + const wire1 = () => construct([x1, y1], [x1, y4], [x5, y4], [x5, y3], [x4, y3]); + const wire2 = () => construct([x1, y1], [x1, y16], [x3, y16], [x3, y3], [x4, y3]); + const wire3 = () => construct([x1, y1], [x1, y4], [x12, y4], [x12, y10], [x3, y10], [x3, y3], [x4, y3]); + const wire4 = () => construct([x1, y1], [x1, y4], [x13, y4], [x13, y10], [x3, y10], [x3, y3], [x4, y3]); + + // `outConnector` point and `inConnector` point lying on the same horizontal grid line and `outConnector` point lies to the right of `inConnector` point + if (outConnectorY === inConnectorY && outConnectorX > inConnectorX && (verticalOut || !verticalIn)) return construct([x1, y1], [x2, y1], [x2, y2], [x3, y2], [x3, y3], [x4, y3]); // Handle straight lines - if ((verticalOut && verticalIn && outConnectorX === inConnectorX) || (!verticalOut && !verticalIn && outConnectorY === inConnectorY)) { - // `outConnector` point and `inConnector` point lying on the same horizontal grid line and `outConnector` point lies to the right of `inConnector` point - if (!verticalOut && !verticalIn && outConnectorY === inConnectorY && outConnectorX > inConnectorX) return shape0(); - - return shape1(); - } - - // Handle L-shaped paths - if ((verticalOut && !verticalIn && outConnectorX === inConnectorX) || (!verticalOut && verticalIn && outConnectorY === inConnectorY)) return shape1(); + if (outConnectorY === inConnectorY || (outConnectorX === inConnectorX && verticalOut)) return construct([x1, y1], [x4, y3]); // Handle standard right-angle paths // Start vertical, then horizontal @@ -347,41 +286,41 @@ // `outConnector` point lies above `inConnector` point if (outConnectorY < inConnectorY) { // `outConnector` point lies on the vertical grid line 4 units to the left of `inConnector` point point - if (-4 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX < -3 * gridSpacing) return shape2(); + if (-4 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX < -3 * gridSpacing) return wire1(); // `outConnector` point lying on vertical grid lines 3 and 2 units to the left of `inConnector` point if (-3 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= -1 * gridSpacing) { - if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return shape3(); + if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return construct([x1, y1], [x1, y2], [x2, y2], [x2, y3], [x4, y3]); - if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return shape4(); + if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return construct([x1, y1], [x1, y4], [x6, y4], [x6, y3], [x4, y3]); - return shape5(); + return construct([x1, y1], [x1, y4], [x7, y4], [x7, y5], [x3, y5], [x3, y3], [x4, y3]); } // `outConnector` point lying on vertical grid line 1 units to the left of `inConnector` point if (-1 * gridSpacing < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { // `outConnector` point lying on horizontal grid line 1 unit above `inConnector` point - if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return shape6(); + if (-2 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return construct([x1, y6], [x2, y6], [x8, y3]); // `outConnector` point lying on the same horizontal grid line as `inConnector` point - if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return shape7(); + if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return construct([x1, y7], [x4, y3]); - return shape8(); + return construct([x1, y1], [x1, y2], [x9, y2], [x9, y5], [x3, y5], [x3, y3], [x4, y3]); } - return shape9(); + return construct([x1, y1], [x1, y4], [x10, y4], [x10, y3], [x4, y3]); } // `outConnector` point lies below `inConnector` point // `outConnector` point lying on vertical grid line 1 unit to the left of `inConnector` point if (-1 * gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 0 * gridSpacing) { // `outConnector` point lying on the horizontal grid lines 1 and 2 units below the `inConnector` point - if (0 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) shape10(); + if (0 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) construct([x1, y6], [x11, y6], [x11, y3], [x4, y3]); - return shape11(); + return wire2(); } - return shape12(); + return construct([x1, y1], [x1, y3], [x4, y3]); } // `outConnector` point lies to the right of `inConnector` point @@ -389,40 +328,42 @@ // `outConnector` point lying on any horizontal grid line above `inConnector` point if (outConnectorY < inConnectorY) { // `outConnector` point lying on horizontal grid line 1 unit above `inConnector` point - if (-2 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return shape2(); + if (-2 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= -1 * gridSpacing) return wire1(); // `outConnector` point lying on the same horizontal grid line as `inConnector` point - if (-1 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return shape13(); + if (-1 * gridSpacing < outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 0 * gridSpacing) return construct([x1, y1], [x1, y8], [x5, y8], [x5, y3], [x4, y3]); // `outConnector` point lying on vertical grid lines 1 and 2 units to the right of `inConnector` point - if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) return shape14(); + if (gridSpacing <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 3 * gridSpacing) { + return construct([x1, y1], [x1, y4], [x9, y4], [x9, y5], [x3, y5], [x3, y3], [x4, y3]); + } - return shape15(); + return construct([x1, y1], [x1, y4], [x10, y4], [x10, y5], [x5, y5], [x5, y3], [x4, y3]); } // `outConnector` point lies below `inConnector` point if (outConnectorY - inConnectorY <= gridSpacing) { // `outConnector` point lies on the horizontal grid line 1 unit below the `inConnector` Point - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) return shape16(); + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) return construct([x1, y9], [x3, y9], [x3, y3], [x4, y3]); - if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) return shape17(); + if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) return wire3(); - return shape18(); + return wire4(); } // `outConnector` point lies on the horizontal grid line 2 units below `outConnector` point - if (1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) return shape19(); + if (gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= 2 * gridSpacing) { + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 13 * gridSpacing) return construct([x1, y7], [x5, y7], [x5, y3], [x4, y3]); - if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) return shape17(); + if (13 < outConnectorX - inConnectorX && outConnectorX - inConnectorX <= 18 * gridSpacing) return wire3(); - return shape18(); + return wire4(); } // 0 to 4 units below the `outConnector` Point - if (outConnectorY - inConnectorY <= 4 * gridSpacing) return shape2(); + if (outConnectorY - inConnectorY <= 4 * gridSpacing) return wire1(); - return shape11(); + return wire2(); } // Start horizontal, then vertical @@ -430,57 +371,59 @@ // when `outConnector` lies below `inConnector` if (outConnectorY > inConnectorY) { // `outConnectorX` lies to the left of `inConnectorX` - if (outConnectorX < inConnectorX) return shape20(); + if (outConnectorX < inConnectorX) return construct([x1, y1], [x4, y1], [x4, y3]); // `outConnectorX` lies to the right of `inConnectorX` if (outConnectorY - inConnectorY <= gridSpacing) { // `outConnector` point directly below `inConnector` point - if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= gridSpacing) return shape21(); + if (0 <= outConnectorX - inConnectorX && outConnectorX - inConnectorX <= gridSpacing) return construct([x1, y1], [x14, y1], [x14, y2], [x4, y2], [x4, y3]); // `outConnector` point lies below `inConnector` point and strictly to the right of `inConnector` point - return shape22(); + return construct([x1, y1], [x2, y1], [x2, y111], [x4, y111], [x4, y3]); } - return shape23(); + return construct([x1, y1], [x2, y1], [x2, y2], [x4, y2], [x4, y3]); } // `outConnectorY` lies on or above the `inConnectorY` point if (-6 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { // edge case: `outConnector` point lying on vertical grid lines ranging from 4 units to left to 5 units to right of `inConnector` point - if (-1 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) return shape24(); + if (-1 * gridSpacing < inConnectorX - outConnectorX && inConnectorX - outConnectorX < 4 * gridSpacing) { + return construct([x1, y1], [x2, y1], [x2, y2], [x15, y2], [x15, y12], [x4, y12], [x4, y3]); + } - return shape25(); + return construct([x1, y1], [x16, y1], [x16, y12], [x4, y12], [x4, y3]); } // left of edge case: `outConnector` point lying on vertical grid lines more than 4 units to left of `inConnector` point - if (4 * gridSpacing < inConnectorX - outConnectorX) return shape26(); + if (4 * gridSpacing < inConnectorX - outConnectorX) return construct([x1, y1], [x17, y1], [x17, y12], [x4, y12], [x4, y3]); // right of edge case: `outConnector` point lying on the vertical grid lines more than 5 units to right of `inConnector` point - if (6 * gridSpacing > inConnectorX - outConnectorX) return shape27(); + if (6 * gridSpacing > inConnectorX - outConnectorX) return construct([x1, y1], [x18, y1], [x18, y12], [x4, y12], [x4, y3]); } // Both horizontal - use horizontal middle point // When `inConnector` point is one of the two closest diagonally opposite points if (0 <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= gridSpacing && inConnectorY - outConnectorY >= -1 * gridSpacing && inConnectorY - outConnectorY <= gridSpacing) { - return shape28(); + return construct([x19, y1], [x19, y3], [x4, y3]); } // When `inConnector` point lies on the horizontal line 1 unit above and below the `outConnector` point if (-1 * gridSpacing <= outConnectorY - inConnectorY && outConnectorY - inConnectorY <= gridSpacing && outConnectorX > inConnectorX) { // Horizontal line above `outConnectorY` - if (inConnectorY < outConnectorY) return shape29(); + if (inConnectorY < outConnectorY) return construct([x1, y1], [x2, y1], [x2, y13], [x3, y13], [x3, y3], [x4, y3]); // Horizontal line below `outConnectorY` - return shape30(); + return construct([x1, y1], [x2, y1], [x2, y14], [x3, y14], [x3, y3], [x4, y3]); } // `outConnector` point to the right of `inConnector` point - if (outConnectorX > inConnectorX - gridSpacing) return shape31(); + if (outConnectorX > inConnectorX - gridSpacing) return construct([x1, y1], [x18, y1], [x18, y15], [x5, y15], [x5, y3], [x4, y3]); // When `inConnector` point lies on the vertical grid line two units to the right of `outConnector` point - if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) return shape32(); + if (gridSpacing <= inConnectorX - outConnectorX && inConnectorX - outConnectorX <= 2 * gridSpacing) return construct([x1, y1], [x18, y1], [x18, y3], [x4, y3]); - return shape33(); + return construct([x1, y1], [x20, y1], [x20, y3], [x4, y3]); } function buildWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { From f23f7ab283155a7b9322aeebd2bda47643530660 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Wed, 12 Feb 2025 22:51:54 -0800 Subject: [PATCH 13/13] Add preference for wire style --- .../preferences_dialog_message_handler.rs | 66 ++++++++++++----- .../src/messages/frontend/frontend_message.rs | 2 + .../document/document_message_handler.rs | 3 + .../node_graph/node_graph_message_handler.rs | 10 ++- .../document/node_graph/utility_types.rs | 29 ++++++++ .../portfolio/portfolio_message_handler.rs | 2 + .../preferences/preferences_message.rs | 2 + .../preferences_message_handler.rs | 8 +++ frontend/src/components/views/Graph.svelte | 70 +++++++++++++++++-- frontend/src/messages.ts | 2 + frontend/src/state-providers/node-graph.ts | 2 + 11 files changed, 173 insertions(+), 23 deletions(-) diff --git a/editor/src/messages/dialog/preferences_dialog/preferences_dialog_message_handler.rs b/editor/src/messages/dialog/preferences_dialog/preferences_dialog_message_handler.rs index a4b13e70fb..8c0df6d42c 100644 --- a/editor/src/messages/dialog/preferences_dialog/preferences_dialog_message_handler.rs +++ b/editor/src/messages/dialog/preferences_dialog/preferences_dialog_message_handler.rs @@ -1,4 +1,5 @@ use crate::messages::layout::utility_types::widget_prelude::*; +use crate::messages::portfolio::document::node_graph::utility_types::GraphWireStyle; use crate::messages::preferences::SelectionMode; use crate::messages::prelude::*; @@ -32,6 +33,29 @@ impl PreferencesDialogMessageHandler { const TITLE: &'static str = "Editor Preferences"; fn layout(&self, preferences: &PreferencesMessageHandler) -> Layout { + // ===== + // INPUT + // ===== + + let zoom_with_scroll_tooltip = "Use the scroll wheel for zooming instead of vertically panning (not recommended for trackpads)"; + let input_section = vec![TextLabel::new("Input").italic(true).widget_holder()]; + let zoom_with_scroll = vec![ + CheckboxInput::new(preferences.zoom_with_scroll) + .tooltip(zoom_with_scroll_tooltip) + .on_update(|checkbox_input: &CheckboxInput| { + PreferencesMessage::ModifyLayout { + zoom_with_scroll: checkbox_input.checked, + } + .into() + }) + .widget_holder(), + TextLabel::new("Zoom with Scroll").table_align(true).tooltip(zoom_with_scroll_tooltip).widget_holder(), + ]; + + // ========= + // SELECTION + // ========= + let selection_section = vec![TextLabel::new("Selection").italic(true).widget_holder()]; let selection_mode = RadioInput::new(vec![ RadioEntryData::new(SelectionMode::Touched.to_string()) @@ -65,20 +89,28 @@ impl PreferencesDialogMessageHandler { .selected_index(Some(preferences.selection_mode as u32)) .widget_holder(); - let zoom_with_scroll_tooltip = "Use the scroll wheel for zooming instead of vertically panning (not recommended for trackpads)"; - let input_section = vec![TextLabel::new("Input").italic(true).widget_holder()]; - let zoom_with_scroll = vec![ - CheckboxInput::new(preferences.zoom_with_scroll) - .tooltip(zoom_with_scroll_tooltip) - .on_update(|checkbox_input: &CheckboxInput| { - PreferencesMessage::ModifyLayout { - zoom_with_scroll: checkbox_input.checked, - } - .into() - }) - .widget_holder(), - TextLabel::new("Zoom with Scroll").table_align(true).tooltip(zoom_with_scroll_tooltip).widget_holder(), - ]; + // ================ + // NODE GRAPH WIRES + // ================ + + let node_graph_section_tooltip = "Appearance of the wires running between node connections in the graph"; + let node_graph_section = vec![TextLabel::new("Node Graph Wires").tooltip(node_graph_section_tooltip).italic(true).widget_holder()]; + let graph_wire_style = RadioInput::new(vec![ + RadioEntryData::new(GraphWireStyle::GridAligned.to_string()) + .label(GraphWireStyle::GridAligned.to_string()) + .tooltip(GraphWireStyle::GridAligned.tooltip_description()) + .on_update(move |_| PreferencesMessage::GraphWireStyle { style: GraphWireStyle::GridAligned }.into()), + RadioEntryData::new(GraphWireStyle::Direct.to_string()) + .label(GraphWireStyle::Direct.to_string()) + .tooltip(GraphWireStyle::Direct.tooltip_description()) + .on_update(move |_| PreferencesMessage::GraphWireStyle { style: GraphWireStyle::Direct }.into()), + ]) + .selected_index(Some(preferences.graph_wire_style as u32)) + .widget_holder(); + + // ============ + // EXPERIMENTAL + // ============ let vello_tooltip = "Use the experimental Vello renderer (your browser must support WebGPU)"; let renderer_section = vec![TextLabel::new("Experimental").italic(true).widget_holder()]; @@ -126,10 +158,12 @@ impl PreferencesDialogMessageHandler { // ]; Layout::WidgetLayout(WidgetLayout::new(vec![ - LayoutGroup::Row { widgets: selection_section }, - LayoutGroup::Row { widgets: vec![selection_mode] }, LayoutGroup::Row { widgets: input_section }, LayoutGroup::Row { widgets: zoom_with_scroll }, + LayoutGroup::Row { widgets: selection_section }, + LayoutGroup::Row { widgets: vec![selection_mode] }, + LayoutGroup::Row { widgets: node_graph_section }, + LayoutGroup::Row { widgets: vec![graph_wire_style] }, LayoutGroup::Row { widgets: renderer_section }, LayoutGroup::Row { widgets: use_vello }, LayoutGroup::Row { widgets: vector_meshes }, diff --git a/editor/src/messages/frontend/frontend_message.rs b/editor/src/messages/frontend/frontend_message.rs index 3bbf2791b5..89306b2111 100644 --- a/editor/src/messages/frontend/frontend_message.rs +++ b/editor/src/messages/frontend/frontend_message.rs @@ -250,6 +250,8 @@ pub enum FrontendMessage { UpdateNodeGraph { nodes: Vec, wires: Vec, + #[serde(rename = "wiresDirectNotGridAligned")] + wires_direct_not_grid_aligned: bool, }, UpdateNodeGraphControlBarLayout { #[serde(rename = "layoutTarget")] diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index f60d19be31..8cef1fb930 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -42,6 +42,7 @@ pub struct DocumentMessageData<'a> { pub persistent_data: &'a PersistentData, pub executor: &'a mut NodeGraphExecutor, pub current_tool: &'a ToolType, + pub preferences: &'a PreferencesMessageHandler, } #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] @@ -172,6 +173,7 @@ impl MessageHandler> for DocumentMessag persistent_data, executor, current_tool, + preferences, } = data; let selected_nodes_bounding_box_viewport = self.network_interface.selected_nodes_bounding_box_viewport(&self.breadcrumb_network_path); @@ -222,6 +224,7 @@ impl MessageHandler> for DocumentMessag graph_view_overlay_open: self.graph_view_overlay_open, graph_fade_artwork_percentage: self.graph_fade_artwork_percentage, navigation_handler: &self.navigation_handler, + preferences, }, ); } diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index 4a452864ca..b38429f767 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -35,6 +35,7 @@ pub struct NodeGraphHandlerData<'a> { pub graph_view_overlay_open: bool, pub graph_fade_artwork_percentage: f64, pub navigation_handler: &'a NavigationMessageHandler, + pub preferences: &'a PreferencesMessageHandler, } #[derive(Debug, Clone)] @@ -93,6 +94,7 @@ impl<'a> MessageHandler> for NodeGrap graph_view_overlay_open, graph_fade_artwork_percentage, navigation_handler, + preferences, } = data; match message { @@ -1293,8 +1295,14 @@ impl<'a> MessageHandler> for NodeGrap let wires = Self::collect_wires(network_interface, breadcrumb_network_path); let nodes = self.collect_nodes(network_interface, breadcrumb_network_path); let (layer_widths, chain_widths, has_left_input_wire) = network_interface.collect_layer_widths(breadcrumb_network_path); + let wires_direct_not_grid_aligned = preferences.graph_wire_style.is_direct(); + responses.add(NodeGraphMessage::UpdateImportsExports); - responses.add(FrontendMessage::UpdateNodeGraph { nodes, wires }); + responses.add(FrontendMessage::UpdateNodeGraph { + nodes, + wires, + wires_direct_not_grid_aligned, + }); responses.add(FrontendMessage::UpdateLayerWidths { layer_widths, chain_widths, diff --git a/editor/src/messages/portfolio/document/node_graph/utility_types.rs b/editor/src/messages/portfolio/document/node_graph/utility_types.rs index 24e1ee4129..c3cca33883 100644 --- a/editor/src/messages/portfolio/document/node_graph/utility_types.rs +++ b/editor/src/messages/portfolio/document/node_graph/utility_types.rs @@ -200,3 +200,32 @@ pub enum Direction { Left, Right, } + +#[derive(Copy, Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize, specta::Type)] +pub enum GraphWireStyle { + #[default] + GridAligned = 0, + Direct = 1, +} + +impl std::fmt::Display for GraphWireStyle { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GraphWireStyle::GridAligned => write!(f, "Grid-Aligned"), + GraphWireStyle::Direct => write!(f, "Direct"), + } + } +} + +impl GraphWireStyle { + pub fn tooltip_description(&self) -> &'static str { + match self { + GraphWireStyle::GridAligned => "Wires follow the grid, running in straight lines between nodes", + GraphWireStyle::Direct => "Wires bend to run at an angle directly between nodes", + } + } + + pub fn is_direct(&self) -> bool { + *self == GraphWireStyle::Direct + } +} diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index 89497669df..6afd3683f7 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -106,6 +106,7 @@ impl MessageHandler> for PortfolioMes persistent_data: &self.persistent_data, executor: &mut self.executor, current_tool, + preferences, }; document.process_message(message, responses, document_inputs) } @@ -121,6 +122,7 @@ impl MessageHandler> for PortfolioMes persistent_data: &self.persistent_data, executor: &mut self.executor, current_tool, + preferences, }; document.process_message(message, responses, document_inputs) } diff --git a/editor/src/messages/preferences/preferences_message.rs b/editor/src/messages/preferences/preferences_message.rs index d060267a70..63f7d59aae 100644 --- a/editor/src/messages/preferences/preferences_message.rs +++ b/editor/src/messages/preferences/preferences_message.rs @@ -1,3 +1,4 @@ +use crate::messages::portfolio::document::node_graph::utility_types::GraphWireStyle; use crate::messages::preferences::SelectionMode; use crate::messages::prelude::*; @@ -13,6 +14,7 @@ pub enum PreferencesMessage { SelectionMode { selection_mode: SelectionMode }, VectorMeshes { enabled: bool }, ModifyLayout { zoom_with_scroll: bool }, + GraphWireStyle { style: GraphWireStyle }, // ImaginateRefreshFrequency { seconds: f64 }, // ImaginateServerHostname { hostname: String }, } diff --git a/editor/src/messages/preferences/preferences_message_handler.rs b/editor/src/messages/preferences/preferences_message_handler.rs index f52b109b9a..2b51aa2814 100644 --- a/editor/src/messages/preferences/preferences_message_handler.rs +++ b/editor/src/messages/preferences/preferences_message_handler.rs @@ -1,4 +1,5 @@ use crate::messages::input_mapper::key_mapping::MappingVariant; +use crate::messages::portfolio::document::node_graph::utility_types::GraphWireStyle; use crate::messages::preferences::SelectionMode; use crate::messages::prelude::*; @@ -12,6 +13,7 @@ pub struct PreferencesMessageHandler { pub zoom_with_scroll: bool, pub use_vello: bool, pub vector_meshes: bool, + pub graph_wire_style: GraphWireStyle, } impl PreferencesMessageHandler { @@ -37,6 +39,7 @@ impl Default for PreferencesMessageHandler { imaginate_hostname: host_name, use_vello, } = Default::default(); + Self { imaginate_server_hostname: host_name, imaginate_refresh_frequency: 1., @@ -44,6 +47,7 @@ impl Default for PreferencesMessageHandler { zoom_with_scroll: matches!(MappingVariant::default(), MappingVariant::ZoomWithScroll), use_vello, vector_meshes: false, + graph_wire_style: GraphWireStyle::default(), } } } @@ -95,6 +99,10 @@ impl MessageHandler for PreferencesMessageHandler { PreferencesMessage::SelectionMode { selection_mode } => { self.selection_mode = selection_mode; } + PreferencesMessage::GraphWireStyle { style } => { + self.graph_wire_style = style; + responses.add(NodeGraphMessage::SendGraph); + } } // TODO: Reenable when Imaginate is restored (and move back up one line since the auto-formatter doesn't like it in that block) // PreferencesMessage::ImaginateRefreshFrequency { seconds } => { diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 8ae281f8ab..589a8411ac 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -159,11 +159,13 @@ return { nodeOutput, nodeInput }; } - function createWirePath(outputPort: SVGSVGElement, inputPort: SVGSVGElement, verticalOut: boolean, verticalIn: boolean, dashed: boolean): WirePath { + function createWirePath(outputPort: SVGSVGElement, inputPort: SVGSVGElement, verticalOut: boolean, verticalIn: boolean, dashed: boolean, directNotGridAligned: boolean): WirePath { const inputPortRect = inputPort.getBoundingClientRect(); const outputPortRect = outputPort.getBoundingClientRect(); - const pathString = buildWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn); + const pathString = directNotGridAligned + ? buildCurvedWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn) + : buildStraightWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn); const dataType = (outputPort.getAttribute("data-datatype") as FrontendGraphDataType) || "General"; const thick = verticalIn && verticalOut; @@ -184,7 +186,7 @@ const wireEndNode = wire.wireEnd.nodeId !== undefined ? $nodeGraph.nodes.get(wire.wireEnd.nodeId) : undefined; const wireEnd = (wireEndNode?.isLayer && Number(wire.wireEnd.index) === 0) || false; - return [createWirePath(nodeOutput, nodeInput, wireStart, wireEnd, wire.dashed)]; + return [createWirePath(nodeOutput, nodeInput, wireStart, wireEnd, wire.dashed, $nodeGraph.wiresDirectNotGridAligned)]; }); } @@ -198,7 +200,7 @@ return iconMap[icon] || "NodeNodes"; } - function buildWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { + function buildStraightWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { if (!nodesContainer) return []; const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; @@ -426,8 +428,8 @@ return construct([x1, y1], [x20, y1], [x20, y3], [x4, y3]); } - function buildWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { - const locations = buildWirePathLocations(outputBounds, inputBounds, verticalOut, verticalIn); + function buildStraightWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { + const locations = buildStraightWirePathLocations(outputBounds, inputBounds, verticalOut, verticalIn); if (locations.length === 0) return "[error]"; if (locations.length === 2) return `M${locations[0].x},${locations[0].y} L${locations[1].x},${locations[1].y}`; @@ -461,6 +463,62 @@ return path; } + function buildCurvedWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { + if (!nodesContainer) return []; + + const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; + + const containerBounds = nodesContainer.getBoundingClientRect(); + + const outX = verticalOut ? outputBounds.x + outputBounds.width / 2 : outputBounds.x + outputBounds.width - 1; + const outY = verticalOut ? outputBounds.y + VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : outputBounds.y + outputBounds.height / 2; + const outConnectorX = (outX - containerBounds.x) / $nodeGraph.transform.scale; + const outConnectorY = (outY - containerBounds.y) / $nodeGraph.transform.scale; + + const inX = verticalIn ? inputBounds.x + inputBounds.width / 2 : inputBounds.x + 1; + const inY = verticalIn ? inputBounds.y + inputBounds.height - VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : inputBounds.y + inputBounds.height / 2; + const inConnectorX = (inX - containerBounds.x) / $nodeGraph.transform.scale; + const inConnectorY = (inY - containerBounds.y) / $nodeGraph.transform.scale; + const horizontalGap = Math.abs(outConnectorX - inConnectorX); + const verticalGap = Math.abs(outConnectorY - inConnectorY); + + const curveLength = 24; + const curveFalloffRate = curveLength * Math.PI * 2; + + const horizontalCurveAmount = -(2 ** ((-10 * horizontalGap) / curveFalloffRate)) + 1; + const verticalCurveAmount = -(2 ** ((-10 * verticalGap) / curveFalloffRate)) + 1; + const horizontalCurve = horizontalCurveAmount * curveLength; + const verticalCurve = verticalCurveAmount * curveLength; + + return [ + { x: outConnectorX, y: outConnectorY }, + { x: verticalOut ? outConnectorX : outConnectorX + horizontalCurve, y: verticalOut ? outConnectorY - verticalCurve : outConnectorY }, + { x: verticalIn ? inConnectorX : inConnectorX - horizontalCurve, y: verticalIn ? inConnectorY + verticalCurve : inConnectorY }, + { x: inConnectorX, y: inConnectorY }, + ]; + } + + function buildCurvedWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { + const locations = buildCurvedWirePathLocations(outputBounds, inputBounds, verticalOut, verticalIn); + if (locations.length === 0) return "[error]"; + + const SMOOTHING = 0.5; + const delta01 = { x: (locations[1].x - locations[0].x) * SMOOTHING, y: (locations[1].y - locations[0].y) * SMOOTHING }; + const delta23 = { x: (locations[3].x - locations[2].x) * SMOOTHING, y: (locations[3].y - locations[2].y) * SMOOTHING }; + + return ` + M${locations[0].x},${locations[0].y} + L${locations[1].x},${locations[1].y} + C${locations[1].x + delta01.x},${locations[1].y + delta01.y} + ${locations[2].x - delta23.x},${locations[2].y - delta23.y} + ${locations[2].x},${locations[2].y} + L${locations[3].x},${locations[3].y} + ` + .split("\n") + .map((line) => line.trim()) + .join(" "); + } + function toggleLayerDisplay(displayAsLayer: boolean, toggleId: bigint) { let node = $nodeGraph.nodes.get(toggleId); if (node) editor.handle.setToNodeOrLayer(node.id, displayAsLayer); diff --git a/frontend/src/messages.ts b/frontend/src/messages.ts index ca0da8f94f..f6e7188dec 100644 --- a/frontend/src/messages.ts +++ b/frontend/src/messages.ts @@ -100,6 +100,8 @@ export class UpdateNodeGraph extends JsMessage { @Type(() => FrontendNodeWire) readonly wires!: FrontendNodeWire[]; + + readonly wiresDirectNotGridAligned!: boolean; } export class UpdateNodeGraphTransform extends JsMessage { diff --git a/frontend/src/state-providers/node-graph.ts b/frontend/src/state-providers/node-graph.ts index 25e9c51980..266dcf18b8 100644 --- a/frontend/src/state-providers/node-graph.ts +++ b/frontend/src/state-providers/node-graph.ts @@ -41,6 +41,7 @@ export function createNodeGraphState(editor: Editor) { addExport: undefined as { x: number; y: number } | undefined, nodes: new Map(), wires: [] as FrontendNodeWire[], + wiresDirectNotGridAligned: false, wirePathInProgress: undefined as WirePath | undefined, inputTypeDescriptions: new Map(), nodeDescriptions: new Map(), @@ -123,6 +124,7 @@ export function createNodeGraphState(editor: Editor) { state.nodes.set(node.id, node); }); state.wires = updateNodeGraph.wires; + state.wiresDirectNotGridAligned = updateNodeGraph.wiresDirectNotGridAligned; return state; }); });