# Pie Chart (`pie-chart`) - SignalOS widget

> Fully presentational pie/donut chart widget using Recharts. Supports custom colors, labels, semi-circles, padding angles, and responsive design.

- **Version:** 0.2.2
- **Kind:** widget · **Category:** charts
- **Install:** `npx shadcn@latest add @signalos/pie-chart`
- **Registry dependencies (pulled automatically):** @signalos/tokens, @signalos/chart-core
- **npm dependencies:** recharts@^2.15.0
- **Files installed:** `src/components/widgets/pie-chart/PieChart.tsx`, `src/components/widgets/pie-chart/PieChart.types.ts`

## Access

This is a private registry: pulling source requires a `SIGNALOS_REGISTRY_TOKEN`
(GitHub fine-grained PAT with read access to the signal-widgets repo) and an
`@signalos` entry in components.json `"registries"`. Previews and this document are public.

## Usage

```tsx
import { PieChart } from "@/components/widgets/pie-chart/PieChart"
```

## Example

```tsx
import { PieChart } from "@/components/widgets/pie-chart/PieChart"

const data = [
  { name: "Desktop", value: 400 },
  { name: "Mobile", value: 300 },
  { name: "Tablet", value: 200 },
  { name: "Other", value: 100 },
]

export default function PieChartExample() {
  return (
    <PieChart
      data={data}
      height={400}
      innerRadius={60}
      label={{
        show: true,
        position: "inside",
        formatter: (entry) => `${Math.round(entry.percent * 100)}%`,
      }}
    />
  )
}
```

## Props

### `PieChartDataPoint`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `name` | `string` | yes | - | Segment name/label |
| `value` | `number` | yes | - | Segment value |
| `fill` | `string \| undefined` | no | - | Optional custom fill color for this segment |

### `PieChartLabelPayload`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `percent` | `number` | yes | - |  |
| `name` | `string` | yes | - | Segment name/label |
| `value` | `number` | yes | - | Segment value |
| `fill` | `string \| undefined` | no | - | Optional custom fill color for this segment |

### `PieChartLegend`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `verticalAlign` | `"bottom" \| "top" \| "middle" \| undefined` | no | - | Legend position |
| `align` | `"left" \| "center" \| "right" \| undefined` | no | - |  |
| `layout` | `"horizontal" \| "vertical" \| undefined` | no | - | Legend layout |
| `iconType` | `"line" \| "plainline" \| "square" \| "rect" \| "circle" \| "cross" \| "diamond" \| "star" \| "triangle" \| "wye" \| undefined` | no | - | Custom icon type |
| `formatter` | `((value: string, entry: unknown, index: number) => ReactNode) \| undefined` | no | - | Custom legend formatter |

### `PieChartTooltip`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `formatter` | `Formatter<ValueType, NameType> \| undefined` | no | - | Custom tooltip formatter |

### `PieChartLabel`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `show` | `boolean \| undefined` | no | - | Show labels on segments |
| `position` | `"center" \| "inside" \| "outside" \| undefined` | no | - | Label position |
| `formatter` | `((entry: PieChartLabelPayload) => string) \| undefined` | no | - | Custom label formatter |

### `PieChartProps`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `data` | `PieChartDataPoint[]` | yes | - | Array of data points (segments) |
| `width` | `number \| undefined` | no | - | Chart width in pixels |
| `height` | `number \| undefined` | no | - | Chart height in pixels |
| `innerRadius` | `string \| number \| undefined` | no | - | Inner radius for donut chart (0-100, percentage of outer radius) |
| `outerRadius` | `string \| number \| undefined` | no | - | Outer radius (in pixels or percentage) |
| `startAngle` | `number \| undefined` | no | - | Starting angle in degrees |
| `endAngle` | `number \| undefined` | no | - | Ending angle in degrees |
| `paddingAngle` | `number \| undefined` | no | - | Padding angle between segments in degrees |
| `legend` | `boolean \| PieChartLegend \| undefined` | no | - | Legend configuration (false to hide) |
| `tooltip` | `boolean \| PieChartTooltip \| undefined` | no | - | Tooltip configuration (false to hide) |
| `label` | `boolean \| PieChartLabel \| undefined` | no | - | Label configuration |
| `colors` | `string[] \| undefined` | no | - | Default colors for segments (if not specified per segment) |
| `isLoading` | `boolean \| undefined` | no | - | Loading state |
| `emptyState` | `ReactNode` | no | - | Empty state content |
| `onSegmentClick` | `((data: unknown, index: number) => void) \| undefined` | no | - | Click handler for pie segments |
| `responsive` | `boolean \| undefined` | no | - | Responsive container (auto-sizes to parent) |
| `className` | `string \| undefined` | no | - | Container className |
| `style` | `CSSProperties \| undefined` | no | - | Custom container styles |
| `data-testid` | `string \| undefined` | no | - | Test identifier rendered as `data-testid` on the root element. The empty and loading states derive `${dataTestId}-empty` / `${dataTestId}-skeleton`. |

## Changelog

# Changelog - PieChart

## 0.2.2

- Add a `data-testid` passthrough on the root element, with the empty and loading
  states deriving `${dataTestId}-empty` / `${dataTestId}-skeleton`.

## 0.2.1

- Update `data-testid` call sites for the renamed prop.

## 0.2.0

- Factor shared colors, tooltip/legend config, skeleton, and empty state into the chart-core widget; public API unchanged.

## 0.1.1

- Added `PieChartLabelPayload` type (includes `percent`) for typed label formatters.
- `innerRadius` and `outerRadius` now accept `string` (e.g. `"80%"`) in addition to `number`.
- `PieChartLabel.formatter` now typed as `(entry: PieChartLabelPayload) => string` instead of `any`.
- `PieChartTooltip.formatter` now uses Recharts' `TooltipProps` formatter type.
- `PieChartLegend.formatter` signature updated to include `index` parameter.
- `onSegmentClick` parameter type changed from `PieChartDataPoint` to `unknown` for runtime safety.
- Fixed label rendering logic: `label.show=false` now correctly hides labels; `label=true` passes through to Recharts default.

## 0.1.0

Initial release.

- Pie chart component with Recharts integration
- Donut chart support via innerRadius
- Semi-circle and custom angle ranges
- Segment padding angles for visual separation
- Custom colors per segment
- Label support with customizable position and formatting
- Configurable legend and tooltip
- Responsive container support
- Loading skeleton and empty state
- Fully presentational (props-in/events-out pattern)
