> ## Documentation Index
> Fetch the complete documentation index at: https://docs.graphy.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Statistics

A **stat** summarises a layer's data before it's drawn. Instead of plotting raw rows, the layer plots a computed result — a count, a mean, or a fitted regression line. Stats are set per layer through a geom's `stat` option, and default to `identity` (draw the data as-is).

```tsx theme={null}
import { stat } from '@graphysdk/react';

geom.line({ stat: stat.smooth({ method: 'linear' }) });
```

## Available stats

| Stat                          | Result                                                          |
| ----------------------------- | --------------------------------------------------------------- |
| `stat.identity()` *(default)* | The data unchanged                                              |
| `stat.count()`                | The number of observations per x-value, per series              |
| `stat.sum()`                  | The total of `y` per x-value, per series                        |
| `stat.mean()`                 | The mean of `y` across the whole layer, as a single observation |
| `stat.smooth({ method })`     | A fitted regression curve through the points                    |

`count` and `sum` group by x plus the layer's grouping variables, so they preserve the series a
reader is comparing. `mean` reduces the layer to one observation, which is why it pairs with
`geom.rule()` rather than with a bar or a line.

`count` computes `y` for you — mapping `y` alongside it is a `CONFLICTING_STAT_MAPPING` error.

Every stat also has a string shorthand, so `geom.bar({ stat: 'count' })` is the same as
`geom.bar({ stat: stat.count() })`. The names are `'identity'`, `'count'`, `'smooth'`, `'mean'` and
`'sum'`.

## Trendlines with `smooth`

The `smooth` stat fits a regression through a layer's points — the basis for trendlines. Add it to a second `geom.line()` layer over your raw data:

```tsx theme={null}
pipe(
  createSpec({ x: 'date', y: 'sales' }),
  geom.point(), // the raw points
  geom.line({ stat: stat.smooth({ method: 'linear' }) }), // the trend
  scale.x(),
  scale.y()
);
```

`method` selects the regression family:

<ParamField path="method" type="'linear' | 'loess' | 'exponential' | 'logarithmic' | 'quadratic' | 'power' | 'polynomial'" default="linear">
  The regression method to fit. The object builder asks for it; the `'smooth'`
  string shorthand takes the default.
</ParamField>

<ParamField path="order" type="number" default="3">
  Polynomial order — only used when `method: 'polynomial'`.
</ParamField>

<ParamField path="bandwidth" type="number" default="0.3">
  Smoothing bandwidth — only used when `method: 'loess'`.
</ParamField>

```tsx theme={null}
stat.smooth({ method: 'polynomial', order: 4 });
stat.smooth({ method: 'loess', bandwidth: 0.5 });
```

## A mean reference line

`stat.mean()` reduces the layer to one observation, which is exactly what a rule needs. Pair the two
to draw a horizontal line at the layer's average:

```tsx theme={null}
pipe(
  createSpec({ x: 'month', y: 'revenue' }),
  geom.bar(),
  geom.rule({ stat: stat.mean() }), // a line at the mean revenue
  scale.x(),
  scale.y()
);
```

## Setting a stat at runtime

Two [commands](/sdk-next/advanced/commands-and-history) reach the stat surface:

| Command               | Params                                                                                             | What it does                                                                                              |
| --------------------- | -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `SetLayerStatCommand` | `layerId?`, `stat`                                                                                 | Sets one layer's stat                                                                                     |
| `SetStatLineCommand`  | `line: 'none' \| 'trend' \| 'average'`, `layerId?`, `method?`, `group?`, `label?`, `removedLayer?` | The switch behind "show a trendline" and "show an average" — swapping one for the other is one undo entry |

## Custom stats

A plugin can contribute its own stat: a `Stat` subclass registered through `plugins`, which earns a
typed builder beside the built-ins. See [Extending](/sdk-next/extending/index) for the registration path.

## Next

* [Transforms](/sdk-next/advanced/transforms) — reshape data before it reaches a stat
* [Reference lines](/sdk-next/emphasis/reference-lines) — the rules `stat.mean()` draws
* [Geoms & layers](/sdk-next/concepts/geoms) — where the `stat` option lives
