Catálogo · Gráficos
Gráfico de columnas
Compara unos pocos valores como columnas de una misma escala de altura, dibujadas desde una tabla nativa que conserva cada cifra como texto.
Encaja mejor en: app — un informe que compara unos pocos valores con un orden, como días o meses
Ejemplo
Paquetes por día esta semana: la cifra, su columna y después el día.
| Mon | Tue | Wed | Thu | Fri | Sat | Sun |
|---|---|---|---|---|---|---|
| 1,204 | 830 | 901 | 1,420 | 1,500 | 377 | 0 |
Varias series
Visitantes por mes, por dispositivo, durante tres meses: una fila por mes y una columna por serie, sin script. Cada mes es un grupo de columnas, y la fila de encabezado es la leyenda. Los datos son de ejemplo: sustitúyelos por los tuyos.
| Month | Desktop | Mobile |
|---|---|---|
| Jan | 186 | 80 |
| Feb | 305 | 200 |
| Mar | 237 | 120 |
Interactivo
Visitantes por día durante cuatro semanas, en <luz-chart type="column" interactive>. Cada serie y su total es un botón que apaga y enciende sus columnas (la última que se muestra sigue encendida); apunta a un día, o ve con Tab al gráfico y usa las flechas, para ver sus cifras. Sin JavaScript es la tabla. Los datos son de ejemplo: sustitúyelos por los tuyos.
| Day | Desktop | Mobile |
|---|---|---|
| Apr 1 | 252 | 148 |
| Apr 2 | 271 | 276 |
| Apr 3 | 182 | 128 |
| Apr 4 | 380 | 247 |
| Apr 5 | 194 | 203 |
| Apr 6 | 191 | 74 |
| Apr 7 | 179 | 98 |
| Apr 8 | 179 | 132 |
| Apr 9 | 281 | 217 |
| Apr 10 | 187 | 171 |
| Apr 11 | 193 | 251 |
| Apr 12 | 278 | 125 |
| Apr 13 | 228 | 152 |
| Apr 14 | 120 | 100 |
| Apr 15 | 331 | 270 |
| Apr 16 | 319 | 125 |
| Apr 17 | 317 | 259 |
| Apr 18 | 271 | 122 |
| Apr 19 | 226 | 121 |
| Apr 20 | 187 | 86 |
| Apr 21 | 146 | 130 |
| Apr 22 | 206 | 248 |
| Apr 23 | 200 | 256 |
| Apr 24 | 248 | 253 |
| Apr 25 | 378 | 284 |
| Apr 26 | 216 | 136 |
| Apr 27 | 190 | 153 |
| Apr 28 | 199 | 94 |
Problemas conocidos
No se conocen problemas.
Código
Copiar el marcado
import "@luz-ds/catalog/components/column-chart.css";
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/column-chart.min.css" integrity="sha384-K41y3b0ofKFEbXhPjLBtb3Df9mEHL3G4TWMgg3TdG6Xv9wQTxynvP/vdgh/m44rk" crossorigin="anonymous">
Una hoja de estilos de @luz-ds/catalog: enlaza components/column-chart.css después de luz.css.
<table class="luz-column-chart">
<caption>Parcels per day, this week</caption>
<thead>
<tr><th scope="col">Mon</th><th scope="col">Tue</th><th scope="col">Wed</th><th scope="col">Thu</th></tr>
</thead>
<tbody>
<tr><td style="--v: .8">1,204</td><td style="--v: .55">830</td><td style="--v: .6">901</td><td style="--v: .95">1,420</td></tr>
</tbody>
</table>
Con varias series, sin script: una fila por categoría, su nombre en un <th scope="row">, y una celda por serie, hasta seis. La fila de encabezado da nombre a las series. Las filas se disponen una junto a otra, y algunos navegadores (Safari con VoiceOver) dejan entonces de distinguir la tabla de un montón de cajas: escribe sus roles, como aquí. <luz-chart interactive> los escribe por ti.
<table class="luz-column-chart" role="table">
<caption>Visitors per month, by device, January and February</caption>
<thead role="rowgroup">
<tr role="row"><th scope="col" role="columnheader">Month</th><th scope="col" role="columnheader">Desktop</th><th scope="col" role="columnheader">Mobile</th></tr>
</thead>
<tbody role="rowgroup">
<tr role="row"><th scope="row" role="rowheader">Jan</th><td role="cell" style="--v: .58">186</td><td role="cell" style="--v: .25">80</td></tr>
<tr role="row"><th scope="row" role="rowheader">Feb</th><td role="cell" style="--v: .95">305</td><td role="cell" style="--v: .62">200</td></tr>
</tbody>
</table>
Interactivo, con la cabecera de las series: enlaza también components/chart.css y carga catalog.js, que carga chart.js cuando la página tiene un <luz-chart>. Una fila por día, su nombre en un <th scope="row">, y una columna por serie. La tabla no lleva clase: el script le da luz-column-chart cuando la dibuja, así que sin el script cabe en cualquier ancho.
<luz-chart type="column" interactive>
<div class="luz-table-wrap" role="region" aria-label="Visitors per day, April 1 to 3" tabindex="0">
<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 style="--v: .5"><data value="252">252</data></td><td style="--v: .3"><data value="148">148</data></td></tr>
<tr><th scope="row">Apr 2</th><td style="--v: .54"><data value="271">271</data></td><td style="--v: .55"><data value="276">276</data></td></tr>
<tr><th scope="row">Apr 3</th><td style="--v: .36"><data value="182">182</data></td><td style="--v: .26"><data value="128">128</data></td></tr>
</tbody>
</table>
</div>
</luz-chart>
Variantes y opciones
| Opción | Efecto |
|---|---|
--v | En cada celda, de 0 a 1: su valor entre el máximo de la escala, el mismo para todas las columnas |
--luz-column-chart-color | Otro color de gráfico para una tabla o una celda, como var(--luz-chart-2) |
--luz-column-chart-h | La altura de las columnas |
--luz-column-chart-bar | El ancho de una columna, var(--luz-space-lg) por defecto; nunca mayor que su parte de la tabla |
Una fila por categoría | Varias series: un <th scope="row"> y después una celda por serie en cada fila, hasta seis. Cada fila es un grupo de columnas, la serie n en --luz-chart-n, con su nombre debajo, y la fila de encabezado es la leyenda |
--luz-column-chart-gap | En el gráfico de varias series solo con CSS, el espacio entre las columnas de un grupo, var(--luz-space-xs) por defecto; los grupos se reparten el espacio que queda. <luz-chart interactive> reparte el ancho entre sus días y no tiene separación que definir |
<luz-chart type="column" interactive> | Alrededor de una tabla de varias series sin clase: el script la dibuja como columnas, con un botón por serie y su total, que apaga y enciende sus columnas, y una lectura del día bajo el puntero o el foco |
Cómo funciona
Una tabla con una fila de encabezado de nombres y una fila de cifras. Cada cifra es el texto de su celda, y la celda dibuja su columna debajo, desde la base hasta --v, en --luz-chart-1, con la pista en --luz-chart-track. Las columnas se reparten el ancho por igual.
Calcula --v como el valor entre el máximo de la escala, el mismo para todas las celdas. El style en línea solo da ese valor. Con un style-src estricto, ponlo en una regla propia, como .sat { --v: .25 }.
Con el tamaño de texto por defecto, hasta siete columnas, o tres grupos de dos, caben en una pantalla de 320 px. Si hay más, o con un texto mayor, mete la tabla en un luz-table-wrap: se desplaza dentro de él.
La cifra de cada celda está sobre su columna y el nombre debajo, como en un eje. Con varias series, cada fila es un grupo de columnas, separadas por --luz-column-chart-gap (en el gráfico solo con CSS), y la fila de encabezado es la leyenda: el nombre de cada serie tras un punto de su color.
Dentro de <luz-chart type="column" interactive>, el script añade una cabecera sobre la tabla: un botón por serie, su nombre y la suma de sus cifras, escrita con el idioma de la página. Una suma sirve para recuentos e importes, como visitantes o euros; no sirve para tasas, proporciones ni medias, cuyo total no dice nada: no uses interactive para ellas, o déjalas fuera. El título de la tabla pasa a ser el título del gráfico. Las columnas pierden su pista: el día bajo el puntero o el foco recibe una banda clara, y las cifras salen de las columnas a una lectura a su lado. Las columnas conservan la escala de su --v cuando se apaga una serie, y la última serie mostrada no se puede apagar. El script no escribe ninguna palabra propia: los nombres, las cifras y el título son tuyos.
Sin JavaScript
No lo necesita. Sin la hoja de estilos se lee como una tabla: una fila de encabezado con los nombres y luego las cifras. El gráfico interactivo es, sin su script, una tabla simple: una fila por día con todas sus cifras, que cabe en la pantalla más estrecha. Una tabla de pocas categorías que deba ser de columnas sin script lleva ella misma la clase luz-column-chart.
Teclado y ARIA
El gráfico simple no recibe el foco. Una tabla conserva sus roles, así que un lector de pantalla lee cada cifra con su nombre. El título de la tabla la nombra e indica la unidad. Con varias series las filas se disponen una junto a otra: escribe los roles de la tabla en su marcado, como hace el fragmento, para que Safari con VoiceOver siga leyendo una tabla.
El gráfico interactivo es un grupo con el nombre del título, y el script escribe los roles de su tabla (table, rowgroup, row, columnheader, rowheader y cell). Sus botones son botones de alternancia (aria-pressed): Enter o Espacio apagan y encienden una serie, y la última serie mostrada sigue encendida. Sus filas reciben el foco, en una sola parada de Tab, y cada fila se nombra con sus propias celdas, a partir de tu texto: «Apr 1, Desktop 252, Mobile 148», con todas las series, mostradas o no. Las flechas pasan al día siguiente o al anterior (izquierda y derecha siguen la dirección de la página), e Inicio y Fin al primero y al último, cuando el foco está en una fila; las teclas del modo de exploración de un lector de pantalla, son suyas.
La lectura tiene el nombre del día como título, así que la banda nunca es la única señal de dónde estás; está oculta para la tecnología de asistencia. Escape la guarda sin mover el puntero ni el foco (vuelve en otro día). Una serie apagada pierde sus columnas pero conserva sus celdas en la tabla, así que un lector de pantalla sigue leyendo todas las cifras.
No ocultes la tabla: son los datos. Las columnas son un dibujo de ella y no llevan texto propio.
El contraste y el foco están en la pestaña Diseño.
Diseño
Cuándo usarlo
Úsalo para comparar unos pocos valores que tienen un orden o un nombre, como los días de una semana o los meses de un año, en una misma escala. Con varias series, compara unas pocas series categoría a categoría, como dos dispositivos mes a mes. Usa el gráfico interactivo para dos o más series a lo largo de muchos días, cuando importan los totales y cada día se lee de uno en uno.
Cuándo no usarlo
No uses el gráfico interactivo cuando haya que ver todas las cifras a la vez: sus cifras están en la lectura, ni para tasas, proporciones ni medias: el total de una serie es una suma. No lo uses para un solo valor (usa un medidor), para nombres largos (usa una lista de barras) ni para una tendencia de muchos puntos. Conserva una tabla cuando importen más los valores exactos.
Qué hacer y qué no
--v con un mismo máximo de escala y escribe cada cifra en su celda: la altura permite comparar y el número indica cuánto hay.Cómo escribir el contenido
Indica la unidad y el periodo en el título de la tabla («Paquetes por día, esta semana»), mantén cada nombre en una o dos palabras y escribe la cifra con su unidad cuando no sea evidente. Nombra cada serie en una o dos palabras: su celda de encabezado es el nombre de su botón. Los datos y las etiquetas son tuyos: el componente solo los dibuja.
Contraste y foco
La columna es un color de gráfico; la pista es más discreta a propósito, porque la cifra lleva el valor. El gráfico interactivo no tiene pista: el día bajo el puntero o el foco tiene una banda clara.
| Parte | Color sobre el fondo | Claro | Oscuro | Alto contraste | Requisitos |
|---|---|---|---|---|---|
Columna sobre su pista | --luz-chart-1 on --luz-chart-track | 3.4:1 | 3.8:1 | 6.8:1 | 2:1 |
Columna sobre la página | --luz-chart-1 on --luz-surface-page | 5.6:1 | 7.7:1 | 14.1:1 | 3:1 |
Columna sobre una tarjeta | --luz-chart-1 on --luz-surface | 5.9:1 | 7.2:1 | 14.1:1 | 3:1 |
Segunda serie sobre su pista | --luz-chart-2 on --luz-chart-track | 3.2:1 | 4.4:1 | 4.4:1 | 2:1 |
Segunda serie sobre la página | --luz-chart-2 on --luz-surface-page | 5.3:1 | 8.9:1 | 9.3:1 | 3:1 |
Columna sobre la banda del día bajo el puntero | --luz-chart-1 on --luz-surface-hover | 5.1:1 | 6.4:1 | 13.5:1 | 3:1 |
Segunda serie sobre la banda | --luz-chart-2 on --luz-surface-hover | 4.8:1 | 7.4:1 | 8.9:1 | 3:1 |
Cifra | --luz-text-primary on --luz-surface-page | 15.8:1 | 15.1:1 | 21.0:1 | 4.5:1 |
Nombre de una columna o de un grupo | --luz-text-secondary on --luz-surface-page | 6.2:1 | 7.5:1 | 19.3:1 | 4.5:1 |
Nombre de una serie en la leyenda | --luz-text-primary on --luz-surface-page | 15.8:1 | 15.1:1 | 21.0:1 | 4.5: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 |
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. Los requisitos son los mínimos de WCAG 2.2 AA: 4,5:1 para el texto y 3:1 para los anillos de foco, los bordes y los iconos; una parte decorativa discreta mantiene 2:1 con aquello sobre lo que se dibuja.
- Foco: el gráfico simple no recibe ninguno. En el interactivo, un botón y una fila reciben el anillo de foco,
--luz-focus-ring, de 2px: dentro del borde de un botón, y alrededor del grupo de columnas de una fila. - 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.
- No solo color: cada columna tiene su cifra en texto, y en colores forzados la columna se dibuja con el resalte del sistema y un borde alrededor de su pista, una segunda serie con el color del texto; en el gráfico interactivo, sin pista, el día bajo el puntero o el foco tiene un borde discontinuo para su banda. Una serie apagada tiene un punto hueco y un nombre más claro, no solo otro color.
Tokens que usa
Los 26 tokens que lee components/column-chart.css, agrupados por familia. Cada familia enlaza a su página, con los valores de cada modo. En Figma son variables con los mismos nombres: consulta Tokens en Figma.
- Color
--luz-chart-1,--luz-chart-2,--luz-chart-3,--luz-chart-4,--luz-chart-5,--luz-chart-6,--luz-chart-track,--luz-divider,--luz-focus-ring,--luz-surface-hover,--luz-text-primary,--luz-text-secondary- 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-mono,--luz-font-sans,--luz-text-sm,--luz-text-xs- Radio
--luz-radius-full,--luz-radius-sm- Capas
--luz-z-raised
El teclado y ARIA están en la pestaña Código.