
# Charts & KPIs

Two components summarise records rather than listing them. Both bind through [`dataSource`](/en/docs/pages-data-binding) and then aggregate what it returns — the raw records are never rendered.

## `chart`

| Property          | Description                                                                         |
| ----------------- | ----------------------------------------------------------------------------------- |
| `dataSource`      | Table binding.                                                                      |
| `chartType`       | `bar`, `line`, `area`, `pie`, `donut`, or `scatter`.                                |
| `chartAggregate`  | How records are summarised (see below).                                             |
| `series`          | One or more plotted series.                                                         |
| `xAxis` / `yAxis` | Axis configuration.                                                                 |
| `legend`          | `{ position, visible }`. `position` is `top`, `bottom`, `left`, `right`, or `none`. |
| `tooltip`         | `{ format }` — a template supporting `{label}` and `{value}`.                       |
| `emptyMessage`    | Shown when the aggregate yields nothing.                                            |

The chart kind is the `chartType` **property**, not the component `type` — a chart component is always `type: chart`.

| `series[]` property | Description                                             |
| ------------------- | ------------------------------------------------------- |
| `field`             | Field plotted by this series.                           |
| `label`             | Series name shown in the legend and tooltip.            |
| `color`             | Theme color token or a raw color value.                 |
| `stack`             | Stack group name. Series sharing a name stack together. |
| `fillOpacity`       | Fill opacity from 0 to 1, for area and bar fills.       |

| Axis property | Description                                 |
| ------------- | ------------------------------------------- |
| `field`       | Field mapped to the axis.                   |
| `label`       | Axis title.                                 |
| `scale`       | `linear` or `logarithmic`.                  |
| `format`      | `date`, `currency`, `number`, or `percent`. |
| `gridLines`   | Draw grid lines along this axis.            |

### `chartAggregate`

| Property   | Description                                                                           |
| ---------- | ------------------------------------------------------------------------------------- |
| `function` | `count`, `sum`, `avg`, `min`, or `max`.                                               |
| `groupBy`  | **Required.** Field the records are grouped by — the chart's categories.              |
| `field`    | Field the function operates on. Omit it for `count`.                                  |
| `interval` | Bucket size when grouping by a date field: `day`, `week`, `month`, `quarter`, `year`. |

```yaml
- type: chart
  chartType: bar
  dataSource: { table: orders }
  chartAggregate: { function: sum, field: total, groupBy: created_at, interval: month }
  xAxis: { field: created_at, label: Month, format: date }
  yAxis: { field: total, label: Revenue, format: currency, gridLines: true }
  series: [{ field: total, label: Revenue, color: primary }]
  legend: { position: bottom, visible: true }
```

## `kpi`

A single summary metric — a stat card — with an optional comparison and sparkline.

| Property       | Description                                                                               |
| -------------- | ----------------------------------------------------------------------------------------- |
| `dataSource`   | Table binding.                                                                            |
| `label`        | The metric's name.                                                                        |
| `icon`         | Icon rendered beside the value.                                                           |
| `kpiAggregate` | `{ function, field }`. `function` is required; omit `field` for `count`.                  |
| `kpiFormat`    | `{ type, options }`. `type` is `number`, `currency`, `percentage`, `compact`, or `bytes`. |
| `trend`        | Comparison against an earlier period (see below).                                         |
| `sparkline`    | Miniature trend line (see below).                                                         |
| `thresholds`   | `{ value, color }` entries that recolor the card once a value is crossed.                 |

### `trend`

All three of `comparisonPeriod`, `direction` and `changePercent` are required when `trend` is present.

| Property           | Description                                                                           |
| ------------------ | ------------------------------------------------------------------------------------- |
| `comparisonPeriod` | `previousDay`, `previousWeek`, `previousMonth`, `previousQuarter`, or `previousYear`. |
| `direction`        | `up`, `down`, or `flat`.                                                              |
| `changePercent`    | The change, as a number.                                                              |
| `color`            | `green`, `red`, `yellow`, or `gray`.                                                  |

:::callout
**`direction` and `color` are independent on purpose.** Revenue up is green; churn up is red. Sovrium will not guess which of your metrics improve by rising, so state the colour you mean.
:::

### `sparkline`

All four properties are required when `sparkline` is present.

| Property   | Description                         |
| ---------- | ----------------------------------- |
| `field`    | Field plotted along the line.       |
| `groupBy`  | Field the points are bucketed by.   |
| `interval` | `day`, `week`, or `month`.          |
| `days`     | How many days back the line covers. |

```yaml
- type: kpi
  label: Revenue this month
  icon: banknote
  dataSource: { table: orders }
  kpiAggregate: { function: sum, field: total }
  kpiFormat: { type: currency, options: { currency: EUR } }
  trend: { comparisonPeriod: previousMonth, direction: up, changePercent: 12.4, color: green }
  sparkline: { field: total, groupBy: created_at, interval: day, days: 30 }
```

## Related Pages

- [Tables & Lists](/en/docs/data-components) — `data-table`, `list`, `data-form`.
- [Boards, Calendars & Timelines](/en/docs/data-components-boards) — the other record views.
- [Data Binding](/en/docs/pages-data-binding) — `dataSource` and filtering.
- [Analytics](/en/docs/analytics) — the built-in traffic metrics.
- [Theme Overview & Colors](/en/docs/theme) — the color tokens series reference.
