cs-2022-class-profile/components/PieChart.tsx

65 lines
1.5 KiB
TypeScript

import { Group } from "@visx/group";
import Pie, { ProvidedProps } from "@visx/shape/lib/shapes/Pie";
import React, { useState } from "react";
import styles from "./PieChart.module.css";
interface PieChartProps {
data: PieChartData[];
width: number;
height: number;
margin: {
top: number;
bottom: number;
left: number;
right: number;
};
className?: string;
}
interface PieChartData {
category: string;
value: number;
}
export function PieChart(props: PieChartProps) {
return (
<svg className={props.className} width={props.width} height={props.height}>
<Group top={props.margin.top} left={props.margin.left}>
<Pie
data={props.data}
fill="aqua"
pieValue={(d: PieChartData) => d.value}
outerRadius={100}
cornerRadius={3}
padAngle={0.1}
>
{(pie) => <PieSlice {...pie} />}
</Pie>
</Group>
</svg>
);
}
// path, arcs, pie
type PieSliceProps<PieChartData> = ProvidedProps<PieChartData>;
export function PieSlice(props: PieSliceProps<PieChartData>) {
return props.arcs.map((arc) => {
const [centroidX, centroidY] = props.path.centroid(arc);
const pathArc = props.path(arc);
return (
<g key={`arc-${arc.data.category}`} className={styles.group}>
<path className={styles.path} d={pathArc} />
<text
className={styles.text}
x={centroidX}
y={centroidY}
textAnchor="middle"
>{`${arc.data.value}%`}</text>
</g>
);
});
}