# Bar chart

> Ranked or long-labelled categories drawn as horizontal bars from a data table, grouped, stacked or as a meter.

## Anatomy

A `<figure class="bar-chart">` draws a `<table>` of values as horizontal bars that grow from zero. The first column of the table labels each row. Each further column is a series named by its header cell.

It takes the same markup as a [column chart](column-chart.html). Use bars when the labels are long, when the rows are a ranking, or when there are more rows than fit across the page. The labels sit at the inline start of each row. The plot grows with the number of rows. A band and a tooltip follow the pointer, and the up and down arrows move them when the chart has focus.

```
<figure class="bar-chart">
  <figcaption>Monthly revenue, first half</figcaption>
  <table>
    <thead>
      <tr><th>Month</th><th>Revenue</th></tr>
    </thead>
    <tbody>
      <tr><th>Jan</th><td>$4,400</td></tr>
      <tr><th>Feb</th><td>$5,500</td></tr>
      <tr><th>Mar</th><td>$4,100</td></tr>
      <!-- One row per month -->
    </tbody>
  </table>
</figure>
```

## Several series

Each value column after the first adds a bar to every row, and a legend appears. Series take `primary`, `tertiary`, `secondary` and `on-surface-variant` in turn. Two or three series per row stay readable. Add `toggle` to the figure to make each legend item a button that shows or hides its series, as on the [line chart](line-chart.html#toggle).

```
<figure class="bar-chart">
  <figcaption>Subscriptions by plan</figcaption>
  <table>
    <thead>
      <tr><th>Month</th><th>Basic</th><th>Premium</th></tr>
    </thead>
    <tbody>
      <tr><th>Jan</th><td>5,500</td><td>4,900</td></tr>
      <!-- One row per month -->
    </tbody>
  </table>
</figure>
```

## Stacked

Add `stacked` to draw one bar per row, with each series after the ones before it. The bar's length is the total. Only the last segment rounds its end. Stack values that add up, and keep them positive. An empty cell leaves the total unknown, so the chart leaves out the segments after it.

```
<figure class="bar-chart stacked">
  <figcaption>Subscriptions by plan, stacked</figcaption>
  <table><!-- … --></table>
</figure>
```

## Track and values

Add `track` to draw a full-width track behind each row and round both ends of its bars. Add `values` to write each cell's text from its bar's base, so a ranking reads without the tooltip. Over the bar, the text takes the series' on-color. A value longer than a short bar runs on past its end in the label color. Put the number in `data-value` when the text is abbreviated.

```
<figure class="bar-chart track values" style="
    --md-comp-bar-chart-row-height: 48px;
    --md-comp-bar-chart-shape: 12px;
    --md-comp-bar-chart-grid-color: transparent">
  <figcaption>Visitors by source</figcaption>
  <table>
    <thead>
      <tr><th>Source</th><th>Visitors</th></tr>
    </thead>
    <tbody>
      <tr><th>Search</th><td data-value="900000">900K</td></tr>
      <tr><th>Instagram</th><td data-value="650000">650K</td></tr>
      <!-- One row per source -->
    </tbody>
  </table>
</figure>
```

## Meter

One stacked row with a `track` and a `data-max` is a meter. The segments are what is used and the track is what is left. Add `split` to separate the segments with a gap and round them at each joint. The legend names the segments, and the tooltip lists every cell. In a stacked bar, `values` keeps each segment's text inside it and cuts what does not fit.

```
<article class="outlined">
  <div class="p-4">
    <dl class="stats my-0">
      <div>
        <dt>Spending limit</dt>
        <dd>$4,200</dd>
        <dd class="stat-change">of $10,000 this month</dd>
      </div>
    </dl>
    <figure class="bar-chart stacked split track" data-max="10000" style="
        --md-comp-bar-chart-bar-height: 100%;
        --md-comp-bar-chart-shape: 8px;
        --md-comp-bar-chart-grid-color: transparent">
      <figcaption class="visually-hidden">Spending by category, April</figcaption>
      <table>
        <thead>
          <tr><th>Month</th><th>Ads</th><th>Software</th><th>Payroll tools</th><th>Team events</th></tr>
        </thead>
        <tbody>
          <tr><th>Apr</th><td>$1,450</td><td>$1,120</td><td>$890</td><td>$740</td></tr>
        </tbody>
      </table>
    </figure>
  </div>
</article>
```

Use `sparkline` for a bar beside a figure that already explains it. It drops the label, grid, legend and tooltip.

## Chart cards

Put a chart in a card with the figures it explains. Labels take up to 40% of the width and end in an ellipsis past it. The card adds no chart styles, so size a chart with its tokens.

```
<article class="outlined">
  <div class="p-4">
    <dl class="stats my-0">…</dl>
    <figure class="bar-chart values"
            style="--md-comp-bar-chart-grid-color: transparent">
      <figcaption class="visually-hidden">Revenue by country</figcaption>
      <table><!-- … --></table>
    </figure>
  </div>
</article>
```

## Values and scale

Cells read as in a column chart. A cell's number is its text without currency signs, percent signs or grouping commas. Text that is not a single number is a gap. In a grouped chart, a gap leaves an empty slot, so the other series stay in place.

The value axis always includes zero. It leaves 10% of the span to spare past the longest bar, and before the shortest when there are negative values. Negative bars grow toward the inline start and round that end. Set `data-min` or `data-max` on the figure to fix either end.

Add `axis` to label the value axis at round values. The labels sit under the plot, with a grid line up from each. The chart widens an end it chose to the next round value, so the labels start and end on the plot's edges. An end set with `data-min` or `data-max` stays where it is. The labels repeat any currency or percent sign the cells are written with, and shorten large numbers, such as `$1.5K`. They are hidden from assistive technology, and the table still carries the values.

```
<figure class="bar-chart axis">
  <figcaption>Net cash flow, first half</figcaption>
  <table>
    <thead><tr><th>Month</th><th>Net</th></tr></thead>
    <tbody>
      <tr><th>Jan</th><td>$1,200</td></tr>
      <tr><th>Feb</th><td>−$400</td></tr>
      <!-- One row per month -->
    </tbody>
  </table>
</figure>
```

## Accessibility

The table is the chart's text alternative. Give it a header row and a header cell per row, and name the chart with a `<figcaption>`. The drawn bars, values, labels and legend are hidden from assistive technology.

The plot is one Tab stop named by the caption. Up and down arrows move between rows. Home and End jump to the ends, and Escape hides the tooltip. On a touch screen, tap a row to show it. In a right-to-left page, the labels sit on the right and the bars grow leftwards. The rows keep their order. The tooltip is a polite live region, so a screen reader hears each row's values as it moves. A sparkline is not focusable. In forced colors the bars keep their series colors so the legend still keys them.

## JavaScript

`AutoInit()` starts every `.bar-chart`. To start one yourself, call `BarChart.init`. After you change its table, call `update()` to redraw it in place. Or put `data-watch` on the figure, and it redraws itself. The bars move from their old values to the new ones, and a new bar grows from zero. With reduced motion, they appear at once. The bar chart takes the column chart's options and methods.

```
const chart = Expressive.BarChart.init(document.querySelector('.bar-chart'), {
  max: 10000
});
chart.show(2);   // highlight the third row; -1 hides the tooltip
chart.update();  // redraw from the table; focus and the highlighted row stay
chart.destroy(); // remove the drawing and show the table again
```

| Option | Default | Description |
| --- | --- | --- |
| `min` | `null` | Lowest value. `data-min` overrides it. |
| `max` | `null` | Highest value. `data-max` overrides it. |

## Tokens

Override these on the `.bar-chart`. The plot is as tall as its rows, so the shared `--md-comp-bar-chart-height` has no effect.

| Token | Default |
| --- | --- |
| `--md-comp-bar-chart-row-height` | 40px, 24px for a sparkline |
| `--md-comp-bar-chart-bar-height` | 60% of each row's height |
| `--md-comp-bar-chart-shape` | 4px |
| `--md-comp-bar-chart-track-color` | `--md-sys-color-surface-container-highest` |
| `--md-comp-bar-chart-grid-color` | `--md-sys-color-outline-variant` |
| `--md-comp-bar-chart-color-1` | `--md-sys-color-primary` |
| `--md-comp-bar-chart-color-2` | `--md-sys-color-tertiary` |
| `--md-comp-bar-chart-color-3` | `--md-sys-color-secondary` |
| `--md-comp-bar-chart-color-4` | `--md-sys-color-on-surface-variant` |
| `--md-comp-bar-chart-on-color-1` … `-4` | `on-primary`, `on-tertiary`, `on-secondary`, `surface`; text from `values` |

For a selective Sass build, include `"bar-chart"` in `$components`.
