Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/main' into tidy/mdf…
Browse files Browse the repository at this point in the history
…ormat

# Conflicts:
#	.pre-commit-config.yaml
#	vizro-core/docs/pages/user-guides/data.md
#	vizro-core/docs/pages/user-guides/filters.md
  • Loading branch information
antonymilne committed Dec 3, 2024
2 parents 3daa404 + fc5a08c commit d96dafb
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 146 deletions.
5 changes: 3 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ repos:
args: [--autofix]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.2
rev: v0.8.1
hooks:
- id: ruff
args: [--fix]
exclude: "vizro-core/examples/scratch_dev/app.py"
- id: ruff-format

- repo: https://github.com/PyCQA/bandit
rev: 1.7.10
rev: 1.8.0
hooks:
- id: bandit
args: [-c, pyproject.toml, -ll]
Expand Down Expand Up @@ -112,3 +112,4 @@ ci:
- codespell
- bandit
- mypy

2 changes: 1 addition & 1 deletion vizro-ai/docs/pages/user-guides/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Vizro-AI supports **any** model that is available via [Langchain's `BaseChatMode

To use OpenAI with Vizro-AI you need an API key, which you can get by [creating an OpenAI account if you don't already have one](https://platform.openai.com/account/api-keys).

We recommend that you consult the [third-party API key section of the disclaimer documentation](../explanation/disclaimer.md) documentation.
We recommend that you consult the [third-party API key section of the disclaimer documentation](../explanation/disclaimer.md).

There are two common ways to set up the API key in a development environment.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--
A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Highlights ✨
- A bullet item for the Highlights ✨ category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Removed
- A bullet item for the Removed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Added
- A bullet item for the Added category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Changed
- A bullet item for the Changed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Deprecated
- A bullet item for the Deprecated category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Fixed
- A bullet item for the Fixed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Security
- A bullet item for the Security category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
172 changes: 123 additions & 49 deletions vizro-core/docs/pages/user-guides/data.md

Large diffs are not rendered by default.

119 changes: 97 additions & 22 deletions vizro-core/docs/pages/user-guides/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

This guide shows you how to add filters to your dashboard. One main way to interact with the charts/components on your page is by filtering the underlying data. A filter selects a subset of rows of a component's underlying DataFrame which alters the appearance of that component on the page.

The [`Page`][vizro.models.Page] model accepts the `controls` argument, where you can enter a [`Filter`][vizro.models.Filter] model. This model enables the automatic creation of [selectors](../user-guides/selectors.md) (such as Dropdown, RadioItems, Slider, ...) that operate upon the charts/components on the screen.
The [`Page`][vizro.models.Page] model accepts the `controls` argument, where you can enter a [`Filter`][vizro.models.Filter] model.
This model enables the automatic creation of [selectors](selectors.md) (for example, `Dropdown` or `RangeSlider`) that operate on the charts/components on the screen.

By default, filters that control components with [dynamic data](data.md#dynamic-data) are [dynamically updated](data.md#filters) when the underlying data changes while the dashboard is running.

## Basic filters

To add a filter to your page, do the following:

1. add the [`Filter`][vizro.models.Filter] model into the `controls` argument of the [`Page`][vizro.models.Page] model
1. configure the `column` argument, which denotes the target column to be filtered
2. configure the `column` argument, which denotes the target column to be filtered

By default, all components on a page with such a `column` present will be filtered. The selector type will be chosen automatically based on the target column, for example, a dropdown for categorical data, a range slider for numerical data, or a date picker for temporal data.
You can also set `targets` to specify which components on the page the filter should apply to. If this is not explicitly set then `targets` defaults to all components on the page whose data source includes `column`.

!!! example "Basic Filter"
=== "app.py"
Expand All @@ -36,7 +39,6 @@ By default, all components on a page with such a `column` present will be filter

Vizro().build(dashboard).run()
```

=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
Expand All @@ -55,15 +57,89 @@ By default, all components on a page with such a `column` present will be filter
type: filter
title: My first page
```
=== "Result"

[![Filter]][Filter]

[Filter]: ../../assets/user_guides/control/control1.png

The selector is configured automatically based on the target column type data as follows:

- Categorical data uses [`vm.Dropdown(multi=True)`][vizro.models.Dropdown] where `options` is the set of unique values found in `column` across all the data sources of components in `targets`.
- [Numerical data](https://pandas.pydata.org/docs/reference/api/pandas.api.types.is_numeric_dtype.html) uses [`vm.RangeSlider`][vizro.models.RangeSlider] where `min` and `max` are the overall minimum and maximum values found in `column` across all the data sources of components in `targets`.
- [Temporal data](https://pandas.pydata.org/docs/reference/api/pandas.api.types.is_datetime64_any_dtype.html) uses [`vm.DatePicker(range=True)`][vizro.models.DatePicker] where `min` and `max` are the overall minimum and maximum values found in `column` across all the data sources of components in `targets`. A column can be converted to this type with [pandas.to_datetime](https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html).

The following example demonstrates these default selector types.

!!! example "Default Filter selectors"
=== "app.py"
```{.python pycafe-link}
import pandas as pd
from vizro import Vizro
import vizro.plotly.express as px
import vizro.models as vm

df_stocks = px.data.stocks(datetimes=True)

df_stocks_long = pd.melt(
df_stocks,
id_vars='date',
value_vars=['GOOG', 'AAPL', 'AMZN', 'FB', 'NFLX', 'MSFT'],
var_name='stocks',
value_name='value'
)

df_stocks_long['value'] = df_stocks_long['value'].round(3)

page = vm.Page(
title="My first page",
components=[
vm.Graph(figure=px.line(df_stocks_long, x="date", y="value", color="stocks")),
],
controls=[
vm.Filter(column="stocks"),
vm.Filter(column="value"),
vm.Filter(column="date"),
],
)

dashboard = vm.Dashboard(pages=[page])

Vizro().build(dashboard).run()
```
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
# See yaml_version example
pages:
- components:
- figure:
_target_: line
data_frame: df_stocks_long
x: date
y: value
color: stocks
type: graph
controls:
- column: stocks
type: filter
- column: value
type: filter
- column: date
type: filter
title: My first page
```
=== "Result"
[![Filter]][filter]
[![Filter]][Filter]

## Changing selectors
[Filter]: ../../assets/user_guides/selectors/default_filter_selectors.png

If you want to have a different selector for your filter, you can give the `selector` argument of the [`Filter`][vizro.models.Filter] a different selector model. Currently available selectors are [`Checklist`][vizro.models.Checklist], [`Dropdown`][vizro.models.Dropdown], [`RadioItems`][vizro.models.RadioItems], [`RangeSlider`][vizro.models.RangeSlider], [`Slider`][vizro.models.Slider], and [`DatePicker`][vizro.models.DatePicker].
## Change selector

!!! example "Filter with custom Selector"
If you want to have a different selector for your filter, you can give the `selector` argument of the [`Filter`][vizro.models.Filter] a different selector model.
Currently available selectors are [`Checklist`][vizro.models.Checklist], [`Dropdown`][vizro.models.Dropdown], [`RadioItems`][vizro.models.RadioItems], [`RangeSlider`][vizro.models.RangeSlider], [`Slider`][vizro.models.Slider], and [`DatePicker`][vizro.models.DatePicker].

!!! example "Filter with different selector"
=== "app.py"
```{.python pycafe-link}
from vizro import Vizro
Expand All @@ -86,7 +162,6 @@ If you want to have a different selector for your filter, you can give the `sele

Vizro().build(dashboard).run()
```

=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
Expand All @@ -106,17 +181,18 @@ If you want to have a different selector for your filter, you can give the `sele
type: filter
title: My first page
```

=== "Result"
[![Selector]][selector]

[![Selector]][Selector]

[Selector]: ../../assets/user_guides/control/control2.png

## Further customization

For further customizations, you can always refer to the [`Filter`][vizro.models.Filter] reference. Some popular choices are:
For further customizations, you can always refer to the [`Filter` model][vizro.models.Filter] reference and the [guide to selectors](selectors.md). Some popular choices are:

- select which component the filter will apply to by using `targets`
- select what the target column type is, hence choosing the default selector by using `column_type`
- choose options of lower level components, such as the `selector` models
- specify configuration of the `selector`, for example `multi` to switch between a multi-option and single-option selector, `options` for a categorical filter or `min` and `max` for a numerical filter

Below is an advanced example where we only target one page component, and where we further customize the chosen `selector`.

Expand All @@ -136,15 +212,14 @@ Below is an advanced example where we only target one page component, and where
vm.Graph(figure=px.scatter(iris, x="petal_length", y="sepal_width", color="species")),
],
controls=[
vm.Filter(column="petal_length",targets=["scatter_chart"],selector=vm.RangeSlider(step=1)),
vm.Filter(column="petal_length",targets=["scatter_chart"], selector=vm.RangeSlider(step=1)),
],
)

dashboard = vm.Dashboard(pages=[page])

Vizro().build(dashboard).run()
```

=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
Expand All @@ -169,17 +244,17 @@ Below is an advanced example where we only target one page component, and where
controls:
- column: petal_length
targets:
- scatter_chart
- scatter_chart
selector:
step: 1
type: range_slider
type: filter
title: My first page
```

=== "Result"
[![Advanced]][advanced]

[advanced]: ../../assets/user_guides/control/control3.png
[filter]: ../../assets/user_guides/control/control1.png
[selector]: ../../assets/user_guides/control/control2.png
[![Advanced]][Advanced]

[Advanced]: ../../assets/user_guides/control/control3.png

To further customize selectors, see our [how-to-guide on creating custom components](custom-components.md).
31 changes: 9 additions & 22 deletions vizro-core/src/vizro/models/_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,31 +308,18 @@ def _make_page_404_layout(self):
return html.Div(
[
# Theme switch is added such that the 404 page has the same theme as the user-selected one.
html.Div(
children=dbc.Switch(
id="theme-selector",
value=self.theme == "vizro_light",
persistence=True,
persistence_type="session",
),
id="settings",
dbc.Switch(
id="theme-selector",
value=self.theme == "vizro_light",
persistence=True,
persistence_type="session",
),
html.Img(src=f"data:image/svg+xml;base64,{error_404_svg}"),
html.Div(
[
html.Div(
children=[
html.H3("This page could not be found.", className="heading-3-600"),
html.P("Make sure the URL you entered is correct."),
],
className="error-text-container",
),
dbc.Button(children="Take me home", href=get_relative_path("/")),
],
className="error-content-container",
),
html.H3("This page could not be found."),
html.P("Make sure the URL you entered is correct."),
dbc.Button(children="Take me home", href=get_relative_path("/"), className="mt-4"),
],
className="page-error-container",
className="d-flex flex-column align-items-center justify-content-center min-vh-100",
)

@staticmethod
Expand Down
25 changes: 0 additions & 25 deletions vizro-core/src/vizro/static/css/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,31 +85,6 @@
border-bottom: 1px solid var(--border-subtleAlpha01);
}

.page-error-container {
align-items: center;
display: flex;
flex-direction: column;
height: 100vh;
justify-content: center;
width: 100vw;
}

.error-content-container {
align-items: center;
display: inline-flex;
flex-direction: column;
gap: 24px;
margin-top: -32px;
}

.error-text-container {
display: flex;
flex-direction: column;
gap: 8px;
text-align: center;
width: 336px;
}

.dashboard_title {
display: flex;
flex-direction: column;
Expand Down
35 changes: 10 additions & 25 deletions vizro-core/tests/unit/vizro/models/test_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,35 +243,20 @@ def test_make_page_404_layout(self, page_1, vizro_app):
# vizro_app fixture is needed to avoid mocking out get_relative_path.
expected = html.Div(
[
html.Div(
children=dbc.Switch(
id="theme-selector",
value=False,
persistence=True,
persistence_type="session",
),
id="settings",
dbc.Switch(
id="theme-selector",
value=False,
persistence=True,
persistence_type="session",
),
html.Img(),
html.Div(
[
html.Div(
[
html.H3("This page could not be found.", className="heading-3-600"),
html.P("Make sure the URL you entered is correct."),
],
className="error-text-container",
),
dbc.Button("Take me home", href="/"),
],
className="error-content-container",
),
html.H3("This page could not be found."),
html.P("Make sure the URL you entered is correct."),
dbc.Button(children="Take me home", href="/", className="mt-4"),
],
className="page-error-container",
className="d-flex flex-column align-items-center justify-content-center min-vh-100",
)

# Strip out src since it's too long to be worth comparing and just comes directly
# from reading a file.
# Strip out src since it's too long to be worth comparing and just comes directly from reading a file.
assert_component_equal(vm.Dashboard(pages=[page_1])._make_page_404_layout(), expected, keys_to_strip={"src"})


Expand Down

0 comments on commit d96dafb

Please sign in to comment.