# DonutChart

Das DonutChart dient zur übersichtlichen Darstellung proportionaler Daten in einem ringförmigen Diagramm. Es eignet sich besonders zur Visualisierung von Verteilungen, Anteilen oder Fortschritten.

## Overview

# Playground

Verwende `<DonutChart />`, um ein DonutChart darzustellen.

```tsx
import { DonutChart } from "@mittwald/flow-react-components";

<DonutChart value={30} aria-label="Auslastung" />
```

---

# Mit Unit

Im default wird das DonutChart immer mit Prozentangabe angezeigt. Über das
Property `formatOptions` können aber auch andere Einheiten gewählt werden. (s.
[Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat))

## Gigabyte

```tsx
import { DonutChart } from "@mittwald/flow-react-components";

<DonutChart
  aria-label="Speicherplatz"
  formatOptions={{ style: "unit", unit: "gigabyte" }}
  maxValue={50}
  value={12}
/>
```

## Dezimalzahl

```tsx
import { DonutChart } from "@mittwald/flow-react-components";

<DonutChart
  aria-label="Performance"
  formatOptions={{ style: "decimal" }}
  maxValue={200}
  value={135}
/>
```

---

# Größen

Die Size des DonutCharts kann Medium oder Large sein. Medium ist dabei die
Standardgröße.

```tsx
import { DonutChart } from "@mittwald/flow-react-components";

<>
  <DonutChart value={30} aria-label="Auslastung" />
  <DonutChart value={30} aria-label="Auslastung" size="l" />
</>
```

---

# Mit alternativem Text

Über die `children` kann der Text innerhalb des DonutCharts überschrieben werden

```tsx
import { DonutChart } from "@mittwald/flow-react-components";

<DonutChart
  value={300}
  maxValue={600}
  aria-label="Speicherplatz"
>
  <strong>300</strong>
  <small>GB</small>
</DonutChart>
```

---

# Status

Je nach Anwendungsfall stehen vier Status-Farben zur Auswahl: **Info**,
**Success**, **Warning** und **Danger**.

```tsx
import { DonutChart } from "@mittwald/flow-react-components";

<>
  <DonutChart
    value={30}
    status="success"
    aria-label="Auslastung"
  />
  <DonutChart value={30} aria-label="Auslastung" />
  <DonutChart
    value={80}
    status="warning"
    aria-label="Auslastung"
  />
  <DonutChart
    value={95}
    status="danger"
    aria-label="Auslastung"
  />
</>
```

---

# Segmente

Die Anzeige des DonutCharts kann über das `segments` Property um einzelne
Abschnitte ergänzt werden. Der `value` ergibt sich in diesem Fall aus der Summe
der Werte der einzelnen Segmente. Um die einzelnen Werte näher zu erläutern wird
automatisch die `Legend` Component angezeigt. Über das `showLegend` Property
kann diese ein- und ausgeblendet werden. Die Position der Legende kann über das
Property `legendPosition` bestimmt werden.

Die Farben der Segmente werden automatisch festgelegt, können aber über das
`color`-Property, mit
[Categorical Colors](/02-foundations/01-design/02-colors#categorical-color) oder
eigenen Colors überschrieben werden. Beim Überschreiben muss darauf geachtet
werden, dass nebeneinander liegende Farben weiterhin einen ausreichenden
Kontrast zueinander haben.

```tsx
import { DonutChart } from "@mittwald/flow-react-components";

<DonutChart
  aria-label="Items"
  segments={[
    { title: "Item 1", value: 28 },
    { title: "Item 2", value: 24 },
    { title: "Item 3", value: 20 },
    { title: "Item 4", value: 10 },
    { title: "Item 5", value: 12 },
    { title: "Item 6", value: 6 },
  ]}
/>
```


## Develop

# Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `status` | `"info" \| "success" \| "warning" \| "danger"` | - | - |
| `size` | `"m" \| "l"` | `"m"` | The size variant of the donut chart. |
| `segments` | `DonutChartSegment[]` | - | Divides the fill of the donut chart into segments |
| `showLegend` | `boolean` | `: true` | Whether the legend component is shown when segments are used. |
| `legendPosition` | `"bottom" \| "top" \| "left" \| "right"` | `"right"` | The position of the legend. |
| `id` | `string` | - | The element's unique identifier. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id). |
| `translate` | `"yes" \| "no"` | - | - |
| `className` | `ClassNameOrFunction<ProgressBarRenderProps>` | `'react-aria-ProgressBar'` | The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the element. A function may be provided to compute the class based on component state. |
| `style` | `StyleOrFunction<TooltipRenderProps>` | - | The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element. A function may be provided to compute the style based on component state. |
| `render` | `DOMRenderFunction<"div", TooltipRenderProps>` | - | Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Requirements: - You must render the expected element type (e.g. if `<button>` is expected, you cannot render an `<a>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate. |
| `dir` | `string` | - | - |
| `lang` | `string` | - | - |
| `hidden` | `boolean` | - | - |
| `inert` | `boolean` | - | - |
| `minValue` | `number` | `0` | The smallest value allowed for the input. |
| `maxValue` | `number` | `100` | The largest value allowed for the input. |
| `value` | `number` | `0` | The current value (controlled). |
| `slot` | `string` | - | A slot name for the component. Slots allow the component to receive props from a parent component. An explicit `null` value indicates that the local props completely override all props received from a parent. |
| `formatOptions` | `NumberFormatOptions` | `{ style: 'percent' }` | The display format of the value label. |
| `isIndeterminate` | `boolean` | - | Whether presentation is indeterminate when progress isn't known. |
| `children` | `ReactNode` | - | - |

### Events

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `onClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onAuxClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onAuxClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onContextMenu` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onContextMenuCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onDoubleClick` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onDoubleClickCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseDown` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseDownCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseEnter` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseLeave` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseMove` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseMoveCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOut` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOutCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOver` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseOverCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseUp` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onMouseUpCapture` | `MouseEventHandler<HTMLDivElement>` | - | - |
| `onTouchCancel` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchCancelCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchEnd` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchEndCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchMove` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchMoveCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchStart` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onTouchStartCapture` | `TouchEventHandler<HTMLDivElement>` | - | - |
| `onPointerDown` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerDownCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerMove` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerMoveCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerUp` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerUpCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerCancel` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerCancelCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerEnter` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerLeave` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOver` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOverCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOut` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onPointerOutCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onGotPointerCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onGotPointerCaptureCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onLostPointerCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onLostPointerCaptureCapture` | `PointerEventHandler<HTMLDivElement>` | - | - |
| `onScroll` | `UIEventHandler<HTMLDivElement>` | - | - |
| `onScrollCapture` | `UIEventHandler<HTMLDivElement>` | - | - |
| `onWheel` | `WheelEventHandler<HTMLDivElement>` | - | - |
| `onWheelCapture` | `WheelEventHandler<HTMLDivElement>` | - | - |
| `onAnimationStart` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationStartCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationEnd` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationEndCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationIteration` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onAnimationIterationCapture` | `AnimationEventHandler<HTMLDivElement>` | - | - |
| `onTransitionCancel` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionCancelCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionEnd` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionEndCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionRun` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionRunCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionStart` | `TransitionEventHandler<HTMLDivElement>` | - | - |
| `onTransitionStartCapture` | `TransitionEventHandler<HTMLDivElement>` | - | - |

### Accessibility

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `aria-label` | `string` | - | Defines a string value that labels the current element. |
| `aria-labelledby` | `string` | - | Identifies the element (or elements) that labels the current element. |
| `aria-describedby` | `string` | - | Identifies the element (or elements) that describes the object. |
| `aria-details` | `string` | - | Identifies the element (or elements) that provide a detailed, extended description for the object. |


## Guidelines

# Grundlagen

Ein DonutChart visualisiert proportionale Daten in Form eines ringförmigen
Diagramms. Es eignet sich besonders zur Darstellung von Anteilen oder
Verteilungen. Es dient als visuelle Alternative zur ProgressBar. Durch seine
ansprechende und fokussierende Darstellung rückt es die Daten besonders in den
Mittelpunkt der Nutzerwahrnehmung, was es ideal für Dashboards und andere
datenintensive Oberflächen macht.

## Best practices

Achte bei der Verwendung eines DonutCharts darauf, dass ...

- jede Segmentfarbe eindeutig und kategorisch unterscheidbar ist. Verwende dafür
  die
  [Categorical Colors](https://flow.mittwald.de/02-foundations/01-design/02-colors).
- die Anzahl der Segmente 6 nicht überschreitet, da eine zu große Segmentanzahl
  die Lesbarkeit stark beeinträchtigt.
- die Segmente nach ihrer Größe sortiert sind, beginnend mit dem größten Wert
  auf der 12-Uhr-Position, und danach im Uhrzeigersinn absteigend folgen.

## Verwendung

Verwende ein DonutChart, um ...

- proportionale Daten übersichtlich und intuitiv darzustellen.
- verschiedene Kategorien oder Anteile innerhalb eines Ganzen hervorzuheben.
- Daten gezielt in den Fokus der User zu rücken, etwa in Dashboards oder anderen
  datenintensiven Oberflächen.

