79771071

Date: 2025-09-21 20:15:21
Score: 1.5
Natty:
Report link

Here is custom implemention enter image description here

import React, { useState } from "react";

type PieSlice = {
  name: string;
  value: number;
  color: string;
};


interface CustomPieChartProps {
  innerRadius?: number;
  outerRadius?: number;
  gapAngle?: number; // Gap between slices in degrees
  data: PieSlice[];
}

const CustomPieChart: React.FC<CustomPieChartProps> = ({
  innerRadius = 35,
  outerRadius = 60,
  gapAngle = 18,
  data
}) => {
  const total = data.reduce((acc, item) => acc + item.value, 0);
  let cumulativeAngle = -90; // Start from top (12 o'clock position)

  const [tooltip, setTooltip] = useState<{ x: number; y: number; text: string } | null>(null);

  // Function to create donut slice path with asymmetric curved ends
  const createSlice = (startAngle: number, endAngle: number, innerR: number, outerR: number) => {
    const rad = Math.PI / 180;
    const capRadius = 12; // Radius for the rounded caps
    const endCapRadius = capRadius + 10; // Radius for the rounded caps at the end

    // Adjust angles to account for the curved caps
    const adjustedStartAngle = startAngle + gapAngle / 2;
    const adjustedEndAngle = endAngle - (gapAngle) / 2;

    // Outer arc points
    const x1Outer = outerR + outerR * Math.cos(-adjustedStartAngle * rad);
    const y1Outer = outerR + outerR * Math.sin(-adjustedStartAngle * rad);
    const x2Outer = outerR + outerR * Math.cos(-adjustedEndAngle * rad);
    const y2Outer = outerR + outerR * Math.sin(-adjustedEndAngle * rad);

    // Inner arc points
    const x1Inner = outerR + innerR * Math.cos(-adjustedEndAngle * rad);
    const y1Inner = outerR + innerR * Math.sin(-adjustedEndAngle * rad);
    const x2Inner = outerR + innerR * Math.cos(-adjustedStartAngle * rad);
    const y2Inner = outerR + innerR * Math.sin(-adjustedStartAngle * rad);

    const largeArcFlag = adjustedEndAngle - adjustedStartAngle > 180 ? 1 : 0;

    return `
      M${x1Outer},${y1Outer}
      A${outerR},${outerR} 0 ${largeArcFlag} 0 ${x2Outer},${y2Outer}
      A${capRadius},${capRadius} 0 0 0 ${x1Inner},${y1Inner}
      A${innerR},${innerR} 0 ${largeArcFlag} 1 ${x2Inner},${y2Inner}
      A${endCapRadius},${endCapRadius} 0 0 1 ${x1Outer},${y1Outer}
      Z
    `;
  };

  return (
    <div style={{ position: "relative", width: outerRadius * 2, height: outerRadius * 2 }}>
      <svg width={outerRadius * 2} height={outerRadius * 2}>
        {data.map((slice) => {
          const startAngle = cumulativeAngle;
          const angle = (slice.value / total) * 360;
          cumulativeAngle += angle;
          const endAngle = cumulativeAngle;

          return (
            <path
              key={slice.name}
              d={createSlice(startAngle, endAngle, innerRadius, outerRadius)}
              fill={slice.color}
              onMouseMove={(e) =>
                setTooltip({
                  x: e.nativeEvent.offsetX,
                  y: e.nativeEvent.offsetY,
                  text: `${(slice.value / total * 100).toFixed(2)}%`,
                })
              }
              onMouseLeave={() => setTooltip(null)}
              style={{ cursor: "pointer" }}
            />
          );
        })}
      </svg>

      {tooltip && (
        <div
          style={{
            position: "absolute",
            top: tooltip.y + 10,
            left: tooltip.x + 10,
            background: "rgba(0,0,0,0.75)",
            color: "white",
            padding: "4px 8px",
            borderRadius: "8px",
            pointerEvents: "none",
            fontSize: "12px",
            zIndex: 10,
          }}
        >
          {tooltip.text}
        </div>
      )}
    </div>
  );
};

export default CustomPieChart;
Reasons:
  • Blacklisted phrase (1): enter image description here
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: Anmol Gupta