From a45de02105438be4167e0e4d0de992ecdb8f19d3 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Sat, 14 Jun 2025 03:33:23 +0200 Subject: [PATCH] Make sure all connections are drawn at most once --- src/components/Connection.tsx | 2 +- src/components/RegionMap.tsx | 83 ++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/components/Connection.tsx b/src/components/Connection.tsx index 4a64a65..2634a36 100644 --- a/src/components/Connection.tsx +++ b/src/components/Connection.tsx @@ -27,7 +27,7 @@ export const Connection: React.FC = ({ from, to, fromColor, toC y1={from.y} x2={to.x} y2={to.y} - stroke="#a855f7" + stroke={fromColor || "#a855f7"} strokeWidth="1" opacity="0.7" className="transition-all duration-300" diff --git a/src/components/RegionMap.tsx b/src/components/RegionMap.tsx index 70f7f1e..45cf8d8 100644 --- a/src/components/RegionMap.tsx +++ b/src/components/RegionMap.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useCallback, useEffect } from 'react'; +import React, { useState, useRef, useCallback, useEffect, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { MapNode } from './MapNode'; import { Connection } from './Connection'; @@ -20,6 +20,14 @@ interface Position { y: number; } +interface ProcessedConnection { + key: string; + from: Position; + to: Position; + fromColor: string; + toColor: string; +} + const fetchRegionData = async (regionName: string): Promise => { const response = await fetch(`/${regionName}.json`); if (!response.ok) { @@ -41,6 +49,46 @@ export const RegionMap: React.FC<{ regionName: string }> = ({ regionName }) => { queryFn: () => fetchRegionData(regionName), }); + // Process connections once when systems or nodePositions change + const processedConnections = useMemo(() => { + if (!systems || !nodePositions) return []; + + const connections = new Map(); + + systems.forEach(system => { + system.connectedSystems?.forEach(connectedSystem => { + // Create a unique key by sorting system names alphabetically + const connectionKey = [system.solarSystemName, connectedSystem].sort().join('-'); + + // Skip if we've already processed this connection + if (connections.has(connectionKey)) return; + + const fromPos = nodePositions[system.solarSystemName]; + const toPos = nodePositions[connectedSystem]; + + // Skip if positions are not available + if (!fromPos || !toPos) return; + + // Calculate average security for the connection + const toSystem = systems.find(s => s.solarSystemName === connectedSystem); + if (!toSystem) return; + + const avgSecurity = (system.security + toSystem.security) / 2; + const connectionColor = getSecurityColor(avgSecurity); + + connections.set(connectionKey, { + key: connectionKey, + from: fromPos, + to: toPos, + fromColor: connectionColor, + toColor: connectionColor + }); + }); + }); + + return Array.from(connections.values()); + }, [systems, nodePositions]); + // Initialize node positions when data is loaded useEffect(() => { if (systems) { @@ -191,30 +239,15 @@ export const RegionMap: React.FC<{ regionName: string }> = ({ regionName }) => { {/* Render connections first (behind nodes) */} - {systems?.map((system) => - system.connectedSystems?.map((connectedSystem) => { - const fromPos = nodePositions[system.solarSystemName]; - const toPos = nodePositions[connectedSystem]; - - // If connected system is not in current region, skip the connection - if (!fromPos || !toPos) return null; - - // Get colors for both systems - const fromColor = getSecurityColor(system.security); - const toSystem = systems.find(s => s.solarSystemName === connectedSystem); - const toColor = toSystem ? getSecurityColor(toSystem.security) : fromColor; - - return ( - - ); - }) - )} + {processedConnections.map(connection => ( + + ))} {/* Render systems */} {systems?.map((system) => (