# Column chart

Compares a few values as columns of one height scale, drawn from a native table that keeps every figure as text.

### Known issues
None known.

### Copy the markup
A stylesheet of `@luz-ds/catalog`: link `components/column-chart.css` after `luz.css`.

Column chart markup
```html
<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>
```

With several series, with no script: one row per category, its name in a `<th scope="row">`, and one cell per series, up to six. The head row names the series. The rows are laid out side by side, and some browsers (Safari with VoiceOver) then stop telling the table from a pile of boxes: write its roles, as here. `<luz-chart interactive>` writes them for you.

Column chart markup with several series
```html
<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>
```

Interactive, with the header of the series: link `components/chart.css` too, and load `catalog.js`, which loads `chart.js` when the page has a `<luz-chart>`. One row per day, its name in a `<th scope="row">`, and one column per series. The table has no class: the script gives it `luz-column-chart` when it draws it, so without the script it fits any width.

Interactive column chart markup
```html
<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>
```

### Variants and options
- `--v`: On each cell, from 0 to 1: its value over the top of the scale, the same for every column
- `--luz-column-chart-color`: Another chart colour for a table or a cell, such as `var(--luz-chart-2)`
- `--luz-column-chart-h`: The height of the columns
- `--luz-column-chart-bar`: The width of a column, `var(--luz-space-lg)` by default; never wider than its share of the table
- A row per category: Several series: a `<th scope="row">` then a cell per series in each row, up to six. Each row is a group of columns, series n in `--luz-chart-n`, its name below it, and the head row is the legend
- `--luz-column-chart-gap`: In the CSS-only several-series chart, the space between the columns of a group, `var(--luz-space-xs)` by default; the groups take the space that is left. `<luz-chart interactive>` shares the width of its days and has no gap to set
- `<luz-chart type="column" interactive>`: Around a table of several series with no class: drawn as columns by the script, with a button per series and its total, which turns its columns off and on, and a readout of the day under the pointer or the focus

### How it works
A table of one head row of names and one row of figures. Each figure is the text of its cell, and the cell draws its column under it, from the foot up to `--v`, in `--luz-chart-1`, with the track in `--luz-chart-track`. The columns share the width evenly.

Work out `--v` as the value over the top of the scale, the same top for every cell. The inline `style` sets only that. With a strict `style-src`, set it in a rule of your own, such as `.sat { --v: .25 }`.

At the default text size, up to seven columns, or three groups of two, fit a 320 px screen. For more, or with larger text, put the table in a `luz-table-wrap`: it scrolls inside it.

The figure of each cell is above its column and the name below it, as an axis. With several series, each row is a group of columns, `--luz-column-chart-gap` apart (in the CSS-only chart), and the head row is the legend: each series' name after a dot of its colour.

Inside `<luz-chart type="column" interactive>`, the script adds a header above the table: a button per series, its name and the sum of its figures, written with the page's language. A sum suits counts and amounts, such as visitors or euros; it does not suit rates, shares or averages, whose total says nothing: do not use `interactive` for them, or leave their cells out of it. The caption becomes the title. The columns lose their track: the day under the pointer or the focus gets a light band, and the figures leave the columns for a readout beside it. The columns keep the scale of their `--v` when a series is turned off, and the last series shown cannot be turned off. The script writes no word of its own: the names, the figures and the caption are yours.

### Without JavaScript
It needs none. Without the stylesheet it reads as a table: a head row of names, then the figures. The interactive chart is, without its script, a plain table: a row per day with every figure, which fits the narrowest screen. A table of a few categories that should be columns with no script takes the class `luz-column-chart` itself.

### Keyboard and ARIA
The plain chart takes no focus. A table keeps its roles, so a screen reader reads each figure with its name. The caption names the table and says the unit. With several series the rows are laid out side by side: write the roles of the table in its markup, as the snippet does, so that Safari with VoiceOver still reads a table.

The interactive chart is a group named by the caption, and the script writes the roles of its table (`table`, `rowgroup`, `row`, `columnheader`, `rowheader` and `cell`). Its buttons are toggle buttons (`aria-pressed`): Enter or Space turns a series off and on, and the last series shown stays on. Its rows take the focus, one Tab stop, and each row is named by its own cells, from your text: “Apr 1, Desktop 252, Mobile 148”, with every series, shown or not. When the focus is in a row, the arrow keys move to the next or the previous day (Left and Right follow the direction of the page), and Home and End to the first and the last; the keys of a screen reader’s browse mode are its own.

The readout has the name of the day as its title, so the band is never the only sign of where you are; it is hidden from assistive technology. Escape puts it away without moving the pointer or the focus (it comes back on another day). A series turned off loses its columns but keeps its cells in the table, so a screen reader still reads every figure.

Do not hide the table: it is the data. The columns are a picture of it and carry no text of their own.

### When to use
Use it to compare a few values that have an order or a name, such as the days of a week or the months of a year, on one scale. With several series, it compares a few series category by category, such as two devices month by month. Use the interactive chart for two or more series over many days, when the totals matter and each day is read one at a time.

### When not to use
Do not use the interactive chart when every figure must be seen at once: its figures are in the readout, nor for rates, shares or averages: the total of a series is a sum. Do not use it for one value (use a [meter](https://nandovejer.github.io/luz/docs/components/meter/)), for long names (use a [bar list](https://nandovejer.github.io/luz/docs/catalog/bar-list/)), or for a trend over many points. Keep a [table](https://nandovejer.github.io/luz/docs/components/table/) when exact values matter most.
