# Area Chart (`area-chart`) - SignalOS widget

> Fully presentational area chart widget using Recharts. Supports multiple areas, stacked areas, custom curve types, fill opacity control, and responsive design.

- **Version:** 0.2.2
- **Kind:** widget · **Category:** charts
- **Install:** `npx shadcn@latest add @signalos/area-chart`
- **Registry dependencies (pulled automatically):** @signalos/tokens, @signalos/chart-core
- **npm dependencies:** recharts@^2.15.0
- **Files installed:** `src/components/widgets/area-chart/AreaChart.tsx`, `src/components/widgets/area-chart/AreaChart.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 { AreaChart } from "@/components/widgets/area-chart/AreaChart"
```

## Example

```tsx
import { AreaChart } from "@/components/widgets/area-chart/AreaChart"

const data = [
  { month: "Jan", visitors: 4000, pageviews: 6400 },
  { month: "Feb", visitors: 3000, pageviews: 5398 },
  { month: "Mar", visitors: 2000, pageviews: 4800 },
  { month: "Apr", visitors: 2780, pageviews: 5908 },
  { month: "May", visitors: 1890, pageviews: 4800 },
  { month: "Jun", visitors: 2390, pageviews: 5800 },
]

export default function AreaChartExample() {
  return (
    <AreaChart
      data={data}
      areas={[
        { dataKey: "visitors", name: "Visitors", fill: "var(--chart-1)" },
        { dataKey: "pageviews", name: "Pageviews", fill: "var(--chart-2)" },
      ]}
      xAxis={{ dataKey: "month" }}
      height={350}
    />
  )
}
```

## Props

### `AreaChartArea`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `dataKey` | `string` | yes | - | The data key to plot from your data points |
| `name` | `string \| undefined` | no | - | Display name for the legend and tooltip |
| `fill` | `string \| undefined` | no | - | Area fill color (use CSS custom property or hex) |
| `stroke` | `string \| undefined` | no | - | Area stroke color |
| `strokeWidth` | `number \| undefined` | no | - | Stroke thickness in pixels |
| `fillOpacity` | `number \| undefined` | no | - | Fill opacity (0-1) |
| `stackId` | `string \| undefined` | no | - | Stack ID for stacked areas (areas with same stackId will stack) |
| `animationDuration` | `number \| undefined` | no | - | Whether to animate the area on mount |
| `type` | `"basis" \| "basisClosed" \| "basisOpen" \| "linear" \| "linearClosed" \| "natural" \| "monotoneX" \| "monotoneY" \| "monotone" \| "step" \| "stepBefore" \| "stepAfter" \| undefined` | no | - | Area type |

### `AreaChartAxis`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `dataKey` | `string \| undefined` | no | - | The data key for this axis |
| `axisLine` | `boolean \| undefined` | no | - | Whether to show the axis line |
| `tickLine` | `boolean \| undefined` | no | - | Whether to show tick marks |
| `tickFormatter` | `((value: unknown) => string) \| undefined` | no | - | Custom tick formatter function |
| `label` | `string \| { value: string; angle?: number \| undefined; position?: string \| undefined; } \| undefined` | no | - | Label for the axis |
| `hide` | `boolean \| undefined` | no | - | Whether to hide the axis entirely |
| `tick` | `boolean \| object \| undefined` | no | - | Axis tick styles |

### `AreaChartGrid`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `horizontal` | `boolean \| undefined` | no | - | Show horizontal grid lines |
| `vertical` | `boolean \| undefined` | no | - | Show vertical grid lines |
| `stroke` | `string \| undefined` | no | - | Grid line stroke color |
| `strokeDasharray` | `string \| undefined` | no | - | Grid line stroke dash pattern |

### `AreaChartLegend`

| 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) => ReactNode) \| undefined` | no | - | Custom legend formatter |

### `AreaChartTooltip`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `labelFormatter` | `((label: unknown) => ReactNode) \| undefined` | no | - | Custom tooltip formatter for label |
| `formatter` | `((value: ValueType, name: NameType, item: unknown) => ReactNode) \| undefined` | no | - | Custom tooltip formatter for values |
| `cursor` | `boolean \| object \| undefined` | no | - | Cursor style |

### `AreaChartProps`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `data` | `AreaChartDataPoint[]` | yes | - | Array of data points to plot |
| `areas` | `AreaChartArea[]` | yes | - | Array of area configurations |
| `width` | `number \| undefined` | no | - | Chart width in pixels |
| `height` | `number \| undefined` | no | - | Chart height in pixels |
| `xAxis` | `AreaChartAxis \| undefined` | no | - | X-axis configuration |
| `yAxis` | `AreaChartAxis \| undefined` | no | - | Y-axis configuration |
| `grid` | `boolean \| AreaChartGrid \| undefined` | no | - | Grid configuration |
| `legend` | `boolean \| AreaChartLegend \| undefined` | no | - | Legend configuration (false to hide) |
| `tooltip` | `boolean \| AreaChartTooltip \| undefined` | no | - | Tooltip configuration (false to hide) |
| `margin` | `{ top?: number \| undefined; right?: number \| undefined; bottom?: number \| undefined; left?: number \| undefined; } \| undefined` | no | - | Chart margin (top, right, bottom, left) |
| `isLoading` | `boolean \| undefined` | no | - | Loading state |
| `emptyState` | `ReactNode` | no | - | Empty state content |
| `onDataPointClick` | `((data: unknown, index: number) => void) \| undefined` | no | - | Click handler for area data points |
| `responsive` | `boolean \| undefined` | no | - | Responsive container (auto-sizes to parent) |
| `className` | `string \| undefined` | no | - | Container className |
| `style` | `CSSProperties \| undefined` | no | - | Custom container styles |

## Changelog

# Changelog - AreaChart

## 0.2.2

- Fix `onDataPointClick`'s `index` argument always being `0` regardless of
  which point was clicked. Now derived from Recharts' `activeTooltipIndex`
  via `chart-core`'s `resolveChartClickIndex`.

## 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

- Replaced `any` types with proper Recharts types (`ValueType`, `NameType`) in `AreaChartTooltip.formatter` and `AreaChartTooltip.labelFormatter`.
- Tightened `tickFormatter`, `onDataPointClick` signatures from `any` to `unknown`.

## 0.1.0

Initial release.

- Area chart component with Recharts integration
- Support for multiple areas with custom colors and styling
- Stacked areas support via stackId
- Multiple curve types (monotone, natural, step, linear, etc.)
- Fill opacity control for transparency effects
- Configurable axes, grid, legend, and tooltip
- Responsive container support
- Loading skeleton and empty state
- Fully presentational (props-in/events-out pattern)
