# Pareto

> Package `@umriss-ui/charts`, version 0.40.0. Demo page: <https://romanhaendler.github.io/umriss-ui/charts/pareto/>. Every page in one line: [llms.txt](https://romanhaendler.github.io/umriss-ui/charts/llms.txt); every page in full: [llms-full.txt](https://romanhaendler.github.io/umriss-ui/charts/llms-full.txt).

Causes sorted by weight with a cumulative line (a Pareto chart). Reach for it after a bad week, to see which few causes make most of the trouble.

```ts
import { pareto } from "@umriss-ui/charts";
```

Demo page: https://romanhaendler.github.io/umriss-ui/charts/pareto/

`pareto()` sorts, adds up and folds the tail into one entry that stands last whatever its size; the bars, the line and the second axis are yours to compose.

## Examples

### Sort causes and collect the tail

`pareto()` sorts descending, adds up and folds everything past `collectRank` into one entry that stands last; the bars and the line are yours, and the x axis reads each entry's `name`.

```tsx
import { useMemo } from "react";
import { Legend, LimitLine, Tooltip, pareto, useChart } from "@umriss-ui/charts";

/* Why deliveries failed last month, in no particular order. */
const FAILED_DELIVERIES = [
  { name: "Damaged in transit", value: 21 },
  { name: "Nobody home", value: 312 },
  { name: "Address incomplete", value: 96 },
  { name: "Refused", value: 34 },
  { name: "Business closed", value: 58 },
  { name: "No access code", value: 147 },
  { name: "Wrong address", value: 12 },
  { name: "Parcel not found", value: 8 },
  { name: "Weather", value: 6 },
  { name: "Vehicle breakdown", value: 4 },
];

export default function ParetoExample() {
  const { entries } = useMemo(() => pareto(FAILED_DELIVERIES, { collectRank: 6, remainderName: "Other" }), []);
  const { Chart, XAxis, YAxis, Bar, Line } = useChart(entries);
  return (
    <Chart height={300} ariaLabel="Failed deliveries by cause, sorted, with the cumulative share">
      <XAxis value="name" />
      <YAxis label="Failed deliveries" />
      <YAxis
        id="share"
        position="right"
        domain={[0, 100]}
        tickFormat={(v) => `${v.toFixed(0)} %`}
        label="cumulative"
      />
      <Bar value="value" name="Failed" barWidth={0.72} />
      <Line value={(d) => d.cumulative * 100} yAxisId="share" name="cumulative" markers="always" strokeWidth={1.75} />
      <LimitLine value={80} axisId="share" severity="warning" label="80 %" inExtent={false} />
      <Legend placement="top" />
      <Tooltip mode="x" />
    </Chart>
  );
}
```

## Keyboard

The keys of [Chart](https://romanhaendler.github.io/umriss-ui/charts/chart/#keyboard-chart) apply here.

## Props on this page

From `ChartProps` — the full table stands on [Chart](https://romanhaendler.github.io/umriss-ui/charts/chart/#type-ChartProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`height`](https://romanhaendler.github.io/umriss-ui/charts/chart/#ChartProps-height) | `number` | fills the frame, at least 300 px | Height in CSS pixels, fixed. Left out, the chart fills its frame - a stretched grid cell, a card the grid stretches, a container of definite height - and never goes below 300 px, which is also its height in a frame without one. A different floor goes through `style`'s `minHeight` ([ADR-0050](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0050-a-chart-fills-its-frame-never-below-its-floor.md)). |
| [`children`](https://romanhaendler.github.io/umriss-ui/charts/chart/#ChartProps-children) | `ReactNode` | — | The axes, series and companions of this chart. They draw nothing themselves: each registers its configuration and the scene draws it, and the order in the JSX is the drawing order. |

#### Accessibility

| Prop | Type | Default | Description |
|---|---|---|---|
| [`ariaLabel`](https://romanhaendler.github.io/umriss-ui/charts/chart/#ChartProps-ariaLabel) | `string` | — | Required in DEV through a warning. |

From `XAxisProps` — the full table stands on [Axis](https://romanhaendler.github.io/umriss-ui/charts/axis/#type-XAxisProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`value`](https://romanhaendler.github.io/umriss-ui/charts/axis/#XAxisProps-value) *required* | [`AxisField`](https://romanhaendler.github.io/umriss-ui/charts/axis/#type-AxisField)`<T> \| ((d: T, index: number) => `[`AxisValue`](https://romanhaendler.github.io/umriss-ui/charts/axis/#type-AxisValue)`)` | — | Where a row lies on this axis: a field of the row, compared by its name, or a function of it, compared by its source text as a series' is (`ValueFunction`) - with the same closure limit. A number is a position, a `Date` an instant, a string a category: every distinct one gets a place of its own, in the order the rows bring them, a tick and its name as the label ([ADR-0052](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0052-a-chart-reads-its-rows-as-they-come.md)). The type decides, never the content - `"2024"` is a category, `2024` a number - and a row without a value has no place. The axis reads the rows of every series bound to it; where those bring their own `data`, name their row: `<XAxis<HourCount> value="hour" />`. |
| [`id`](https://romanhaendler.github.io/umriss-ui/charts/axis/#XAxisProps-id) | `string` | `"x"` | Axis id, through which series bind themselves. |
| [`label`](https://romanhaendler.github.io/umriss-ui/charts/axis/#XAxisProps-label) | `string` | — | Axis title. |
| [`tickFormat`](https://romanhaendler.github.io/umriss-ui/charts/axis/#XAxisProps-tickFormat) | `(v: number) => string` | — | Label of a tick. Compared by its source text: one that reads a changed closure variable under the same text does not relabel the axis - give it a new text or remount. A bound `Intl.NumberFormat#format` is compared by identity. |

From `YAxisProps` — the full table stands on [Axis](https://romanhaendler.github.io/umriss-ui/charts/axis/#type-YAxisProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`domain`](https://romanhaendler.github.io/umriss-ui/charts/axis/#YAxisProps-domain) | `"nice" \| "data" \| "visible" \| readonly [number, number]` | `"nice"` | As on the x axis, and `"visible"`: what the series show inside their x axis' domain - a zoomed hour gets the hour's range, not the week's -, widened to ticks as `"nice"` is. Where the x domain is not fixed that is every point. |
| [`position`](https://romanhaendler.github.io/umriss-ui/charts/axis/#YAxisProps-position) | `"left" \| "right"` | `"left"` | Which edge the axis stands at. Several y axes per side are stacked outwards, so that extents of clearly different magnitude stay readable. |
| [`id`](https://romanhaendler.github.io/umriss-ui/charts/axis/#YAxisProps-id) | `string` | `"y"` | Axis id, through which series bind themselves. |
| [`label`](https://romanhaendler.github.io/umriss-ui/charts/axis/#YAxisProps-label) | `string` | — | Axis title. |
| [`tickFormat`](https://romanhaendler.github.io/umriss-ui/charts/axis/#YAxisProps-tickFormat) | `(v: number) => string` | — | Label of a tick. Compared by its source text: one that reads a changed closure variable under the same text does not relabel the axis - give it a new text or remount. A bound `Intl.NumberFormat#format` is compared by identity. |

From `LineProps` — the full table stands on [Line](https://romanhaendler.github.io/umriss-ui/charts/line/#type-LineProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`value`](https://romanhaendler.github.io/umriss-ui/charts/line/#LineProps-value) *required* | [`Value`](https://romanhaendler.github.io/umriss-ui/charts/line/#type-Value)`<T>` | — | Y value - a number field of the row or a function of it; null/undefined/NaN/±Infinity means a gap. |
| [`yAxisId`](https://romanhaendler.github.io/umriss-ui/charts/line/#LineProps-yAxisId) | `string` | `"y"` | Binding to a y axis. |
| [`name`](https://romanhaendler.github.io/umriss-ui/charts/line/#LineProps-name) | `string` | "Series n", after its place in the chart | The name in legend and tooltip. Without one a warning stands in DEV - an unnamed series is a colour nobody can look up. |
| [`strokeWidth`](https://romanhaendler.github.io/umriss-ui/charts/line/#LineProps-strokeWidth) | `number` | `1.5` | Line width in CSS pixels. |
| [`markers`](https://romanhaendler.github.io/umriss-ui/charts/line/#LineProps-markers) | `"auto" \| "always" \| "never"` | `"auto"` | When the individual points are drawn as marks: `auto` every point up to 60 points and above that only a point between two gaps - it has no line to be seen by - `always`, or `never`, not even that one. |

From `BarProps` — the full table stands on [Bar](https://romanhaendler.github.io/umriss-ui/charts/bar/#type-BarProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`value`](https://romanhaendler.github.io/umriss-ui/charts/bar/#BarProps-value) *required* | [`Value`](https://romanhaendler.github.io/umriss-ui/charts/bar/#type-Value)`<T>` | — | Height - a number field of the row or a function of it; null/undefined/NaN/±Infinity means a gap. |
| [`name`](https://romanhaendler.github.io/umriss-ui/charts/bar/#BarProps-name) | `string` | "Series n", after its place in the chart | The name in legend and tooltip. Without one a warning stands in DEV - an unnamed series is a colour nobody can look up. |
| [`barWidth`](https://romanhaendler.github.io/umriss-ui/charts/bar/#BarProps-barWidth) | `number` | `0.8` | Width as a fraction of the step; just under 1, so that neighbours do not touch. Several bar series share this fraction. |

From `LimitLineProps` — the full table stands on [LimitLine](https://romanhaendler.github.io/umriss-ui/charts/limitline/#type-LimitLineProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`value`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitLineProps-value) *required* | `number \| Date` | — | Where the line lies, in domain units of its axis; along a time axis an instant, in milliseconds or as a `Date`. |
| [`axisId`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitLineProps-axisId) | `string` | the first axis of the orientation | Axis on which the value lies. |
| [`severity`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitLineProps-severity) | [`Severity`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#type-Severity)<br>`"warning" \| "alarm"` | `"alarm"` | Two severities, not five: five urgencies are five colours, and five colours on a dense screen are noise. |
| [`label`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitLineProps-label) | `string` | — | What the value means. A line at 90 does not say what 90 is. |
| [`inExtent`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitLineProps-inExtent) | `boolean` | `true` | Whether the value widens the axis extent, so that the limit is certainly visible. |

From `LimitBandProps` — the full table stands on [LimitLine](https://romanhaendler.github.io/umriss-ui/charts/limitline/#type-LimitBandProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`axisId`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitBandProps-axisId) | `string` | the first axis of the orientation | Axis on which the value lies. |
| [`severity`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitBandProps-severity) | [`Severity`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#type-Severity)<br>`"warning" \| "alarm"` | `"warning"` | Two severities, not five: five urgencies are five colours, and five colours on a dense screen are noise. |
| [`label`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitBandProps-label) | `string` | — | What the value means. A line at 90 does not say what 90 is. |
| [`inExtent`](https://romanhaendler.github.io/umriss-ui/charts/limitline/#LimitBandProps-inExtent) | `boolean` | `true` | Whether the value widens the axis extent, so that the limit is certainly visible. |

From `TooltipProps` — the full table stands on [Tooltip](https://romanhaendler.github.io/umriss-ui/charts/tooltip/#type-TooltipProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`mode`](https://romanhaendler.github.io/umriss-ui/charts/tooltip/#TooltipProps-mode) | `"x" \| "nearest"` | `"x"` | "x": every series at the x position; "nearest": only the nearest point. |

From `LegendProps` — the full table stands on [Legend](https://romanhaendler.github.io/umriss-ui/charts/legend/#type-LegendProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`placement`](https://romanhaendler.github.io/umriss-ui/charts/legend/#LegendProps-placement) | `"top" \| "bottom"` | `"top"` | Which side of the plot area the legend stands on. |
