Ir al contenido
Contenido y datosServer Component

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.

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

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 ← →.

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.

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.

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

Generadas del TypeScript del paquete. Las propias del componente, más las heredadas del primitivo que tienen algo que explicar —marcadas «heredada de Base UI»—. El resto está en la línea «hereda de».

MetricChart

Hereda las props de <div>.

PropTipoPor defectoDescripción
aria-label*string—Qué mide el gráfico. Es su nombre accesible.
areabooleantruePinta el área bajo la curva. Por defecto true.
axisFormatIntl.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.
datareadonly MetricChartDatum[]—Una serie: { label, value }[], de izquierda a derecha. Con menos de dos puntos válidos no dibuja nada.
formatIntl.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.
heightnumber—El alto en px. Sin él, llena a su contenedor (mínimo 8 rem): en una Card de StatGrid ocupa el alto que sobra.
interactivebooleantrueCon false no hay puntero, teclado ni tooltip, y no se carga el JS del cliente. Por defecto true.
labelsPartial<MetricChartLabels>—Textos internos (español por defecto: metricChartLabels).
localestring"es-AR"El idioma de los números. Por defecto, es-AR.
namestring—El nombre de la serie única (data).
seriesreadonly MetricChartSeries[]—Varias series: { name?, data, color? }[]. Le gana a data.
showAxisbooleantrueDibuja guías y etiquetas del eje Y, a la derecha. Por defecto true.
styleCSSProperties—Estilos en línea de la caja del gráfico; con height se mezclan con el alto.
yTicksnumber4Cuántas etiquetas aproximadas en el eje Y (la escala redondea a pasos 1-2-5). Por defecto 4.
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

Teclado

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