# Sankey chart

> Flows between nodes, each link as thick as its value.

## Anatomy

A `<figure class="sankey-chart">` draws flows between nodes from a `<table>`, each link as thick as its value.

Each row is one flow. The first column names its source node, the second its target node, and the third holds its value. A node with the same name in either column is one node, so a node can take flows in and send them on. To compare parts of one whole, use a [pie chart](pie-chart.html).

```
<figure class="sankey-chart">
  <figcaption>Energy flow (TWh)</figcaption>
  <table>
    <thead>
      <tr><th>Source</th><th>Target</th><th>TWh</th></tr>
    </thead>
    <tbody>
      <tr><th>Solar</th><td>Grid</td><td>30</td></tr>
      <tr><th>Wind</th><td>Grid</td><td>50</td></tr>
      <tr><th>Grid</th><td>Homes</td><td>60</td></tr>
      <!-- One row per flow -->
    </tbody>
  </table>
</figure>
```

## Columns and order

A node that takes no flow stands in the first column. Every other node stands one column past the furthest of its sources, so each link runs toward the inline end. In a right-to-left page the columns run from right to left.

Within a column, nodes stack in the order their names first appear in the table, reading row by row and source before target. The chart does not reorder them, so sort the rows to change the order or to cut crossing links. Each node's links leave and arrive in table order down its edges.

## Values and skipped rows

The value cell reads as in a line chart. Its number is its `data-value`, or its text without currency signs, percent signs or grouping commas. The tooltip shows the text as written. Each link is as thick as its value, and each node as tall as the larger of what flows in and what flows out, on one scale that fits the tallest column to the chart's height.

A row draws nothing when its value is not a positive number, when a name is missing, when its source and target are the same node, or when its link would lead back to a node above it and close a loop. The rest of the chart draws as if the row were not there. The table still shows every row.

## 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 chart and its node names are hidden from assistive technology.

The plot is one Tab stop named by the caption. Keyboard focus shows the first link. The arrow keys step through the links in table order: right and down go to the next link, left and up to the one before, skipping the rows that draw nothing. Home and End jump to the first and last links, and Escape hides the tooltip. The arrows keep this meaning in a right-to-left page, since table order is not a direction on screen. The pointer shows the link under it. The tooltip is a polite live region, so a screen reader hears the source, the target and the value as it moves. Nodes are not reached this way; their totals are in the table. In forced colors the nodes and links keep their colors.

## JavaScript

`AutoInit()` starts every `.sankey-chart`. To start one yourself, call `SankeyChart.init`. After changing its table, call `update()` to redraw it in place, or put `data-watch` on the figure and it redraws itself. Links and nodes move from their old shapes to the new ones, or appear at once with reduced motion. It has the line chart's options and methods.

```
const chart = Expressive.SankeyChart.init(document.querySelector('.sankey-chart'));
chart.show(2);   // highlight the third drawn link in table order; -1 hides the tooltip
chart.update();  // redraw from the table; focus and the highlighted link stay
chart.destroy(); // remove the drawing and show the table again
```

## Tokens

Override these on the `.sankey-chart`.

| Token | Default |
| --- | --- |
| `--md-comp-sankey-chart-height` | 240px |
| `--md-comp-sankey-chart-link-opacity` | 0.4 |
| `--md-comp-sankey-chart-color-1` … `-6` | `primary`, `tertiary`, `secondary`, `on-surface-variant`, then `primary-container` and `tertiary-container` deepened toward `on-surface` |

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