Saltar al contenido principal

Catálogo · Gráficos

Gráfico

Dibuja una línea, un área o una línea de tendencia pequeña a partir de una tabla o de una lista de números que ya escribiste, y que sigue en la página a su lado.

Encaja mejor en: cualquier sitio — una página que muestra una tendencia: un informe, un panel, una entrada con algunas cifras

Esta traducción la ha escrito una IA y todavía no la ha revisado ninguna persona. Leer esta página en inglés

Ejemplo

Paquetes por ruta durante seis meses, como una tabla que puedes leer y como un gráfico de líneas dibujado a partir de ella. El botón cambia el dibujo por la tabla; un lector de pantalla siempre tiene la tabla.

Parcels per route, January to June
MonthSevillaCádizJerez
Jan1,204312640
Feb1,310340620
Mar1,180365700
Apr1,420410690
May1,390398760
Jun1,480452810

Una columna es una serie, hasta seis. Sin JavaScript es la tabla.

Parcels to Sevilla, January to June
MonthSevilla
Jan1,204
Feb1,310
Mar1,180
Apr1,420
May1,390
Jun1,480

Con variant="area".

Parcels a day, last 7 days
  • 41
  • 38
  • 44
  • 52
  • 47
  • 58
  • 63

type="spark": una línea pequeña y su última cifra como texto. Las otras seis quedan en la lista para un lector de pantalla.

Interactivo

Visitantes por día durante cuatro semanas, con interactive: cada serie y su total es un botón que apaga y enciende su línea, en la misma escala. Apunta a un día, o ve con Tab al gráfico y usa las flechas, para ver sus cifras y una banda sobre él. Sin JavaScript es la tabla. Los datos son de ejemplo: sustitúyelos por los tuyos.

Visitors per day, April 1 to 28
DayDesktopMobile
Apr 1252148
Apr 2271276
Apr 3182128
Apr 4380247
Apr 5194203
Apr 619174
Apr 717998
Apr 8179132
Apr 9281217
Apr 10187171
Apr 11193251
Apr 12278125
Apr 13228152
Apr 14120100
Apr 15331270
Apr 16319125
Apr 17317259
Apr 18271122
Apr 19226121
Apr 2018786
Apr 21146130
Apr 22206248
Apr 23200256
Apr 24248253
Apr 25378284
Apr 26216136
Apr 27190153
Apr 2819994

Problemas conocidos

Cuatro cosas que conviene saber antes de fiarse de él.

  • Sin interactive no hay lectura de valores al pasar el puntero ni al enfocar: las cifras están en la tabla, que muestra el botón. Con él, la lectura sigue por igual al puntero y al foco.
  • Lee la tabla al conectarse, cuando la tabla cambia y cuando la caja cambia de tamaño. Una tabla añadida a la página más tarde, cuando esta ya cargó el script, necesita que el elemento se añada con ella.
  • El trazado se dibuja de izquierda a derecha en todos los idiomas, como un eje de tiempo; la tabla, el título, la leyenda y el botón siguen la dirección de la página.
  • No se ha probado con un lector de pantalla.

Código

Copia el marcado

Bundler
import "@luz-ds/catalog/components/chart.css";
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/chart.min.css" integrity="sha384-ELc0v0M/zEVoqPmwPSIjtJN98bz6vLurMqk58If0SOBFCqQT+JLI28PND1wWsOfG" crossorigin="anonymous">

Escribe primero la tabla, como la página en la que aterriza un lector sin JavaScript. La primera columna es el eje X, un th de su fila; cada una de las demás es una serie, con el nombre de su th. Pon cada número en un <data value> y escríbelo como quieres que se lea. Envuelve la tabla en un .luz-table-wrap solo cuando pueda ser más ancha que la pantalla, como en el ejemplo de tres series, y da a cada td un data-label para que en una pantalla estrecha sus filas se apilen y sigan nombrando sus celdas. Una tabla que siempre cabe no necesita contenedor: con uno, el grupo, la región y la tabla leerían el mismo nombre tres veces. El gráfico oculta el contenedor junto con la tabla y este no recibe parada de Tab mientras tanto.

catalog.min.js carga el archivo propio del elemento, chart.min.js, cuando analiza la página; una página sin catalog.min.js carga ese archivo por su cuenta. Enlaza components/chart.css, después del de core.

HTML
<script type="module" src="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/catalog.min.js"></script>

<luz-chart type="line" data-luz-label-table="Show table" data-luz-label-chart="Show chart">
  <table class="luz-table">
    <caption>Parcels per route, January to March</caption>
    <thead>
      <tr><th scope="col">Month</th><th scope="col">Sevilla</th><th scope="col">Cádiz</th></tr>
    </thead>
    <tbody>
      <tr><th scope="row">Jan</th><td data-label="Sevilla"><data value="1204">1,204</data></td><td data-label="Cádiz"><data value="312">312</data></td></tr>
      <tr><th scope="row">Feb</th><td data-label="Sevilla"><data value="1310">1,310</data></td><td data-label="Cádiz"><data value="340">340</data></td></tr>
      <tr><th scope="row">Mar</th><td data-label="Sevilla"><data value="1180">1,180</data></td><td data-label="Cádiz"><data value="365">365</data></td></tr>
    </tbody>
  </table>
</luz-chart>

Con interactive, una cabecera con las series y sus totales, y una lectura de un día:

HTML
<luz-chart type="line" interactive data-luz-label-table="Show table" data-luz-label-chart="Show chart">
  <table class="luz-table">
    <caption>Visitors per day, April 1 to 3</caption>
    <thead>
      <tr><th scope="col">Day</th><th scope="col">Desktop</th><th scope="col">Mobile</th></tr>
    </thead>
    <tbody>
      <tr><th scope="row">Apr 1</th><td><data value="252">252</data></td><td><data value="148">148</data></td></tr>
      <tr><th scope="row">Apr 2</th><td><data value="271">271</data></td><td><data value="276">276</data></td></tr>
      <tr><th scope="row">Apr 3</th><td><data value="182">182</data></td><td><data value="128">128</data></td></tr>
    </tbody>
  </table>
</luz-chart>

Una línea pequeña toma una lista de elementos <data>, en cualquier marcado, y muestra el último:

HTML
<luz-chart type="spark">
  <span>Parcels a day, last 4 days</span>
  <ul class="luz-chart__values" role="list">
    <li><data value="41">41</data></li>
    <li><data value="38">38</data></li>
    <li><data value="44">44</data></li>
    <li><data value="52">52</data></li>
  </ul>
</luz-chart>

Tus scripts pueden preguntar qué dibujaría el gráfico:

JS
import { readChart } from "@luz-ds/catalog/chart";

// What the chart draws: the names of the rows, and one series per column
const { rows, series } = readChart(document.querySelector("luz-chart"));

Variantes y opciones

Clase o atributoEfecto
<luz-chart>
El elemento personalizado que define el módulo, alrededor de la tabla o de la lista. Se conecta solo al incorporarse
type
line (por defecto) dibuja las columnas de la tabla; spark dibuja una línea pequeña con los elementos <data> que contiene. Con cualquier otro valor queda la tabla
variant="area"
Rellena el área bajo cada línea con un tono suave del color de la serie
interactive
Con type="line" (o type="column" en un gráfico de columnas): una cabecera con un botón por serie, su nombre y su total, que apaga y enciende su línea, y una lectura del día bajo el puntero o el foco. Sustituye a la leyenda
data-luz-label-table, data-luz-label-chart
Las dos palabras del botón: «Ver tabla» y «Ver gráfico», en el idioma de la página, en el elemento o en un ancestro (una vez en <body> sirve a todos los gráficos). LUZ no tiene texto en inglés por defecto: si falta alguna no hay botón y la tabla se muestra bajo el gráfico
--luz-chart-ratio
La forma del dibujo, 2 / 1 por defecto. Se define en el elemento: style="--luz-chart-ratio: 3 / 1"
caption
El título: el pie de la tabla da nombre al grupo y se copia sobre el dibujo
th scope="col"
El nombre de una serie, en la leyenda. La primera columna es el eje X; cada una de las demás es una serie, hasta seis, y las que sobran quedan solo en la tabla
td con <data value>
Un número: el value de un <data> o el texto simple de la celda. Cualquier otra cosa es un hueco en la línea
.luz-chart__values
La lista de un type="spark": los elementos <data> son los puntos y el último se muestra como texto
data-luz-view, data-luz-ready, data-luz-end
Los escribe el script: chart, table o both según lo que se muestra; el elemento está listo; la última cifra de un spark. Dales estilo, nunca los pongas tú
readChart(el)
Lo exporta @luz-ds/catalog/chart: los nombres de las filas y las series que contiene la tabla, o null

Cómo funciona

CSS de @luz-ds/catalog y un archivo propio, @luz-ds/catalog/chart (dist/chart.min.js, menos de 5 kB comprimido), que define <luz-chart>. No usa ninguna biblioteca y dibuja solo con llamadas al DOM, así que una página que prohíbe scripts y estilos en línea lo ejecuta tal cual. Para comparar valores por longitud sin script, usa la lista de barras, el gráfico de columnas, la barra apilada o el mapa de calor.

  • La tabla: sigue en la página. Mientras se muestra el gráfico, la tabla se saca de la pantalla, no se oculta, así que un lector de pantalla la lee como siempre; cuando el botón muestra la tabla, el dibujo desaparece. En papel se imprime la tabla y no el dibujo.
  • El dibujo: un SVG marcado con aria-hidden, dibujado de nuevo cuando cambia la caja o la tabla. No tiene animación. Las series son --luz-chart-1 a --luz-chart-6, de modo que un cambio de modo no repinta nada.
  • Distinguir las series: cada línea termina en una marca de forma propia (un círculo, un cuadrado, un triángulo, un rombo, un más y una cruz), repetida en la leyenda. En colores forzados todas las líneas tienen el color del texto, cada una con sus propios guiones.
  • Los números: la escala empieza en cero, o más abajo si una cifra es negativa, en pasos redondos (1, 2 o 5 veces una potencia de diez). Los ejes se escriben con Intl.NumberFormat en el idioma de la página, como 1.2K.
  • Interactivo: la cabecera tiene un botón de alternancia por serie, con su nombre y la suma de sus cifras. El total es una suma: sirve para recuentos e importes, como visitantes o euros, y no para tasas, proporciones ni medias, cuyo total no dice nada. Una línea apagada ya no se dibuja, en la misma escala, y la última línea mostrada no se puede apagar. El día bajo el puntero, o la fila con el foco, recibe una banda clara y una lectura con su nombre y la cifra de cada línea mostrada, copiada de las celdas.
  • Las palabras: el script no escribe ninguna propia. Las dos palabras del botón son tuyas, en data-luz-label-*; el título y la leyenda copian tu pie de tabla y las cabeceras de tus columnas.

Sin JavaScript

La tabla, o la lista, es todo lo que hay, y está completa: el pie, todas las cifras, todos los nombres. El elemento es un bloque y el botón no existe. Con interactive tampoco hay cabecera ni lectura: todas las cifras están en la tabla. Es igual cuando la página no tiene la tabla o type no es uno de los dos.

Teclado y ARIA

  • Teclas: Tab llega al botón «Ver tabla»; Enter o Espacio lo pulsan. Sin interactive, nada en la imagen recibe el foco.
  • Interactivo: los botones de la cabecera son botones de alternancia (aria-pressed): Enter o Espacio apagan y encienden una línea, y la última línea mostrada sigue encendida. Después, la imagen recibe el foco, en una sola parada de Tab. Es un grupo nombrado por el título de la tabla y contiene un estado de cortesía que, en cada tecla, dice la etiqueta del día, el mismo texto que la fila de la tabla. Cada fila se nombra con sus propias celdas, a partir de tu texto, «Apr 1, Desktop 252, Mobile 148», todas las series, mostradas o no. Con el foco en la imagen, las flechas pasan al día siguiente o al anterior (la flecha derecha es siempre el siguiente, porque el trazado va de izquierda a derecha), e Inicio y Fin al primero y al último; las teclas del modo de exploración de un lector de pantalla son suyas. Entrar dice su nombre y nada más, y salir vacía el estado.
  • La lectura: su título es el nombre del día, así que la banda nunca es la única señal de dónde estás. Escape la guarda sin mover el puntero ni el foco; vuelve en otro día. Está oculta para la tecnología de asistencia, que lee la fila. Una línea apagada no se dibuja, pero sus celdas siguen en la tabla, leídas como antes. El script escribe los roles de la tabla (table, rowgroup, row, columnheader, rowheader y cell) para que las filas los conserven en todos los navegadores.
  • Nombre: el elemento es un grupo con el nombre del pie de la tabla, y el botón se describe con él, así que «Ver tabla» se oye junto con lo que muestra. El dibujo, su título y su leyenda son aria-hidden: la tabla lo dice todo.

Contraste y foco están en la pestaña Diseño.

Diseño

Cuándo usarlo

Úsalo para mostrar cómo cambian unas pocas series a lo largo de un eje ordenado, como los meses, cuando la forma del cambio es lo que el lector debe ver y ya tienes los números en una tabla. Añade interactive para muchos días y dos o más series, cuando importan los totales y un día se lee de uno en uno. La línea pequeña (type="spark") es para una cifra que necesita su tendencia a su lado.

Cuándo no usarlo

No lo uses cuando importan más los valores exactos que la forma: una tabla los dice mejor. Para comparar unos pocos valores en una sola escala, usa un gráfico de columnas o una lista de barras, que no necesitan script.

  • No lo uses para partes de un todo: usa una barra apilada. No hay gráficos circulares ni de anillo.
  • No uses interactive para tasas, proporciones ni medias: el total de su cabecera es una suma.
  • No lo uses para más de seis series, ni para series que no pueden compartir escala: sepáralas en dos gráficos.

Sustituye a una biblioteca de gráficos que dibuja un lienzo sin texto a su lado. No se elimina nada de LUZ.

Qué hacer y qué no

Do Nombra cada columna por lo que cuenta: la leyenda y la tabla usan el mismo nombre.
Don't Llamarlas «Series 1» y «Series 2»: la leyenda no dice nada al lector, y la tabla tampoco.

Escribir el contenido

El pie es el título del gráfico y dice qué se cuenta, dónde y cuándo: «Paquetes por ruta, de enero a junio». Es el nombre que un lector de pantalla da al grupo.

  • Nombra cada columna como debe leerse la leyenda, con su unidad si la tiene, y escribe cada cifra en su celda como quieres que se lea: 1,204, no 1204, con el número simple en el value.
  • Escribe el botón como la acción y la cosa: «Ver tabla», «Ver gráfico». Define ambos en la página, una vez, en su idioma.
  • Con interactive, la cabecera de cada columna es también el nombre de su botón: una palabra o dos.
  • Mantén cortos los nombres de las filas: son las etiquetas del eje X y algunas se omiten cuando no caben.

Contraste y foco

Las seis series son colores de gráfico, cada una con 3:1 o más sobre la página y sobre una tarjeta, en todos los modos; ninguna es roja, verde ni amarilla, porque esos colores dicen un estado. La rejilla es una línea fina, más tenue que cualquier serie, porque las cifras están en la tabla.

ParteColor sobre fondoClaroOscuroAlto contrasteNecesita
Serie 1, línea, marca y leyenda
--luz-chart-1 on --luz-surface-page
5.6:1
7.7:1
14.1:1
3:1
Serie 2, línea, marca y leyenda
--luz-chart-2 on --luz-surface-page
5.3:1
8.9:1
9.3:1
3:1
Serie 3, línea, marca y leyenda
--luz-chart-3 on --luz-surface-page
9.6:1
10.6:1
10.9:1
3:1
Serie 4, línea, marca y leyenda
--luz-chart-4 on --luz-surface-page
9.8:1
6.1:1
6.6:1
3:1
Serie 5, línea, marca y leyenda
--luz-chart-5 on --luz-surface-page
3.9:1
5.0:1
6.2:1
3:1
Serie 6, línea, marca y leyenda
--luz-chart-6 on --luz-surface-page
3.7:1
5.4:1
14.7:1
3:1
Serie 6, sobre una tarjeta
--luz-chart-6 on --luz-surface
3.8:1
5.0:1
14.7:1
3:1
Cifras de los ejes y de la leyenda
--luz-text-secondary on --luz-surface-page
6.2:1
7.5:1
19.3:1
4.5:1
Título
--luz-text-primary on --luz-surface-page
15.8:1
15.1:1
21.0:1
4.5:1
Rejilla, sobre la página
--luz-chart-grid on --luz-surface-page
1.4:1
1.7:1
3.2:1
1.3:1
Serie 1 sobre la banda de un día
--luz-chart-1 on --luz-surface-hover
5.1:1
6.4:1
13.5:1
3:1
Serie 2 sobre la banda de un día
--luz-chart-2 on --luz-surface-hover
4.8:1
7.4:1
8.9:1
3:1
Serie mostrada: su nombre y su total
--luz-text-primary on --luz-surface-muted
15.8:1
15.1:1
20.1:1
4.5:1
Serie mostrada: la línea bajo ella
--luz-brand-primary on --luz-surface-muted
5.6:1
7.7:1
13.5:1
3:1
Serie apagada: su nombre y su total
--luz-text-secondary on --luz-surface-page
6.2:1
7.5:1
19.3:1
4.5:1
Lectura: la cifra
--luz-text-primary on --luz-surface-strong
13.5:1
10.9:1
18.0:1
4.5:1
Lectura: el nombre de la serie
--luz-text-secondary on --luz-surface-strong
5.3:1
5.4:1
16.5:1
4.5:1
Anillo de foco
--luz-focus-ring on --luz-surface-page
5.6:1
7.7:1
21.0:1
3:1

Medido a partir de los valores de los tokens de cada modo, redondeado hacia abajo. Necesita es el mínimo de WCAG 2.2 AA: 4.5:1 para el texto, 3:1 para las líneas y las marcas; la rejilla es decorativa y conserva una línea fina de 1.3:1 o más.

  • Foco: el botón «Ver tabla» es el botón fantasma de core y toma su anillo de foco. La imagen no recibe ninguno. Con interactive, un botón de la cabecera toma el anillo de foco, --luz-focus-ring, de 2px, dentro de su borde, y también la imagen: el anillo se dibuja alrededor de ella, a 2px de su borde, porque es la imagen la que tiene el foco.
  • Objetivo y foco: cada botón de la cabecera interactiva mide más de 24 por 24 px (WCAG 2.2, 2.5.8), y la lectura se coloca junto al día que tiene el foco y nunca sobre él (2.4.11). Ambos criterios son nuevos en WCAG 2.2 y todavía no los exige EN 301 549 v3.2.1.
  • Una serie se distingue por su color, por la marca con que termina y por la leyenda; en colores forzados todas las líneas tienen el color del texto, con sus propios guiones, el área no se rellena y la rejilla es el gris del texto. Una serie apagada tiene un punto hueco y un nombre más claro, y la banda de un día es un borde discontinuo en colores forzados.

Tokens que usa

Los 33 tokens que lee components/chart.css, por familia; el botón es de core. Cada familia enlaza a su página, con los valores en cada modo. En Figma son variables con los mismos nombres: consulta Tokens en Figma.

Espaciado y tamaños
--luz-space-2xl, --luz-space-2xs, --luz-space-3xs, --luz-space-lg, --luz-space-md, --luz-space-sm, --luz-space-xs
Tipografía
--luz-font-heading, --luz-font-mono, --luz-font-sans, --luz-text-sm, --luz-text-xl, --luz-text-xs
Radio
--luz-radius-full, --luz-radius-md, --luz-radius-sm
Sombras
--luz-shadow-md
Capas
--luz-z-raised

Teclado y ARIA están en la pestaña Código.