mediahub-fe/app/[locale]/(protected)/charts/rechart/charts-rechart-pie/piewith-needle.tsx

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;