# MetricChart

> El gráfico de una métrica en SVG a mano: área o línea con guías, eje Y a la derecha y tooltip con línea punteada al pasar el puntero o con el teclado.

```tsx
import { MetricChart } from "sebs7n-ui/metric-chart"
```

Sin `"use client"`: sirve en un Server Component.

## Ejemplos

### Una serie

Guías, eje Y a la derecha y, con el puntero o las flechas, línea punteada y tooltip. Probá Tab y ← →.

```tsx
import { Card, CardContent } from "sebs7n-ui/card"
import { MetricChart } from "sebs7n-ui/metric-chart"

function Basic() {
  return (
    <Card className="w-full max-w-xl">
      <CardContent>
        <MetricChart aria-label="Cobros de los últimos 12 meses" data={points(PAID, 12)} format={{ style: "currency", currency: "USD", maximumFractionDigits: 0 }} height={180} name="Cobrado" />
      </CardContent>
    </Card>
  )
}
```

### Varias series

El color sale de un token (`brand`, `green`, `amber`, `red`); el tooltip lista cada serie con su punto.

```tsx
import { Card, CardContent } from "sebs7n-ui/card"
import { MetricChart } from "sebs7n-ui/metric-chart"

function Series() {
  return (
    <Card className="w-full max-w-xl">
      <CardContent>
        <MetricChart
          aria-label="Facturado y cobrado en 2026"
          height={180}
          series={[
            { name: "Facturado", data: points(BILLED, 12), color: "amber" },
            { name: "Cobrado", data: points(PAID, 12), color: "green" },
          ]}
        />
      </CardContent>
    </Card>
  )
}
```

### En una card de indicadores

`StatGrid` con `chart` y `actions`: rótulo, cifra con variación, menú «…» y el gráfico llenando el resto de la card.

```tsx
import { DropdownMenuItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger } from "sebs7n-ui/dropdown-menu"
import { MetricChart } from "sebs7n-ui/metric-chart"
import { StatGrid } from "sebs7n-ui/stat-grid"
import { useState } from "react"

function InStatGrid() {
  const [months, setMonths] = useState(6)
  const [refreshes, setRefreshes] = useState(0)
  return (
    <StatGrid
      className="w-full"
      columns={2}
      items={[
        {
          id: "paid",
          label: "Cobrado",
          value: "US$ 4.100",
          delta: "↗ 20,6 %",
          trend: "up",
          hint: refreshes ? `Actualizado ${refreshes} ${refreshes === 1 ? "vez" : "veces"}` : `Últimos ${months} meses`,
          chart: <MetricChart aria-label={`Cobrado, últimos ${months} meses`} data={points(PAID, months)} format={{ style: "currency", currency: "USD", maximumFractionDigits: 0 }} height={140} />,
          actions: (
            <>
              <DropdownMenuItem>Ver detalle</DropdownMenuItem>
              <DropdownMenuItem onClick={() => setRefreshes((n) => n + 1)}>Actualizar</DropdownMenuItem>
              <DropdownMenuSub>
                <DropdownMenuSubTrigger>Período</DropdownMenuSubTrigger>
                <DropdownMenuSubContent>
                  <DropdownMenuItem onClick={() => setMonths(6)}>6 meses</DropdownMenuItem>
                  <DropdownMenuItem onClick={() => setMonths(12)}>12 meses</DropdownMenuItem>
                </DropdownMenuSubContent>
              </DropdownMenuSub>
              <DropdownMenuSeparator />
              <DropdownMenuItem variant="destructive">Quitar</DropdownMenuItem>
            </>
          ),
        },
        {
          id: "overdue",
          label: "Vencido",
          value: "US$ 1.800",
          delta: "↘ 7,1 %",
          trend: "up",
          hint: "Menos es mejor",
          chart: <MetricChart aria-label="Vencido, últimos 6 meses" color="red" data={points([900, 1100, 1500, 2100, 1940, 1800], 6)} height={140} />,
          actions: <DropdownMenuItem>Ver detalle</DropdownMenuItem>,
        },
      ]}
    />
  )
}
```

## Props

### MetricChart

Hereda las props de `<div>`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `aria-label` * | `string` | — | Qué mide el gráfico. Es su nombre accesible. |
| `area` | `boolean` | `true` | Pinta el área bajo la curva. Por defecto `true`. |
| `axisFormat` | `Intl.NumberFormatOptions \| ((value: number) => string)` | — | El formato del eje Y, si tiene que ser distinto del tooltip. |
| `color` | `"brand" \| "red" \| "amber" \| "green"` | `"brand"` | Color token de la serie única. Por defecto `brand`. |
| `data` | `readonly MetricChartDatum[]` | — | Una serie: `{ label, value }[]`, de izquierda a derecha. Con menos de dos puntos válidos no dibuja nada. |
| `format` | `Intl.NumberFormatOptions \| ((value: number) => string)` | — | Cómo se escriben los valores: opciones de `Intl.NumberFormat` o una función. El eje las compacta (`3K`) salvo que pases `axisFormat`. |
| `height` | `number` | — | El alto en px. Sin él, llena a su contenedor (mínimo 8 rem): en una `Card` de `StatGrid` ocupa el alto que sobra. |
| `interactive` | `boolean` | `true` | Con `false` no hay puntero, teclado ni tooltip, y no se carga el JS del cliente. Por defecto `true`. |
| `labels` | `Partial<MetricChartLabels>` | — | Textos internos (español por defecto: `metricChartLabels`). |
| `locale` | `string` | `"es-AR"` | El idioma de los números. Por defecto, `es-AR`. |
| `name` | `string` | — | El nombre de la serie única (`data`). |
| `series` | `readonly MetricChartSeries[]` | — | Varias series: `{ name?, data, color? }[]`. Le gana a `data`. |
| `showAxis` | `boolean` | `true` | Dibuja guías y etiquetas del eje Y, a la derecha. Por defecto `true`. |
| `style` | `CSSProperties` | — | Estilos en línea de la caja del gráfico; con `height` se mezclan con el alto. |
| `yTicks` | `number` | `4` | Cuántas etiquetas aproximadas en el eje Y (la escala redondea a pasos 1-2-5). Por defecto 4. |
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

`*` obligatoria.

## Teclado

| Tecla | Qué hace |
|---|---|
| Tab | Entra al gráfico y muestra el último punto. |
| ← → | Mueven el punto activo (y su tooltip) de a uno. |
| Inicio · Fin | Saltan al primer y al último punto. |
| Escape | Suelta el punto: desaparecen la línea y el tooltip. |

## Accesibilidad

- Es una imagen con nombre (`role="img"`, `aria-label` obligatorio: «Facturación de los últimos 6 meses») y un resumen en `aria-describedby` (cantidad de puntos, mínimo, máximo y último). Aparte lleva una tabla `sr-only` con todos los datos, que es lo que lee el lector.
- El punto activo se anuncia en una región `aria-live="polite"` («Mar: 1.800»). El foco se ve con el anillo del sistema.
- La línea usa los tokens `-900` (brand, green, red, amber): 3:1 como mínimo sobre la card en claro y en oscuro. El valor nunca depende solo del color: el tooltip lo escribe.
- No anima nada propio: el reset de movimiento reducido de `base.css` alcanza.

## Reglas de uso

- `data` para una serie, `series` para varias (mismos rótulos; la primera manda). `height` fija el alto en px; sin él llena a su contenedor (mínimo 8 rem), que es lo que hace dentro de una `StatGrid`.
- `format` (opciones de `Intl.NumberFormat` o una función) escribe el valor del tooltip, de la tabla y, compacto («3K»), del eje; `axisFormat` lo separa del eje. `yTicks` es la cantidad aproximada de etiquetas: la escala se redondea a pasos 1, 2 o 5.
- Es un Server Component: el dibujo sale del servidor y solo el marco interactivo es cliente. Con `interactive={false}` no hay tooltip ni foco y no se carga ese JS.
- Para una curva decorativa en una fila, `Sparkline`; para barras, escalas múltiples o leyendas, `chart` (Recharts). Solo por subpath (`sebs7n-ui/metric-chart`).

## Relacionados

[sparkline](/docs/components/sparkline.md) · [stat-grid](/docs/components/stat-grid.md) · [chart](/docs/components/chart.md)
