---
title: Widgets and charts
description: Show figures and charts that summarize data, for dashboards and overview pages.
---

A widget is a small block that summarizes data. It shows a figure, a chart, or both,
with the text that explains them. Widgets are the parts of a dashboard, and they also
work above a table to give the totals of a list.

This introduction explains the parts of a widget, how charts fit into it, and how to
build a dashboard. The pages of this category have the full options.

## The parts of a widget

A widget has two optional data parts, and it needs one of them at least.

The stat is one figure, such as the number of subscribers. You supply the value and
a number field. The field gives the format, so the client can show `12480` as
`12,480` or as `12.5K` with the locale of the user. When you also supply the value of
the prior period, the client calculates the change and shows it next to the figure.

The chart is a small visualization, such as the trend of the last 30 days. You
create it with the `charts` factory and give it to the widget with `setChart`.

Around these parts, a widget has context: a title, a description, a footnote, and a
caption. The example below shows two widgets with a stat and a change from the prior
period.

<BacklitExample path="widgets/widget/change" view="overview" />

The sign of a change has no meaning by itself. An increase in subscribers is good,
and an increase in refunds is not. Thus you set the `tone` of the stat, and the
client selects the color for that tone.

## Your query calculates the figures

A widget does not aggregate your data. Your view runs the count, the sum, or the
average, and gives the result to the widget. Fields describe the values here in the
same way that they describe the columns of a table. This is the usual case of a
field that has no database column.

```ts
const revenue = fields.number('revenue', { format: 'currency', currency: 'USD' })

orders.view('overview', async () => {
  const { current, prior } = await db.orders.revenueByMonth()

  return widget()
    .setTitle('Revenue')
    .setStat({ value: current, prior, field: revenue, delta: 'percent', tone: 'success' })
})
```

## Charts

A chart is not a block. It always goes inside a widget, and the widget gives it a
title and its context. You give a chart your rows and the fields that read them. The
number fields give the format of the axis values and the tooltips.

| Your need                                           | Chart                                                  |
| --------------------------------------------------- | ------------------------------------------------------ |
| Rank rows by one value, such as the top ten pages   | [Bar list](/reference/widgets/charts#bar-list)          |
| Show one or more series against time or a category  | [Line](/reference/widgets/charts#line)                  |
| Show a small trend next to a figure, without axes   | [Spark area](/reference/widgets/charts#spark-area)      |
| Show the parts of one total, such as plan shares    | [Category bar](/reference/widgets/charts#category-bar)  |

Chart colors are tokens from `1` through `5` and not color values, so a chart
follows the theme of your app in light mode and in dark mode.

## Build a dashboard

A widget group tells the client that its widgets belong together. The group has no
columns and no layout options. The client arranges the widgets from the width that
is available. To give a group a heading, put it in a `section`.

```ts
return section('This month').setContent([
  widgets.group([subscribersWidget, openRateWidget, revenueWidget]),
  panel([table(recentOrders).setFields(columns)]).setTitle('Recent orders'),
])
```

Each figure of a dashboard usually needs its own query, and some queries are slow. A
widget group accepts zones that produce a widget. Put a slow widget in a zone, so
that a refresh of that widget does not run the queries of the other widgets.

Filters work on a dashboard in the same way that they work on a list. A
[date range filter](/reference/filters/date-range) lets the user select the time
range, and a [period filter](/reference/filters/period) lets the user select the
grouping unit of a chart, such as day or month.

## Pages of this category

| Page                                   | Content                                                     |
| -------------------------------------- | ----------------------------------------------------------- |
| [Widget](/reference/widgets/widget)     | The stat, the change from a prior period, tone, and context |
| [Group](/reference/widgets/group)       | Sets of widgets, and zones inside a group                   |
| [Charts](/reference/widgets/charts)     | The four chart types and their options                      |
