import Link from "next/link"; import React, { FC } from "react"; import styles from "./Radar.module.css"; import { Blip } from "@/components/Radar/Blip"; import { Item, Quadrant, Ring } from "@/lib/types"; export interface RadarProps { size?: number; quadrants: Quadrant[]; rings: Ring[]; items: Item[]; } export const Radar: FC = ({ size = 800, quadrants = [], rings = [], items = [], }) => { const viewBoxSize = size; const center = size / 2; const startAngles = [270, 0, 180, 90]; // Corresponding to positions 1, 2, 3, and 4 respectively // Helper function to convert polar coordinates to cartesian const polarToCartesian = ( radius: number, angleInDegrees: number, ): { x: number; y: number } => { const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0; return { x: Math.round(center + radius * Math.cos(angleInRadians)), y: Math.round(center + radius * Math.sin(angleInRadians)), }; }; // Function to generate the path for a ring segment const describeArc = (radiusPercentage: number, position: number): string => { // Define the start and end angles based on the quadrant position const startAngle = startAngles[position - 1]; const endAngle = startAngle + 90; const radius = radiusPercentage * center; // Convert percentage to actual radius const start = polarToCartesian(radius, endAngle); const end = polarToCartesian(radius, startAngle); // prettier-ignore return [ "M", start.x, start.y, "A", radius, radius, 0, 0, 0, end.x, end.y, ].join(" "); }; const renderGlow = (position: number, color: string) => { const gradientId = `glow-${position}`; const cx = position === 1 || position === 3 ? 1 : 0; const cy = position === 1 || position === 2 ? 1 : 0; const x = position === 1 || position === 3 ? 0 : center; const y = position === 1 || position === 2 ? 0 : center; return ( <> ); }; // Function to place items inside their rings and quadrants const renderItem = (item: Item) => { const ring = rings.find((r) => r.id === item.ring); const quadrant = quadrants.find((q) => q.id === item.quadrant); if (!ring || !quadrant) return null; // If no ring or quadrant, don't render item const padding = 15; // Padding in pixels const paddingAngle = 10; // Padding in degrees // Random factors to determine position within the ring const [randomRadius, randomAngleFactor] = item.random || [ Math.sqrt(Math.random()), Math.random(), ]; const innerRadius = (rings[rings.indexOf(ring) - 1]?.radius || 0) + padding / center; // Add inner padding const outerRadius = (ring.radius || 1) - padding / center; // Subtract outer padding const ringWidth = (outerRadius - innerRadius) * center; // Width of the ring in the SVG // Calculate the position within the ring const itemRadius = innerRadius * center + randomRadius * ringWidth; // Calculate the angle with padding offset, avoiding the exact edges const startAngle = startAngles[quadrant.position - 1] + paddingAngle; const endAngle = startAngle + 90 - 2 * paddingAngle; // Subtract padding from both sides const itemAngle = startAngle + (endAngle - startAngle) * randomAngleFactor; // Convert polar coordinates to cartesian for the item's position const { x, y } = polarToCartesian(itemRadius, itemAngle); return ( ); }; return (
{quadrants.map((quadrant) => ( {renderGlow(quadrant.position, quadrant.color)} {rings.map((ring) => ( ))} ))} {items.map((item) => renderItem(item))}
); }; export default Radar;