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

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

### Copia el marcado
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.

Marcado del gráfico
```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:

Marcado del gráfico interactivo
```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:

Marcado del spark
```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:

Script que lee la tabla
```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
- `<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](https://nandovejer.github.io/luz/es/docs/catalog/column-chart/)): 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](https://nandovejer.github.io/luz/es/docs/catalog/bar-list/), el [gráfico de columnas](https://nandovejer.github.io/luz/es/docs/catalog/column-chart/), la [barra apilada](https://nandovejer.github.io/luz/es/docs/catalog/stacked-bar/) o el [mapa de calor](https://nandovejer.github.io/luz/es/docs/catalog/heat-map/).

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

### 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](https://nandovejer.github.io/luz/es/docs/components/table/) los dice mejor. Para comparar unos pocos valores en una sola escala, usa un [gráfico de columnas](https://nandovejer.github.io/luz/es/docs/catalog/column-chart/) o una [lista de barras](https://nandovejer.github.io/luz/es/docs/catalog/bar-list/), que no necesitan script.

- No lo uses para partes de un todo: usa una [barra apilada](https://nandovejer.github.io/luz/es/docs/catalog/stacked-bar/). 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.
