65 lines
1.5 KiB
TypeScript
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>
|
|
);
|
|
});
|
|
}
|