---
product: "AG Studio"
title: "Blanks and Missing Values"
description: "See how AG Studio displays, sorts, groups, filters and aggregates blank and missing values, consistently for every data type."
framework: react
version: "3.1.0"
related:
    - title: "Data Panel"
      url: "https://www.ag-grid.com/studio/analysts/data-panel/"
    - title: "Fields in Widgets"
      url: "https://www.ag-grid.com/studio/analysts/fields-in-widgets/"
    - title: "Calculations"
      url: "https://www.ag-grid.com/studio/analysts/calculations/"
    - title: "Formatting Values"
      url: "https://www.ag-grid.com/studio/analysts/formatting-values/"
llms: "https://www.ag-grid.com/studio/llms.txt"
---

# Blanks and Missing Values

A blank is a value that is missing from the data. AG Studio handles blanks the same way for every data type, and this page describes how they display, sort, group, filter and aggregate.

> **Note**
>
> The behaviour on this page is the default. Your developer can change some of it, such as the text shown for a blank value.

The example below shows each behaviour on this page over five orders that have blank values. Order 1 has a blank amount, true/false value and date, Order 3 has a blank region, and every amount in Team B is blank.

#### Blank Values

```ts
import {
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
  enableStudioDevValidations,
} from "ag-studio";
import { getData } from "./data.ts";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableStudioDevValidations();
}

const initialState: AgReportState = {
  pages: [
    {
      id: "page1",
      widgets: {
        display: {
          type: "grid",
          dataMapping: {
            cols: [
              { id: "orders.order" },
              { id: "orders.region" },
              { id: "orders.amount" },
              { id: "orders.paid" },
              { id: "orders.shipped" },
            ],
          },
          format: {
            title: {
              enabled: true,
              text: "Display",
            },
          },
        },
        "sort-ascending": {
          type: "grid",
          dataMapping: {
            cols: [
              { id: "orders.region" },
              { id: "orders.order", aggregation: "count" },
            ],
          },
          format: {
            title: {
              enabled: true,
              text: "Region, Ascending",
            },
          },
          sort: [
            {
              field: { id: "orders.region" },
              direction: "asc",
            },
          ],
        },
        "sort-descending": {
          type: "grid",
          dataMapping: {
            cols: [
              { id: "orders.region" },
              { id: "orders.order", aggregation: "count" },
            ],
          },
          format: {
            title: {
              enabled: true,
              text: "Region, Descending",
            },
          },
          sort: [
            {
              field: { id: "orders.region" },
              direction: "desc",
            },
          ],
        },
        chart: {
          type: "column-chart-grouped",
          dataMapping: {
            categoryKey: [{ id: "orders.region" }],
            valueKey: [{ id: "orders.order", aggregation: "count" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Orders by Region",
            },
          },
        },
        "not-equal": {
          type: "grid",
          dataMapping: {
            cols: [{ id: "orders.order" }, { id: "orders.region" }],
          },
          format: {
            title: {
              enabled: true,
              text: "Does Not Equal North",
            },
          },
        },
        blank: {
          type: "grid",
          dataMapping: {
            cols: [{ id: "orders.order" }, { id: "orders.region" }],
          },
          format: {
            title: {
              enabled: true,
              text: "Region Blank",
            },
          },
        },
        "not-blank": {
          type: "grid",
          dataMapping: {
            cols: [{ id: "orders.order" }, { id: "orders.region" }],
          },
          format: {
            title: {
              enabled: true,
              text: "Region Not Blank",
            },
          },
        },
        aggregation: {
          type: "grid",
          dataMapping: {
            cols: [
              { id: "orders.team" },
              { id: "orders.amount", aggregation: "sum" },
              { id: "orders.amount", aggregation: "avg" },
              { id: "orders.amount", aggregation: "min" },
              { id: "orders.amount", aggregation: "max" },
              { id: "orders.amount", aggregation: "count" },
              { id: "orders.amount", aggregation: "first" },
              { id: "orders.amount", aggregation: "last" },
              { id: "orders.region", aggregation: "countd" },
            ],
          },
          format: {
            title: {
              enabled: true,
              text: "Aggregation by Team",
            },
          },
        },
      },
      widgetLayout: {
        display: { xTrack: 0, yTrack: 0, xSpan: 24, ySpan: 14 },
        "sort-ascending": { xTrack: 0, yTrack: 14, xSpan: 8, ySpan: 14 },
        "sort-descending": { xTrack: 8, yTrack: 14, xSpan: 8, ySpan: 14 },
        chart: { xTrack: 16, yTrack: 14, xSpan: 8, ySpan: 14 },
        "not-equal": { xTrack: 0, yTrack: 28, xSpan: 8, ySpan: 13 },
        blank: { xTrack: 8, yTrack: 28, xSpan: 8, ySpan: 13 },
        "not-blank": { xTrack: 16, yTrack: 28, xSpan: 8, ySpan: 13 },
        aggregation: { xTrack: 0, yTrack: 41, xSpan: 24, ySpan: 11 },
      },
      filter: {
        widget: {
          "not-equal": [
            {
              field: { id: "orders.region" },
              model: { operator: "notEqual", value: "North" },
            },
          ],
          blank: [
            { field: { id: "orders.region" }, model: { operator: "isBlank" } },
          ],
          "not-blank": [
            {
              field: { id: "orders.region" },
              model: { operator: "isNotBlank" },
            },
          ],
        },
      },
    },
  ],
  selectedPageId: "page1",
  panels: {
    filters: {
      collapsed: true,
    },
    data: {
      collapsed: true,
    },
    edit: {
      collapsed: true,
    },
  },
};

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  data: getData(),
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
```

[Live example: Blank Values](https://www.ag-grid.com/studio/examples/blanks-and-missing-values/blank-values/typescript/)

## Display

Where a Widget shows a blank value, the text it shows depends on the field's data type:

| Data Type | Blank Display |
| --- | --- |
| Text | `(Blanks)` |
| Number | `N/A` |
| Boolean | Empty |
| Date and Date Time | Empty |

Chart category labels, Selection Filter lists, and List and Button [Filter Widgets](https://www.ag-grid.com/studio/analysts/filter-widgets/) show a blank value as `(Blanks)` for every data type.

## Sorting

A blank sorts as the smallest value, so an Ascending sort puts blanks first and a Descending sort puts them last. See [Sorting](https://www.ag-grid.com/studio/analysts/fields-in-widgets/#sorting).

## Grouping

When a field is used as a [Group by](https://www.ag-grid.com/studio/analysts/fields-in-widgets/#grouping), rows with a blank value form their own group. A chart labels the group `(Blanks)`.

## Filtering

A [Simple Filter](https://www.ag-grid.com/studio/analysts/filter-types/#simple-filter) condition treats a blank as having no value:

- Conditions that ask for a value to match, such as **Equals**, **Contains** and **Between**, exclude blanks.
- Conditions that ask for a value not to match keep blanks. These are **Does not equal** (**Not on** for dates) and **Does not contain**.
- **Blank** keeps only blanks, and **Not blank** removes them.

For example, Region **Does not equal** "North" keeps rows where Region is blank. To remove those rows as well, add a second condition, **Not blank**, joined with AND.

A [Selection Filter](https://www.ag-grid.com/studio/analysts/filter-types/#selection-filter) lists `(Blanks)` at the top when the field has blank values. You can select or clear it like any other value.

When you click a `(Blanks)` category in a chart, [Cross-Filtering](https://www.ag-grid.com/studio/analysts/cross-filtering/) restricts the other Widgets to rows where that field is blank.

## Aggregation

[Aggregations](https://www.ag-grid.com/studio/analysts/fields-in-widgets/#aggregation) treat blanks as follows:

- **Sum**, **Average**, **Minimum** and **Maximum** ignore blanks. The Average of 10, a blank and 20 is 15.
- If every value in a group is blank, Sum, Average, Minimum and Maximum return a blank, not 0. A number field shows this result as `N/A`.
- **Count** counts only the values that are not blank. If every value in a group is blank, Count also returns a blank, not 0.
- **Count (Distinct)** counts blank as one distinct value. The values North, South and a blank give a Count (Distinct) of 3.
- **First** and **Last** return the first or last value that is not blank.
