import React from 'react'; import type { OffsetProject } from '../types'; import { getProjectColor } from '../utils/portfolioColors'; interface StaticPortfolioPieChartProps { projects: OffsetProject[]; totalTons: number; size?: number; } export function StaticPortfolioPieChart({ projects, totalTons, size = 280, }: StaticPortfolioPieChartProps) { const centerX = size / 2; const centerY = size / 2; const radius = size * 0.35; const innerRadius = size * 0.20; // Slightly smaller for better labeling const labelRadius = size * 0.50; // Distance for label lines // Helper function to convert polar coordinates to cartesian const polarToCartesian = (centerX: number, centerY: number, radius: number, angleInDegrees: number) => { const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0; return { x: centerX + radius * Math.cos(angleInRadians), y: centerY + radius * Math.sin(angleInRadians), }; }; // Generate SVG path for a donut segment const createSegmentPath = ( startAngle: number, endAngle: number, outerR: number, innerR: number ): string => { const start = polarToCartesian(centerX, centerY, outerR, endAngle); const end = polarToCartesian(centerX, centerY, outerR, startAngle); const innerStart = polarToCartesian(centerX, centerY, innerR, endAngle); const innerEnd = polarToCartesian(centerX, centerY, innerR, startAngle); const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1'; return [ 'M', start.x, start.y, 'A', outerR, outerR, 0, largeArcFlag, 0, end.x, end.y, 'L', innerEnd.x, innerEnd.y, 'A', innerR, innerR, 0, largeArcFlag, 1, innerStart.x, innerStart.y, 'Z', ].join(' '); }; // Calculate segments with label positions const segments: Array<{ path: string; percentage: number; project: OffsetProject; color: string; midAngle: number; tons: number; }> = []; let currentAngle = 0; projects.forEach((project, index) => { if (!project.percentage) return; const percentage = project.percentage * 100; const segmentAngle = (percentage / 100) * 360; const midAngle = currentAngle + segmentAngle / 2; const tons = parseFloat((totalTons * project.percentage).toFixed(2)); const color = getProjectColor(index, projects.length); segments.push({ path: createSegmentPath(currentAngle, currentAngle + segmentAngle, radius, innerRadius), percentage, project, color, midAngle, tons, }); currentAngle += segmentAngle; }); return (
{/* SVG Chart */} {/* Donut segments */} {segments.map((segment, index) => { const labelPoint = polarToCartesian(centerX, centerY, labelRadius, segment.midAngle); const textAnchor = labelPoint.x > centerX ? 'start' : 'end'; const lineEndX = labelPoint.x > centerX ? labelPoint.x + 40 : labelPoint.x - 40; return ( {/* Segment path */} {/* Label line */} {/* Label text */} {segment.project.name} {segment.tons} tons {segment.percentage.toFixed(1)}% ); })} {/* Center text showing total */} {totalTons} tons CO₂ {/* Legend below chart (for print clarity) */}
{segments.map((segment, index) => (

{segment.project.name}

{segment.tons} tons ({segment.percentage.toFixed(1)}%)

))}
); }