> Documentation index: https://www.gooddata.ai/docs/gooddata-ui/llms.txt lists every page of these docs as Markdown.

# Apply filters to visualizations

> Create attribute, date, measure-value, and ranking filters and apply them to charts, InsightView, or individual measures.

API reference: [newPositiveAttributeFilter()](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-model/sdk-model.newpositiveattributefilter/index.md) (function), [newNegativeAttributeFilter()](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-model/sdk-model.newnegativeattributefilter/index.md) (function)

Filter a visualization component by attribute values, dates, measure values, or rank through its `filters` prop, which takes an array of filters. To let users change the filters, use the [`AttributeFilter`](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/attribute-filter/index.md),
[`DateFilter`](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/date-filter/index.md),
[`MeasureValueFilterDropdown`](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/measure-value-filter/index.md), and
[`RankingFilterDropdown`](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/ranking-filter/index.md) components.

GoodData.UI always combines global filters and filters set on measures as an intersection of all of them (`f1 AND f2 AND f3 ...`).

Create the filters with the factory functions from `@gooddata/sdk-model`.

## [Filter by attribute values](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#filter-by-attribute-values)

Attribute filters reference a display form (attribute label) and match attribute elements by their values. On GoodData Cloud and GoodData.CN, the value of an element is its primary key.

When using text filters, remember to escape special characters `"` and `\`. If you want to filter out this exact string: `Foo\"`, enter it as `'Foo\\"'` or `"Foo\\\""`, which will result in `"Foo\\\""`.
The browser will send `"Foo\\\""` to the server where `"Foo\\\""` will be queried as `Foo\"`.

Single quotes and double quotes behave differently when you escape characters.

### [Positive attribute filter](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#positive-attribute-filter)

A **positive attribute filter** lists only those items whose attribute elements match the `inElements` array.
Use the `newPositiveAttributeFilter` factory function to create a new positive attribute filter:

```ts
newPositiveAttributeFilter(displayFormId, inElements)
```

where:

-  `displayFormId` is the identifier of the display form to filter by. You can specify the identifier explicitly as a string
   or pass an instance of [`IAttribute`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-model/sdk-model.iattribute/index.md) generated by [catalog-export](https://www.gooddata.ai/docs/gooddata-ui/latest/data-layer/data-model/export-catalog/index.md).

-  `inElements` is an array of attribute element values to filter by, for example `["California", "Texas"]`.

### [Negative attribute filter](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#negative-attribute-filter)

A **negative attribute filter** lists only those items whose attribute elements are *not* included in the `notInElements` array.
Use the `newNegativeAttributeFilter` factory function to create a new negative attribute filter:

```ts
newNegativeAttributeFilter(displayFormId, notInElements)
```

where:

-  `displayFormId` is the identifier of the display form to filter by. You can specify the identifier explicitly as a string
   or pass an instance of [`IAttribute`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-model/sdk-model.iattribute/index.md) generated by [catalog-export](https://www.gooddata.ai/docs/gooddata-ui/latest/data-layer/data-model/export-catalog/index.md).

-  `notInElements` is an array of attribute element values to filter out.

> **Legacy URI form:**
> The factories also accept `{ uris: [...] }` instead of an array of values. This form comes from GoodData Legacy. GoodData Cloud and GoodData.CN treat its items as primary key values, so use plain values instead.

## [Filter by date](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#filter-by-date)

### [Absolute date filter](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#absolute-date-filter)

An **absolute date filter** shows data that falls within a defined time range. Use the `newAbsoluteDateFilter` factory
function to create a new absolute date filter:

```ts
newAbsoluteDateFilter(dateDataSet, from, to)
```

where:

-  `dateDataSet` is the identifier of the date dataset to filter by.
-  `from` is the start date in the format `YYYY-MM-DD`.
-  `to` is the end date in the format `YYYY-MM-DD`.

### [Relative date filter](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#relative-date-filter)

A **relative date filter** shows data that falls within a time range defined relatively to the current date. Filter granularity (`granularity`) defines how a time range can be broken down to smaller time units (week, month, quarter, and so on).

`granularity` can be set to:

| Value | Description |
| :--- | :--- |
| `"GDC.time.date"` | Days |
| `"GDC.time.week"` | Weeks starting on Monday |
| `"GDC.time.week_us"` | Weeks starting on Sunday |
| `"GDC.time.month"` | Months |
| `"GDC.time.quarter"` | Quarters of a year |
| `"GDC.time.year"` | Years |
| `"GDC.time.hour"` | Hours |
| `"GDC.time.minute"` | Minutes |

The date filter dropdown and the [date filter presets](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/customize-date-filter-presets/index.md) use `GDC.time.week_us` for weeks; `GDC.time.week` is available only in filters you build in code.

The `from` and `to` properties set the number of granularity units (for example, weeks) before or after the current date. That is, `from` and `to`  define the filter range.

* `0` for the current day, week, month, quarter, or year (depending on the chosen granularity)
* `-1` for the previous period
* `-n` for the *n*th previous period

Use the `newRelativeDateFilter` factory function to create a new relative date filter:

```ts
newRelativeDateFilter(dateDataSet, granularity, from, to);
```

where:

-  `dateDataSet` is the identifier of the date dataset to filter by.
-  `granularity` is one of the supported values.
-  `from` is the relative start time.
-  `to` is the relative end time.

### [Relative date filter examples](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#relative-date-filter-examples)

The seven days before today (yesterday and the six days before it), without today:

```ts
newRelativeDateFilter("<date-dataset-identifier>", "GDC.time.date", -7, -1);
```

This range differs from the "Last 7 days" preset of the date filter dropdown, which is `-6` to `0` and includes today.

The last 12 months including the current month:

```ts
newRelativeDateFilter("<date-dataset-identifier>", "GDC.time.month", -11, 0);
```

The previous quarter only:

```ts
newRelativeDateFilter("<date-dataset-identifier>", "GDC.time.quarter", -1, -1);
```

## [Filter by a measure value](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#filter-by-a-measure-value)

You can filter a visualization by the value of a measure. You can filter only the measures that are present in the visualization, on the granularity defined by the attributes in the visualization.

> **Notes:**
> * The numbers rendered by a visualization are often rounded up/down. However, filters are applied to the original exact numbers (those before rounding), and that may lead to unexpected results. For example, the number `400.01` rounded to a whole number would be `400`, but it will still be included in the visualization with a filter that filters out the values smaller than or equal to `400`.
> * A [rollup total](https://www.gooddata.ai/docs/gooddata-ui/latest/data-layer/execution/table-totals/index.md) is not supported in visualizations with measure value filters. Such visualizations are not rendered, and the error message is shown instead.

### [Compare a measure value to a value](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#compare-a-measure-value-to-a-value)

When you filter a measure by comparing its value to some predefined value, the filter shows only the data whose measure matches a comparison condition.

You can create comparative measure value filters using the `newMeasureValueFilter` factory function:

```ts
newMeasureValueFilter(measureOrLocalId, operator, value, treatNullValuesAs)
```

where:

-  `measureOrLocalId` is `localIdentifier` of the measure to filter. You can specify the localIdentifier explicitly or
   pass an instance of measure and the factory will extract the localIdentifier for you.

-  `operator` is one of the following:
    * `"GREATER_THAN"`: The measure value is greater than `value`.
    * `"GREATER_THAN_OR_EQUAL_TO"`: The measure value is greater than `value` or equal to `value`.
    * `"LESS_THAN"`: The measure value is less than `value`.
    * `"LESS_THAN_OR_EQUAL_TO"`: The measure value is less than `value` or equal to `value`.
    * `"EQUAL_TO"`: The measure value is equal to `value`.
    * `"NOT_EQUAL_TO"`: The measure value is not equal to `value`.

-  `value` is the measure value to filter against.
-  `treatNullValuesAs` is optional; by default, any filter condition filters out null values. If you want a filter
   condition to treat null values as a number and to include them in the filtering process, use this parameter.

### [Compare a measure value to a range](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#compare-a-measure-value-to-a-range)

When you filter a measure by comparing its value against some predefined range of values, the filter shows only the data whose measure matches a range condition.

You can create comparative measure value filters using the `newMeasureValueFilter` factory function:

```ts
newMeasureValueFilter(measureOrLocalId, operator, from, to, treatNullValuesAs)
```

where:

-  `measureOrLocalId` is `localIdentifier` of the measure to filter. You can specify `localIdentifier` explicitly or
   pass an instance of the measure, and the factory will extract `localIdentifier` for you.

-  `operator` is one of the following:
    * `"BETWEEN"`: The measure value is between the `from` and `to` values (including the boundaries).
    * `"NOT_BETWEEN"`: The measure value is not between the `from` and `to` values (excluding the boundaries).

-  `from` is the start boundary.
-  `to` is the end boundary.
-  `treatNullValuesAs` is optional; by default, any filter condition filters out null values. If you want a filter
   condition to treat null values as a number and to include them in the filtering process, use this parameter.

### [Filter by a percentage measure](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#filter-by-a-percentage-measure)

You can use several methods to get measures to be rendered as a percentage. Depending on the method you used, measure value filters applied to such measures behave differently.

#### [Measures shown in %](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#measures-shown-in-)
When a visualization is filtered by a measure that is shown in % (that is, the measure has `computeRatio=true`), the filter value is based on the range of the actual measure values and not on the percentage values rendered by the visualization.

For example, if the visualization renders the values `100`, `200`, and `700` as `10%`, `20%`, and `70%`, the filter that filters out the first two values would use a comparison condition with the operator `GREATER_THAN` and the condition value `200`. The result would contain only the value `700` rendered as `100%` in the visualization.

The reason is that the percentage values are always computed for the current execution result. By applying the measure value filter, the result changes and so the percentage values will change as well. That would result in the filter and the values displayed to have a different scale which would be confusing. For instance, accepting only values lower than 50% could still produce visualizations with values higher than 50%.

#### [Measures in charts stacked to 100%](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#measures-in-charts-stacked-to-100)
When a visualization is filtered by a measure that is stacked to 100%, the filter value is based on the range of the actual measure values and not on the percentage values rendered by the visualization.

The example and the reason behind this behavior are similar to those described above for the measures shown in %.

#### [Measures formatted in %](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#measures-formatted-in-)
When a visualization is filtered by a measure that is formatted in %, the filter value is based on the percentage values rendered by the visualization and not on the range of the actual measure values.

For example, if the visualization renders the formatted values `100%`, `20%`, and `3%`, the filter that filters out only one value would use the operator `NOT_EQUAL_TO` and the filter values `1`, `0.2`, or `0.03`, respectively.

This applies to the following types of measures:
* Measures that have the percentage format set by the `format` measure property
* Calculated measures with the percentage format set in the metadata catalog
* Arithmetic measures with the `change` operator that has the percentage property `format` set

## [Filter by rank](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#filter-by-rank)

A ranking filter shows the data from a set of the highest or lowest ranked values of an attribute based on the ranking criteria that you establish. You can filter only the measures that are present in the visualization, on the granularity defined by the attributes in the visualization.

> **Notes:**
> * A [rollup total](https://www.gooddata.ai/docs/gooddata-ui/latest/data-layer/execution/table-totals/index.md) and measures that are shown in % (that is, the measures with `computeRatio=true` property) are not supported in visualizations with ranking filters. Such visualizations are not rendered, and the error message is shown instead.
> * Ranking filters do not affect visualization sorting. For example, when you filter to get top three highest values of a measure, the visualization keeps its sorting order, which may or may not have been applied to the filtered measure.

When you apply a ranking filter to a measure, the filter shows only the data whose measure values match the condition. More records than requested can be returned if they share the same value.

You can create ranking filters using one of the following `newRankingFilter` factory functions:

```ts
newRankingFilter(measureOrLocalId, operator, value)
```

```ts
newRankingFilter(measureOrLocalId, attributesOrLocalIds, operator, value)
```

where:

-  `measureOrLocalId` is `localIdentifier` of the measure to filter. You can specify `localIdentifier` explicitly or
   pass an instance of the measure, and the factory will extract `localIdentifier` for you.

- `attributesOrLocalIds` is an array of `localIdentifier` strings of the attributes that defines the ranking granularity.
You can specify `localIdentifier` explicitly or pass an instance of the attribute, and the factory will extract `localIdentifier` for you.
This parameter is optional. If it is not specified, the ranking behaves as if you would enter the list of all attributes in the visualization.

-  `operator` is one of the following:
    * `"TOP"` returns records with the highest values of the filtered measure for the granularity specified by the filter attributes.
    * `"BOTTOM"` returns records with the lowest values of the filtered measure for the granularity specified by the filter attributes.

-  `value` is the number of the ranked records to return. The number must be a positive integer (1, 2, 3, ...).

## [Filter a single measure](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#filter-a-single-measure)

Applying a filter to a specific measure is helpful when you have duplicate measures with different filters. You can apply
filters to measures created from facts or MAQL metrics using the `modifySimpleMeasure` function:

```ts
modifySimpleMeasure(measure, modifications)
```

* When both the measure filter of the [`DateFilter`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-filters/sdk-ui-filters.datefilter/index.md) type and the global filter of the [`DateFilter`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-filters/sdk-ui-filters.datefilter/index.md) type are set with
  the **same** date dimension, the measure date filter overrides the global date filter for this
  measure (global date filters still apply to the other measures that have no measure date filter).
* When the measure filter of the [`DateFilter`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-filters/sdk-ui-filters.datefilter/index.md) type and the global filter of the [`DateFilter`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-filters/sdk-ui-filters.datefilter/index.md) type are set with **different**
  date dimensions, the filters are interpreted as an intersection of those filters (f1 AND f2).

```tsx
import { ColumnChart } from "@gooddata/sdk-ui-charts";
import { modifySimpleMeasure, newPositiveAttributeFilter } from "@gooddata/sdk-model";
import * as Md from "./catalog.js";

const californiaSales = modifySimpleMeasure(
                            Md.$TotalSales,
                            m => m.filters(newPositiveAttributeFilter(Md.StateName, ["California"])).alias("California Sales")
                        );

const style = { height: 300 };

<div style={style}>
    <ColumnChart
        measures={[ californiaSales ]}
    />
</div>
```

## [Pass filters to a component](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#pass-filters-to-a-component)

### [Filter a saved visualization](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#filter-a-saved-visualization)

```tsx
import "@gooddata/sdk-ui-ext/styles/css/main.css";
import { InsightView } from "@gooddata/sdk-ui-ext";
import { newPositiveAttributeFilter } from "@gooddata/sdk-model";
import * as Md from "./catalog.js";

const filters = [
    newPositiveAttributeFilter(Md.StateName, ["California"]),
    newPositiveAttributeFilter(Md.IsKidsItem, ["true"])
];

<div style={{ height: 400, width: 600 }}>
    <InsightView
        insight="<visualization-identifier>"
        filters={filters}
    />
</div>
```

If you reference a saved visualization with active filters and set the `filters` prop on [`InsightView`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-ext/sdk-ui-ext.insightview/index.md), both sets of filters will be merged using the following rules:

* If the active filter in the saved visualization and the filter defined with the `filters` prop reference the same object (by identifier), the filter from the `filters` prop overwrites the active filter in the saved visualization.
* All other filters, both saved and from the `filters` prop, will be added.

### [Filter a chart](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#filter-a-chart)

```tsx
import { ColumnChart } from "@gooddata/sdk-ui-charts";
import { newNegativeAttributeFilter } from "@gooddata/sdk-model";
import * as Md from "./catalog.js";

const style = { height: 300 };

<div style={style}>
    <ColumnChart
        measures={[Md.$TotalSales]}
        filters={[
            newNegativeAttributeFilter(Md.StateName, ["Alaska", "Hawaii"]),
        ]}
    />
</div>
```

### [Let users filter a chart](https://www.gooddata.ai/docs/gooddata-ui/latest/filters/filter-visual-components/#let-users-filter-a-chart)

[`AttributeFilter`](https://www.gooddata.ai/docs/gooddata-ui/latest/api-reference/sdk-ui-filters/sdk-ui-filters.attributefilter/index.md) renders a dropdown with the values of an attribute. When a user clicks **Apply**, its `onApply` callback receives an attribute filter: a positive filter with the selected values, or a negative filter with the values that aren't selected. Keep the filter in state and pass it to the chart.

```tsx
import { useState } from "react";
import { ColumnChart } from "@gooddata/sdk-ui-charts";
import { AttributeFilter } from "@gooddata/sdk-ui-filters";
import { newNegativeAttributeFilter } from "@gooddata/sdk-model";
import "@gooddata/sdk-ui-filters/styles/css/main.css";
import "@gooddata/sdk-ui-charts/styles/css/main.css";
import * as Md from "./catalog.js";

export const FilteredChart = () => {
    const [filter, setFilter] = useState(newNegativeAttributeFilter(Md.StateName, []));

    return (
        <div>
            <AttributeFilter filter={filter} onApply={setFilter} />
            <div style={{ height: 300 }}>
                <ColumnChart measures={[Md.$TotalSales]} viewBy={Md.StateName} filters={[filter]} />
            </div>
        </div>
    );
};
```
