# Donut chart

Two to eight parts of a whole as a ring, with the total in the middle and a legend beside it that names each part with its value.

Block: `smbk-donut-chart`. Status: experimental. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Desktop and mobile: differ by presentation only.

## Options

| Axis | Values | Default | Meaning |
|---|---|---|---|

Parts: `smbk-donut-chart__ring`, `smbk-donut-chart__svg`, `smbk-donut-chart__part`, `smbk-donut-chart__center`, `smbk-donut-chart__figure`, `smbk-donut-chart__caption`, `smbk-donut-chart__legend`, `smbk-donut-chart__table`, `smbk-donut-chart__data`

## Markup

```html
<div data-entrance="load" class="smbk-donut-chart">
  <div
    class="smbk-donut-chart__ring"
    role="img"
    aria-label="Others the largest part at 35%, then design at 27%."
  ><svg class="smbk-donut-chart__svg" viewBox="0 0 100 100" focusable="false" aria-hidden="true"><path class="smbk-donut-chart__part smbk-donut-chart__part--swatch-1" d="M51 0.01 A50 50 0 0 1 99.81 54.31 L86.86 53.19 A37 37 0 0 0 50.74 13.01 Z" fill-rule="evenodd"><title>Design: $1,357 (26.7%)</title></path><path class="smbk-donut-chart__part smbk-donut-chart__part--swatch-2" d="M99.6 56.3 A50 50 0 0 1 44.95 99.74 L46.27 86.81 A37 37 0 0 0 86.71 54.66 Z" fill-rule="evenodd"><title>Hosting: $1,283 (25.2%)</title></path><path class="smbk-donut-chart__part smbk-donut-chart__part--swatch-3" d="M42.97 99.5 A50 50 0 0 1 10.7 80.91 L20.92 72.87 A37 37 0 0 0 44.8 86.63 Z" fill-rule="evenodd"><title>Tools: $650 (12.8%)</title></path><path class="smbk-donut-chart__part smbk-donut-chart__part--swatch-4" d="M9.49 79.31 A50 50 0 0 1 49 0.01 L49.26 13.01 A37 37 0 0 0 20.02 71.69 Z" fill-rule="evenodd"><title>Others: $1,794 (35.3%)</title></path></svg><span class="smbk-donut-chart__center"><span class="smbk-donut-chart__figure">$5,084</span><span class="smbk-donut-chart__caption">7 days</span></span></div>
  <ul class="smbk-donut-chart__legend">
    <li class="smbk-legend-item smbk-legend-item--swatch-1">
      <span class="smbk-legend-item__swatch" aria-hidden="true"></span>
      <span class="smbk-legend-item__label">Design</span>
      <span class="smbk-legend-item__value">$1,357</span>
    </li>
    <li class="smbk-legend-item smbk-legend-item--swatch-2">
      <span class="smbk-legend-item__swatch" aria-hidden="true"></span>
      <span class="smbk-legend-item__label">Hosting</span>
      <span class="smbk-legend-item__value">$1,283</span>
    </li>
    <li class="smbk-legend-item smbk-legend-item--swatch-3">
      <span class="smbk-legend-item__swatch" aria-hidden="true"></span>
      <span class="smbk-legend-item__label">Tools</span>
      <span class="smbk-legend-item__value">$650</span>
    </li>
    <li class="smbk-legend-item smbk-legend-item--swatch-4">
      <span class="smbk-legend-item__swatch" aria-hidden="true"></span>
      <span class="smbk-legend-item__label">Others</span>
      <span class="smbk-legend-item__value">$1,794</span>
    </li>
  </ul>
  <table class="smbk-donut-chart__table"><caption>Spend by product, last 7 days</caption><thead><tr><th scope="col">Part</th><th scope="col">Value</th><th scope="col">Share</th></tr></thead><tbody><tr><th scope="row">Design</th><td>$1,357</td><td>26.7%</td></tr><tr><th scope="row">Hosting</th><td>$1,283</td><td>25.2%</td></tr><tr><th scope="row">Tools</th><td>$650</td><td>12.8%</td></tr><tr><th scope="row">Others</th><td>$1,794</td><td>35.3%</td></tr></tbody></table>
</div>
```

## React

```tsx
import { DonutChart } from './design-system/components/donut-chart/donut-chart.js';

<DonutChart label="Spend by product, last 7 days" summary="Others the largest part at 35%, then design at 27%." parts={[{ name: "Design", value: 1357 }, { name: "Hosting", value: 1283 }, { name: "Tools", value: 650 }, { name: "Others", value: 1794 }]} caption="7 days" format={() => {}} legend />
```

## Stylesheet

```css
/* smbk-donut-chart — Donut chart. Figma "Donut chart" 7580:1283.
 * A ring of two to eight parts, clockwise from the top in the categorical colors, a small gap between each, the
 * figure in the middle with its caption under it, and a legend beside the ring naming each part with its value.
 * A ninth part and the rest are gathered as one, in the muted gray. In a narrow layout the legend goes under
 * the ring. The first time the chart comes into view the ring sweeps round from the top; pointing at a part fades
 * the others. Nothing takes focus, unless the parts are made focusable: then a focused part is outlined in the
 * focus color and the others fade. */

.smbk-donut-chart {
  display: flex;
  align-items: center;
  gap: var(--smbk-space-inline-xl);
  min-width: 0;
  max-width: var(--smbk-size-width-400);
}

/* The block frames the words it hides for screen readers, so they stay inside it wherever it is placed: without a
   frame they hang from the page itself and stretch it, past the end of an area that scrolls. No weight, so a parent
   that places the block keeps its say. */
:where(.smbk-donut-chart) {
  position: relative;
}

.smbk-donut-chart__ring {
  position: relative;
  flex: none;
  width: var(--smbk-size-chart-donut);
  height: var(--smbk-size-chart-donut);
}

.smbk-donut-chart__svg {
  display: block;
  width: 100%;
  height: 100%;
}

.smbk-donut-chart__part {
  fill: var(--smbk-color-data-categorical-1);
  stroke: none;
}

/* ---- each part's color ---- */

.smbk-donut-chart__part--swatch-2 { fill: var(--smbk-color-data-categorical-2); }
.smbk-donut-chart__part--swatch-3 { fill: var(--smbk-color-data-categorical-3); }
.smbk-donut-chart__part--swatch-4 { fill: var(--smbk-color-data-categorical-4); }
.smbk-donut-chart__part--swatch-5 { fill: var(--smbk-color-data-categorical-5); }
.smbk-donut-chart__part--swatch-6 { fill: var(--smbk-color-data-categorical-6); }
.smbk-donut-chart__part--swatch-7 { fill: var(--smbk-color-data-categorical-7); }
.smbk-donut-chart__part--swatch-8 { fill: var(--smbk-color-data-categorical-8); }
.smbk-donut-chart__part--swatch-muted { fill: var(--smbk-color-surface-track); }

/* The figure and its caption, centred in the hole. */
.smbk-donut-chart__center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.smbk-donut-chart__figure {
  color: var(--smbk-color-text-default);
  font-family: var(--smbk-typography-heading-xs-font-family);
  font-size: var(--smbk-typography-heading-xs-font-size);
  font-weight: var(--smbk-typography-heading-xs-font-weight);
  line-height: var(--smbk-typography-heading-xs-line-height);
  letter-spacing: var(--smbk-typography-heading-xs-letter-spacing);
  text-transform: var(--smbk-typography-heading-xs-text-transform);
  font-variant-numeric: tabular-nums;
}

/* A long figure steps down, so it keeps clear of the ring: the wrapper sets the size from how far the figure runs, the
   smaller heading first and a label after it. The heading the ring draws reaches it at seven characters. */
.smbk-donut-chart__figure--size-md {
  font-family: var(--smbk-typography-heading-2xs-font-family);
  font-size: var(--smbk-typography-heading-2xs-font-size);
  font-weight: var(--smbk-typography-heading-2xs-font-weight);
  line-height: var(--smbk-typography-heading-2xs-line-height);
  letter-spacing: var(--smbk-typography-heading-2xs-letter-spacing);
  text-transform: var(--smbk-typography-heading-2xs-text-transform);
}

.smbk-donut-chart__figure--size-sm {
  font-family: var(--smbk-typography-label-lg-font-family);
  font-size: var(--smbk-typography-label-lg-font-size);
  font-weight: var(--smbk-typography-label-lg-font-weight);
  line-height: var(--smbk-typography-label-lg-line-height);
  letter-spacing: var(--smbk-typography-label-lg-letter-spacing);
  text-transform: var(--smbk-typography-label-lg-text-transform);
}

.smbk-donut-chart__caption {
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-body-xs-font-family);
  font-size: var(--smbk-typography-body-xs-font-size);
  font-weight: var(--smbk-typography-body-xs-font-weight);
  line-height: var(--smbk-typography-body-xs-line-height);
  letter-spacing: var(--smbk-typography-body-xs-letter-spacing);
  text-transform: var(--smbk-typography-body-xs-text-transform);
}

.smbk-donut-chart__legend {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--smbk-space-stack-sm);
  min-width: 0;
  margin: 0;
  padding: 0;
}

/* The table, for screen readers only, unless the page shows it in the disclosure under the chart. */
/* .smbk-donut-chart__table: hidden from view, kept for screen readers and the keyboard, by the shared rule in visually-hidden/visually-hidden.css. */

/* A table takes the room its rows need whatever width and height it is given, so the hidden one is full size, only
   unseen. It hangs from the block's end corner, reaching back and up, the way a page never scrolls: it adds no room
   to the block or to any area that scrolls around it, and stays a table for screen readers. */
.smbk-donut-chart__table {
  inset-block-end: 0;
  inset-inline-end: 0;
}

/* The disclosure that shows the table takes the chart's whole width, under the ring and the legend. */
.smbk-donut-chart:has(> .smbk-donut-chart__data) {
  flex-wrap: wrap;
}

.smbk-donut-chart__data {
  flex: 1 0 100%;
}

/* A narrow space puts the legend under the ring. */
@container style(--smbk-layout: narrow) {
  .smbk-donut-chart {
    flex-direction: column;
    align-items: stretch;
    max-width: none;
  }

  .smbk-donut-chart__ring {
    align-self: center;
  }
}

/* ---- pointing at a part ----
   Where there is a mouse, pointing at a part of the ring fades every other part to the faded opacity, half, so the
   one pointed at stands out; with nothing pointed at, the parts wait the hover close delay before coming back, so
   crossing the thin gap between two parts never flashes the whole ring; the fade moves with the feedback purpose, under reduced motion too, since nothing moves. The middle
   lets the pointer through to the ring under it. Nothing is told by the fade alone: the legend and the table name
   every part with its value. Parts take no focus unless made focusable (below). At rest every part is
   whole. */

@media (hover: hover) {
  .smbk-donut-chart__center {
    pointer-events: none;
  }

  .smbk-donut-chart__svg:has(.smbk-donut-chart__part:hover) .smbk-donut-chart__part:not(:hover) {
    opacity: var(--smbk-opacity-faded);
    transition-delay: 0s;
  }

  .smbk-donut-chart__svg:has(.smbk-donut-chart__part:hover) .smbk-donut-chart__part:hover {
    transition-delay: 0s;
  }

  .smbk-donut-chart__part {
    transition: opacity var(--smbk-motion-feedback-duration) var(--smbk-motion-feedback-easing) var(--smbk-motion-hover-close-delay);
  }
}

/* ---- a part that takes focus ----
   Parts made focusable (a tabindex on each, one of them 0, and each named by its figures) draw the focus ring as an
   edge in the focus color along the part's own outline, the ring's width on screen whatever the chart's size, and a
   focused part stands out as a pointed one does: every other part fades to the faded opacity, on any screen, since
   a keyboard has no hover. */

.smbk-donut-chart__part:focus {
  outline: none;
}

.smbk-donut-chart__part:focus-visible {
  stroke: var(--smbk-color-border-focus);
  stroke-width: var(--smbk-focus-ring-width);
  vector-effect: non-scaling-stroke;
}

.smbk-donut-chart__svg:has(.smbk-donut-chart__part:focus-visible) .smbk-donut-chart__part:not(:focus-visible) {
  opacity: var(--smbk-opacity-faded);
}

/* The ring reaches the drawing's edge, so the edge's outer half would be cut off there. */
.smbk-donut-chart__svg:has(.smbk-donut-chart__part:focus-visible) {
  overflow: visible;
}

/* ---- motion: the entrance ----
   The wrapper marks the chart `data-entrance` the first time it comes into view (simbolik/components/entrance.ts):
   waiting while it is out of view, the ring hidden; playing once it is seen, the ring uncovered clockwise from the
   top, the way its parts run, with the chart entrance purpose: a conic mask whose edge turns from nothing to the
   whole circle. --smbk-donut-chart-sweep is that edge, as a share of the circle; it is registered so it can move
   smoothly. The middle and the legend stay. Without the mark (markup written by hand, the rendered pictures, after
   the entrance) the ring is simply drawn, and under reduced motion nothing moves. Only the mask changes, so
   nothing shifts. The mask reads only how opaque its paint is, so the text color stands in for "shown". */

@property --smbk-donut-chart-sweep {
  syntax: "<number>";
  inherits: false;
  initial-value: 100;
}

@media screen and (prefers-reduced-motion: no-preference) {
  .smbk-donut-chart[data-entrance] .smbk-donut-chart__svg {
    mask-image: conic-gradient(currentcolor calc(var(--smbk-donut-chart-sweep) * 1%), transparent 0);
  }

  .smbk-donut-chart[data-entrance="waiting"] .smbk-donut-chart__svg {
    --smbk-donut-chart-sweep: 0;
  }

  .smbk-donut-chart:is([data-entrance="load"], [data-entrance="playing"]) .smbk-donut-chart__svg {
    animation: smbk-donut-chart-sweep var(--smbk-motion-chart-entrance-reveal-duration) var(--smbk-motion-chart-entrance-easing) backwards;
  }
}

@keyframes smbk-donut-chart-sweep {
  from {
    --smbk-donut-chart-sweep: 0;
  }
}

/* ---- high contrast (forced colors) ---- */
/* The parts keep their colors, so each still matches its legend swatch. */

@media (forced-colors: active) {
  .smbk-donut-chart__svg {
    forced-color-adjust: none;
  }

  .smbk-donut-chart__part:focus-visible {
    stroke: Highlight;
  }
}
```

## Tokens it reads

```json
{
  "space": {
    "inline": {
      "xl": {
        "$type": "dimension",
        "$value": "{{space.16}}",
        "$description": "Gap between things side by side, extra large."
      }
    },
    "stack": {
      "sm": {
        "$type": "dimension",
        "$value": "{{space.8}}",
        "$description": "Gap between things stacked one above another, small."
      }
    }
  },
  "size": {
    "width": {
      "400": {
        "$type": "dimension",
        "$value": "400px",
        "$description": "A fixed width of 400 px: a narrow column, a list’s greatest height. Semantic sizes point here."
      }
    },
    "chart": {
      "donut": {
        "$type": "dimension",
        "$value": "140px",
        "$description": "Width and height of a donut chart's ring. A fixed frame size in Figma with no variable behind it; it should become one."
      }
    }
  },
  "color": {
    "data": {
      "categorical": {
        "1": {
          "$type": "color",
          "$value": "{{palette.light.categorical.1}}",
          "$description": "Categorical position 1 (blue). Fixed order, never cycled. Light blue/600, dark blue/400. Marks reach 3:1 on the plot background; never colour alone: direct labels, markers or patterns too."
        },
        "2": {
          "$type": "color",
          "$value": "{{palette.light.categorical.2}}",
          "$description": "Categorical position 2 (orange). Light orange/500, dark orange/400. Marks reach 3:1 on the plot background; never colour alone: direct labels, markers or patterns too."
        },
        "3": {
          "$type": "color",
          "$value": "{{palette.light.categorical.3}}",
          "$description": "Categorical position 3 (neutral). Light grey/700, dark grey/300. Marks reach 3:1 on the plot background; never colour alone: direct labels, markers or patterns too."
        },
        "4": {
          "$type": "color",
          "$value": "{{palette.light.categorical.4}}",
          "$description": "Categorical position 4 (green). Light green/500, dark green/400. Marks reach 3:1 on the plot background; never colour alone: direct labels, markers or patterns too."
        },
        "5": {
          "$type": "color",
          "$value": "{{palette.light.categorical.5}}",
          "$description": "Categorical position 5 (purple). Light purple/500, dark purple/300. Marks reach 3:1 on the plot background; never colour alone: direct labels, markers or patterns too."
        },
        "6": {
          "$type": "color",
          "$value": "{{palette.light.categorical.6}}",
          "$description": "Categorical position 6 (teal). Light teal/600, dark teal/500. Marks reach 3:1 on the plot background; never colour alone: direct labels, markers or patterns too."
        },
        "7": {
          "$type": "color",
          "$value": "{{palette.light.categorical.7}}",
          "$description": "Categorical position 7 (yellow). Light yellow/500, dark yellow/500. Marks reach 3:1 on the plot background; never colour alone: direct labels, markers or patterns too."
        },
        "8": {
          "$type": "color",
          "$value": "{{palette.light.categorical.8}}",
          "$description": "Categorical position 8 (pink). Light pink/600, dark pink/300. Marks reach 3:1 on the plot background; never colour alone: direct labels, markers or patterns too."
        }
      }
    },
    "surface": {
      "track": {
        "$type": "color",
        "$value": "{{color.grey.500}}",
        "$description": "The filled track of a switch that is off: 3:1 against the page so the switch shows where it is (decision C)."
      }
    },
    "text": {
      "default": {
        "$type": "color",
        "$value": "{{color.grey.900}}",
        "$description": "Main text."
      },
      "subtle": {
        "$type": "color",
        "$value": "{{color.grey.700}}",
        "$description": "Secondary text: descriptions, metadata."
      }
    },
    "border": {
      "focus": {
        "$type": "color",
        "$value": "{{color.red.600}}",
        "$description": "Keyboard focus ring on controls."
      }
    }
  },
  "typography": {
    "heading-xs": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Funnel Display, Funnel Display Fallback, system-ui, sans-serif",
        "fontSize": {
          "min": "20px",
          "max": "28px"
        },
        "fontWeight": 400,
        "lineHeight": 1.2,
        "letterSpacing": "0px"
      }
    },
    "heading-2xs": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Funnel Display, Funnel Display Fallback, system-ui, sans-serif",
        "fontSize": {
          "min": "18px",
          "max": "24px"
        },
        "fontWeight": 400,
        "lineHeight": 1.2,
        "letterSpacing": "0px"
      }
    },
    "label-lg": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "16px",
        "fontWeight": 500,
        "lineHeight": 1.4,
        "letterSpacing": "0px"
      },
      "$description": "Label LG: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD."
    },
    "body-xs": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "12px",
        "fontWeight": 400,
        "lineHeight": 1.5,
        "letterSpacing": "0px"
      }
    }
  },
  "opacity": {
    "faded": {
      "$type": "number",
      "$value": 0.5,
      "$description": "Half see-through: the parts of a chart not pointed at, set back so the one pointed at stands out. 50%."
    }
  },
  "motion": {
    "feedback": {
      "duration": {
        "$type": "duration",
        "$value": "{{duration.150}}"
      },
      "easing": {
        "$type": "cubicBezier",
        "$value": "{{easing.expo-out}}"
      }
    },
    "hover": {
      "close-delay": {
        "$type": "duration",
        "$value": "{{duration.320}}",
        "$description": "From the pointer leaving the opener and panel to the panel closing; coming back within it keeps the panel open."
      }
    },
    "chart-entrance": {
      "reveal-duration": {
        "$type": "duration",
        "$value": "{{duration.1000}}",
        "$description": "How long a line takes to be uncovered across the plot, or a ring to sweep round."
      },
      "easing": {
        "$type": "cubicBezier",
        "$value": "{{easing.steep-out}}"
      }
    }
  },
  "focus": {
    "ring": {
      "width": {
        "$type": "dimension",
        "$value": "{{border-width.2}}",
        "$description": "Thickness of the focus ring."
      }
    }
  }
}
```

## Purpose

Shows how a whole splits into two to eight parts, such as a week's spend by product, with the total in the middle and each part's value beside the ring.

## Anatomy

- The block: the ring and the legend side by side, the table after them.
- The ring part, the picture: the svg part with a part for each part of the whole, clockwise from the top, its color a modifier of the part; the center part holding the figure part, the total unless given, and the caption part under it. A long figure takes a size modifier of the figure part, `--size-md` or `--size-sm`; the wrapper sets it, and markup written by hand adds it.
- The legend part: a list of legend items, each part's name and value, in the order the ring runs.
- The table part: each part's value and share in a table, for screen readers; or the data part, the same table in a closed disclosure under the chart.

## When to use

- A total and the two to eight parts it is made of, where the reader wants the parts' sizes against the whole.

## When not to use

- For parts that must be compared exactly, or that are close in size. Use a [bar chart](bar-chart.md), or the numbers.
- For change over time. Use a [line chart](line-chart.md) or a bar chart.
- For more than eight parts. Gather the smallest, or use a bar chart.
- When one number answers the question. Show the number.

## Behavior

The ring keeps one size; the legend takes the room beside it. The parts run clockwise from the top in the eight series colors, in a fixed order, a small gap between each. A ninth part and the rest are gathered as Other, in gray. A part can name its own color (`swatch`, a number from 1 to 8), so it keeps it whatever its place, the same color it has on the page's other charts; the parts that name none take the colors left, in order, and `swatch="muted"` gathers a part into Other. A part with nothing in it draws nothing, and stays in the legend unless `legendEmpty` is turned off; the table lists it either way. The middle shows the total unless the page gives another figure, with an optional caption such as the period. A figure too long for its full size steps down, so it keeps clear of the ring: `$5,084` stays as it is, `$99,999` takes a smaller heading and `$1,250,000` a label. The middle holds ten characters. In a narrow layout the legend goes under the ring. The first time the chart comes into view the ring sweeps round from the top, while the middle and the legend stay, and later changes to the data land at once. Under reduced motion, and in markup written by hand, it appears at once. With a mouse, pointing at a part of the ring fades the other parts, so the one pointed at stands out. Pointing at a part also shows the browser's own tooltip, with its name, value and share; hand-written markup puts the same words in a `title` element inside the part's path. Nothing takes focus unless the chart is made `focusable`: then the parts are one stop for the Tab key, the arrow keys move round the ring, and the focused part is outlined in the focus color while the others fade, as when pointed at. A focusable part is named by its figures instead of showing the browser's tooltip, which would be read a second time. `onActiveChange` tells the page the part pointed at or focused, with its name and value, and `null` when there is none, so the page can show it in a readout. The wrapper writes the values and shares in English unless `locale` names another language or `format` writes the values, so a page prepared on a server shows the same numbers once its script runs.

## Accessibility

### What it does for you

- The ring is an image named by the summary.
- The legend is a list a screen reader reads, each part with its value.
- Every part is in a table titled by the chart's label, with its value and its share of the whole. The table lists each part, even those gathered as Other in the picture. It is out of sight, for screen readers, unless the page shows it in the disclosure under the chart, which the keyboard reaches.
- The parts differ by color, so the legend names them in the order the ring runs, with their values; the eight series colors are chosen to stay apart for readers with color blindness, the first and the last too, which meet at the top.
- In high contrast mode the ring keeps its colors, so each part still matches the legend.
- Nothing in the ring takes focus unless made focusable; the legend and the table name every part and value. Made focusable, the ring is a group named by the summary and each part an image named by its name, value and share, one stop for the Tab key.

### What you must do

- Write the summary as the chart's main message: the total and the largest part, with its share.
- In markup written by hand, name the ring with `role="img"` and its summary, and keep the legend and the table. For parts that take focus, make the ring `role="group"` named by the summary and the drawing `role="presentation"`, give each part `role="img"`, its figures in `aria-label` and a `tabindex`, `0` on one and `-1` on the rest, and move focus with the arrow keys yourself.
- When the parts take focus, show the figures of the part pointed at or focused near the chart, from `onActiveChange`: sighted readers no longer get the browser's tooltip.

### How to test

- With a screen reader, the ring is read as an image by its summary, then the legend as a list with each part and its value.
- Show the data: Tab to the disclosure under the chart and open it with the keyboard. The table gives each part with its value and share.
- With the colors removed, the legend still names every part and its value.
- With text at 200% and the page 320 pixels wide, the legend goes under the ring and stays whole.
- In a forced-color mode, each part of the ring still matches the legend.
- With parts that take focus, Tab once to reach the ring, move round it with the arrow keys, and hear each part's name, value and share.

### Keyboard

| Key | What it does |
|---|---|
| Tab | Moves focus to the parts when they take focus, to the part focused last or else the first, then to the disclosure under the chart when the page shows the data. |
| Right arrow or Down arrow | On a part, moves focus to the next part, clockwise. |
| Left arrow or Up arrow | On a part, moves focus to the part before. |
| Home or End | On a part, moves focus to the first or the last part. |
| Enter or Space | Opens or closes the disclosure that shows the table. |

## Usage rules

### Do

- Keep to a few parts, eight at most, and give each its value in the legend.
- Put the period or the unit under the total, such as "7 days".
- Keep the figure to ten characters. Give a longer total a shorter form with `figure`, such as `$1.3M`.
- Say the largest part and its share in the summary.
- Give each part the color it has on the page's other charts, so a reader matches them at a glance.

### Don't

- Leave out the legend: color alone cannot name the parts.
- Use a donut for parts that are nearly the same size.
- Put a value only in the picture: the legend and the table hold them.
