import React from 'react'; import { USP } from '../types'; interface GeometricChartProps { data: USP[]; } export const GeometricChart: React.FC = ({ data }) => { // Increased canvas size to prevent labels (especially on the right side like 'Privacy') from being cut off const size = 500; const center = size / 2; const radius = 110; // Slightly increased radius for better visibility const sides = data.length; // Mint Color #94FBE0 const accentColor = "#94FBE0"; // Calculate polygon points const getPoints = (r: number) => { return data.map((_, i) => { const angle = (Math.PI * 2 * i) / sides - Math.PI / 2; const x = center + r * Math.cos(angle); const y = center + r * Math.sin(angle); return `${x},${y}`; }).join(' '); }; // Calculate data points based on score const getDataPoints = () => { return data.map((item, i) => { const normalizedScore = item.score / 100; const r = radius * normalizedScore; const angle = (Math.PI * 2 * i) / sides - Math.PI / 2; const x = center + r * Math.cos(angle); const y = center + r * Math.sin(angle); return `${x},${y}`; }).join(' '); }; // Calculate label positions (pushed out slightly further) const labelRadius = radius + 55; // Increased padding for labels const labels = data.map((item, i) => { const angle = (Math.PI * 2 * i) / sides - Math.PI / 2; const x = center + labelRadius * Math.cos(angle); const y = center + labelRadius * Math.sin(angle); // Adjust text anchor based on position let anchor: 'start' | 'middle' | 'end' = 'middle'; if (x < center - 20) anchor = 'end'; if (x > center + 20) anchor = 'start'; return { x, y, text: item.label, sub: item.subLabel, anchor, score: item.score }; }); return (
{/* Background Grids (Concentric) - Increased Opacity for Visibility */} {[1, 0.75, 0.5, 0.25].map((scale, i) => ( ))} {/* Axes Lines - Increased Opacity */} {data.map((_, i) => { const angle = (Math.PI * 2 * i) / sides - Math.PI / 2; const x = center + radius * Math.cos(angle); const y = center + radius * Math.sin(angle); return ( ); })} {/* Data Shape */} {/* Data Points (Dots) - Increased base size and highlight size */} {data.map((item, i) => { const normalizedScore = item.score / 100; const r = radius * normalizedScore; const angle = (Math.PI * 2 * i) / sides - Math.PI / 2; const x = center + r * Math.cos(angle); const y = center + r * Math.sin(angle); const isHigh = item.score >= 90; return ( {isHigh && ( )} {/* Base dot is brighter (white) for all, slightly smaller for non-high */} ) })} {/* Labels */} {labels.map((l, i) => { const isHigh = l.score >= 90; return ( {l.text} {l.sub} ); })}
); };