https://dev.kronoz.win/r/marzneshin.git
1import { FC, useState } from 'react';
2import { Pie } from '@visx/shape';
3import { Group } from '@visx/group';
4import { Text } from '@visx/text';
5
6export type PieChartDataRecord = {
7 symbol: string,
8 amount: number,
9 color: string
10};
11
12export interface PieChartProps {
13 data: PieChartDataRecord[];
14 width: number;
15 height: number;
16 total: number;
17 label: string;
18}
19
20export const PieChart: FC<PieChartProps> = ({ data, width, height, total, label }) => {
21 const half = width / 2;
22 const [active, setActive] = useState<PieChartDataRecord | null>(null);
23
24 return (
25 <svg width={width} height={height}>
26 <Group top={half} left={half}>
27 <Pie
28 data={data}
29 pieValue={(data) => data.amount}
30 outerRadius={half}
31 innerRadius={({ data }) => (active && (active.symbol === data.symbol) ? half - 14 : half - 8)}
32 padAngle={0.01}
33 >
34 {pie => {
35 return pie.arcs.map(arc => {
36 return (
37 <g
38 key={arc.data.symbol}
39 onMouseEnter={() => setActive(arc.data)}
40 onMouseLeave={() => setActive(null)}
41 >
42 <path d={pie.path(arc) ?? ''} className={arc.data.color}></path>
43 </g>
44 )
45 })
46 }}
47 </Pie>
48 <Text
49 textAnchor="middle"
50 fontSize={30}
51 dy={-10}
52 className='fill-primary'
53 >
54 {active ? active.amount : total}
55 </Text>
56 <Text
57 textAnchor="middle"
58 fontSize={15}
59 dy={10}
60 className='fill-muted-foreground'
61 >
62 {label}
63 </Text>
64 </Group>
65 </svg>
66 );
67};