# Custom charts

Build charts over your telemetry — pick a dataset, a metric, a chart type, and how to group and filter it.

A **custom chart** is a chart you define yourself: choose what to measure, how to slice it, and how to draw it, and Brizz renders it against your telemetry. Charts live on [custom dashboards](/docs/platform/custom-dashboards.md) — this page is about the charts themselves.

## What it is

A chart is a **saved query, not saved data.** You describe *what to ask* — a metric, a way to group it, some filters — and Brizz runs that query against your telemetry every time the chart is shown. Change your date range or send new data and the chart reflects it immediately; there's no snapshot to regenerate.

That's the mental model to keep: you're building a question, and the chart is its live answer.

## Three ways to add a chart

When you add a block to a dashboard you can:

1. **Build a custom chart** — define a new query from scratch in the chart builder (below). This is the main path.
2. **Add from the library** — start from a ready-made chart instead of a blank one, then tweak it. A fast way to get a common view without wiring it up yourself.
3. **Add a text block** — a Markdown block for a title, a note, or a section header. Not a query — just text to give the board structure.

## The chart builder

The builder walks you from *what data* to *how to draw it*. You don't have to touch every step — sensible defaults fill in as you go.

1. **Dataset** — pick what you're measuring over: **sessions**, **users**, or **organizations** (see [Datasets](#datasets)).
2. **Chart type** — pick how it's drawn: a line, a bar chart, a number card, a table, and so on (see [Chart types](#chart-types)).
3. **Metric and aggregation** — pick the number (cost, duration, tokens, a count, a rate, …) and how to roll it up (sum, average, a percentile, …).
4. **Group by** — pick how to break the metric out: by model, over time, by outcome, by intent, and more (see [Group by and top-N](#group-by-and-top-n)).
5. **Filter** — narrow to the rows you care about before the metric is computed.
6. **Advanced** — the optional knobs: `having`, ordering and limits, time-series fill, thresholds, and formulas (below).

Throughout, the builder's **pickers show what's actually available for your choices** — the metric list changes with the dataset, the group-by options reflect what Brizz knows about your data. Trust the picker over any fixed list: it's the live source of truth for what you can chart.

## Datasets

Every chart is built on one of three datasets. Pick the one whose "one row" matches the question you're asking:

- **Sessions** — one row per conversation. Answers "how are individual sessions doing?" — cost per session, duration, error rates, outcomes, satisfaction.
- **Users** — one row per end user. Answers "how are my users doing?" — activity, retention-shaped counts, per-user rollups.
- **Organizations** — one row per organization (the accounts your users belong to). Answers the same kinds of questions at the account level.

There's no raw SQL — the dataset plus the builder's pickers define what's queryable, which keeps every chart tenant-scoped and safe.

## Chart types

The **type selector** offers a spread of visualizations; pick the family that fits the shape of your answer:

- **Time series** (line, area) — a metric over time.
- **Bar** (bar, stacked bar) — compare a metric across categories, optionally split into sub-segments.
- **Pie / donut** — parts of a whole.
- **Table** — the raw grouped rows, with columns.
- **Number card** — a single headline figure.
- **Gauge** — one value against a target or range.
- **Scatter** — two metrics plotted against each other.

Not every type fits every query — the selector reflects what makes sense for the metric and grouping you've chosen.

## Group by and top-N

**Group by** is how a metric becomes a chart with more than one value. Brizz offers grouping by the dimensions it understands about your data — for example by **model**, by **time bucket**, by **outcome**, by **satisfaction**, by **journey**, by **intent**, by **issue type**, or by **tool** — plus dynamic dimensions derived from your own data, such as a **custom property**, a **label**, or an **N-day** window.

When a grouping has many values, use **top-N** to keep the chart readable — chart the largest N groups and let the rest fall away. As with everything else, the available group-by options come from the picker, which reflects your data rather than a fixed menu.

## Filters vs. having

Two ways to narrow a chart — they act at different stages:

- **Filters** apply **before** aggregation. They pick which rows go into the metric ("only sessions from the checkout service", "only paid users"). Use a filter to define the population you're measuring.
- **Having** applies **after** aggregation. It filters the *grouped results* by their computed value ("only models where average cost > $0.10", "only intents with more than 100 sessions"). Use `having` to hide small or uninteresting groups.

Reach for a filter to change *what you're counting*, and `having` to change *which results you keep*.

## Time series and bucketing

For a time-series chart, Brizz buckets your data into time intervals and plots one point per bucket. Empty buckets are **filled** so the line is continuous rather than skipping gaps — a quiet hour shows up as a real zero, not a missing point, which keeps trends honest. The dashboard's [date range](/docs/platform/custom-dashboards.md#date-range) sets the outer window; the chart's bucketing sets the granularity within it.

## Thresholds and formulas

Two ways to make a chart say more:

- **Thresholds** — draw a reference line (a target, an SLO, a budget) so "good vs. bad" is visible at a glance, and gauges color against it.
- **Formulas** — derive a value from other metrics (a ratio, a rate, a cost-per-something) rather than charting a single raw metric.

To read a chart *period-over-period* — this window versus the one before it — subscribe it to a [Slack digest](#slack-chart-digest), which compares the two windows for you.

## Editing and duplicating charts

Open any chart's menu to **edit** it — you re-enter the builder with its current definition loaded, so you can adjust the metric, grouping, or type in place. **Duplicate** a chart to spin off a variant (same query, one knob changed) without rebuilding it. Chart edits, like layout changes, are part of the dashboard **draft** until you save.

## Slack chart digest

Any chart can be turned into a recurring **Slack digest** — subscribe a chart and Brizz renders it as an image and posts it to a Slack channel on a schedule:

- **Cadence** — **daily** or **weekly**.
- **Optional AI summary** — a short written read of what the chart shows and what moved, alongside the numbers.
- **Period-over-period shifts** — each digest compares the current window against the previous one and calls out the notable movers, so the signal isn't buried.

This is per **chart**, not per dashboard — there's no whole-dashboard scheduled export; you subscribe the specific charts worth a recurring nudge. Setting one up requires the [Slack integration](/docs/integrations/slack.md) to be connected.

## Limits

A chart returns a **capped number of rows** so a runaway grouping can't pull an unbounded result set — the builder shows the current default and ceiling when you set a limit, and top-N is the intended tool for high-cardinality groupings. If a chart looks truncated, tighten it with a filter, a smaller top-N, or a coarser grouping rather than trying to raise the cap.

## See also

- [Custom dashboards](/docs/platform/custom-dashboards.md) — the boards these charts live on.
- [Cost calculation](/docs/platform/cost-calculation.md) — how the cost metric behind cost charts is computed.
- [Slack integration](/docs/integrations/slack.md) — connect Slack to receive chart digests.
- [Labels](/docs/platform/labels.md) — group any chart by a label.
- [Sessions](/docs/platform/sessions.md) — the session data most charts aggregate.
