Make sure all connections are drawn at most once
This commit is contained in:
		@@ -27,7 +27,7 @@ export const Connection: React.FC<ConnectionProps> = ({ from, to, fromColor, toC
 | 
				
			|||||||
        y1={from.y}
 | 
					        y1={from.y}
 | 
				
			||||||
        x2={to.x}
 | 
					        x2={to.x}
 | 
				
			||||||
        y2={to.y}
 | 
					        y2={to.y}
 | 
				
			||||||
        stroke="#a855f7"
 | 
					        stroke={fromColor || "#a855f7"}
 | 
				
			||||||
        strokeWidth="1"
 | 
					        strokeWidth="1"
 | 
				
			||||||
        opacity="0.7"
 | 
					        opacity="0.7"
 | 
				
			||||||
        className="transition-all duration-300"
 | 
					        className="transition-all duration-300"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 { useNavigate } from 'react-router-dom';
 | 
				
			||||||
import { MapNode } from './MapNode';
 | 
					import { MapNode } from './MapNode';
 | 
				
			||||||
import { Connection } from './Connection';
 | 
					import { Connection } from './Connection';
 | 
				
			||||||
@@ -20,6 +20,14 @@ interface Position {
 | 
				
			|||||||
  y: number;
 | 
					  y: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ProcessedConnection {
 | 
				
			||||||
 | 
					  key: string;
 | 
				
			||||||
 | 
					  from: Position;
 | 
				
			||||||
 | 
					  to: Position;
 | 
				
			||||||
 | 
					  fromColor: string;
 | 
				
			||||||
 | 
					  toColor: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const fetchRegionData = async (regionName: string): Promise<SolarSystem[]> => {
 | 
					const fetchRegionData = async (regionName: string): Promise<SolarSystem[]> => {
 | 
				
			||||||
  const response = await fetch(`/${regionName}.json`);
 | 
					  const response = await fetch(`/${regionName}.json`);
 | 
				
			||||||
  if (!response.ok) {
 | 
					  if (!response.ok) {
 | 
				
			||||||
@@ -41,6 +49,46 @@ export const RegionMap: React.FC<{ regionName: string }> = ({ regionName }) => {
 | 
				
			|||||||
    queryFn: () => fetchRegionData(regionName),
 | 
					    queryFn: () => fetchRegionData(regionName),
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Process connections once when systems or nodePositions change
 | 
				
			||||||
 | 
					  const processedConnections = useMemo(() => {
 | 
				
			||||||
 | 
					    if (!systems || !nodePositions) return [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const connections = new Map<string, ProcessedConnection>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
					  // Initialize node positions when data is loaded
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    if (systems) {
 | 
					    if (systems) {
 | 
				
			||||||
@@ -191,30 +239,15 @@ export const RegionMap: React.FC<{ regionName: string }> = ({ regionName }) => {
 | 
				
			|||||||
            </defs>
 | 
					            </defs>
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            {/* Render connections first (behind nodes) */}
 | 
					            {/* Render connections first (behind nodes) */}
 | 
				
			||||||
            {systems?.map((system) =>
 | 
					            {processedConnections.map(connection => (
 | 
				
			||||||
              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 (
 | 
					 | 
				
			||||||
              <Connection
 | 
					              <Connection
 | 
				
			||||||
                    key={`${system.solarSystemName}-${connectedSystem}`}
 | 
					                key={connection.key}
 | 
				
			||||||
                    from={fromPos}
 | 
					                from={connection.from}
 | 
				
			||||||
                    to={toPos}
 | 
					                to={connection.to}
 | 
				
			||||||
                    fromColor={fromColor}
 | 
					                fromColor={connection.fromColor}
 | 
				
			||||||
                    toColor={toColor}
 | 
					                toColor={connection.toColor}
 | 
				
			||||||
              />
 | 
					              />
 | 
				
			||||||
                );
 | 
					            ))}
 | 
				
			||||||
              })
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            {/* Render systems */}
 | 
					            {/* Render systems */}
 | 
				
			||||||
            {systems?.map((system) => (
 | 
					            {systems?.map((system) => (
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user