import { SECTORS } from '@/constants.tsx'; import { Organization } from '@/types.ts'; export interface GraphNode { id: string; label: string; x: number; y: number; color: string; size: number; orgCount: number; } export interface GraphLink { source: string; target: string; value: number; } export const generateGraphData = ( organizations: Organization[], t: (key: string) => string ): { nodes: GraphNode[]; links: GraphLink[] } => { const sectorMap = new Map(); // Map sector nameKey to org IDs SECTORS.forEach((s) => sectorMap.set(s.nameKey, [])); organizations.forEach((org) => { if (sectorMap.has(org.sector)) { sectorMap.get(org.sector)!.push(org.id); } }); // Create nodes const angleStep = (2 * Math.PI) / SECTORS.length; const radius = 150; const nodes: GraphNode[] = SECTORS.map((sector, i) => { const orgCount = sectorMap.get(sector.nameKey)!.length; const sectorName = t(`${sector.nameKey}.name`); return { id: sector.nameKey, label: typeof sectorName === 'string' ? sectorName : sector.nameKey, x: 200 + radius * Math.cos(angleStep * i - Math.PI / 2), y: 200 + radius * Math.sin(angleStep * i - Math.PI / 2), color: sector.colorKey, size: Math.max(10, (orgCount || 0) * 2), orgCount: orgCount, }; }); // Create links const linksMap = new Map(); // key: "source-target" for (let i = 0; i < organizations.length; i++) { for (let j = i + 1; j < organizations.length; j++) { const orgA = organizations[i]; const orgB = organizations[j]; const hasConnection = orgA.offers.some((o) => orgB.needs.some((n) => n.resource.toLowerCase().includes(o.resource.toLowerCase())) ) || orgB.offers.some((o) => orgA.needs.some((n) => n.resource.toLowerCase().includes(o.resource.toLowerCase())) ); if (hasConnection && orgA.sector !== orgB.sector) { const linkKey = [orgA.sector, orgB.sector].sort().join('-'); linksMap.set(linkKey, (linksMap.get(linkKey) || 0) + 1); } } } const links: GraphLink[] = Array.from(linksMap.entries()).map(([key, value]) => { const [source, target] = key.split('-'); return { source, target, value }; }); return { nodes, links }; };