74 lines
2.2 KiB
TypeScript
74 lines
2.2 KiB
TypeScript
"use client"
|
|
|
|
import { useTheme } from "next-themes";
|
|
import { colors } from "@/lib/colors";
|
|
import { useConfig } from "@/hooks/use-config";
|
|
import { ResponsiveContainer, PieChart, Pie, Cell } from 'recharts';
|
|
|
|
const RADIAN = Math.PI / 180;
|
|
const data = [
|
|
{ name: "A", value: 80, color: "#ff0000" },
|
|
{ name: "B", value: 45, color: "#00ff00" },
|
|
{ name: "C", value: 25, color: "#0000ff" },
|
|
];
|
|
const cx = 300;
|
|
const cy = 160;
|
|
const iR = 50;
|
|
const oR = 100;
|
|
const value = 50;
|
|
|
|
const needle = (value: number, data: any, cx: number, cy: number, iR: number, oR: number, color: string) => {
|
|
let total = 0;
|
|
data.forEach((v: any) => {
|
|
total += v.value;
|
|
});
|
|
const ang = 180.0 * (1 - value / total);
|
|
const length = (iR + 2 * oR) / 3;
|
|
const sin = Math.sin(-RADIAN * ang);
|
|
const cos = Math.cos(-RADIAN * ang);
|
|
const r = 5;
|
|
const x0 = cx + 5;
|
|
const y0 = cy + 5;
|
|
const xba = x0 + r * sin;
|
|
const yba = y0 - r * cos;
|
|
const xbb = x0 - r * sin;
|
|
const ybb = y0 + r * cos;
|
|
const xp = x0 + length * cos;
|
|
const yp = y0 + length * sin;
|
|
|
|
return [
|
|
<circle cx={x0} cy={y0} r={r} fill={color} stroke="none" key="pie-needle-circle" />,
|
|
<path d={`M${xba} ${yba}L${xbb} ${ybb} L${xp} ${yp} L${xba} ${yba}`} stroke="#none" fill={color} key="pie-needle-path" />,
|
|
];
|
|
};
|
|
|
|
const PieWithNeedle = ({ height = 300 }) => {
|
|
|
|
const { theme: mode } = useTheme();
|
|
|
|
return (
|
|
<ResponsiveContainer width="100%" height={height}>
|
|
<PieChart height={height}>
|
|
<Pie
|
|
dataKey="value"
|
|
startAngle={180}
|
|
endAngle={0}
|
|
data={data}
|
|
cx={cx}
|
|
cy={cy}
|
|
innerRadius={iR}
|
|
outerRadius={oR}
|
|
fill={colors.primary}
|
|
stroke="none"
|
|
>
|
|
{data.map((entry, index) => (
|
|
<Cell key={`cell-${index}`} fill={entry.color} />
|
|
))}
|
|
</Pie>
|
|
{needle(value, data, cx, cy, iR, oR, colors.warning)}
|
|
</PieChart>
|
|
</ResponsiveContainer>
|
|
);
|
|
};
|
|
|
|
export default PieWithNeedle; |