# Line Chart (`line-chart`) - SignalOS widget

> Fully presentational line chart widget using Recharts. Supports multiple lines, custom styling, legends, tooltips, and responsive layouts.

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

## Example

```tsx
import { LineChart } from "@/components/widgets/line-chart/LineChart"

const data = [
  { month: "Jan", revenue: 4000, expenses: 2400 },
  { month: "Feb", revenue: 3000, expenses: 1398 },
  { month: "Mar", revenue: 2000, expenses: 9800 },
  { month: "Apr", revenue: 2780, expenses: 3908 },
  { month: "May", revenue: 1890, expenses: 4800 },
  { month: "Jun", revenue: 2390, expenses: 3800 },
]

export default function LineChartExample() {
  return (
    <LineChart
      data={data}
      lines={[
        { dataKey: "revenue", name: "Revenue", stroke: "var(--chart-1)" },
        { dataKey: "expenses", name: "Expenses", stroke: "var(--chart-2)" },
      ]}
      xAxis={{ dataKey: "month" }}
      yAxis={{ tickFormatter: (value) => `$${value}` }}
      height={350}
    />
  )
}
```

## Props

### `LineChartLine`

| 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 |
| `stroke` | `string \| undefined` | no | - | Line color (use CSS custom property or hex) |
| `strokeWidth` | `number \| undefined` | no | - | Line thickness in pixels |
| `strokeDasharray` | `string \| undefined` | no | - | Dash pattern (e.g., "5 5" for dashed line) |
| `dot` | `boolean \| undefined` | no | - | Whether to show dots on data points |
| `animationDuration` | `number \| undefined` | no | - | Whether to animate the line on mount |

### `LineChartAxis`

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

### `LineChartGrid`

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

### `LineChartLegend`

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

### `LineChartTooltip`

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

### `LineChartProps`

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `data` | `LineChartDataPoint[]` | yes | - | Array of data points to plot |
| `lines` | `LineChartLine[]` | yes | - | Array of line configurations |
| `width` | `number \| undefined` | no | - | Chart width in pixels |
| `height` | `number \| undefined` | no | - | Chart height in pixels |
| `xAxis` | `LineChartAxis \| undefined` | no | - | X-axis configuration |
| `yAxis` | `LineChartAxis \| undefined` | no | - | Y-axis configuration |
| `grid` | `boolean \| LineChartGrid \| undefined` | no | - | Grid configuration |
| `legend` | `boolean \| LineChartLegend \| undefined` | no | - | Legend configuration (false to hide) |
| `tooltip` | `boolean \| LineChartTooltip \| 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 line 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 - LineChart

## 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`, `Payload`) in `LineChartTooltip.formatter`, `labelFormatter`, `tickFormatter`, and `onDataPointClick`.

## 0.1.0

Initial release.

- Line chart component with Recharts integration
- Support for multiple lines with custom colors and styling
- Configurable axes, grid, legend, and tooltip
- Responsive container support
- Loading skeleton and empty state
- Fully presentational (props-in/events-out pattern)
