value: number;
color: string;
};
export default function Towers() {
const data: NewData[] = [
{ name: 'A', value: 120, color: '#FF6384' },
{ name: 'B', value: 150, color: '#36A2EB' },
{ name: 'C', value: 90, color: '#FFCE56' },
{ name: 'D', value: 90, color: '#4BC0C0' },
{ name: 'E', value: 150, color: '#9966FF' },
{ name: 'F', value: 60, color: '#FF9F40' },
{ name: 'G', value: 60, color: '#FF6384' },
{ name: 'H', value: 150, color: '#36A2EB' },
{ name: 'I', value: 120, color: '#FFCE56' },
{ name: 'J', value: 120, color: '#4BC0C0' },
];
const totalItems = data.length;
const anglePerSlice = 360 / totalItems; // Each slice gets an equal angle
const getCoordinatesForAngle = (angle: number) => {
const radians = (angle * Math.PI) / 180;
const x = Math.cos(radians);
const y = Math.sin(radians);
return [x, y];
};
let cumulativeAngle = 0;
return (
<div style={{ width: '500px', height: '500px' }}>
<svg viewBox='0 0 2 2' style={{ transform: 'rotate(-90deg)' }}>
{data.map((slice, index) => {
const [startX, startY] = getCoordinatesForAngle(cumulativeAngle);
cumulativeAngle += anglePerSlice;
const [endX, endY] = getCoordinatesForAngle(cumulativeAngle);
const largeArcFlag = anglePerSlice > 180 ? 1 : 0;
const pathData = `
M ${startX + 1} ${startY + 1}
A 1 1 0 ${largeArcFlag} 1 ${endX + 1} ${endY + 1}
L 1 1
`;
// Calculate midpoint for label rotation
const midAngle = cumulativeAngle - anglePerSlice / 2;
return (
<g key={index}>
{/* Slice */}
<path
d={pathData}
fill={slice.color}
stroke='#fff'
strokeWidth='0.01'
onClick={() => alert(`Clicked on ${slice.name}`)}
/>
{/* Rotated Labels */}
<text
x='1'
y='1'
fontSize='0.1'
textAnchor='middle'
fill='#000'
transform={`rotate(${midAngle} 1 1) translate(0 -0.8)`}
onClick={() => alert(`Clicked on label: ${slice.name}`)}
>
{slice.name}
</text>
</g>
);
})}
{/* White inner circle for the donut effect */}
<circle cx='1' cy='1' r='0.6' fill='white' />
</svg>
</div>
);
}
Start with simpler test data
Обсуждают сегодня