diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 44e958f1c..ea40a09f2 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -6,8 +6,8 @@
- [ ] I acknowledge and agree that, by checking this box and clicking "Submit Pull Request":
- - I submit this contribution under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0.txt) and represent that I am entitled to do so on behalf of myself, my employer, or relevant third parties, as applicable.
- - I certify that (a) this contribution is my original creation and / or (b) to the extent it is not my original creation, I am authorized to submit this contribution on behalf of the original creator(s) or their licensees.
- - I certify that the use of this contribution as authorized by the Apache 2.0 license does not violate the intellectual property rights of anyone else.
- - I have not referenced individuals, products or companies in any commits, directly or indirectly.
- - I have not added data or restricted code in any commits, directly or indirectly.
+ - I submit this contribution under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0.txt) and represent that I am entitled to do so on behalf of myself, my employer, or relevant third parties, as applicable.
+ - I certify that (a) this contribution is my original creation and / or (b) to the extent it is not my original creation, I am authorized to submit this contribution on behalf of the original creator(s) or their licensees.
+ - I certify that the use of this contribution as authorized by the Apache 2.0 license does not violate the intellectual property rights of anyone else.
+ - I have not referenced individuals, products or companies in any commits, directly or indirectly.
+ - I have not added data or restricted code in any commits, directly or indirectly.
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 6fc461d5c..d0596372c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -34,8 +34,9 @@ repos:
description: Linter for json, yaml, md, css and more
entry: prettier --write --ignore-unknown
language: node
- "types": [text]
+ types: [text]
additional_dependencies: ["prettier@3.3.3"]
+ exclude_types: [markdown]
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.14.0
@@ -83,16 +84,19 @@ repos:
- stylelint-order@4.1.0
args: ["--fix"]
- - repo: https://github.com/errata-ai/vale
- rev: v3.9.1
+ - repo: https://github.com/executablebooks/mdformat
+ rev: 0.7.18
hooks:
- - id: vale
- args: [--config=.vale/.vale.ini]
- # There's no way to automatically convert vale suggestions/warnings to errors, and so they won't appear at all unless
- # there's an error raised.
- # pre-commit's verbose mode means that suggestions and warnings are always shown even if there's no error raised.
- # See https://github.com/errata-ai/vale/issues/575.
- verbose: true
+ - id: mdformat
+ args:
+ [
+ --ignore-missing-references,
+ --wrap=no,
+ --align-semantic-breaks-in-lists,
+ ]
+ exclude: ^vizro-core/docs/pages/API-reference|^vizro-ai/docs/pages/API-reference|vizro-core/docs/pages/user-guides/custom-components.md|^vizro-core/changelog.d|^vizro-ai/changelog.d
+ additional_dependencies:
+ - mdformat-mkdocs[recommended]==3.1.1
# Configuration for https://pre-commit.ci/.
ci:
@@ -108,4 +112,3 @@ ci:
- codespell
- bandit
- mypy
- - vale
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 421f29147..6173d9378 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -2,17 +2,11 @@
## Our Pledge
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, sex characteristics, gender identity and expression,
-level of experience, education, socioeconomic status, nationality, personal
-appearance, race, religion, or sexual identity and orientation.
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
-Examples of behavior that contributes to creating a positive environment
-include:
+Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
@@ -22,57 +16,34 @@ include:
Examples of unacceptable behavior by participants include:
-- The use of sexualised language or imagery and unwelcome sexual attention or
- advances
+- The use of sexualised language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
-- Publishing others' private information, such as a physical or electronic
- address, without explicit permission
-- Other conduct which could reasonably be considered inappropriate in a
- professional setting
+- Publishing others' private information, such as a physical or electronic address, without explicit permission
+- Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
**Investigation Timeline:** The project team will make all reasonable efforts to initiate and conclude the investigation in a timely fashion. Depending on the type of investigation the steps and timeline for each investigation will vary.
## Attribution
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
-[homepage]: https://www.contributor-covenant.org
+For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq
-For answers to common questions about this code of conduct, see
-https://www.contributor-covenant.org/faq
+[homepage]: https://www.contributor-covenant.org
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 66bcc019a..31a65c178 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1,3 @@
# Contributing
-Contributions of all experience levels are welcome! If you're interested in making a contribution,
-please refer to our [contributing guide](https://vizro.readthedocs.io/en/stable/pages/explanation/contributing/) for more information.
+Contributions of all experience levels are welcome! If you're interested in making a contribution, please refer to our [contributing guide](https://vizro.readthedocs.io/en/stable/pages/explanation/contributing/) for more information.
diff --git a/README.md b/README.md
index be083bde8..d30fa8e29 100644
--- a/README.md
+++ b/README.md
@@ -11,19 +11,13 @@
-[![Python version](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue.svg)](https://pypi.org/project/vizro/)
-[![PyPI version](https://badge.fury.io/py/vizro.svg)](https://badge.fury.io/py/vizro)
-[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/mckinsey/vizro/blob/main/LICENSE.md)
-[![Documentation](https://readthedocs.org/projects/vizro/badge/?version=stable)](https://vizro.readthedocs.io/)
-[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7858/badge)](https://www.bestpractices.dev/projects/7858)
+[![Python version](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue.svg)](https://pypi.org/project/vizro/) [![PyPI version](https://badge.fury.io/py/vizro.svg)](https://badge.fury.io/py/vizro) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/mckinsey/vizro/blob/main/LICENSE.md) [![Documentation](https://readthedocs.org/projects/vizro/badge/?version=stable)](https://vizro.readthedocs.io/) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7858/badge)](https://www.bestpractices.dev/projects/7858)
+ type: card
+ - text: |
+ Commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit.
+
+ Fugiat iusto fuga praesentium option, eaque rerum! Provident similique accusantium nemo autem.
+
+ Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
+
+ Culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas.
+ title: Paragraphs
+ type: card
+ - text: |
+ >
+ > A block quote is a long quotation, indented to create a separate block of text.
+ >
+ title: Block Quotes
+ type: card
+ - text: |
+ * Item A
+ * Sub Item 1
+ * Sub Item 2
+ * Item B
+ title: Lists
+ type: card
+ - text: |
+ This word will be *italic*
+
+ This word will be **bold**
+
+ This word will be _**bold and italic**_
+ title: Emphasis
+ type: card
+ title: Customizing Text
```
- === "Result"
- [![CardText]][CardText]
- [CardText]: ../../assets/user_guides/components/card_text.png
+ === "Result"
+ [![CardText]][cardtext]
### Place an image on a card
@@ -189,11 +185,10 @@ Images can be added to the `text` parameter by using the standard markdown synta
`![Image ALT text](Image URL)`
-An image ALT text offers a description to your image and serves as a text placeholder or to improve the
-accessibility of your app. Providing an image ALT text is optional.
+An image ALT text offers a description to your image and serves as a text placeholder or to improve the accessibility of your app. Providing an image ALT text is optional.
1. To use a relative Image URL, place an image of your choice into your `assets` folder first
-2. Use markdown to render your image by using one of the following syntax:
+1. Use markdown to render your image by using one of the following syntax:
- Relative Image URL: `![Image ALT text](/path/to/image.png)`
- Absolute Image URL: `![Image ALT text](https://XXXXXX)`
@@ -228,55 +223,50 @@ accessibility of your app. Providing an image ALT text is optional.
Run and edit this code in PyCafe
-
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
# See from_yaml example
pages:
- - components:
- - text: |
- ![continent](assets/images/continents/africa.svg)
+ - components:
+ - text: |
+ ![continent](assets/images/continents/africa.svg)
- Commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit.
+ Commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit.
- Fugiat iusto fuga praesentium option, eaque rerum! Provident similique accusantium nemo autem.
+ Fugiat iusto fuga praesentium option, eaque rerum! Provident similique accusantium nemo autem.
- Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
- title: My card with image!
- type: card
- title: Placing Images
+ Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
+ title: My card with image!
+ type: card
+ title: Placing Images
```
- === "Result"
- [![CardImageDefault]][CardImageDefault]
- [CardImageDefault]: ../../assets/user_guides/components/card_image_default.png
+ === "Result"
+ [![CardImageDefault]][cardimagedefault]
!!! note
-
- Note that inserting images using html is by default turned off by the `dcc.Markdown` to prevent users being exposed
- to cross-site scripting attacks. If you need to turn it on, a custom component would have to be created.
+ Note that inserting images using HTML is by default turned off by the `dcc.Markdown` to prevent users being exposed to cross-site scripting attacks. If you need to turn it on, a custom component would have to be created.
You might notice that the image is quite large. You'll find out how to style images in terms of their position and size in the next section.
-
### Style a card image
To change the size or position of the image, add a URL hash to your image like this:
`![Image ALT text](Image URL#my-image)`
-Note the added URL hash `#my-image`. Now create a CSS file placed in your `assets` folder
-and give an attribute selector to select images with that matching URL hash.
+Note the added URL hash `#my-image`. Now create a CSS file placed in your `assets` folder and give an attribute selector to select images with that matching URL hash.
!!! example "Card with styled image"
=== "images.css"
- ```css
- img[src*="#my-image"] {
- width: 120px;
- height: 120px;
- }
- ```
+ ```css
+ img[src*="#my-image"] {
+ width: 120px;
+ height: 120px;
+ }
+ ```
+
=== "app.py"
```py
import vizro.models as vm
@@ -313,23 +303,22 @@ and give an attribute selector to select images with that matching URL hash.
# Still requires a .py to add data to the data manager and parse YAML configuration
# See from_yaml example
pages:
- - components:
- - text: |
- ![](assets/images/continents/europe.svg#my-image)
+ - components:
+ - text: |
+ ![](assets/images/continents/europe.svg#my-image)
- Commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit.
+ Commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit.
- Fugiat iusto fuga praesentium option, eaque rerum! Provident similique accusantium nemo autem.
+ Fugiat iusto fuga praesentium option, eaque rerum! Provident similique accusantium nemo autem.
- Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
- title: My card with image!
- type: card
- title: Styling Images
+ Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
+ title: My card with image!
+ type: card
+ title: Styling Images
```
- === "Result"
- [![CardImageStyled]][CardImageStyled]
- [CardImageStyled]: ../../assets/user_guides/components/card_image_styled.png
+ === "Result"
+ [![CardImageStyled]][cardimagestyled]
Use the following pre-defined URL hashes in your image path to apply Vizro's default styling.
@@ -341,12 +330,13 @@ Use the following pre-defined URL hashes in your image path to apply Vizro's def
!!! example "Card with floating image"
=== "images.css"
- ```css
- img[src*="#my-image"] {
- width: 120px;
- height: 120px;
- }
- ```
+ ```css
+ img[src*="#my-image"] {
+ width: 120px;
+ height: 120px;
+ }
+ ```
+
=== "app.py"
```py
import vizro.models as vm
@@ -389,29 +379,28 @@ Use the following pre-defined URL hashes in your image path to apply Vizro's def
# Still requires a .py to add data to the data manager and parse YAML configuration
# See from_yaml example
pages:
- - components:
- - text: |
- ![](assets/images/continents/europe.svg#my-image#floating-right)
+ - components:
+ - text: |
+ ![](assets/images/continents/europe.svg#my-image#floating-right)
- Commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit.
+ Commodi repudiandae consequuntur voluptatum laborum numquam blanditiis harum quisquam eius sed odit.
- Fugiat iusto fuga praesentium option, eaque rerum! Provident similique accusantium nemo autem.
+ Fugiat iusto fuga praesentium option, eaque rerum! Provident similique accusantium nemo autem.
- Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
+ Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
- Culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas.
+ Culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas.
- Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
+ Obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam nihil, eveniet aliquid.
- Culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas.
- title: My card with floating image!
- type: card
- title: Floating Images
+ Culpa officia aut! Impedit sit sunt quaerat, odit, tenetur error, harum nesciunt ipsum debitis quas.
+ title: My card with floating image!
+ type: card
+ title: Floating Images
```
- === "Result"
- [![CardImageFloating]][CardImageFloating]
- [CardImageFloating]: ../../assets/user_guides/components/card_image_floating.png
+ === "Result"
+ [![CardImageFloating]][cardimagefloating]
#### Card with icon
@@ -442,38 +431,34 @@ Use the following pre-defined URL hashes in your image path to apply Vizro's def
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 from_yaml example
pages:
- - components:
- - text: |
- ![](assets/images/icons/hypotheses.svg#icon-top)
+ - components:
+ - text: |
+ ![](assets/images/icons/hypotheses.svg#icon-top)
- ### Card Title
+ ### Card Title
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut fringilla dictum lacus eget fringilla.
- Maecenas in various nibh, quis venenatis nulla. Integer et libero ultrices, scelerisque velit sed.
- type: card
- title: Card with icon
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut fringilla dictum lacus eget fringilla.
+ Maecenas in various nibh, quis venenatis nulla. Integer et libero ultrices, scelerisque velit sed.
+ type: card
+ title: Card with icon
```
- === "Result"
- [![CardIcon]][CardIcon]
-
- [CardIcon]: ../../assets/user_guides/components/card_icon.png
+ === "Result"
+ [![CardIcon]][cardicon]
### Make an icon responsive to theme switch
-To make an icon responsive to the theme switch, override the value of the [`filter` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/filter).
-The `filter` CSS property lets you add visual effects to elements using different functions. In our example, we're using the `--inverse-color` CSS variable from the Vizro theme.
-It uses the CSS `invert()` function to flip the color of the icon when you switch themes. Note that this only works if your initial icon has a white fill color. If your icon is not white, you can change its color by adding `fill="white"` to the SVG code.
-Assign the predefined CSS variable `--inverse-color` to the `filter` property of your selected icon.
+To make an icon responsive to the theme switch, override the value of the [`filter` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/filter). The `filter` CSS property lets you add visual effects to elements using different functions. In our example, we're using the `--inverse-color` CSS variable from the Vizro theme. It uses the CSS `invert()` function to flip the color of the icon when you switch themes. Note that this only works if your initial icon has a white fill color. If your icon is not white, you can change its color by adding `fill="white"` to the SVG code. Assign the predefined CSS variable `--inverse-color` to the `filter` property of your selected icon.
```css
img[src*="#my-image"] {
- filter: var(--inverse-color);
+ filter: var(--inverse-color);
}
```
@@ -482,18 +467,15 @@ img[src*="#my-image"] {
### Create a navigation card
-This section describes how to use the [`Card`][vizro.models.Card] component to create a navigation card,
-enabling users to navigate to another page by clicking on the card area.
+This section describes how to use the [`Card`][vizro.models.Card] component to create a navigation card, enabling users to navigate to another page by clicking on the card area.
-For a button-style link navigation component, see the [separate guide on creating a link button](#create-a-link-button).
-To configure the navigation panel on the left hand side of the screen, refer to the
-[separate guide on navigation](navigation.md).
+For a button-style link navigation component, see the [separate guide on creating a link button](#create-a-link-button). To configure the navigation panel on the left hand side of the screen, refer to the [separate guide on navigation](navigation.md).
To create a navigation card:
1. Insert the [`Card`][vizro.models.Card] into the `components` argument of the [`Page`][vizro.models.Page].
-2. Pass your markdown text to the `Card.text`.
-3. Pass a relative or absolute URL to the `Card.href`.
+1. Pass your markdown text to the `Card.text`.
+1. Pass a relative or absolute URL to the `Card.href`.
!!! example "Navigation Card"
=== "app.py"
@@ -537,72 +519,65 @@ To create a navigation card:
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
# See from_yaml example
pages:
- - components:
- - text: |
- ### Filters and parameters
-
- Leads to the first page on click
- href: /filters-and-parameters
- type: card
- - text: |
- ### Google - External Link
-
- Leads to an external link on click.
- href: https://google.com
- type: card
- title: Homepage
- - components:
- - figure:
- _target_: scatter
- color: sepal_width
- data_frame: iris
- x: sepal_length
- y: petal_width
- type: graph
- title: Filters and parameters
+ - components:
+ - text: |
+ ### Filters and parameters
+
+ Leads to the first page on click
+ href: /filters-and-parameters
+ type: card
+ - text: |
+ ### Google - External Link
+
+ Leads to an external link on click.
+ href: https://google.com
+ type: card
+ title: Homepage
+ - components:
+ - figure:
+ _target_: scatter
+ color: sepal_width
+ data_frame: iris
+ x: sepal_length
+ y: petal_width
+ type: graph
+ title: Filters and parameters
```
- === "Result"
- [![NavCard]][NavCard]
- [NavCard]: ../../assets/user_guides/components/nav_card.png
+ === "Result"
+ [![NavCard]][navcard]
If you now click on the card area, you should automatically be redirected to the relevant `href`.
!!! note
-
When using the [`Card`][vizro.models.Card], keep the following in mind:
- If the href given is a relative URL, it should match the `path` of the [`Page`][vizro.models.Page] that the [`Card`][vizro.models.Card] should navigate to.
- If the href given is an absolute link, it should start with `https://` or an equivalent protocol.
-
### Create a KPI card
-To create a KPI card, you can use the existing KPI card functions from [`vizro.figures`](../API-reference/figure-callables.md).
-Unlike the static text card `vm.Card`, a KPI card must be created using a figure function,
-which enables the text content of the KPI to change based on input from controls or actions.
+
+To create a KPI card, you can use the existing KPI card functions from [`vizro.figures`](../API-reference/figure-callables.md). Unlike the static text card `vm.Card`, a KPI card must be created using a figure function, which enables the text content of the KPI to change based on input from controls or actions.
For detailed examples on how to create a KPI card, refer to the [figure user guide on KPI cards](figure.md#key-performance-indicator-kpi-cards).
## Buttons
-The Button component is commonly used for interactive dashboard interactions
-such as form submissions, navigation links, and other action triggers.
-
-To add a [`Button`][vizro.models.Button], insert it into the `components` argument of the
-[`Page`][vizro.models.Page].
+The Button component is commonly used for interactive dashboard interactions such as form submissions, navigation links, and other action triggers.
+To add a [`Button`][vizro.models.Button], insert it into the `components` argument of the [`Page`][vizro.models.Page].
### Customize button text
You can configure the `text` argument to alter the display text of the [`Button`][vizro.models.Button].
!!! example "Customize text"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -616,26 +591,24 @@ You can configure the `text` argument to alter the display text of the [`Button`
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 from_yaml example
pages:
- components:
- - type: button
- text: I'm a button!
+ - type: button
+ text: I'm a button!
title: Button with text
```
- === "Result"
- [![ButtonText]][ButtonText]
-
- [ButtonText]: ../../assets/user_guides/components/button_text.png
+ === "Result"
+ [![ButtonText]][buttontext]
### Create a link button
-To navigate to a different page using a button with an anchor tag, assign an absolute or relative URL to the
-`Button.href`.
+To navigate to a different page using a button with an anchor tag, assign an absolute or relative URL to the `Button.href`.
```python
import vizro.models as vm
@@ -645,16 +618,11 @@ vm.Button(text="Leave us a star! ⭐", href="https://github.com/mckinsey/vizro")
### Attach an action
-You can use the [`Button`][vizro.models.Button] to trigger predefined action functions, such as exporting data.
-To explore the available options for [`Actions`][vizro.models.Action], refer to our [API reference][vizro.actions].
-Use the `Button.actions` argument to specify which action function executes when the button is clicked.
-
-The example below demonstrates how to configure a button to export the filtered data of a target chart using the
-[export_data][vizro.actions.export_data] action function.
+You can use the [`Button`][vizro.models.Button] to trigger predefined action functions, such as exporting data. To explore the available options for [`Actions`][vizro.models.Action], refer to our [API reference][vizro.actions]. Use the `Button.actions` argument to specify which action function executes when the button is clicked.
+The example below demonstrates how to configure a button to export the filtered data of a target chart using the [export_data][vizro.actions.export_data] action function.
!!! example "Button with action"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -690,29 +658,30 @@ The example below demonstrates how to configure a button to export the filtered
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
# See from_yaml example
pages:
- components:
- - figure:
- _target_: scatter
- x: sepal_width
- y: sepal_length
- color: species
- size: petal_length
- data_frame: iris
- id: scatter_chart
- type: graph
- - type: button
- text: Export data
- id: export_data
- actions:
- - function:
- _target_: export_data
- targets:
- - scatter_chart
+ - figure:
+ _target_: scatter
+ x: sepal_width
+ y: sepal_length
+ color: species
+ size: petal_length
+ data_frame: iris
+ id: scatter_chart
+ type: graph
+ - type: button
+ text: Export data
+ id: export_data
+ actions:
+ - function:
+ _target_: export_data
+ targets:
+ - scatter_chart
controls:
- column: species
selector:
@@ -728,14 +697,13 @@ The example below demonstrates how to configure a button to export the filtered
- [1]
title: My first page
```
- === "Result"
- [![Button]][Button]
- [Button]: ../../assets/user_guides/components/button.png
+ === "Result"
+ [![Button]][button]
### Use as a control
-The [`Button`][vizro.models.Button] component is currently reserved to be used inside the main panel (right-side) of the dashboard.
-However, there might be use cases where one would like to place the `Button` inside the control panel (left-side) with the other controls.
+
+The [`Button`][vizro.models.Button] component is currently reserved to be used inside the main panel (right-side) of the dashboard. However, there might be use cases where one would like to place the `Button` inside the control panel (left-side) with the other controls.
In this case, follow the user-guide outlined for [creating custom components](custom-components.md) and manually add the `Button` as a valid type to the `controls` argument by running the following lines before your dashboard configurations:
@@ -748,3 +716,13 @@ vm.Page.add_type("controls", vm.Button)
# Add dashboard configurations below
...
```
+
+[button]: ../../assets/user_guides/components/button.png
+[buttontext]: ../../assets/user_guides/components/button_text.png
+[card]: ../../assets/user_guides/components/card.png
+[cardicon]: ../../assets/user_guides/components/card_icon.png
+[cardimagedefault]: ../../assets/user_guides/components/card_image_default.png
+[cardimagefloating]: ../../assets/user_guides/components/card_image_floating.png
+[cardimagestyled]: ../../assets/user_guides/components/card_image_styled.png
+[cardtext]: ../../assets/user_guides/components/card_text.png
+[navcard]: ../../assets/user_guides/components/nav_card.png
diff --git a/vizro-core/docs/pages/user-guides/components.md b/vizro-core/docs/pages/user-guides/components.md
index 106bf6a0b..45ea5a123 100755
--- a/vizro-core/docs/pages/user-guides/components.md
+++ b/vizro-core/docs/pages/user-guides/components.md
@@ -1,8 +1,6 @@
# Components
-The [`Page`][vizro.models.Page] model accepts the `components` argument, where you can enter any of the components
-listed below to fill your dashboard with visuals.
-
+The [`Page`][vizro.models.Page] model accepts the `components` argument, where you can enter any of the components listed below to fill your dashboard with visuals.
@@ -38,7 +36,6 @@ listed below to fill your dashboard with visuals.
[:octicons-arrow-right-24: View user guide](card-button.md)
-
- :octicons-table-16:{ .lg .middle } __Containers__
---
diff --git a/vizro-core/docs/pages/user-guides/container.md b/vizro-core/docs/pages/user-guides/container.md
index c7e327c5f..2f379709e 100755
--- a/vizro-core/docs/pages/user-guides/container.md
+++ b/vizro-core/docs/pages/user-guides/container.md
@@ -2,30 +2,22 @@
This guide shows you how to use containers to group your components into sections and subsections within the page.
-A [`Container`][vizro.models.Container] complements the idea of a [`Page`][vizro.models.Page], and the two models have almost identical arguments.
- [`Page.layout`](layouts.md) offers a way to structure the overall layout of the page, and a `Container` enables more granular control within a specific section of that page.
+A [`Container`][vizro.models.Container] complements the idea of a [`Page`][vizro.models.Page], and the two models have almost identical arguments. [`Page.layout`](layouts.md) offers a way to structure the overall layout of the page, and a `Container` enables more granular control within a specific section of that page.
-While there is currently no clear difference in rendering, extra functionality will be added to the `Container` soon (including controls specific to that container),
-enhancing the ability to manage related components.
+While there is currently no clear difference in rendering, extra functionality will be added to the `Container` soon (including controls specific to that container), enhancing the ability to manage related components.
!!! note "Displaying multiple containers inside Tabs"
-
An alternative way to display multiple containers on one page is to place them inside [Tabs](tabs.md).
- [`Tabs`][vizro.models.Tabs] organize and separate groups of related content in a dashboard, letting users switch between different sections or views.
- They are a way of putting multiple containers into the same screen space, and letting the user switch between them.
+ [`Tabs`][vizro.models.Tabs] organize and separate groups of related content in a dashboard, letting users switch between different sections or views. They are a way of putting multiple containers into the same screen space, and letting the user switch between them.
![tabs](../../assets/user_guides/components/tabs-info.png){ width="500" }
-
-
## When to use containers
-In general, any arbitrarily granular layout can already be achieved by [using `Page.layout`](layouts.md) alone and is our
-recommended approach if you want to arrange components on a page with consistent row and/or column spacing.
-`Page.layout` has a `grid` argument that sets the overall layout of the page.
-`Container.layout` also has a `grid` argument. This enables you to insert a further `grid` into a component's space on the page,
-enabling more granular control by breaking the overall page grid into subgrids.
+In general, any arbitrarily granular layout can already be achieved by [using `Page.layout`](layouts.md) alone and is our recommended approach if you want to arrange components on a page with consistent row and/or column spacing.
+
+`Page.layout` has a `grid` argument that sets the overall layout of the page. `Container.layout` also has a `grid` argument. This enables you to insert a further `grid` into a component's space on the page, enabling more granular control by breaking the overall page grid into subgrids.
Here are a few cases where you might want to use a `Container` instead of `Page.layout`:
@@ -34,14 +26,14 @@ Here are a few cases where you might want to use a `Container` instead of `Page.
- If you want different row and column spacing between subgrids
- If you want to apply controls to selected subgrids (will be supported soon)
-
## Basic containers
+
To add a [`Container`][vizro.models.Container] to your page, do the following:
1. Insert the `Container` into the `components` argument of the [`Page`][vizro.models.Page]
-2. Set a `title` for your `Container`
-3. Configure your `components`, [read the overview page for various options](components.md)
-4. (optional) Configure your `layout`, see [the guide on `Layout`](layouts.md)
+1. Set a `title` for your `Container`
+1. Configure your `components`, [read the overview page for various options](components.md)
+1. (optional) Configure your `layout`, see [the guide on `Layout`](layouts.md)
!!! example "Container"
=== "app.py"
@@ -105,7 +97,7 @@ To add a [`Container`][vizro.models.Container] to your page, do the following:
```
1. Note that the `Page.layout` argument is not specified here and will therefore defaults to `[[0], [1]]`, meaning the containers will be **vertically stacked** down the page in one column.
- 2. **Horizontally stack** the components side-by-side inside this `Container` in one row.
+ 1. **Horizontally stack** the components side-by-side inside this `Container` in one row.
=== "app.yaml"
```yaml
@@ -149,27 +141,20 @@ To add a [`Container`][vizro.models.Container] to your page, do the following:
title: Container II
title: Containers
```
- === "Result"
- [![Container]][Container]
- [Container]: ../../assets/user_guides/components/containers.png
+ === "Result"
+ [![Container]][container]
Note that an almost identical layout can also be achieved using solely the [`Page.layout`](layouts.md) by configuring the `Page.layout` as `vm.Layout(grid = [[0, 1], [2, 2]])`.
## Nested containers
-Containers can be nested, providing a hierarchical structure for organizing components.
-This nesting capability enables users to create more complex layouts and manage related components at any level of granularity.
+
+Containers can be nested, providing a hierarchical structure for organizing components. This nesting capability enables users to create more complex layouts and manage related components at any level of granularity.
To create nested containers, add a `Container` to the `components` argument of another `Container`.
```python title="Example"
-vm.Container(
- title="Parent Container",
- components=[
- vm.Container(
- title="Child Container",
- components=[vm.Button()]
- )
- ]
-)
+vm.Container(title="Parent Container", components=[vm.Container(title="Child Container", components=[vm.Button()])])
```
+
+[container]: ../../assets/user_guides/components/containers.png
diff --git a/vizro-core/docs/pages/user-guides/custom-actions.md b/vizro-core/docs/pages/user-guides/custom-actions.md
index e5fa3afd8..2fb66cd2c 100644
--- a/vizro-core/docs/pages/user-guides/custom-actions.md
+++ b/vizro-core/docs/pages/user-guides/custom-actions.md
@@ -1,17 +1,16 @@
# How to create custom actions
-This guide demonstrates the usage of custom actions, an idea that shares similarities with, but is not identical to [callbacks](https://dash.plotly.com/basic-callbacks) in `Dash`.
-If you want to use the [`Action`][vizro.models.Action] model to perform functions that are not available in the [pre-defined action functions][vizro.actions], you can create your own custom action.
-Like other [actions](actions.md), custom actions could also be added as an element inside the [actions chain](actions.md#chain-actions), and it can be triggered with one of many dashboard components.
+This guide demonstrates the usage of custom actions, an idea that shares similarities with, but is not identical to [callbacks](https://dash.plotly.com/basic-callbacks) in `Dash`. If you want to use the [`Action`][vizro.models.Action] model to perform functions that are not available in the [pre-defined action functions][vizro.actions], you can create your own custom action. Like other [actions](actions.md), custom actions could also be added as an element inside the [actions chain](actions.md#chain-actions), and it can be triggered with one of many dashboard components.
+
## Simple custom action
Custom actions enable you to implement your own action function. Simply do the following:
1. define a function
-2. decorate it with the `@capture("action")` decorator
-3. add it as a `function` argument inside the [`Action`][vizro.models.Action] model
+1. decorate it with the `@capture("action")` decorator
+1. add it as a `function` argument inside the [`Action`][vizro.models.Action] model
The following example shows how to create a custom action that postpones execution of the next action in the chain for `t` seconds.
@@ -58,27 +57,24 @@ The following example shows how to create a custom action that postpones executi
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
- ```yaml
- # Custom actions are currently only possible via Python configuration
- ```
-
+ Custom actions are currently only possible via Python configuration.
+
## Interact with inputs and outputs
+
When a custom action needs to interact with the dashboard, it is possible to define `inputs` and `outputs` for the custom action.
-- `inputs` represents dashboard component properties whose values are passed to the custom action function as arguments.
-It is a list of strings in the format `"."` (for example, `"my_selector.value`").
-- `outputs` represents dashboard component properties corresponding to the custom action function return value(s).
-Similar to `inputs`, it is a list of strings in the format `"."` (for example, `"my_card.children"`).
+- `inputs` represents dashboard component properties whose values are passed to the custom action function as arguments. It is a list of strings in the format `"."` (for example, `"my_selector.value`").
+- `outputs` represents dashboard component properties corresponding to the custom action function return value(s). Similar to `inputs`, it is a list of strings in the format `"."` (for example, `"my_card.children"`).
### Example of `value` as input
-The following example shows a custom action that takes the `value` of the `vm.RadioItem` and returns it inside a
-[`Card`][vizro.models.Card] component.
-!!! example "Display `value` in Card"
+The following example shows a custom action that takes the `value` of the `vm.RadioItem` and returns it inside a [`Card`][vizro.models.Card] component.
+!!! example "Display `value` in Card"
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -113,23 +109,18 @@ The following example shows a custom action that takes the `value` of the `vm.Ra
dashboard = vm.Dashboard(pages=[page])
Vizro().build(dashboard).run()
```
- === "app.yaml"
- ```yaml
- # Custom actions are currently only possible via Python configuration
- ```
- === "Result"
- [![ValueAction]][ValueAction]
- [ValueAction]: ../../assets/user_guides/custom_actions/value_as_input.png
+ === "app.yaml"
+ Custom actions are currently only possible via Python configuration.
+ === "Result"
+ [![ValueAction]][valueaction]
### Example of `clickData` as input
-The following example shows how to create a custom action that shows the `clickData` of a chart in a
-[`Card`][vizro.models.Card] component. For further information on the structure and content of the `clickData`
-property, refer to the Dash documentation on [interactive visualizations](https://dash.plotly.com/interactive-graphing).
-!!! example "Display `clickData` in Card"
+The following example shows how to create a custom action that shows the `clickData` of a chart in a [`Card`][vizro.models.Card] component. For further information on the structure and content of the `clickData` property, refer to the Dash documentation on [interactive visualizations](https://dash.plotly.com/interactive-graphing).
+!!! example "Display `clickData` in Card"
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -173,21 +164,18 @@ property, refer to the Dash documentation on [interactive visualizations](https:
```
1. Just as for any Python function, the names of the arguments `show_species` and `points_data` are arbitrary and do not need to match on to the names of `inputs` in any particular way.
- 2. We _bind_ (set) the argument `show_species` to the value `True` in the initial specification of the `function` field. These are static values that are fixed when the dashboard is _built_.
- 3. The content of `inputs` will "fill in the gaps" by setting values for the remaining unbound arguments in `my_custom_action`. Here there is one such argument, named `points_data`. Values for these are bound _dynamically at runtime_ to reflect the live state of your dashboard.
+ 1. We _bind_ (set) the argument `show_species` to the value `True` in the initial specification of the `function` field. These are static values that are fixed when the dashboard is _built_.
+ 1. The content of `inputs` will "fill in the gaps" by setting values for the remaining unbound arguments in `my_custom_action`. Here there is one such argument, named `points_data`. Values for these are bound _dynamically at runtime_ to reflect the live state of your dashboard.
+
=== "app.yaml"
- ```yaml
- # Custom actions are currently only possible via Python configuration
- ```
- === "Result"
- [![CustomAction]][CustomAction]
+ Custom actions are currently only possible via Python configuration.
- [CustomAction]: ../../assets/user_guides/custom_actions/clickdata_as_input.png
+ === "Result"
+ [![CustomAction]][customaction]
## Multiple return values
-The return value of the custom action function is propagated to the dashboard components that are defined in the `outputs` argument of the [`Action`][vizro.models.Action] model.
-If there is a single `output` defined then the function return value is directly assigned to the component property.
-If there are multiple `outputs` defined then the return value is iterated through and each part is assigned to each component property given in `outputs` in turn. This behavior is identical to Python's flexibility in managing multiple return values.
+
+The return value of the custom action function is propagated to the dashboard components that are defined in the `outputs` argument of the [`Action`][vizro.models.Action] model. If there is a single `output` defined then the function return value is directly assigned to the component property. If there are multiple `outputs` defined then the return value is iterated through and each part is assigned to each component property given in `outputs` in turn. This behavior is identical to Python's flexibility in managing multiple return values.
!!! example "Multiple return values"
=== "app.py"
@@ -246,17 +234,17 @@ If there are multiple `outputs` defined then the return value is iterated throug
```
1. `my_custom_action` returns two values (which will be in Python tuple).
- 2. These values are assigned to the `outputs` in the same order.
- === "app.yaml"
- ```yaml
- # Custom actions are currently only possible via Python configuration
- ```
- === "Result"
- [![CustomAction2]][CustomAction2]
+ 1. These values are assigned to the `outputs` in the same order.
- [CustomAction2]: ../../assets/user_guides/custom_actions/custom_action_multiple_return_values.png
+ === "app.yaml"
+ Custom actions are currently only possible via Python configuration.
+ === "Result"
+ [![CustomAction2]][customaction2]
!!! warning
+ Note that users of this package are responsible for the content of any custom action function that they write. Take care to avoid leaking any sensitive information or exposing to any security threat during implementation. You should always [treat the content of user input as untrusted](https://community.plotly.com/t/writing-secure-dash-apps-community-thread/54619).
- Note that users of this package are responsible for the content of any custom action function that they write - especially with regard to leaking any sensitive information or exposing to any security threat during implementation. You should always [treat the content of user input as untrusted](https://community.plotly.com/t/writing-secure-dash-apps-community-thread/54619).
+[customaction]: ../../assets/user_guides/custom_actions/clickdata_as_input.png
+[customaction2]: ../../assets/user_guides/custom_actions/custom_action_multiple_return_values.png
+[valueaction]: ../../assets/user_guides/custom_actions/value_as_input.png
diff --git a/vizro-core/docs/pages/user-guides/custom-charts.md b/vizro-core/docs/pages/user-guides/custom-charts.md
index cb26614c8..1b77d0869 100644
--- a/vizro-core/docs/pages/user-guides/custom-charts.md
+++ b/vizro-core/docs/pages/user-guides/custom-charts.md
@@ -1,9 +1,9 @@
# How to create custom charts
-This guide shows you how to create custom charts and how to add them to your dashboard.
-The [`Graph`][vizro.models.Graph] model accepts the `figure` argument, where you can enter _any_ [`plotly.express`](https://plotly.com/python/plotly-express/) chart as explained in the [user guide on graphs](graph.md).
+This guide shows you how to create custom charts and how to add them to your dashboard. The [`Graph`][vizro.models.Graph] model accepts the `figure` argument, where you can enter _any_ [`plotly.express`](https://plotly.com/python/plotly-express/) chart as explained in the [user guide on graphs](graph.md).
## When to use a custom chart
+
In general, you should use the custom chart decorator `@capture("graph")` if your plotly chart needs any post-update calls or customization. For example:
- You want to use any of the post figure update calls by `plotly` such as `update_layout`, `update_xaxes`, `update_traces` (for more details, see the docs on [plotly's update calls](https://plotly.com/python/creating-and-updating-figures/#other-update-methods))
@@ -12,11 +12,10 @@ In general, you should use the custom chart decorator `@capture("graph")` if you
## Steps to create a custom chart
1. Define a function that returns a `go.Figure()`.
-2. Decorate it with `@capture("graph")`.
-3. The function must accept a `data_frame` argument (of type `pandas.DataFrame`).
-4. The visualization should be derived from and require only one `pandas.DataFrame`. Dataframes from other arguments
-will not react to dashboard controls such as [`Filter`](filters.md).
-5. Pass your function to the `figure` argument of the [`Graph`][vizro.models.Graph] model.
+1. Decorate it with `@capture("graph")`.
+1. The function must accept a `data_frame` argument (of type `pandas.DataFrame`).
+1. The visualization should be derived from and require only one `pandas.DataFrame`. Dataframes from other arguments will not react to dashboard controls such as [`Filter`](filters.md).
+1. Pass your function to the `figure` argument of the [`Graph`][vizro.models.Graph] model.
The minimal example below can be used as a base to build more sophisticated charts.
@@ -39,12 +38,10 @@ To alter the data in the `data_frame` argument, consider using a [Filter](filter
## Enhanced `plotly.express` chart with reference line
-The below examples shows a case where we enhance an existing `plotly.express` chart. We add a new argument (`hline`), that is used to draw a grey reference line at the height determined by the value of `hline`. The important thing to note is that we then
-add a `Parameter` that enables the dashboard user to interact with the argument, and hence move the line in this case. See the `Result` tab for an animation.
+The below examples shows a case where we enhance an existing `plotly.express` chart. We add a new argument (`hline`), that is used to draw a grey reference line at the height determined by the value of `hline`. The important thing to note is that we then add a `Parameter` that enables the dashboard user to interact with the argument, and hence move the line in this case. See the `Result` tab for an animation.
!!! example "Custom `plotly.express` scatter chart with a `Parameter`"
=== "app.py"
-
```{.python pycafe-link}
import vizro.models as vm
import vizro.plotly.express as px
@@ -86,17 +83,14 @@ add a `Parameter` that enables the dashboard user to interact with the argument,
Vizro().build(dashboard).run()
```
- 1. Note that arguments of the custom chart can be parametrized. Here we choose to parametrize the `hline` argument (see below).
- 2. Here we parametrize the `hline` argument, but any other argument can be parametrized as well. Since there is complete flexibility regarding what can be derived from such arguments, the dashboard user has a wide range of customization options.
- === "app.yaml"
- ```yaml
- # Custom charts are currently only possible via Python configuration
- ```
- === "Result"
- [![Graph2]][Graph2]
+ 1. Note that arguments of the custom chart can be parametrized. Here we choose to parametrize the `hline` argument (see below).
+ 1. Here we parametrize the `hline` argument, but any other argument can be parametrized as well. Since there is complete flexibility regarding what can be derived from such arguments, the dashboard user has a wide range of customization options.
- [Graph2]: ../../assets/user_guides/custom_charts/custom_chart_showcase_parameter.gif
+ === "app.yaml"
+ Custom charts are currently only possible via Python configuration.
+ === "Result"
+ [![Graph2]][graph2]
## New Waterfall chart based on `go.Figure()`
@@ -104,7 +98,6 @@ The below examples shows a more involved use-case. We create and style a waterfa
!!! example "Custom `go.Figure()` waterfall chart with a `Parameter`"
=== "app.py"
-
```{.python pycafe-link}
import pandas as pd
import plotly.graph_objects as go
@@ -162,10 +155,10 @@ The below examples shows a more involved use-case. We create and style a waterfa
```
=== "app.yaml"
- ```yaml
- # Custom charts are currently only possible via Python configuration
- ```
+ Custom charts are currently only possible via Python configuration.
+
=== "Result"
- [![Graph3]][Graph3]
+ [![Graph3]][graph3]
- [Graph3]: ../../assets/user_guides/custom_charts/custom_chart_waterfall.png
+[graph2]: ../../assets/user_guides/custom_charts/custom_chart_showcase_parameter.gif
+[graph3]: ../../assets/user_guides/custom_charts/custom_chart_waterfall.png
diff --git a/vizro-core/docs/pages/user-guides/custom-css.md b/vizro-core/docs/pages/user-guides/custom-css.md
index dd2d22275..d5bc5f7dc 100755
--- a/vizro-core/docs/pages/user-guides/custom-css.md
+++ b/vizro-core/docs/pages/user-guides/custom-css.md
@@ -1,25 +1,20 @@
# Customizing Vizro dashboard CSS
-Vizro is opinionated about visual formatting, and some elements, such as the layout of the navigation and controls,
-are fixed. You can customize some settings such as background colors, fonts, and other styles via CSS overrides.
+Vizro is opinionated about visual formatting, and some elements, such as the layout of the navigation and controls, are fixed. You can customize some settings such as background colors, fonts, and other styles via CSS overrides.
To make customizations, you need to:
1. **Add a CSS file to your `assets` folder**. Refer to our user guide on [adding static assets](assets.md#how-to-add-static-assets).
-2. **Identify the correct CSS selector** for the component you want to style.
-3. **Change the relevant CSS properties** in your CSS file.
-
-
+1. **Identify the correct CSS selector** for the component you want to style.
+1. **Change the relevant CSS properties** in your CSS file.
## Introduction to Vizro CSS
+
For a short introduction to CSS, we recommend reading this article: [Get Started with CSS in 5 Minutes](https://www.freecodecamp.org/news/get-started-with-css-in-5-minutes-e0804813fc3e/).
-For a more comprehensive tutorial, refer to the [W3Schools CSS tutorial](https://www.w3schools.com/css/default.asp).
-The entire tutorial is beneficial, but the section on [CSS selectors](https://www.w3schools.com/css/css_selectors.asp)
-will be particularly useful.
+For a more comprehensive tutorial, refer to the [W3Schools CSS tutorial](https://www.w3schools.com/css/default.asp). The entire tutorial is beneficial, but the section on [CSS selectors](https://www.w3schools.com/css/css_selectors.asp) will be particularly useful.
-In Vizro, the CSS file is read in as an external stylesheet. The most common way of applying any styling to
-Vizro is therefore through the use of CSS selectors:
+In Vizro, the CSS file is read in as an external stylesheet. The most common way of applying any styling to Vizro is therefore through the use of CSS selectors:
- **Element Selector**: Applies the style to all elements inside the Vizro app.
@@ -33,8 +28,7 @@ Vizro is therefore through the use of CSS selectors:
}
```
-- **Class selector:** Targets all elements with the given class for styling. All CSS classes must be preceded with a
-`.` symbol.
+- **Class selector:** Targets all elements with the given class for styling. All CSS classes must be preceded with a `.` symbol.
```
.card {
@@ -50,30 +44,25 @@ Vizro is therefore through the use of CSS selectors:
}
```
-
## Identify the correct CSS selector
Use Chrome DevTools or a similar tool (Web Inspector, Web Developer Tools, etc.) to inspect the HTML document in your browser.
-1. **Open DevTools:** In Google Chrome, right-click on the app and select "Inspect" from the context menu. This opens the
-HTML document of your Vizro app.
+1. **Open DevTools:** In Google Chrome, right-click on the app and select "Inspect" from the context menu. This opens the HTML document of your Vizro app.
![Inspect panel](../../assets/user_guides/custom_css/inspect-panel.png)
-
-2. **Select an element:** Suppose you want to change the background color of your cards. Click the
-"Select an element in the page to inspect it" icon in the top left corner of the inspect panel.
+1. **Select an element:** Suppose you want to change the background color of your cards. Click the "Select an element in the page to inspect it" icon in the top left corner of the inspect panel.
![Inspect icon](../../assets/user_guides/custom_css/inspect-icon.png)
-3. **Find the HTML Block:** Hover over the component you want to style. The corresponding HTML block will be
-highlighted in the HTML document.
+1. **Find the HTML Block:** Hover over the component you want to style. The corresponding HTML block will be highlighted in the HTML document.
![Highlighted element](../../assets/user_guides/custom_css/highlighted-element.png)
Notice that the selected HTML block corresponds to the container of the card and has a CSS class, here it is `card`.
-4. **Apply CSS:** Use this CSS class to style the card component. In your CSS file, you can write:
+1. **Apply CSS:** Use this CSS class to style the card component. In your CSS file, you can write:
```
.card {
@@ -83,25 +72,25 @@ highlighted in the HTML document.
This changes the background color for any HTML element with the `card` class.
-**Tip:** You can also test your CSS live by editing the CSS attributes in the "Elements" panel.
-For example, temporarily add `background: blue;`. Note that this change will be lost upon reloading the page.
+**Tip:** You can also test your CSS live by editing the CSS attributes in the "Elements" panel. For example, temporarily add `background: blue;`. Note that this change will be lost upon reloading the page.
![Temporary changes](../../assets/user_guides/custom_css/temporary-changes.png)
-
## CSS overwrites
### Overwrite CSS globally
-To overwrite any global CSS property, you need to target the element selector and place your CSS file with the
-overwrites in the `assets` folder.
+
+To overwrite any global CSS property, you need to target the element selector and place your CSS file with the overwrites in the `assets` folder.
!!! example "Overwrite CSS globally"
=== "my_css_file.css"
- ```css
- h1, h2 {
- color: hotpink;
- }
- ```
+ ```css
+ h1,
+ h2 {
+ color: hotpink;
+ }
+ ```
+
=== "app.py"
```py
import os
@@ -134,44 +123,41 @@ overwrites in the `assets` folder.
# Still requires a .py to add data to the data manager and parse YAML configuration
# See yaml_version example
pages:
- - components:
- - text: |
- # This is an
tag
+ - components:
+ - text: |
+ # This is an
tag
- ## This is an
tag
+ ## This is an
tag
- ###### This is an
tag
- type: card
- title: Changing the header color
+ ###### This is an
tag
+ type: card
+ title: Changing the header color
```
- === "Result"
- [![AssetsCSS]][AssetsCSS]
-
- [AssetsCSS]: ../../assets/user_guides/assets/css_change.png
+ === "Result"
+ [![AssetsCSS]][assetscss]
### Overwrite CSS for selected pages
-To style components for a specific page, use the page's `id` in the CSS selectors. By default, this is the
-[same as the page `title`](pages.md), but such a value might not be a valid CSS identifier.
-A suitable `id` must be unique across all models in the dashboard and should contain only alphanumeric
-characters, hyphens (`-`) and underscores (`_`). In particular, note that spaces are _not_ allowed.
+To style components for a specific page, use the page's `id` in the CSS selectors. By default, this is the [same as the page `title`](pages.md), but such a value might not be a valid CSS identifier.
+
+A suitable `id` must be unique across all models in the dashboard and should contain only alphanumeric characters, hyphens (`-`) and underscores (`_`). In particular, note that spaces are _not_ allowed.
Suppose you want to hide the page title on one page only. Here's how you can achieve this:
1. Give a valid `id` to the `Page`, for example `Page(id="page-with-hidden-title", title="Page with hidden title", ...)`.
-2. Identify the CSS class or CSS `id` you need to target. To hide the page title, you need to hide the parent container with the id `right-header`.
-3. Use the `id` to hide the content.
-4. Add your custom css file to the `assets` folder.
-
+1. Identify the CSS class or CSS `id` you need to target. To hide the page title, you need to hide the parent container with the id `right-header`.
+1. Use the `id` to hide the content.
+1. Add your custom css file to the `assets` folder.
!!! example "Hide page title on selected pages"
=== "my_css_file.css"
- ```css
- #page-with-hidden-title #right-header {
- display: none;
- }
- ```
+ ```css
+ #page-with-hidden-title #right-header {
+ display: none;
+ }
+ ```
+
=== "app.py"
```py
import vizro.models as vm
@@ -199,25 +185,24 @@ Suppose you want to hide the page title on one page only. Here's how you can ach
# Still requires a .py to add data to the data manager and parse YAML configuration
# See yaml_version example
pages:
- - components:
- - text: |
- # Placeholder
- type: card
- title: Page with hidden title
- id: page-with-hidden-title
- - components:
- - text: |
- # Placeholder
- type: card
- title: Page with shown title
+ - components:
+ - text: |
+ # Placeholder
+ type: card
+ title: Page with hidden title
+ id: page-with-hidden-title
+ - components:
+ - text: |
+ # Placeholder
+ type: card
+ title: Page with shown title
```
- === "Result"
- [![PageTitle]][PageTitle]
-
- [PageTitle]: ../../assets/user_guides/assets/css_page_title.png
+ === "Result"
+ [![PageTitle]][pagetitle]
### Overwrite CSS for selected components
+
To adjust CSS properties for specific components, such as altering the appearance of a selected [`Card`][vizro.models.Card] rather than all Cards, you need to supply an `id` to the component you want to style.
Let's say we want to change the `background-color` and `color` of a specific `Card`.
@@ -225,41 +210,43 @@ Let's say we want to change the `background-color` and `color` of a specific `Ca
Here's how you can do it:
1. Assign a unique `id` to the relevant `Card`, for example: `Card(id="custom-card", ...)`
-2. Run your dashboard and open it in your browser
-3. View the HTML document to find the appropriate CSS class or element you need to target, as explained in the section
-on [identifying the correct CSS selector](#identify-the-correct-css-selector).
+1. Run your dashboard and open it in your browser
+1. View the HTML document to find the appropriate CSS class or element you need to target, as explained in the section on [identifying the correct CSS selector](#identify-the-correct-css-selector).
-It's essential to understand the relationship between the targeted CSS class or element and the component assigned
-`id`, for example:
+It's essential to understand the relationship between the targeted CSS class or element and the component assigned `id`, for example:
-```html title="HTML structure of a `Card`"
+
+```html title="HTML structure of a card"
-
-
Lorem ipsum dolor sit amet consectetur adipisicing elit.
-
+
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+
+
```
-
-* **Main element with `id`:** There is a `
` with our `id="custom-card"`.
-* **Parent element:** That `
` is wrapped inside a parent `
` with the class name `"card"`. This is the element we need to target to change the background color.
-* **Child element:** The card text is wrapped inside a `
` that is a child of the `
` with our `id`. This is the element we need to target to change the font color.
+
+- **Main element with `id`:** There is a `
` with our `id="custom-card"`.
+- **Parent element:** That `
` is wrapped inside a parent `
` with the class name `"card"`. This is the element we need to target to change the background color.
+- **Child element:** The card text is wrapped inside a `
` that is a child of the `
` with our `id`. This is the element we need to target to change the font color.
!!! example "Customizing CSS properties in selective components"
=== "my_css_file.css"
- ```css
- /* Apply styling to parent */
- .card:has(#custom-card) {
- background-color: white;
- }
+ ```css
+ /* Apply styling to parent */
+ .card:has(#custom-card) {
+ background-color: white;
+ }
+
+ /* Apply styling to child */
+ #custom-card p {
+ color: black;
+ }
+ ```
- /* Apply styling to child */
- #custom-card p {
- color: black;
- }
- ```
=== "app.py"
```py
import vizro.models as vm
@@ -285,77 +272,65 @@ It's essential to understand the relationship between the targeted CSS class or
# Still requires a .py to add data to the data manager and parse YAML configuration
# See yaml_version example
pages:
- - components:
- - text: |
- Lorem ipsum dolor sit amet consectetur adipisicing elit.
- type: card
- id: custom-card
- - text: |
- Lorem ipsum dolor sit amet consectetur adipisicing elit.
- type: card
- title: Changing the card color
+ - components:
+ - text: |
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+ type: card
+ id: custom-card
+ - text: |
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+ type: card
+ title: Changing the card color
```
- === "Result"
- [![CardCSS]][CardCSS]
-
- [CardCSS]: ../../assets/user_guides/assets/css_change_card.png
+ === "Result"
+ [![CardCSS]][cardcss]
!!! note "Relationship between model ID and CSS ID"
+ Some Vizro components produce a single HTML element with an ID that matches the model ID, allowing you to target it directly using the CSS #id selector. Other components generate multiple HTML elements. Within these, the "core" element will have an ID matching the model ID, while non-core elements may have IDs that are variations of it, such as `{model-id}-title`.
- Some Vizro components produce a single HTML element with an ID that matches the model ID, allowing you to target it
- directly using the CSS #id selector. Other components generate multiple HTML elements. Within these, the "core"
- element will have an ID matching the model ID, while non-core elements may have IDs that are variations of it,
- such as `{model-id}-title`.
-
- In all instances, you can determine the correct selector by using Chrome DevTools or a similar tool after setting the
- appropriate model ID.
-
+ In all instances, you can determine the correct selector by using Chrome DevTools or a similar tool after setting the appropriate model ID.
## Common examples
### Make your CSS responsive to theme switches with variables
-To ensure your CSS adapts to theme changes, we recommend using CSS variables (`var`) whenever possible. For a
-comprehensive list of available variable names, refer to the
-[Bootstrap documentation](https://getbootstrap.com/docs/5.3/customize/css-variables/). Note that our
-Bootstrap stylesheet is still under development, so not all Bootstrap variables are currently available.
-Additionally, you can define your own CSS variables, as demonstrated in the example on
-[changing the container background color](#change-the-styling-of-a-container).
+
+To ensure your CSS adapts to theme changes, we recommend using CSS variables (`var`) whenever possible. For a comprehensive list of available variable names, refer to the [Bootstrap documentation](https://getbootstrap.com/docs/5.3/customize/css-variables/). Note that our Bootstrap stylesheet is still under development, so not all Bootstrap variables are currently available. Additionally, you can define your own CSS variables, as demonstrated in the example on [changing the container background color](#change-the-styling-of-a-container).
### Turn off page title
+
See the example above on [hiding the page title on selected pages](#overwrite-css-for-selected-pages).
### Change the background color of a card
+
See the example above on [customizing CSS properties in selective components](#overwrite-css-for-selected-components).
### Change the global font
+
The default fonts for a Vizro app are `Inter, sans-serif, Arial, serif`.
If you need to change the global font, perhaps to adhere to branding guidelines, follow these steps:
1. Download the desired font from a font provider such as [Google Fonts](https://fonts.google.com/).
-2. Place the font file (`.ttf`, `woff2`, etc.) into your `assets` folder. Here’s an example of what the assets folder might look like:
- ![Font Change](../../assets/user_guides/custom_css/font-change.png)
+1. Place the font file (`.ttf`, `woff2`, etc.) into your `assets` folder. Here’s an example of what the assets folder might look like:
-3. Add the font to your CSS file using the `@font-face` rule and apply the font globally to your Vizro app, making sure
-to specify fallback fonts. Add the following to your `custom.css` file:
+ ![Font Change](../../assets/user_guides/custom_css/font-change.png)
+1. Add the font to your CSS file using the `@font-face` rule and apply the font globally to your Vizro app, making sure to specify fallback fonts. Add the following to your `custom.css` file:
```css
@font-face {
- font-family: PlayfairDisplay;
- src: url("PlayfairDisplay-VariableFont_wght.ttf") format("truetype");
+ font-family: PlayfairDisplay;
+ src: url("PlayfairDisplay-VariableFont_wght.ttf") format("truetype");
}
* {
- font-family: PlayfairDisplay, Inter, sans-serif, Arial, serif;
+ font-family: PlayfairDisplay, Inter, sans-serif, Arial, serif;
}
```
-
-4. Note that the modification above applies solely to the dashboard font. To also change the font within the
-Plotly charts, you must specify this at the beginning of your `app.py` file:
+1. Note that the modification above applies solely to the dashboard font. To also change the font within the Plotly charts, you must specify this at the beginning of your `app.py` file:
```python
import plotly.io as pio
@@ -365,44 +340,42 @@ Plotly charts, you must specify this at the beginning of your `app.py` file:
```
### Reposition the logo
-By default, the logo appears in the top left corner of the dashboard. You can move it further to the left or right by
-adjusting the `padding` of the `#page-header` element. Here is an example of how to achieve this:
+
+By default, the logo appears in the top left corner of the dashboard. You can move it further to the left or right by adjusting the `padding` of the `#page-header` element. Here is an example of how to achieve this:
```css
#page-header {
- padding-left: 8px;
+ padding-left: 8px;
}
```
![Logo positioning](../../assets/user_guides/custom_css/logo-position.png)
-
### Change the styling of a container
-If you want to make the subsections of your dashboard stand out more, you can do this by placing your components
-inside a [Container](container.md) and changing the container's styling, for example, background color, borders, padding, etc.
-To do this, you need to change the container's CSS class. Using the DevTool, as explained in the section on
-[identifying the correct CSS selector](#identify-the-correct-css-selector), you'll find that the CSS class for the
-`Container` is `page-component-container`. You can then use this class to set a new `background-color` and `padding`.
+If you want to make the subsections of your dashboard stand out more, you can do this by placing your components inside a [Container](container.md) and changing the container's styling, for example, background color, borders, padding, etc.
+
+To do this, you need to change the container's CSS class. Using the DevTool, as explained in the section on [identifying the correct CSS selector](#identify-the-correct-css-selector), you'll find that the CSS class for the `Container` is `page-component-container`. You can then use this class to set a new `background-color` and `padding`.
!!! example "Style a container"
=== "custom.css"
- ```css
- /* Assign a variable to the dark and light theme */
- [data-bs-theme="dark"] {
- --container-bg-color: #232632;
- }
-
- [data-bs-theme="light"] {
- --container-bg-color: #F5F6F6;
- }
+ ```css
+ /* Assign a variable to the dark and light theme */
+ [data-bs-theme="dark"] {
+ --container-bg-color: #232632;
+ }
+
+ [data-bs-theme="light"] {
+ --container-bg-color: #F5F6F6;
+ }
+
+ /* Use the custom variable var(--container-bg-color) */
+ .page-component-container {
+ background: var(--container-bg-color);
+ padding: 12px;
+ }
+ ```
- /* Use the custom variable var(--container-bg-color) */
- .page-component-container {
- background: var(--container-bg-color);
- padding: 12px;
- }
- ```
=== "app.py"
```py
import vizro.models as vm
@@ -437,12 +410,12 @@ To do this, you need to change the container's CSS class. Using the DevTool, as
# Still requires a .py to add data to the data manager and parse YAML configuration
# See yaml_version example
pages:
- - title: "Page with subsections"
+ - title: Page with subsections
layout:
grid: [[0, 1]]
components:
- type: container
- title: "Container I"
+ title: Container I
components:
- type: graph
figure:
@@ -452,7 +425,7 @@ To do this, you need to change the container's CSS class. Using the DevTool, as
y: sepal_length
color: species
- type: container
- title: "Container II"
+ title: Container II
components:
- type: graph
figure:
@@ -462,13 +435,11 @@ To do this, you need to change the container's CSS class. Using the DevTool, as
y: sepal_length
color: species
```
- === "Result"
- [![StyleContainer]][StyleContainer]
- [StyleContainer]: ../../assets/user_guides/custom_css/style-container.png
+ === "Result"
+ [![StyleContainer]][stylecontainer]
-You will notice that the background colors of the charts are different. To align it with the colors of the container,
-you can make the charts' background transparent.
+You will notice that the background colors of the charts are different. To align it with the colors of the container, you can make the charts' background transparent.
To make the background of all charts transparent:
@@ -492,3 +463,8 @@ def custom_chart(data_frame):
```
![Transparent charts](../../assets/user_guides/custom_css/transparent-charts.png)
+
+[assetscss]: ../../assets/user_guides/assets/css_change.png
+[cardcss]: ../../assets/user_guides/assets/css_change_card.png
+[pagetitle]: ../../assets/user_guides/assets/css_page_title.png
+[stylecontainer]: ../../assets/user_guides/custom_css/style-container.png
diff --git a/vizro-core/docs/pages/user-guides/custom-figures.md b/vizro-core/docs/pages/user-guides/custom-figures.md
index f135127be..3a178932f 100644
--- a/vizro-core/docs/pages/user-guides/custom-figures.md
+++ b/vizro-core/docs/pages/user-guides/custom-figures.md
@@ -1,41 +1,36 @@
# How to create custom figures
-This guide explains how to create custom figures, which is useful when you need a component that reacts to
-[filter](filters.md) and [parameter](parameters.md) controls.
+This guide explains how to create custom figures, which is useful when you need a component that reacts to [filter](filters.md) and [parameter](parameters.md) controls.
-The [`Figure`][vizro.models.Figure] model accepts the `figure` argument, where you can enter _any_ custom figure function
-as explained in the [user guide on figures](figure.md).
+The [`Figure`][vizro.models.Figure] model accepts the `figure` argument, where you can enter _any_ custom figure function as explained in the [user guide on figures](figure.md).
## When to use a custom figure
-As described in the flowchart detailing [when to use `Figure`](figure.md), custom figures should be used if
-**both** of the following conditions are met:
+
+As described in the flowchart detailing [when to use `Figure`](figure.md), custom figures should be used if **both** of the following conditions are met:
- You need a figure that doesn't fit into the existing pre-defined components ([`Graph`][vizro.models.Graph], [`Table`][vizro.models.Table] or [`AgGrid`][vizro.models.AgGrid]).
- You need a figure that isn't available in our pre-defined figure functions [`vizro.figures`](../API-reference/figure-callables.md).
## Steps to create a custom figure
-1. Define a function that returns a [Dash component](https://dash.plotly.com/#open-source-component-libraries).
-This can, but does not need to, be based on code in our pre-defined figure functions in [`vizro.figures`](../API-reference/figure-callables.md).
-2. Decorate it with `@capture("figure")`.
-3. The function must accept a `data_frame` argument (of type `pandas.DataFrame`).
-4. The figure should be derived from and require only one `pandas.DataFrame`. Dataframes from other arguments
-will not react to dashboard controls such as [`Filter`](filters.md).
-5. Pass your function to the `figure` argument of the [`Figure`][vizro.models.Figure] model.
+1. Define a function that returns a [Dash component](https://dash.plotly.com/#open-source-component-libraries). This can, but does not need to, be based on code in our pre-defined figure functions in [`vizro.figures`](../API-reference/figure-callables.md).
+1. Decorate it with `@capture("figure")`.
+1. The function must accept a `data_frame` argument (of type `pandas.DataFrame`).
+1. The figure should be derived from and require only one `pandas.DataFrame`. Dataframes from other arguments will not react to dashboard controls such as [`Filter`](filters.md).
+1. Pass your function to the `figure` argument of the [`Figure`][vizro.models.Figure] model.
The following examples can be used as a base to build more sophisticated figures.
## Examples of custom figures
### Custom KPI card
-To change the design or content of our existing KPI (key performance indicator) cards from
-[`vizro.figures`](../API-reference/figure-callables.md), you can do so by following the steps described above.
-For instance, to make a KPI card with the icon positioned on the right side of the title instead of the left,
-copy and paste the [source code of `kpi_card`](../API-reference/figure-callables.md#vizro.figures.kpi_card) and
-adjust the return statement of the function.
+To change the design or content of our existing KPI (key performance indicator) cards from [`vizro.figures`](../API-reference/figure-callables.md), you can do so by following the steps described above.
+
+For instance, to make a KPI card with the icon positioned on the right side of the title instead of the left, copy and paste the [source code of `kpi_card`](../API-reference/figure-callables.md#vizro.figures.kpi_card) and adjust the return statement of the function.
+
!!! example "Custom KPI card"
=== "app.py"
```{.python pycafe-link}
@@ -107,29 +102,26 @@ adjust the return statement of the function.
```
1. Here we decorate our custom figure function with the `@capture("figure")` decorator.
- 2. The custom figure function needs to have a `data_frame` argument and return a `Dash` component.
- 3. We adjust the return statement to include the icon on the right side of the title. This is achieved by swapping the order of the `html.H2` and `html.P` compared to the original `kpi_card`.
- 4. This creates a [`layout`](layouts.md) with four rows and columns. The KPI cards are positioned in the first two cells, while the remaining cells are empty.
- 5. For more information, refer to the API reference for the [`kpi_card`](../API-reference/figure-callables.md#vizro.figures.kpi_card).
- 6. Our custom figure function `custom_kpi_card` now needs to be passed on to the `vm.Figure`.
+ 1. The custom figure function needs to have a `data_frame` argument and return a `Dash` component.
+ 1. We adjust the return statement to include the icon on the right side of the title. This is achieved by swapping the order of the `html.H2` and `html.P` compared to the original `kpi_card`.
+ 1. This creates a [`layout`](layouts.md) with four rows and columns. The KPI cards are positioned in the first two cells, while the remaining cells are empty.
+ 1. For more information, refer to the API reference for the [`kpi_card`](../API-reference/figure-callables.md#vizro.figures.kpi_card).
+ 1. Our custom figure function `custom_kpi_card` now needs to be passed on to the `vm.Figure`.
=== "app.yaml"
- ```yaml
- # Custom figures are currently only possible via Python configuration
- ```
- === "Result"
- [![CustomKPI]][CustomKPI]
+ Custom figures are currently only possible via Python configuration.
- [CustomKPI]: ../../assets/user_guides/figure/custom_kpi.png
+ === "Result"
+ [![CustomKPI]][customkpi]
### Dynamic HTML header
-You can create a custom figure for any [Dash component](https://dash.plotly.com/#open-source-component-libraries).
-Below is an example of a custom figure that returns a `html.H2` component that dynamically updates based on the selected
-name from a filter.
+
+You can create a custom figure for any [Dash component](https://dash.plotly.com/#open-source-component-libraries). Below is an example of a custom figure that returns a `html.H2` component that dynamically updates based on the selected name from a filter.
+
!!! example "Dynamic HTML header"
=== "app.py"
```{.python pycafe-link}
@@ -159,27 +151,24 @@ name from a filter.
```
1. Here we decorate our custom figure function with the `@capture("figure")` decorator.
- 2. The custom figure function needs to have a `data_frame` argument and return a `Dash` component.
- 3. We return a `html.H2` component that dynamically updates based on the selected name from the filter.
- 4. Our custom figure function `dynamic_html_header` now needs to be passed on to the `vm.Figure`.
+ 1. The custom figure function needs to have a `data_frame` argument and return a `Dash` component.
+ 1. We return a `html.H2` component that dynamically updates based on the selected name from the filter.
+ 1. Our custom figure function `dynamic_html_header` now needs to be passed on to the `vm.Figure`.
=== "app.yaml"
- ```yaml
- # Custom figures are currently only possible via Python configuration
- ```
- === "Result"
- [![CustomHTML]][CustomHTML]
+ Custom figures are currently only possible via Python configuration.
- [CustomHTML]: ../../assets/user_guides/figure/custom_html.png
+ === "Result"
+ [![CustomHTML]][customhtml]
-
### Dynamic number of cards
-The example below shows how to create multiple cards created from a `pandas.DataFrame` where the
-number of cards displayed dynamically adjusts based on a `vm.Parameter`.
+
+The example below shows how to create multiple cards created from a `pandas.DataFrame` where the number of cards displayed dynamically adjusts based on a `vm.Parameter`.
+
!!! example "Dynamic number of cards"
=== "app.py"
```py
@@ -239,40 +228,39 @@ number of cards displayed dynamically adjusts based on a `vm.Parameter`.
```
1. Here we decorate our custom figure function with the `@capture("figure")` decorator.
- 2. The custom figure function needs to have a `data_frame` argument and return a `Dash` component.
- 3. Our decorated figure function `multiple_cards` now needs to be passed on to the `vm.Figure`.
- 4. We add a [`vm.Parameter`](parameters.md) to dynamically adjust the number of cards displayed.
- The parameter targets the `n_rows` argument of the `multiple_cards` function, determining the number of rows
- taken from the data.
+ 1. The custom figure function needs to have a `data_frame` argument and return a `Dash` component.
+ 1. Our decorated figure function `multiple_cards` now needs to be passed on to the `vm.Figure`.
+ 1. We add a [`vm.Parameter`](parameters.md) to dynamically adjust the number of cards displayed. The parameter targets the `n_rows` argument of the `multiple_cards` function, determining the number of rows taken from the data.
Run and edit this code in PyCafe
=== "styling.css"
```css
.multiple-cards-container {
- display: flex;
- flex-wrap: wrap;
- gap: 12px;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
}
.figure-container {
- height: unset;
- width: unset;
+ height: unset;
+ width: unset;
}
.figure-container .card {
- height: 210px;
- width: 240px;
+ height: 210px;
+ width: 240px;
}
```
- === "app.yaml"
- ```yaml
- # Custom figures are currently only possible via Python configuration
- ```
- === "Result"
- [![CustomFigure]][CustomFigure]
- [CustomFigure]: ../../assets/user_guides/figure/custom_multiple_cards.png
+ === "app.yaml"
+ Custom figures are currently only possible via Python configuration.
+ === "Result"
+ [![CustomFigure]][customfigure]
+
+[customfigure]: ../../assets/user_guides/figure/custom_multiple_cards.png
+[customhtml]: ../../assets/user_guides/figure/custom_html.png
+[customkpi]: ../../assets/user_guides/figure/custom_kpi.png
diff --git a/vizro-core/docs/pages/user-guides/custom-tables.md b/vizro-core/docs/pages/user-guides/custom-tables.md
index e990cfbb0..42748820b 100644
--- a/vizro-core/docs/pages/user-guides/custom-tables.md
+++ b/vizro-core/docs/pages/user-guides/custom-tables.md
@@ -1,21 +1,18 @@
# How to create custom Dash AG Grids and Dash DataTables
-In cases where the available arguments for the [`dash_ag_grid`][vizro.tables.dash_ag_grid] or [`dash_data_table`][vizro.tables.dash_data_table] models are not sufficient,
-you can create a custom Dash AG Grid or Dash DataTable.
+In cases where the available arguments for the [`dash_ag_grid`][vizro.tables.dash_ag_grid] or [`dash_data_table`][vizro.tables.dash_data_table] models are not sufficient, you can create a custom Dash AG Grid or Dash DataTable.
-The [`Table`][vizro.models.Table] and the [`AgGrid`][vizro.models.AgGrid] model accept the `figure` argument, where you can enter
-_any_ [`dash_ag_grid`][vizro.tables.dash_ag_grid] or [`dash_data_table`][vizro.tables.dash_data_table] chart as explained in the [user guide on tables](table.md).
+The [`Table`][vizro.models.Table] and the [`AgGrid`][vizro.models.AgGrid] model accept the `figure` argument, where you can enter _any_ [`dash_ag_grid`][vizro.tables.dash_ag_grid] or [`dash_data_table`][vizro.tables.dash_data_table] chart as explained in the [user guide on tables](table.md).
One reason could be that you want to create a table/grid that requires computations that can be controlled by parameters (see the example below).
### Steps to create a custom table
1. Define a function that returns a `dash_ag_grid.AgGrid` or `dash_table.DataTable` object.
-2. Decorate it with `@capture("ag_grid")` or `@capture("table")`.
-3. The function must accept a `data_frame` argument (of type `pandas.DataFrame`).
-4. The table should be derived from and require only one `pandas.DataFrame`. Dataframes from other arguments
-will not react to dashboard controls such as [`Filter`](filters.md).
-5. Pass your function to the `figure` argument of the [`Table`][vizro.models.Table] or [`AgGrid`][vizro.models.AgGrid] model.
+1. Decorate it with `@capture("ag_grid")` or `@capture("table")`.
+1. The function must accept a `data_frame` argument (of type `pandas.DataFrame`).
+1. The table should be derived from and require only one `pandas.DataFrame`. Dataframes from other arguments will not react to dashboard controls such as [`Filter`](filters.md).
+1. Pass your function to the `figure` argument of the [`Table`][vizro.models.Table] or [`AgGrid`][vizro.models.AgGrid] model.
The following examples show a possible version of a custom table. In this case the argument `chosen_columns` was added, which you can control with a parameter:
@@ -70,14 +67,12 @@ The following examples show a possible version of a custom table. In this case t
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
- ```yaml
- # Custom tables are currently only possible via Python configuration
- ```
- === "Result"
- [![Table3]][Table3]
+ Custom tables are currently only possible via Python configuration.
- [Table3]: ../../assets/user_guides/table/custom_table.png
+ === "Result"
+ [![Table3]][table3]
??? example "Custom Dash AgGrid"
=== "app.py"
@@ -136,11 +131,12 @@ The following examples show a possible version of a custom table. In this case t
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
- ```yaml
- # Custom Ag Grids are currently only possible via Python configuration
- ```
+ Custom Ag Grids are currently only possible via Python configuration.
+
=== "Result"
- [![GridCustom]][GridCustom]
+ [![GridCustom]][gridcustom]
- [GridCustom]: ../../assets/user_guides/table/custom_grid.png
+[gridcustom]: ../../assets/user_guides/table/custom_grid.png
+[table3]: ../../assets/user_guides/table/custom_table.png
diff --git a/vizro-core/docs/pages/user-guides/dashboard.md b/vizro-core/docs/pages/user-guides/dashboard.md
index 0b37e03fa..244f65256 100644
--- a/vizro-core/docs/pages/user-guides/dashboard.md
+++ b/vizro-core/docs/pages/user-guides/dashboard.md
@@ -1,16 +1,15 @@
# How to create a dashboard
-This guide shows you how to configure and call a [`Dashboard`][vizro.models.Dashboard] using either
-pydantic models, Python dictionaries, YAML, or JSON.
+
+This guide shows you how to configure and call a [`Dashboard`][vizro.models.Dashboard] using either pydantic models, Python dictionaries, YAML, or JSON.
To create a dashboard:
1. Choose one of the possible configuration syntaxes
-2. Create your `pages`, see our [guide on Pages](pages.md)
-3. (optional) Choose a `theme`, see our [guide on Themes](themes.md)
-4. (optional) Customize your `navigation`, see our [guide on Navigation](navigation.md)
-5. (optional) Set a `title` for your dashboard
-6. Add your `dashboard` to the `build` call of Vizro
-
+1. Create your `pages`, see our [guide on Pages](pages.md)
+1. (optional) Choose a `theme`, see our [guide on Themes](themes.md)
+1. (optional) Customize your `navigation`, see our [guide on Navigation](navigation.md)
+1. (optional) Set a `title` for your dashboard
+1. Add your `dashboard` to the `build` call of Vizro
## Use dashboard configuration options
@@ -37,6 +36,7 @@ To create a dashboard:
Vizro().build(dashboard).run()
```
+
=== "app.py - Python dict"
```py
import vizro.plotly.express as px
@@ -77,6 +77,7 @@ To create a dashboard:
Vizro().build(dashboard).run()
```
+
=== "dashboard.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -101,50 +102,49 @@ To create a dashboard:
type: filter
title: My first dashboard
```
+
=== "dashboard.json"
```json
{
- "pages": [
+ "pages": [
+ {
+ "components": [
+ {
+ "figure": {
+ "_target_": "scatter",
+ "color": "species",
+ "data_frame": "iris",
+ "x": "sepal_length",
+ "y": "petal_width"
+ },
+ "type": "graph"
+ },
{
- "components": [
- {
- "figure": {
- "_target_": "scatter",
- "color": "species",
- "data_frame": "iris",
- "x": "sepal_length",
- "y": "petal_width"
- },
- "type": "graph"
- },
- {
- "figure": {
- "_target_": "histogram",
- "color": "species",
- "data_frame": "iris",
- "x": "sepal_width",
- },
- "type": "graph"
- }
- ],
- "controls": [
- {
- "column": "species",
- "type": "filter"
- }
- ],
- "title": "My first dashboard"
+ "figure": {
+ "_target_": "histogram",
+ "color": "species",
+ "data_frame": "iris",
+ "x": "sepal_width"
+ },
+ "type": "graph"
}
- ]
+ ],
+ "controls": [
+ {
+ "column": "species",
+ "type": "filter"
+ }
+ ],
+ "title": "My first dashboard"
+ }
+ ]
}
```
- === "Result"
- [![Dashboard]][Dashboard]
- [Dashboard]: ../../assets/user_guides/dashboard/dashboard.png
+ === "Result"
+ [![Dashboard]][dashboard]
!!! note "Extra `.py` files for `yaml` and `json` required"
-
Note that in the `yaml` and `json` example an extra `.py` is required to register the data and parse the yaml/json configuration.
=== "app.py for yaml"
@@ -164,6 +164,7 @@ To create a dashboard:
Vizro().build(dashboard).run()
```
+
=== "app.py for json"
```py
import json
@@ -187,7 +188,6 @@ After running the dashboard, you can access the dashboard via `localhost:8050`.
If supplied, the `title` of the [`Dashboard`][vizro.models.Dashboard] displays a heading at the top of every page.
-
## Add a dashboard logo
Vizro will [automatically incorporate the dashboard logo](assets.md/#add-a-logo-image) in the top-left corner of each page if an image named `logo.` is present within the assets folder.
@@ -196,11 +196,10 @@ Vizro will [automatically incorporate the dashboard logo](assets.md/#add-a-logo-
## Browser title
-The [website icon](assets.md/#change-the-favicon), Dashboard `title` (if supplied) and [Page `title`][vizro.models.Page] are displayed in the browser's
-title bar. For example, if your Dashboard `title` is "Vizro Demo" and the Page `title` is "Homepage", then the title in the browser tab will be "Vizro Demo: Homepage".
+The [website icon](assets.md/#change-the-favicon), Dashboard `title` (if supplied) and [Page `title`][vizro.models.Page] are displayed in the browser's title bar. For example, if your Dashboard `title` is "Vizro Demo" and the Page `title` is "Homepage", then the title in the browser tab will be "Vizro Demo: Homepage".
## Meta tags for social media
-Vizro automatically adds [meta tags](https://metatags.io/) to display a preview card when your app is shared on social media and chat
-clients. The preview includes the `URL`, `title`, plus an [image](assets.md/#include-a-meta-tags-image) and
-[Page `description`][vizro.models.Page] (if supplied). To see an example, try sharing an example from the [Vizro examples gallery](https://vizro.mckinsey.com/).
+Vizro automatically adds [meta tags](https://metatags.io/) to display a preview card when your app is shared on social media and chat clients. The preview includes the `URL`, `title`, plus an [image](assets.md/#include-a-meta-tags-image) and [Page `description`][vizro.models.Page] (if supplied). To see an example, try sharing an example from the [Vizro examples gallery](https://vizro.mckinsey.com/).
+
+[dashboard]: ../../assets/user_guides/dashboard/dashboard.png
diff --git a/vizro-core/docs/pages/user-guides/data.md b/vizro-core/docs/pages/user-guides/data.md
index 51bf84b97..d19b8aafb 100644
--- a/vizro-core/docs/pages/user-guides/data.md
+++ b/vizro-core/docs/pages/user-guides/data.md
@@ -2,11 +2,12 @@
Vizro supports two different types of data:
-* [Static data](#static-data): pandas DataFrame. This is the simplest method and best to use if you do not need the more advanced functionality of dynamic data.
-* [Dynamic data](#dynamic-data): function that returns a pandas DataFrame. This is a bit more complex to understand but has more advanced functionality such as the ability to refresh data while the dashboard is running.
+- [Static data](#static-data): pandas DataFrame. This is the simplest method and best to use if you do not need the more advanced functionality of dynamic data.
+- [Dynamic data](#dynamic-data): function that returns a pandas DataFrame. This is a bit more complex to understand but has more advanced functionality such as the ability to refresh data while the dashboard is running.
The following flowchart shows what you need to consider when choosing how to set up your data.
-``` mermaid
+
+```mermaid
graph TD
refresh["`Do you need your data to refresh while the dashboard is running?`"]
specification["`Do you need to specify your dashboard through a configuration language like YAML?`"]
@@ -27,11 +28,10 @@ graph TD
```
??? note "Static vs. dynamic data comparison"
-
This table gives a full comparison between static and dynamic data. Do not worry if you do not yet understand everything in it; it will become clearer after reading more about [static data](#static-data) and [dynamic data](#dynamic-data)!
| | Static | Dynamic |
- |---------------------------------------------------------------|------------------|------------------------------------------|
+ | ------------------------------------------------------------- | ---------------- | ---------------------------------------- |
| Required Python type | pandas DataFrame | Function that returns a pandas DataFrame |
| Can be supplied directly in `data_frame` argument of `figure` | Yes | No |
| Can be referenced by name after adding to data manager | Yes | Yes |
@@ -73,14 +73,13 @@ The below example uses the Iris data saved to a file `iris.csv` in the same dire
```
1. `iris` is a pandas DataFrame created by reading from the CSV file `iris.csv`.
- === "Result"
- [![DataBasic]][DataBasic]
- [DataBasic]: ../../assets/user_guides/data/data_pandas_dataframe.png
+ === "Result"
+ [![DataBasic]][databasic]
The [`Graph`][vizro.models.Graph], [`AgGrid`][vizro.models.AgGrid] and [`Table`][vizro.models.Table] models all have an argument called `figure`. This accepts a function (in the above example, `px.scatter`) that takes a pandas DataFrame as its first argument. The name of this argument is always `data_frame`. When configuring the dashboard using Python, it is optional to give the name of the argument: if you like, you could write `data_frame=iris` instead of `iris`.
-!!! note
+!!! note
With static data, once the dashboard is running, the data shown in the dashboard cannot change even if the source data in `iris.csv` changes. The code `iris = pd.read_csv("iris.csv")` is only executed once when the dashboard is first started. If you would like changes to source data to flow through to the dashboard then you must use [dynamic data](#dynamic-data).
### Reference by name
@@ -107,27 +106,27 @@ If you would like to specify your dashboard configuration through YAML then you
```
1. `"iris"` is the name of a data source added to the data manager. This data is a pandas DataFrame created by reading from the CSV file `iris.csv`.
+
=== "dashboard.yaml"
```yaml
pages:
- - components:
- - figure:
+ - components:
+ figure:
_target_: box
data_frame: iris # (1)!
x: species
y: petal_width
color: species
type: graph
- title: Static data example
+ title: Static data example
```
1. Refer to the `"iris"` data source in the data manager.
- === "Result"
- [![DataBasic]][DataBasic]
- [DataBasic]: ../../assets/user_guides/data/data_pandas_dataframe.png
+ === "Result"
+ [![DataBasic]][databasic]
-It is also possible to refer to a named data source using the Python API: `px.scatter("iris", ...)` or `px.scatter(data_frame="iris", ...)` would work if the `"iris"` data source has been registered in the data manager.
+It is also possible to refer to a named data source using the Python API: `px.scatter("iris", ...)` or `px.scatter(data_frame="iris", ...)` would work if the `"iris"` data source has been registered in the data manager.
## Dynamic data
@@ -166,14 +165,12 @@ The example below shows how data is fetched dynamically every time the page is r
```
1. `iris` is a pandas DataFrame created by reading from the CSV file `iris.csv`.
- 2. To demonstrate that dynamic data can change when the page is refreshed, select 50 points at random. This simulates what would happen if your file `iris.csv` were constantly changing.
- 3. To use `load_iris_data` as dynamic data it must be added to the data manager. You should **not** actually call the function as `load_iris_data()`; doing so would result in static data that cannot be reloaded.
- 4. Dynamic data is referenced by the name of the data source `"iris"`.
+ 1. To demonstrate that dynamic data can change when the page is refreshed, select 50 points at random. This simulates what would happen if your file `iris.csv` were constantly changing.
+ 1. To use `load_iris_data` as dynamic data it must be added to the data manager. You should **not** actually call the function as `load_iris_data()`; doing so would result in static data that cannot be reloaded.
+ 1. Dynamic data is referenced by the name of the data source `"iris"`.
=== "Result"
- [![DynamicData]][DynamicData]
-
- [DynamicData]: ../../assets/user_guides/data/dynamic_data.gif
+ [![DynamicData]][dynamicdata]
Since dynamic data sources must always be added to the data manager and referenced by name, they may be used in YAML configuration [exactly the same way as for static data sources](#reference-by-name).
@@ -184,10 +181,10 @@ By default, a dynamic data function executes every time the dashboard is refresh
The Vizro data manager has a server-side caching mechanism to help solve this. Vizro's cache uses [Flask-Caching](https://flask-caching.readthedocs.io/en/latest/), which supports a number of possible cache backends and [configuration options](https://flask-caching.readthedocs.io/en/latest/#configuring-flask-caching). By default, the cache is turned off.
+
In a development environment the easiest way to enable caching is to use a [simple memory cache](https://cachelib.readthedocs.io/en/stable/simple/) with the default configuration options. This is achieved by adding one line to the above example to set `data_manager.cache`:
!!! example "Simple cache with default timeout of 5 minutes"
-
```py hl_lines="13"
from flask_caching import Cache
from vizro import Vizro
@@ -225,7 +222,6 @@ data_manager.cache = Cache(config={"CACHE_TYPE": "SimpleCache", "CACHE_DEFAULT_T
```
!!! warning
-
Simple cache exists purely for single-process development purposes and is not intended to be used in production. If you deploy with multiple workers, [for example with Gunicorn](run.md/#gunicorn), then you should use a production-ready cache backend. All of Flask-Caching's [built-in backends](https://flask-caching.readthedocs.io/en/latest/#built-in-cache-backends) other than `SimpleCache` are suitable for production. In particular, you might like to use [`FileSystemCache`](https://cachelib.readthedocs.io/en/stable/file/) or [`RedisCache`](https://cachelib.readthedocs.io/en/stable/redis/):
```py title="Production-ready caches"
@@ -239,7 +235,9 @@ data_manager.cache = Cache(config={"CACHE_TYPE": "SimpleCache", "CACHE_DEFAULT_T
Since Flask-Caching relies on [`pickle`](https://docs.python.org/3/library/pickle.html), which can execute arbitrary code during unpickling, you should not cache data from untrusted sources. Doing so [could be unsafe](https://github.com/pallets-eco/flask-caching/pull/209).
Note that when a production-ready cache backend is used, the cache is persisted beyond the Vizro process and is not cleared by restarting your server. To clear the cache then you must do so manually, for example, if you use `FileSystemCache` then you would delete your `cache` directory. Persisting the cache can also be useful for development purposes when handling data that takes a long time to load: even if you do not need the data to refresh while your dashboard is running, it can speed up your development loop to use dynamic data with a cache that is persisted between repeated runs of Vizro.
+
+
#### Set timeouts
You can change the timeout of the cache independently for each dynamic data source in the data manager using the `timeout` setting (measured in seconds). A `timeout` of 0 indicates that the cache does not expire. This is effectively the same as using [static data](#static-data).
@@ -278,8 +276,8 @@ In general, a parametrized dynamic data source should always return a pandas Dat
To add a parameter to control a dynamic data source, do the following:
1. add the appropriate argument to your dynamic data function and specify a default value for the argument.
-2. give an `id` to all components that have the data source you wish to alter through a parameter.
-3. [add a parameter](parameters.md) with `targets` of the form `.data_frame.` and a suitable [selector](selectors.md).
+1. give an `id` to all components that have the data source you wish to alter through a parameter.
+1. [add a parameter](parameters.md) with `targets` of the form `.data_frame.` and a suitable [selector](selectors.md).
For example, let us extend the [dynamic data example](#dynamic-data) above into an example of how parametrized dynamic data works. The `load_iris_data` can take an argument `number_of_points` controlled from the dashboard with a [`Slider`][vizro.models.Slider].
@@ -318,21 +316,18 @@ For example, let us extend the [dynamic data example](#dynamic-data) above into
```
1. `load_iris_data` takes a single argument, `number_of_points`, with a default value of 10.
- 2. `iris` is a pandas DataFrame created by reading from the CSV file `iris.csv`.
- 3. Sample points at random, where `number_of_points` gives the number of points selected.
- 4. To use `load_iris_data` as dynamic data it must be added to the data manager. You should **not** actually call the function as `load_iris_data()` or `load_iris_data(number_of_points=...)`; doing so would result in static data that cannot be reloaded.
- 5. Give the `vm.Graph` component `id="graph"` so that the `vm.Parameter` can target it. Dynamic data is referenced by the name of the data source `"iris"`.
- 6. Create a `vm.Parameter` to target the `number_of_points` argument for the `data_frame` used in `graph`.
+ 1. `iris` is a pandas DataFrame created by reading from the CSV file `iris.csv`.
+ 1. Sample points at random, where `number_of_points` gives the number of points selected.
+ 1. To use `load_iris_data` as dynamic data it must be added to the data manager. You should **not** actually call the function as `load_iris_data()` or `load_iris_data(number_of_points=...)`; doing so would result in static data that cannot be reloaded.
+ 1. Give the `vm.Graph` component `id="graph"` so that the `vm.Parameter` can target it. Dynamic data is referenced by the name of the data source `"iris"`.
+ 1. Create a `vm.Parameter` to target the `number_of_points` argument for the `data_frame` used in `graph`.
=== "Result"
- [![ParametrizedDynamicData]][ParametrizedDynamicData]
-
- [ParametrizedDynamicData]: ../../assets/user_guides/data/parametrized_dynamic_data.gif
+ [![ParametrizedDynamicData]][parametrizeddynamicdata]
Parametrized data loading is compatible with [caching](#configure-cache). The cache uses [memoization](https://flask-caching.readthedocs.io/en/latest/#memoization), so that the dynamic data function's arguments are included in the cache key. This means that `load_iris_data(number_of_points=10)` is cached independently of `load_iris_data(number_of_points=20)`.
!!! warning
-
You should always [treat the content of user input as untrusted](https://community.plotly.com/t/writing-secure-dash-apps-community-thread/54619). For example, you should not expose a filepath to load without passing it through a function like [`werkzeug.utils.secure_filename`](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.utils.secure_filename), or you might enable arbitrary access to files on your server.
You cannot pass [nested parameters](parameters.md#nested-parameters) to dynamic data. You can only target the top-level arguments of the data loading function, not the nested keys in a dictionary.
@@ -354,7 +349,6 @@ When the page is refreshed, the behavior of a dynamic filter is as follows:
For example, let us add two filters to the [dynamic data example](#dynamic-data) above:
!!! example "Dynamic filters"
-
```py hl_lines="10 20 21"
from vizro import Vizro
import pandas as pd
@@ -386,8 +380,8 @@ For example, let us add two filters to the [dynamic data example](#dynamic-data)
```
1. We sample only 5 rather than 50 points so that changes to the available values in the filtered columns are more apparent when the page is refreshed.
- 2. This filter implicitly controls the dynamic data source `"iris"`, which supplies the `data_frame` to the targeted `vm.Graph`. On page refresh, Vizro reloads this data, finds all the unique values in the `"species"` column and sets the categorical selector's `options` accordingly.
- 3. Similarly, on page refresh, Vizro finds the minimum and maximum values of the `"sepal_length"` column in the reloaded data and sets new `min` and `max` values for the numerical selector accordingly.
+ 1. This filter implicitly controls the dynamic data source `"iris"`, which supplies the `data_frame` to the targeted `vm.Graph`. On page refresh, Vizro reloads this data, finds all the unique values in the `"species"` column and sets the categorical selector's `options` accordingly.
+ 1. Similarly, on page refresh, Vizro finds the minimum and maximum values of the `"sepal_length"` column in the reloaded data and sets new `min` and `max` values for the numerical selector accordingly.
Consider a filter that depends on dynamic data, where you do **not** want the available values to change when the dynamic data changes. You should manually specify the `selector`'s `options` field (categorical selector) or `min` and `max` fields (numerical selector). In the above example, this could be achieved as follows:
@@ -409,10 +403,13 @@ controls = [
When Vizro initially builds a filter that depends on parametrized dynamic data loading, data is loaded using the default argument values. This data is used to:
-* perform initial validation
-* check which data sources contain the specified `column` (unless `targets` is explicitly specified) and
-* find the type of selector to use (unless `selector` is explicitly specified).
+- perform initial validation
+- check which data sources contain the specified `column` (unless `targets` is explicitly specified) and
+- find the type of selector to use (unless `selector` is explicitly specified).
!!! note
-
When the value of a dynamic data parameter is changed by a dashboard user, the data underlying a dynamic filter can change. Currently this change affects page components such as `vm.Graph` but does not affect the available values shown in a dynamic filter, which only update on page refresh. This functionality will be coming soon!
+
+[databasic]: ../../assets/user_guides/data/data_pandas_dataframe.png
+[dynamicdata]: ../../assets/user_guides/data/dynamic_data.gif
+[parametrizeddynamicdata]: ../../assets/user_guides/data/parametrized_dynamic_data.gif
diff --git a/vizro-core/docs/pages/user-guides/extensions.md b/vizro-core/docs/pages/user-guides/extensions.md
index 2c7efc9ac..74a740448 100644
--- a/vizro-core/docs/pages/user-guides/extensions.md
+++ b/vizro-core/docs/pages/user-guides/extensions.md
@@ -2,64 +2,49 @@
At its simplest, Vizro enables low-code configuration, but you can also customize it to go beyond its default capabilities by incorporating any Dash component, Dash callback, or Plotly chart.
-* **[Vizro customizations](#vizro-customizations)**. You can customize Vizro to extend the default functionality of Vizro and create Python functions as customized Plotly charts, tables, dashboard components, actions, or reactive HTML components, and then plug them directly into the existing Vizro dashboard configuration (as explained below).
+- **[Vizro customizations](#vizro-customizations)**. You can customize Vizro to extend the default functionality of Vizro and create Python functions as customized Plotly charts, tables, dashboard components, actions, or reactive HTML components, and then plug them directly into the existing Vizro dashboard configuration (as explained below).
-* **[Dash customizations](#dash-customizations)**. You can add custom Dash callbacks directly to any Vizro dashboard, enabling you to code beneath the Vizro layer and control Dash directly.
+- **[Dash customizations](#dash-customizations)**. You can add custom Dash callbacks directly to any Vizro dashboard, enabling you to code beneath the Vizro layer and control Dash directly.
-* **[CSS customizations](#css-customizations)**. You can add custom CSS to any Vizro dashboard, enabling users to deviate from the default styling and create a unique look and feel for their dashboard.
-
-* **[React.js customizations](#reactjs-customizations)**. You can add custom React.js components directly to any Vizro dashboard, enabling users to go beneath both the Vizro and Dash layers and control React.js directly
+- **[CSS customizations](#css-customizations)**. You can add custom CSS to any Vizro dashboard, enabling users to deviate from the default styling and create a unique look and feel for their dashboard.
+- **[React.js customizations](#reactjs-customizations)**. You can add custom React.js components directly to any Vizro dashboard, enabling users to go beneath both the Vizro and Dash layers and control React.js directly
Vizro offers the ability to combine ease of use of low-code configuration, with the flexibility of a range of high-code extensions to expand your dashboard's functionality.
-
## Vizro customizations
### [Custom charts](custom-charts.md)
-You can create custom chart functions in Vizro by wrapping Plotly chart code inside a
-Vizro chart function wrapper, and then use the functions directly inside the Vizro dashboard configuration. This enables the creation of `plotly.graph_objects` charts with multiple traces, or `plotly_express` charts with post update customizations
-
+You can create custom chart functions in Vizro by wrapping Plotly chart code inside a Vizro chart function wrapper, and then use the functions directly inside the Vizro dashboard configuration. This enables the creation of `plotly.graph_objects` charts with multiple traces, or `plotly_express` charts with post update customizations
### [Custom tables](custom-tables.md)
If the available arguments for the [`dash_ag_grid`][vizro.tables.dash_ag_grid] or [`dash_data_table`][vizro.tables.dash_data_table] models are insufficient, you can create a custom Dash AG Grid or Dash DataTable.
-
### [Custom components](custom-components.md)
-You can create a custom component based on any dash-compatible component (for example, [dash-core-components](https://dash.plotly.com/dash-core-components),
-[dash-bootstrap-components](https://dash-bootstrap-components.opensource.faculty.ai/), [dash-html-components](https://github.com/plotly/dash/tree/dev/components/dash-html-components)).
+You can create a custom component based on any dash-compatible component (for example, [dash-core-components](https://dash.plotly.com/dash-core-components), [dash-bootstrap-components](https://dash-bootstrap-components.opensource.faculty.ai/), [dash-html-components](https://github.com/plotly/dash/tree/dev/components/dash-html-components)).
All Vizro's components are based on `Dash` and ship with a set of defaults that can be modified. If you would like to overwrite one of those defaults, or if you would like to use extra `args` or `kwargs` of those components, then this is the correct way to include those. You can use any existing attribute of any underlying [Dash component](https://dash.plotly.com/#open-source-component-libraries) with this method.
-
### [Custom actions](custom-actions.md)
-If you want to use the [`Action`][vizro.models.Action] model to perform functions that are not available in the [pre-defined action functions][vizro.actions], you can create your own custom action.
-Like other [actions](actions.md), custom actions can also be added as an element inside the [actions chain](actions.md#chain-actions), and triggered with one of dashboard components.
-
+If you want to use the [`Action`][vizro.models.Action] model to perform functions that are not available in the [pre-defined action functions][vizro.actions], you can create your own custom action. Like other [actions](actions.md), custom actions can also be added as an element inside the [actions chain](actions.md#chain-actions), and triggered with one of dashboard components.
### [Custom figures](custom-figures.md)
-Custom figures are useful when you need a component that reacts to
-[filter](filters.md) and [parameter](parameters.md) controls.
-
-Vizro's [`Figure`][vizro.models.Figure] model accepts the `figure` argument, where you can enter _any_ custom figure function
-as described in the [how-to guide for figures](figure.md).
+Custom figures are useful when you need a component that reacts to [filter](filters.md) and [parameter](parameters.md) controls.
+Vizro's [`Figure`][vizro.models.Figure] model accepts the `figure` argument, where you can enter _any_ custom figure function as described in the [how-to guide for figures](figure.md).
## Dash customizations
-Since Vizro is built using Dash, it is possible to use [Dash callbacks](https://dash.plotly.com/basic-callbacks) directly in any Vizro dashboard. This enables you to code beneath the Vizro layer and control Dash directly,
-which is especially useful when working with callbacks
+Since Vizro is built using Dash, it is possible to use [Dash callbacks](https://dash.plotly.com/basic-callbacks) directly in any Vizro dashboard. This enables you to code beneath the Vizro layer and control Dash directly, which is especially useful when working with callbacks
-Here is an example showing a Dash callback within Vizro,
-enabling an interaction between data points in a scatter plot and the content of a text card:
+Here is an example showing a Dash callback within Vizro, enabling an interaction between data points in a scatter plot and the content of a text card:
!!! example "Dash callback example"
-
=== "app.py"
```{.python pycafe-link}
from dash import callback, Input, Output
@@ -93,14 +78,12 @@ enabling an interaction between data points in a scatter plot and the content of
## CSS customizations
-Vizro is opinionated about visual formatting, and some elements, such as the layout of the navigation and controls,
-are fixed. You can customize some settings such as background colors, fonts, and other styles via CSS overrides.
+Vizro is opinionated about visual formatting, and some elements, such as the layout of the navigation and controls, are fixed. You can customize some settings such as background colors, fonts, and other styles via CSS overrides.
For more information, see our documentation on [customizing CSS](custom-css.md)
## React.js customizations
-It is possible to create custom React.js components and add them
-directly to any Vizro dashboard so enabling you to code beneath both the Vizro and Dash layers and control React.js directly
+It is possible to create custom React.js components and add them directly to any Vizro dashboard so enabling you to code beneath both the Vizro and Dash layers and control React.js directly
For more information, see the documentation on [using React.js components with Dash](https://dash.plotly.com/plugins)
diff --git a/vizro-core/docs/pages/user-guides/figure.md b/vizro-core/docs/pages/user-guides/figure.md
index 0589fad3b..03bfa412a 100644
--- a/vizro-core/docs/pages/user-guides/figure.md
+++ b/vizro-core/docs/pages/user-guides/figure.md
@@ -1,26 +1,19 @@
# How to use figures
-This guide shows you how to add any [Dash component](https://dash.plotly.com/#open-source-component-libraries) that needs to be reactive to [filter](filters.md) and [parameter](parameters.md) controls.
-If you want to add a static Dash component to your page, use [custom components](custom-components.md) instead.
+This guide shows you how to add any [Dash component](https://dash.plotly.com/#open-source-component-libraries) that needs to be reactive to [filter](filters.md) and [parameter](parameters.md) controls. If you want to add a static Dash component to your page, use [custom components](custom-components.md) instead.
-[`Figure`][vizro.models.Figure] provides a flexible foundation for all types of reactive Dash components in Vizro.
-The [`Graph`][vizro.models.Graph], [`Table`][vizro.models.Table] and [`AgGrid`][vizro.models.AgGrid] components are
-specific implementations of `Figure`. They serve as intuitive shortcuts, embedding behaviors and interactions specific
-to their purposes.
+[`Figure`][vizro.models.Figure] provides a flexible foundation for all types of reactive Dash components in Vizro. The [`Graph`][vizro.models.Graph], [`Table`][vizro.models.Table] and [`AgGrid`][vizro.models.AgGrid] components are specific implementations of `Figure`. They serve as intuitive shortcuts, embedding behaviors and interactions specific to their purposes.
-If these more specific models already achieve what you need then they should be used in preference to
-the more generic `Figure`. Remember that it is possible to supply [custom charts](custom-charts.md) to `Graph`
-and [custom tables](custom-tables.md) to `Table`.
+If these more specific models already achieve what you need then they should be used in preference to the more generic `Figure`. Remember that it is possible to supply [custom charts](custom-charts.md) to `Graph` and [custom tables](custom-tables.md) to `Table`.
-There are already a few figure functions you can reuse, see the section on [KPI cards](#key-performance-indicator-kpi-cards)
-for more details:
+There are already a few figure functions you can reuse, see the section on [KPI cards](#key-performance-indicator-kpi-cards) for more details:
- [`kpi_card`][vizro.figures.kpi_card]
- [`kpi_card_reference`][vizro.figures.kpi_card_reference]
The following flowchart shows what you need to consider when choosing which model to use:
-``` mermaid
+```mermaid
graph TD
first["`Does your desired component exist in Vizro, e.g. Graph, Table or AgGrid?`"]
specific-component([Use the specific component])
@@ -40,14 +33,12 @@ graph TD
classDef clickable color:#4051b5;
```
-
To add a `Figure` to your page:
1. Add the `Figure` model to the components argument of the [Page][vizro.models.Page] model.
-2. Use an existing figure function from [`vizro.figures`](../API-reference/figure-callables.md) and pass it to the `figure` argument of the `Figure` model.
+1. Use an existing figure function from [`vizro.figures`](../API-reference/figure-callables.md) and pass it to the `figure` argument of the `Figure` model.
!!! example "Use existing figure functions"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -99,40 +90,25 @@ To add a `Figure` to your page:
selector:
type: radio_items
layout:
- grid:
- [
- [0, -1, -1, -1],
- [-1, -1, -1, -1],
- [-1, -1, -1, -1],
- [-1, -1, -1, -1],
- [-1, -1, -1, -1],
- ]
+ grid: [[0, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1],
+ [-1, -1, -1, -1]]
title: KPI card
```
- === "Result"
- [![Figure]][Figure]
-
- [Figure]: ../../assets/user_guides/figure/figure.png
+ === "Result"
+ [![Figure]][figure]
### Key Performance Indicator (KPI) cards
-A KPI card is a dynamic card that can display a single value, but optionally, can also include a title, icon, and reference value.
-It is a common visual component to display key metrics in a dashboard. Vizro supports two pre-defined KPI card functions:
-- [`kpi_card`](../API-reference/figure-callables.md#vizro.figures.kpi_card): A KPI card that shows a single value found
-by performing an aggregation function (by default, `sum`) over a specified column.
-Required arguments are `data_frame` and `value_column`.
+A KPI card is a dynamic card that can display a single value, but optionally, can also include a title, icon, and reference value. It is a common visual component to display key metrics in a dashboard. Vizro supports two pre-defined KPI card functions:
-- [`kpi_card_with_reference`](../API-reference/figure-callables.md#vizro.figures.kpi_card_reference): A KPI card that shows a single value
-and a delta comparison to a reference value found by performing an aggregation function (by default, `sum`) over the specified columns.
-Required arguments are `data_frame`, `value_column` and `reference_column`.
+- [`kpi_card`](../API-reference/figure-callables.md#vizro.figures.kpi_card): A KPI card that shows a single value found by performing an aggregation function (by default, `sum`) over a specified column. Required arguments are `data_frame` and `value_column`.
-As described in the [API reference](../API-reference/figure-callables.md) and illustrated in the below example, these
-functions have several arguments to customize your KPI cards. If you require a level of customization that is not
-possible with the built-in functions then you can create a [custom figure](custom-figures.md).
+- [`kpi_card_with_reference`](../API-reference/figure-callables.md#vizro.figures.kpi_card_reference): A KPI card that shows a single value and a delta comparison to a reference value found by performing an aggregation function (by default, `sum`) over the specified columns. Required arguments are `data_frame`, `value_column` and `reference_column`.
-!!! example "KPI card variations"
+As described in the [API reference](../API-reference/figure-callables.md) and illustrated in the below example, these functions have several arguments to customize your KPI cards. If you require a level of customization that cannot be done with the built-in functions then you can create a [custom figure](custom-figures.md).
+!!! example "KPI card variations"
=== "app.py"
```{.python pycafe-link}
import pandas as pd
@@ -258,8 +234,8 @@ possible with the built-in functions then you can create a [custom figure](custo
value_column: Actual
reference_column: Reference
title: KPI reference with formatting
- value_format: "{value:.2f}€"
- reference_format: "{delta:+.2f}€ vs. last year ({reference:.2f}€)"
+ value_format: '{value:.2f}€'
+ reference_format: '{delta:+.2f}€ vs. last year ({reference:.2f}€)'
type: figure
- figure:
_target_: kpi_card_reference
@@ -276,7 +252,9 @@ possible with the built-in functions then you can create a [custom figure](custo
grid: [[0, 1, 2, 3], [4, 5, 6, 7], [-1, -1, -1, -1], [-1, -1, -1, -1]]
title: KPI cards
```
+
=== "Result"
- [![KPICards]][KPICards]
+ [![KPICards]][kpicards]
- [KPICards]: ../../assets/user_guides/figure/kpi_cards.png
+[figure]: ../../assets/user_guides/figure/figure.png
+[kpicards]: ../../assets/user_guides/figure/kpi_cards.png
diff --git a/vizro-core/docs/pages/user-guides/filters.md b/vizro-core/docs/pages/user-guides/filters.md
index bc3649178..8228ecbe7 100644
--- a/vizro-core/docs/pages/user-guides/filters.md
+++ b/vizro-core/docs/pages/user-guides/filters.md
@@ -2,8 +2,7 @@
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](selectors.md) (for example, `Dropdown` or `RangeSlider`) that operate on 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.
@@ -12,7 +11,7 @@ By default, filters that control components with [dynamic data](data.md#dynamic-
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
-2. configure the `column` argument, which denotes the target column to be filtered
+1. configure the `column` argument, which denotes the target column to be filtered
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`.
@@ -39,6 +38,7 @@ You can also set `targets` to specify which components on the page the filter sh
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -57,17 +57,15 @@ You can also set `targets` to specify which components on the page the filter sh
type: filter
title: My first page
```
- === "Result"
- [![Filter]][Filter]
-
- [Filter]: ../../assets/user_guides/control/control1.png
+ === "Result"
+ [![Filter]][filter]
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).
+- 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.
@@ -107,6 +105,7 @@ The following example demonstrates these default selector types.
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -129,15 +128,13 @@ The following example demonstrates these default selector types.
type: filter
title: My first page
```
- === "Result"
- [![Filter]][Filter]
- [Filter]: ../../assets/user_guides/selectors/default_filter_selectors.png
+ === "Result"
+ [![Filter]][filter]
## Change 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].
+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"
@@ -162,6 +159,7 @@ Currently available selectors are [`Checklist`][vizro.models.Checklist], [`Dropd
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -181,11 +179,9 @@ Currently available selectors are [`Checklist`][vizro.models.Checklist], [`Dropd
type: filter
title: My first page
```
- === "Result"
-
- [![Selector]][Selector]
- [Selector]: ../../assets/user_guides/control/control2.png
+ === "Result"
+ [![Selector]][selector]
## Further customization
@@ -220,6 +216,7 @@ Below is an advanced example where we only target one page component, and where
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -244,17 +241,19 @@ 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
+ === "Result"
+ [![Advanced]][advanced]
To further customize selectors, see our [how-to-guide on creating custom components](custom-components.md).
+
+[advanced]: ../../assets/user_guides/control/control3.png
+[filter]: ../../assets/user_guides/control/control1.png
+[selector]: ../../assets/user_guides/control/control2.png
diff --git a/vizro-core/docs/pages/user-guides/graph.md b/vizro-core/docs/pages/user-guides/graph.md
index 36c670997..1c3ffc8bc 100755
--- a/vizro-core/docs/pages/user-guides/graph.md
+++ b/vizro-core/docs/pages/user-guides/graph.md
@@ -6,25 +6,18 @@ The [`Graph`][vizro.models.Graph] model is the most used component in many dashb
To add a [`Graph`][vizro.models.Graph] to your page, do the following:
-1. insert the [`Graph`][vizro.models.Graph] model into the `components` argument of the
-[`Page`][vizro.models.Page] model
-2. enter any of the currently available charts of the open source library [`plotly.express`](https://plotly.com/python/plotly-express/) into the `figure` argument
+1. insert the [`Graph`][vizro.models.Graph] model into the `components` argument of the [`Page`][vizro.models.Page] model
+1. enter any of the currently available charts of the open source library [`plotly.express`](https://plotly.com/python/plotly-express/) into the `figure` argument
!!! note
+ To use the [`plotly.express`](https://plotly.com/python/plotly-express/) chart in a Vizro dashboard, you need to import it as `import vizro.plotly.express as px`. This leaves any of the [`plotly.express`](https://plotly.com/python/plotly-express/) functionality untouched yet enables _direct insertion_ into the [`Graph`][vizro.models.Graph] model _as is_.
- In order to use the [`plotly.express`](https://plotly.com/python/plotly-express/) chart in a Vizro dashboard, you need to import it as `import vizro.plotly.express as px`.
- This leaves any of the [`plotly.express`](https://plotly.com/python/plotly-express/) functionality untouched, but allows _direct insertion_ into the [`Graph`][vizro.models.Graph] model _as is_.
-
- Note also that the `plotly.express` chart needs to have a `data_frame` argument. In case you require a chart without
- a `data_frame` argument (for example, the [`imshow` chart](https://plotly.com/python/imshow/)), refer to our
- [guide on custom charts](custom-charts.md).
-
+ Note also that the `plotly.express` chart needs to have a `data_frame` argument. In case you require a chart without a `data_frame` argument (for example, the [`imshow` chart](https://plotly.com/python/imshow/)), refer to our [guide on custom charts](custom-charts.md).
## Insert Plotly chart
!!! example "Graph"
=== "app.py"
-
```{.python pycafe-link}
import vizro.models as vm
import vizro.plotly.express as px
@@ -47,25 +40,24 @@ To add a [`Graph`][vizro.models.Graph] to your page, do the following:
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_: scatter_matrix
- color: species
- data_frame: iris
- dimensions: ["sepal_length", "sepal_width", "petal_length", "petal_width"]
- type: graph
- title: My first page
+ - components:
+ - figure:
+ _target_: scatter_matrix
+ color: species
+ data_frame: iris
+ dimensions: [sepal_length, sepal_width, petal_length, petal_width]
+ type: graph
+ title: My first page
```
- === "Result"
- [![Graph]][Graph]
-
- [Graph]: ../../assets/user_guides/components/graph.png
+ === "Result"
+ [![Graph]][graph]
In the Python example we directly inserted the pandas DataFrame `df` into `figure=px.scatter_matrix(df, ...)`. This is [one way to supply data to a chart](data.md#supply-directly). For the YAML version, we [refer to the data source by name](data.md#reference-by-name) as `data_frame: iris`. For a full explanation of the different methods you can use to send data to your dashboard, see [our guide to using data in Vizro](data.md).
@@ -73,31 +65,24 @@ In the Python example we directly inserted the pandas DataFrame `df` into `figur
You will need to create a custom chart if you want to customize the Plotly chart beyond a function call, for example by:
-* using post-update methods like `update_layout`, `update_xaxes`, `update_traces`, or
-* by creating a custom `plotly.graph_objects.Figure()` object and manually adding traces with `add_trace`.
-
-For more details, refer to our [user guide on custom chart](custom-charts.md) and the
-[Plotly documentation on updating figures](https://plotly.com/python/creating-and-updating-figures/).
+- using post-update methods like `update_layout`, `update_xaxes`, `update_traces`, or
+- by creating a custom `plotly.graph_objects.Figure()` object and manually adding traces with `add_trace`.
+For more details, refer to our [user guide on custom chart](custom-charts.md) and the [Plotly documentation on updating figures](https://plotly.com/python/creating-and-updating-figures/).
## Add title, header, and footer
-The [`Graph`][vizro.models.Graph] accepts a `title`, `header` and `footer` argument. This is useful for providing
-context to the data being displayed, or for adding a description of the data.
+The [`Graph`][vizro.models.Graph] accepts a `title`, `header` and `footer` argument. This is useful for context on the data being displayed, or for adding a description of the data.
- **title**: Displayed as an [H3 header](https://dash.plotly.com/dash-html-components/h3), useful for summarizing the main topic or insight of the component.
- **header**: Accepts markdown text, ideal for extra descriptions, subtitles, or detailed data insights.
- **footer**: Accepts markdown text, commonly used for citing data sources, providing information on the last update, or adding disclaimers.
-
!!! note
-
- Although you can directly provide a `title` to the Plotly Express chart, we recommend using `Graph.title` for
- proper alignment with other components on the screen.
+ Although you can directly give a `title` to the Plotly Express chart, we recommend using `Graph.title` for proper alignment with other components on the screen.
!!! example "Formatted Graph"
=== "app.py"
-
```{.python pycafe-link}
import vizro.models as vm
@@ -126,31 +111,34 @@ context to the data being displayed, or for adding a description of the data.
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_: scatter
- x: sepal_width
- y: sepal_length
- color: species
- data_frame: iris
- title: Relationships between Sepal Width and Sepal Length
- header: |
- Each point in the scatter plot represents one of the 150 iris flowers, with colors indicating their
- types. The Setosa type is easily identifiable by its short and wide sepals.
-
- However, there is still overlap between the Versicolor and Virginica types when considering only sepal
- width and length.
- footer: |
- SOURCE: **Plotly iris data set, 2024**
- type: graph
- title: Formatted Graph
+ - components:
+ - figure:
+ _target_: scatter
+ x: sepal_width
+ y: sepal_length
+ color: species
+ data_frame: iris
+ title: Relationships between Sepal Width and Sepal Length
+ header: |
+ Each point in the scatter plot represents one of the 150 iris flowers, with colors indicating their
+ types. The Setosa type is easily identifiable by its short and wide sepals.
+
+ However, there is still overlap between the Versicolor and Virginica types when considering only sepal
+ width and length.
+ footer: |
+ SOURCE: **Plotly iris data set, 2024**
+ type: graph
+ title: Formatted Graph
```
+
=== "Result"
- [![FormattedGraph]][FormattedGraph]
+ [![FormattedGraph]][formattedgraph]
- [FormattedGraph]: ../../assets/user_guides/components/formatted_graph.png
+[formattedgraph]: ../../assets/user_guides/components/formatted_graph.png
+[graph]: ../../assets/user_guides/components/graph.png
diff --git a/vizro-core/docs/pages/user-guides/install.md b/vizro-core/docs/pages/user-guides/install.md
index 4d4c01239..6a07911e5 100644
--- a/vizro-core/docs/pages/user-guides/install.md
+++ b/vizro-core/docs/pages/user-guides/install.md
@@ -8,8 +8,8 @@ We recommend that you create a virtual environment for each Vizro project you wo
## Prerequisites to working locally
-* **Python**: Vizro supports macOS, Linux, and Windows. It works with Python 3.9 and later.
-* **Virtual environment**: You specify the version of Python to use with Vizro when you set up the virtual environment. See the following references to learn more about [Python virtual environments](https://realpython.com/python-virtual-environments-a-primer/), [Conda virtual environments](https://docs.conda.io/projects/conda/en/latest/user-guide/getting-started.html#starting-conda) or [watch an explainer video about them](https://youtu.be/YKfAwIItO7M).
+- **Python**: Vizro supports macOS, Linux, and Windows. It works with Python 3.9 and later.
+- **Virtual environment**: You specify the version of Python to use with Vizro when you set up the virtual environment. See the following references to learn more about [Python virtual environments](https://realpython.com/python-virtual-environments-a-primer/), [Conda virtual environments](https://docs.conda.io/projects/conda/en/latest/user-guide/getting-started.html#starting-conda) or [watch an explainer video about them](https://youtu.be/YKfAwIItO7M).
### How to create a virtual environment for your Vizro project
diff --git a/vizro-core/docs/pages/user-guides/kedro-data-catalog.md b/vizro-core/docs/pages/user-guides/kedro-data-catalog.md
index 0e2b0954e..ce4b060fa 100644
--- a/vizro-core/docs/pages/user-guides/kedro-data-catalog.md
+++ b/vizro-core/docs/pages/user-guides/kedro-data-catalog.md
@@ -3,6 +3,7 @@
This page describes how to integrate Vizro with [Kedro](https://docs.kedro.org/en/stable/index.html), an open-source Python framework to create reproducible, maintainable, and modular data science code. For Pandas datasets registered in a Kedro data catalog, Vizro provides a convenient way to visualize them.
## Installation
+
If you already have Kedro installed then you do not need to install any extra dependencies. If you do not have Kedro installed then you should run:
```bash
@@ -10,7 +11,9 @@ pip install vizro[kedro]
```
## Use datasets from the Kedro Data Catalog
+
`vizro.integrations.kedro` provides functions to help generate and process a [Kedro Data Catalog](https://docs.kedro.org/en/stable/data/index.html). Given a Kedro Data Catalog `catalog`, the general pattern to add datasets into the Vizro data manager is:
+
```python
from vizro.integrations import kedro as kedro_integration
from vizro.managers import data_manager
@@ -25,15 +28,14 @@ This imports all datasets of type [`kedro_datasets.pandas`](https://docs.kedro.o
The `catalog` variable may have been created in a number of different ways:
1. Kedro project path. Vizro exposes a helper function `vizro.integrations.kedro.catalog_from_project` to generate a `catalog` given the path to a Kedro project.
-2. [Kedro Jupyter session](https://docs.kedro.org/en/stable/notebooks_and_ipython/kedro_and_notebooks.html). This automatically exposes `catalog`.
-3. Data Catalog configuration file (`catalog.yaml`). This can create a `catalog` entirely independently of a Kedro project using [`kedro.io.DataCatalog.from_config`](https://docs.kedro.org/en/stable/kedro.io.DataCatalog.html#kedro.io.DataCatalog.from_config).
+1. [Kedro Jupyter session](https://docs.kedro.org/en/stable/notebooks_and_ipython/kedro_and_notebooks.html). This automatically exposes `catalog`.
+1. Data Catalog configuration file (`catalog.yaml`). This can create a `catalog` entirely independently of a Kedro project using [`kedro.io.DataCatalog.from_config`](https://docs.kedro.org/en/stable/kedro.io.DataCatalog.html#kedro.io.DataCatalog.from_config).
The full code for these different cases is given below.
!!! example "Import a Kedro Data Catalog into the Vizro data manager"
-
=== "app.py (Kedro project path)"
- ```py
+ ```python
from vizro.integrations import kedro as kedro_integration
from vizro.managers import data_manager
@@ -43,16 +45,18 @@ The full code for these different cases is given below.
for dataset_name, dataset in kedro_integration.datasets_from_catalog(catalog).items():
data_manager[dataset_name] = dataset
```
+
=== "app.ipynb (Kedro Jupyter session)"
- ```py
+ ```python
from vizro.managers import data_manager
for dataset_name, dataset in kedro_integration.datasets_from_catalog(catalog).items():
data_manager[dataset_name] = dataset
```
+
=== "app.py (Data Catalog configuration file)"
- ```py
+ ```python
from kedro.io import DataCatalog
import yaml
diff --git a/vizro-core/docs/pages/user-guides/layouts.md b/vizro-core/docs/pages/user-guides/layouts.md
index 8361560db..af66ec301 100644
--- a/vizro-core/docs/pages/user-guides/layouts.md
+++ b/vizro-core/docs/pages/user-guides/layouts.md
@@ -3,11 +3,10 @@
The [`Page`][vizro.models.Page] model accepts a `layout` argument that enables custom arrangement of charts and components on the screen. This guide shows how to customize the grid specifications in the [`Layout`][vizro.models.Layout].
## The default layout
-The `layout` argument of the [`Page`][vizro.models.Page] model is optional. If no layout is specified, all charts/components are automatically [**stacked vertically**](layouts.md#vertical-and-horizontal-stacking) on the page in one column.
-If you are happy with that arrangement, you can create your charts/components without providing a [`Layout`][vizro.models.Layout].
-!!! example "Default Layout"
+The `layout` argument of the [`Page`][vizro.models.Page] model is optional. If no layout is specified, all charts/components are automatically [**stacked vertically**](layouts.md#vertical-and-horizontal-stacking) on the page in one column. If you are happy with that arrangement, you can create your charts/components without providing a [`Layout`][vizro.models.Layout].
+!!! example "Default Layout"
=== "app.py"
```{.python pycafe-link}
from vizro import Vizro
@@ -23,35 +22,33 @@ If you are happy with that arrangement, you can create your charts/components wi
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:
- - text: |
- # Component 0
- type: card
- - text: |
- # Component 1
- type: card
- title: two_left
+ - components:
+ - text: |
+ # Component 0
+ type: card
+ - text: |
+ # Component 1
+ type: card
+ title: two_left
```
- === "Result"
- [![Layout]][Layout]
-
- [Layout]: ../../assets/user_guides/layout/two_left.png
-
+ === "Result"
+ [![Layout]][layout]
## Configure the grid
+
To customize the grid arrangement, configure the `grid` parameter of the [`Layout`][vizro.models.Layout] model.
The example below shows an example of a valid `grid`:
```python title="Basic example"
-grid = [[0, 1],
- [0, 2]]
+grid = [[0, 1], [0, 2]]
```
- The `grid` must be provided as `list[list[int]]` (for example, `grid = [[0, 1], [0, 2]]`).
@@ -64,16 +61,12 @@ grid = [[0, 1],
- The area spanned by a chart/component in the grid must be rectangular.
- The grid can be arbitrarily large, allowing arbitrarily granular control of the grid.
-
## Vertical and horizontal stacking
+
As described above, when no `Layout` is specified, components are presented **vertically** as a single-column stack. If you have three components, the default `Layout.grid` will be as follows, with three equally sized rows, each containing a component spanning the entire width:
```python title="Vertical stacking"
-grid = [
- [0],
- [1],
- [2]
- ]
+grid = [[0], [1], [2]]
```
To present components **horizontally** in one row:
@@ -89,8 +82,8 @@ This defines a single row that occupies the entire width and height, divided int
## Grid - basic example
-!!! example "Grid Arrangement - Basic Example"
+!!! example "Grid Arrangement - Basic Example"
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -109,39 +102,37 @@ This defines a single row that occupies the entire width and height, divided int
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:
- - text: |
- # Component 0
- type: card
- - text: |
- # Component 1
- type: card
- - text: |
- # Component 2
- type: card
- layout:
- grid: [[0, 1], [0, 2]]
- title: one_left_two_right
+ - components:
+ - text: |
+ # Component 0
+ type: card
+ - text: |
+ # Component 1
+ type: card
+ - text: |
+ # Component 2
+ type: card
+ layout:
+ grid: [[0, 1], [0, 2]]
+ title: one_left_two_right
```
- === "Result"
- [![Grid]][Grid]
- [Grid]: ../../assets/user_guides/layout/one_left_two_right.png
+ === "Result"
+ [![Grid]][grid]
## Grid - advanced example
If you want to divide the grid into subgrids with finer control over these, you can use [`Containers`](container.md). See our section on [when to use `Containers` vs. `Page.layout`](container.md#when-to-use-containers) for more information.
-The `Layout` provides full control over the arrangement of top-level components within a page,
-allowing arbitrarily granular control of the grid by creating larger grids.
+The `Layout` provides full control over the arrangement of top-level components within a page, allowing arbitrarily granular control of the grid by creating larger grids.
!!! example "Grid Arrangement - Advanced Example"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -208,6 +199,7 @@ allowing arbitrarily granular control of the grid by creating larger grids.
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
@@ -260,44 +252,44 @@ allowing arbitrarily granular control of the grid by creating larger grids.
grid: [[0, 1, 3, 4], [2, 2, 3, 4]]
title: Custom Layout - Advanced Example
```
- === "Result"
- [![GridAdv]][GridAdv]
- [GridAdv]: ../../assets/user_guides/layout/grid_advanced.png
+ === "Result"
+ [![GridAdv]][gridadv]
## Custom layout examples
+
Here is a reference table of example layouts:
+
one row with one component, second row with two components stacked horizontally
-| Layout needed | Grid | Code |
-|--------------------------------|----------------------------|-------------------------------------------------------------------------------------|
-| | | `layout=vm.Layout(grid=[[0]])` |
-| | | `layout=vm.Layout(grid=[[0],[1]])` |
-| | | `layout=vm.Layout(grid=[[0,1]])` |
-| | | `layout=vm.Layout(grid=[[0],[1],[2]])` or `layout=None` |
-| | | `layout=vm.Layout(grid=[[0,1],[0,2]])` |
-| | | `layout=vm.Layout(grid=[[0,0],[1,2]])` |
-| | | `layout=vm.Layout(grid=[[0,1],[2,2]])` |
-| | | `layout=vm.Layout(grid=[[0,1],[0,2],[0,3]])` |
-| | | `layout=vm.Layout(grid=[[0,1],[2,3]])` |
-| | | `layout=vm.Layout(grid=[[0,3],[1,3],[2,3]])` |
-| | | `layout=vm.Layout(grid=[[0,0,0],[1,2,3]])` |
-| | | `layout=vm.Layout(grid=[[0,1,2],[3,3,3]])` |
+| Layout needed | Grid | Code |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
+| | | `layout=vm.Layout(grid=[[0]])` |
+| | | `layout=vm.Layout(grid=[[0],[1]])` |
+| | | `layout=vm.Layout(grid=[[0,1]])` |
+| | | `layout=vm.Layout(grid=[[0],[1],[2]])` or `layout=None` |
+| | | `layout=vm.Layout(grid=[[0,1],[0,2]])` |
+| | | `layout=vm.Layout(grid=[[0,0],[1,2]])` |
+| | | `layout=vm.Layout(grid=[[0,1],[2,2]])` |
+| | | `layout=vm.Layout(grid=[[0,1],[0,2],[0,3]])` |
+| | | `layout=vm.Layout(grid=[[0,1],[2,3]])` |
+| | | `layout=vm.Layout(grid=[[0,3],[1,3],[2,3]])` |
+| | | `layout=vm.Layout(grid=[[0,0,0],[1,2,3]])` |
+| | | `layout=vm.Layout(grid=[[0,1,2],[3,3,3]])` |
## Add empty sections to the grid
+
One approach to organize the dashboard's layout involves integrating empty sections by specifying `-1` within the grid layout.
```python title="Example"
-grid = [[0, 1, -1],
- [0, 2, -1]]
+grid = [[0, 1, -1], [0, 2, -1]]
```
!!! example "Adding Empty Spaces"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -316,38 +308,38 @@ grid = [[0, 1, -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
# See yaml_version example
pages:
- - components:
- - text: |
- # Component 0
- type: card
- - text: |
- # Component 1
- type: card
- - text: |
- # Component 2
- type: card
- layout:
- grid: [[0, 1, -1], [0, 2, -1]]
- title: Adding empty spaces
+ - components:
+ - text: |
+ # Component 0
+ type: card
+ - text: |
+ # Component 1
+ type: card
+ - text: |
+ # Component 2
+ type: card
+ layout:
+ grid: [[0, 1, -1], [0, 2, -1]]
+ title: Adding empty spaces
```
- === "Result"
- [![GridEmpty]][GridEmpty]
- [GridEmpty]: ../../assets/user_guides/layout/layout_empty_spaces.png
+ === "Result"
+ [![GridEmpty]][gridempty]
## Control the scroll behavior
+
By default, the grid fits all charts/components on the screen. This can lead to distortions such that the chart/component looks squashed. To control the scroll behavior, you can specify the following:
- `row_min_height`: Sets a chart/component's minimum height. Defaults to 0px.
- `col_min_width`: Sets a chart/component's minimum width. Defaults to 0px.
!!! example "Activate Scrolling"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -371,59 +363,63 @@ By default, the grid fits all charts/components on the screen. This can lead to
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:
- - text: |
- # Component 0
- type: card
- - text: |
- # Component 1
- type: card
- - text: |
- # Component 2
- type: card
- - text: |
- # Component 2
- type: card
- - text: |
- # Component 4
- type: card
- - text: |
- # Component 5
- type: card
- - text: |
- # Component 6
- type: card
- - text: |
- # Component 7
- type: card
- layout:
- grid: [[0], [1], [2], [3], [4], [5], [6], [7]]
- row_min_height: 240px
- title: Activate scrolling
+ - components:
+ - text: |
+ # Component 0
+ type: card
+ - text: |
+ # Component 1
+ type: card
+ - text: |
+ # Component 2
+ type: card
+ - text: |
+ # Component 2
+ type: card
+ - text: |
+ # Component 4
+ type: card
+ - text: |
+ # Component 5
+ type: card
+ - text: |
+ # Component 6
+ type: card
+ - text: |
+ # Component 7
+ type: card
+ layout:
+ grid: [[0], [1], [2], [3], [4], [5], [6], [7]]
+ row_min_height: 240px
+ title: Activate scrolling
```
- === "Result"
- [![GridScroll]][GridScroll]
-
- [GridScroll]: ../../assets/user_guides/layout/grid_scroll.png
+ === "Result"
+ [![GridScroll]][gridscroll]
## Further customization
-For further customization, such as changing the gap between row and column, refer to the
-documentation of the [`Layout`][vizro.models.Layout] model.
+
+For further customization, such as changing the gap between row and column, refer to the documentation of the [`Layout`][vizro.models.Layout] model.
## Alternative layout approaches
+
In general, any arbitrarily granular layout can already be achieved using [`Page.layout`](layouts.md) alone and is our recommended approach if you want to arrange components on a page with consistent row and/or column spacing.
!!! note "Alternative layout approaches: `Tabs` and `Containers`"
-
- [`Tabs`][vizro.models.Tabs] and [`Containers`][vizro.models.Container] provide an alternative approach to customize your page layout.
- For example, if you want to have more granular control and break the overall page grid into subgrids, see our [user guide on Containers](container.md).
+ [`Tabs`][vizro.models.Tabs] and [`Containers`][vizro.models.Container] offer an alternative approach to customize your page layout. For example, if you want to have more granular control and break the overall page grid into subgrids, see our [user guide on Containers](container.md).
If you want to display multiple containers on one page by putting them into the same screen space, and letting the user switch between them, see our [user guide on Tabs](tabs.md).
![tabs](../../assets/user_guides/components/tabs-info.png){ width="500" }
+
+[grid]: ../../assets/user_guides/layout/one_left_two_right.png
+[gridadv]: ../../assets/user_guides/layout/grid_advanced.png
+[gridempty]: ../../assets/user_guides/layout/layout_empty_spaces.png
+[gridscroll]: ../../assets/user_guides/layout/grid_scroll.png
+[layout]: ../../assets/user_guides/layout/two_left.png
diff --git a/vizro-core/docs/pages/user-guides/navigation.md b/vizro-core/docs/pages/user-guides/navigation.md
index 41c6bb9dc..75a661470 100644
--- a/vizro-core/docs/pages/user-guides/navigation.md
+++ b/vizro-core/docs/pages/user-guides/navigation.md
@@ -2,8 +2,7 @@
This guide shows you how to use and customize the navigation that appears on the left of your dashboard.
-The [`Dashboard`][vizro.models.Dashboard] model accepts a `navigation` argument, where you can enter a [`Navigation`][vizro.models.Navigation] model. This enables you to group pages together and customize how they appear in your navigation.
-The dashboard includes a collapsible side panel that users can minimize or expand by a button click. The collapse button, located in the top right corner of the side panel, is visible by default for user convenience.
+The [`Dashboard`][vizro.models.Dashboard] model accepts a `navigation` argument, where you can enter a [`Navigation`][vizro.models.Navigation] model. This enables you to group pages together and customize how they appear in your navigation. The dashboard includes a collapsible side panel that users can minimize or expand by a button click. The collapse button, located in the top right corner of the side panel, is visible by default for user convenience.
## Use the default navigation
@@ -56,8 +55,8 @@ By default, if the `navigation` argument is not specified, Vizro creates a navig
type: graph
title: My first page
- components:
- - text: My text here
- type: card
+ - text: My text here
+ type: card
title: My second page
- components:
- figure:
@@ -69,10 +68,9 @@ By default, if the `navigation` argument is not specified, Vizro creates a navig
type: graph
title: My third page
```
- === "Result"
- [![DefaultNavigation]][DefaultNavigation]
- [DefaultNavigation]: ../../assets/user_guides/navigation/default_navigation.png
+ === "Result"
+ [![DefaultNavigation]][defaultnavigation]
## Include a subset of pages
@@ -132,17 +130,15 @@ To include only some of your dashboard pages in your navigation then list them i
- My first page
- My second page
```
- === "Result"
- [![OnlySomePages]][OnlySomePages]
- [OnlySomePages]: ../../assets/user_guides/navigation/only_some_pages.png
+ === "Result"
+ [![OnlySomePages]][onlysomepages]
## Group pages
You can also group your pages together by specifying `pages` as a dictionary:
!!! example "Grouping pages"
-
=== "snippet.py"
```py
# page_1, page_2, page_3 defined as in default example
@@ -154,7 +150,6 @@ You can also group your pages together by specifying `pages` as a dictionary:
```
=== "app.py"
-
```{.python pycafe-link}
from vizro import Vizro
import vizro.plotly.express as px
@@ -187,6 +182,7 @@ You can also group your pages together by specifying `pages` as a dictionary:
)
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -200,18 +196,15 @@ You can also group your pages together by specifying `pages` as a dictionary:
Group B:
- My third page
```
- === "Result"
- [![GroupedNavigation]][GroupedNavigation]
-
- [GroupedNavigation]: ../../assets/user_guides/navigation/grouped_navigation.png
+ === "Result"
+ [![GroupedNavigation]][groupednavigation]
## Use a navigation bar with icons
Another way to group together pages in the navigation is to use a [`NavBar`][vizro.models.NavBar] with icons. The simplest way to use this is to change the `nav_selector` specified in [`Navigation`][vizro.models.Navigation]:
!!! example "Using `NavBar`"
-
=== "snippet.py"
```py
# page_1, page_2, page_3 defined as in default example
@@ -223,8 +216,8 @@ Another way to group together pages in the navigation is to use a [`NavBar`][viz
)
Vizro().build(dashboard).run()
```
- === "app.py"
+ === "app.py"
```{.python pycafe-link}
from vizro import Vizro
import vizro.plotly.express as px
@@ -276,14 +269,11 @@ Another way to group together pages in the navigation is to use a [`NavBar`][viz
nav_selector:
type: nav_bar
```
- === "Result"
- [![NavBar]][NavBar]
-
- [NavBar]: ../../assets/user_guides/navigation/nav_bar.png
+ === "Result"
+ [![NavBar]][navbar]
-Here, the first level of the navigation hierarchy ("Group A" and "Group B") is represented by an icon in a navigation bar, and the second level of the navigation (the pages) is represented by an accordion.
-By default, the set of icons used are the [`filter` icons from the Google Material icons library](https://fonts.google.com/icons?icon.query=filter). The icon label ("Group A" and "Group B") appears as a tooltip on hovering over the icon.
+Here, the first level of the navigation hierarchy ("Group A" and "Group B") is represented by an icon in a navigation bar, and the second level of the navigation (the pages) is represented by an accordion. By default, the set of icons used are the [`filter` icons from the Google Material icons library](https://fonts.google.com/icons?icon.query=filter). The icon label ("Group A" and "Group B") appears as a tooltip on hovering over the icon.
## Customize the navigation bar
@@ -314,7 +304,6 @@ The same configuration for [grouping pages](#group-pages) applies inside a `NavL
```
=== "app.py"
-
```{.python pycafe-link}
from vizro import Vizro
import vizro.plotly.express as px
@@ -375,10 +364,9 @@ The same configuration for [grouping pages](#group-pages) applies inside a `NavL
Group B:
- My third page
```
- === "Result"
- [![AccordionInsideNavBar]][AccordionInsideNavBar]
- [AccordionInsideNavBar]: ../../assets/user_guides/navigation/accordion_inside_nav_bar.png
+ === "Result"
+ [![AccordionInsideNavBar]][accordioninsidenavbar]
You can alter the icons used by specifying the name of the icon in the [Google Material icons library](https://fonts.google.com/icons):
@@ -402,8 +390,8 @@ You can alter the icons used by specifying the name of the icon in the [Google M
),
)
```
- === "app.py"
+ === "app.py"
```{.python pycafe-link}
from vizro import Vizro
import vizro.plotly.express as px
@@ -468,7 +456,13 @@ You can alter the icons used by specifying the name of the icon in the [Google M
pages:
- My third page
```
- === "Result"
- [![CustomIcons]][CustomIcons]
- [CustomIcons]: ../../assets/user_guides/navigation/custom_icons.png
+ === "Result"
+ [![CustomIcons]][customicons]
+
+[accordioninsidenavbar]: ../../assets/user_guides/navigation/accordion_inside_nav_bar.png
+[customicons]: ../../assets/user_guides/navigation/custom_icons.png
+[defaultnavigation]: ../../assets/user_guides/navigation/default_navigation.png
+[groupednavigation]: ../../assets/user_guides/navigation/grouped_navigation.png
+[navbar]: ../../assets/user_guides/navigation/nav_bar.png
+[onlysomepages]: ../../assets/user_guides/navigation/only_some_pages.png
diff --git a/vizro-core/docs/pages/user-guides/pages.md b/vizro-core/docs/pages/user-guides/pages.md
index 7ae944e9b..71e01e9f9 100644
--- a/vizro-core/docs/pages/user-guides/pages.md
+++ b/vizro-core/docs/pages/user-guides/pages.md
@@ -1,7 +1,6 @@
# How to use pages
-This guide shows you how to add pages to your dashboard and customize the URL paths if needed.
-A [`Page`][vizro.models.Page] lets you place and arrange your dashboard content (for example, chart/components, tables, and text)
-and configure your dashboard interactions (such as filters and parameters).
+
+This guide shows you how to add pages to your dashboard and customize the URL paths if needed. A [`Page`][vizro.models.Page] lets you place and arrange your dashboard content (for example, chart/components, tables, and text) and configure your dashboard interactions (such as filters and parameters).
The [`Dashboard`][vizro.models.Dashboard] model accepts the `pages` argument, where you can insert your [`Page`][vizro.models.Page].
@@ -10,19 +9,19 @@ The [`Dashboard`][vizro.models.Dashboard] model accepts the `pages` argument, wh
A [`Page`][vizro.models.Page] is split up into four main containers:
1. The **navigation container** where you can customize your `navigation` (see [Dashboard](dashboard.md) and [Navigation](navigation.md) for more information). Note that the navigation container needs to be configured via the Dashboard.
-2. The **control container** where you can add your `controls` (see [Filters](filters.md) or [Parameters](parameters.md)) to interact with the dashboard
-3. The **page header** that contains the page title and the theme toggle switch button
-4. The **component container** where you can add your [components](components.md) to visualize your data
+1. The **control container** where you can add your `controls` (see [Filters](filters.md) or [Parameters](parameters.md)) to interact with the dashboard
+1. The **page header** that contains the page title and the theme toggle switch button
+1. The **component container** where you can add your [components](components.md) to visualize your data
![Page Container](../../assets/user_guides/pages/page_containers.png)
To create and add a page to your dashboard, do the following steps:
1. Set a `title` for your [`Page`][vizro.models.Page]
-2. Configure your `components`, see our guide on the [various options](components.md)
-3. (optional) Configure your `controls` , see our guides on [Filters](filters.md) and [Parameters](parameters.md)
-4. (optional) Configure your `layout` , see our guide on [Layouts](layouts.md)
-5. (optional) Give a `description` of your `Page` to the app's [meta tags](https://metatags.io/)
+1. Configure your `components`, see our guide on the [various options](components.md)
+1. (optional) Configure your `controls` , see our guides on [Filters](filters.md) and [Parameters](parameters.md)
+1. (optional) Configure your `layout` , see our guide on [Layouts](layouts.md)
+1. (optional) Give a `description` of your `Page` to the app's [meta tags](https://metatags.io/)
!!! example "Page"
=== "app.py"
@@ -51,51 +50,47 @@ To create and add a page to your dashboard, do the following steps:
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_: sunburst
- path: ['continent', 'country']
- values: pop
- color: lifeExp
- data_frame: gapminder
- id: sunburst
- type: graph
- controls:
- - column: continent
- targets:
- - sunburst
- type: filter
- - selector:
- options: ['lifeExp', 'pop']
- title: Color
- type: radio_items
- targets:
- - sunburst.color
- type: parameter
- title: Page Title
- description: "Longer description of the page content"
+ - components:
+ - figure:
+ _target_: sunburst
+ path: [continent, country]
+ values: pop
+ color: lifeExp
+ data_frame: gapminder
+ id: sunburst
+ type: graph
+ controls:
+ - column: continent
+ targets: [sunburst]
+ type: filter
+ - selector:
+ options: [lifeExp, pop]
+ title: Color
+ type: radio_items
+ targets: [sunburst.color]
+ type: parameter
+ title: Page Title
+ description: Longer description of the page content
```
- === "Result"
- [![Page]][Page]
- [Page]: ../../assets/user_guides/pages/page_sunburst.png
+ === "Result"
+ [![Page]][page]
An accordion page selector is automatically added to your dashboard in the top-left of the control container for through the different pages. It will not be added if your dashboard consists of only one page.
You can additionally navigate through the different pages by going directly to the relevant page URL (more details in next section).
-
## Customize the page URL
-By default, the page URL is automatically generated based on the `id` of the page. For example, if `id="This is my first page"`
-the generated page URL will be `path=this-is-my-first-page`. You can then access the page via `localhost:/this-is-my-first-page`.
-Note that the page `id` defaults to be the same as the page `title` if not set.
-If you have multiple pages with the same `title` then you must assign a unique `id`.
+By default, the page URL is automatically generated based on the `id` of the page. For example, if `id="This is my first page"` the generated page URL will be `path=this-is-my-first-page`. You can then access the page via `localhost:/this-is-my-first-page`.
+
+Note that the page `id` defaults to be the same as the page `title` if not set. If you have multiple pages with the same `title` then you must assign a unique `id`.
The first page always has the URL prefix `/` assigned. A custom URL can, therefore, not be created for the first page.
@@ -137,39 +132,40 @@ To customize the page URL, pass a valid URL name to the `path` argument of [`Pag
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:
- - text: |
- Commodi repudiandae consequuntur voluptatum.
- type: card
- title: Page 1
- - components:
- - figure:
- _target_: sunburst
- path: ['continent', 'country']
- values: pop
- color: lifeExp
- data_frame: gapminder
- id: sunburst
- type: graph
- controls:
- - column: continent
- targets:
- - sunburst
- type: filter
- - selector:
- options: ['lifeExp', 'pop']
- title: Color
- type: radio_items
- targets:
- - sunburst.color
- type: parameter
- title: Page 2
- path: my-custom-url
+ - components:
+ - text: |
+ Commodi repudiandae consequuntur voluptatum.
+ type: card
+ title: Page 1
+ - components:
+ - figure:
+ _target_: sunburst
+ path: [continent, country]
+ values: pop
+ color: lifeExp
+ data_frame: gapminder
+ id: sunburst
+ type: graph
+ controls:
+ - column: continent
+ targets: [sunburst]
+ type: filter
+ - selector:
+ options: [lifeExp, pop]
+ title: Color
+ type: radio_items
+ targets: [sunburst.color]
+ type: parameter
+ title: Page 2
+ path: my-custom-url
```
You can now access the first page via `localhost:/` and the second page via `localhost:/my-custom-url`.
+
+[page]: ../../assets/user_guides/pages/page_sunburst.png
diff --git a/vizro-core/docs/pages/user-guides/parameters.md b/vizro-core/docs/pages/user-guides/parameters.md
index bb39a7a0c..c82707d4a 100644
--- a/vizro-core/docs/pages/user-guides/parameters.md
+++ b/vizro-core/docs/pages/user-guides/parameters.md
@@ -9,8 +9,8 @@ The [`Page`][vizro.models.Page] model accepts the `controls` argument, where you
To add a parameter to your page, do the following:
1. add the [`Parameter`][vizro.models.Parameter] model into the `controls` argument of the [`Page`][vizro.models.Page] model.
-2. add the `targets` argument
-3. add a selector model to the `selector` argument.
+1. add the `targets` argument
+1. add a selector model to the `selector` argument.
In the `targets` argument, you can specify the component and function argument that the parameter should be applied to in the form of `.` (for example, `scatter_chart.title`).
@@ -48,6 +48,7 @@ Unlike for the [`Filter`][vizro.models.Filter] model, you also have to configure
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -64,18 +65,17 @@ Unlike for the [`Filter`][vizro.models.Filter] model, you also have to configure
type: graph
controls:
- selector:
- options: ["My scatter chart", "A better title!", "Another title..."]
- multi: False
+ options: [My scatter chart, A better title!, Another title...]
+ multi: false
type: dropdown
targets:
- scatter_chart.title
type: parameter
title: My first page
```
- === "Result"
- [![Parameter]][Parameter]
- [Parameter]: ../../assets/user_guides/control/control4.png
+ === "Result"
+ [![Parameter]][parameter]
If you would like to pass `None` as a parameter and make a parameter optional, you can specify the string `"NONE"` in the `options` or `value` field.
@@ -133,6 +133,7 @@ If you want to change nested parameters, you can specify the `targets` argument
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -146,7 +147,7 @@ If you want to change nested parameters, you can specify the `targets` argument
y: sepal_length
size: petal_length
color: species
- color_discrete_map: {"setosa": "#00b4ff", "versicolor": "#ff9222"}
+ color_discrete_map: {setosa: '#00b4ff', versicolor: '#ff9222'}
id: scatter_chart
type: graph
- figure:
@@ -155,23 +156,22 @@ If you want to change nested parameters, you can specify the `targets` argument
x: sepal_width
y: sepal_length
color: species
- color_discrete_map: {"setosa": "#00b4ff", "versicolor": "#ff9222"}
+ color_discrete_map: {setosa: '#00b4ff', versicolor: '#ff9222'}
id: bar_chart
type: graph
controls:
- selector:
- options: ["#ff5267", "#3949ab"]
+ options: ['#ff5267', '#3949ab']
value: #3949ab
- multi: False
+ multi: false
type: dropdown
- targets: ["scatter_chart.color_discrete_map.virginica", "bar_chart.color_discrete_map.virginica"]
+ targets: [scatter_chart.color_discrete_map.virginica, bar_chart.color_discrete_map.virginica]
type: parameter
title: My first page
```
- === "Result"
- [![Nested]][Nested]
- [Nested]: ../../assets/user_guides/control/control5.png
+ === "Result"
+ [![Nested]][nested]
In the above example, the object passed to the function argument `color_discrete_map` is a dictionary which maps the different flower species to fixed colors (for example, `{"virginica":"blue"}`). In this case, only the value `blue` should be changed instead of the entire dictionary. This can be achieved by specifying a target as `scatter.color_discrete_map.virginica`.
@@ -180,3 +180,6 @@ Note that in the above example, one parameter affects multiple targets.
## Dynamic data parameters
If you use [dynamic data](data.md/#dynamic-data) that can be updated while the dashboard is running then you can pass parameters to the dynamic data function to alter the data loaded into your dashboard. For detailed instructions, refer to the section on [parametrized data loading](data.md/#parametrize-data-loading).
+
+[nested]: ../../assets/user_guides/control/control5.png
+[parameter]: ../../assets/user_guides/control/control4.png
diff --git a/vizro-core/docs/pages/user-guides/run.md b/vizro-core/docs/pages/user-guides/run.md
index df52e8c14..028eb5027 100644
--- a/vizro-core/docs/pages/user-guides/run.md
+++ b/vizro-core/docs/pages/user-guides/run.md
@@ -15,7 +15,6 @@ Most of our examples have a link below the code, [Run and edit this code in PyCa
You can use [PyCafe](https://py.cafe/snippet/vizro/v1) snippet mode to experiment with your own Vizro dashboards by dropping code into a new project.
-
## Default built-in Flask development server
!!! example "Default built-in Flask development server"
@@ -38,9 +37,10 @@ You can use [PyCafe](https://py.cafe/snippet/vizro/v1) snippet mode to experimen
Vizro().build(dashboard).run()
```
+
1. create a Python file named `app.py`.
-2. type the command `python app.py` into your terminal.
-3. information below will be displayed in your terminal, go to [http://127.0.0.1:8050/](http://127.0.0.1:8050/).
+1. type the command `python app.py` into your terminal.
+1. information below will be displayed in your terminal, go to [http://127.0.0.1:8050/](http://127.0.0.1:8050/).
```
Dash is running on http://127.0.0.1:8050/
@@ -51,8 +51,7 @@ INFO:werkzeug:WARNING: This is a development server. Do not use it in a producti
```
!!! warning "In production"
-
- As per the above warning message, which is [further explained in the Flask documentation](https://flask.palletsprojects.com/en/3.0.x/deploying/), the Flask development server is intended for use only during local development and **should not** be used when deploying to production. Instead, you should instead use a production-ready solution such as [Gunicorn](#gunicorn).
+ The above warning message is [further explained in the Flask documentation](https://flask.palletsprojects.com/en/3.0.x/deploying/). The Flask development server is intended for use only during local development and **should not** be used when deploying to production. Instead, you should instead use a production-ready solution such as [Gunicorn](#gunicorn).
### Automatic reloading and debugging
@@ -64,11 +63,11 @@ Setting `debug=True` enables [Dash Dev Tools](https://dash.plotly.com/devtools).
In addition, some errors generated at run time can also be viewed via the browser console (for example in `Chrome` see `View > Developer > Developer Tools > Console`).
-
## Jupyter
+
The dashboard application can be launched in a Jupyter environment in `inline`, `external`, and `jupyterlab` mode.
-!!! example "Run in a Jupyter Notebook in inline mode"
+!!! example "Run in a Jupyter Notebook in inline mode"
=== "app.ipynb"
```py linenums="1"
from vizro import Vizro
@@ -87,16 +86,16 @@ The dashboard application can be launched in a Jupyter environment in `inline`,
dashboard = vm.Dashboard(pages=[page])
Vizro().build(dashboard).run(jupyter_mode="external")
```
+
- by default, the mode is set to `inline` in `run()` and the dashboard will be displayed inside your Jupyter environment.
- you can specify `jupyter_mode="external"` and a link will be displayed to direct you to the localhost where the dashboard is running.
- you can use tab mode by `jupyter_mode="tab"` to automatically open the app in a new browser
!!! note "Reloading and debugging"
-
Code reloading and hot reloading do not work within a Jupyter Notebook. Instead, there are two methods to reload the dashboard:
- * Restart the Jupyter kernel and re-run your notebook.
- * Add a cell containing `from vizro import Vizro; Vizro._reset()` to the top of your notebook and re-run it. With this method, there is no need to restart the Jupyter kernel.
+ - Restart the Jupyter kernel and re-run your notebook.
+ - Add a cell containing `from vizro import Vizro; Vizro._reset()` to the top of your notebook and re-run it. With this method, there is no need to restart the Jupyter kernel.
## Gunicorn
@@ -126,17 +125,18 @@ The dashboard application can be launched in a Jupyter environment in `inline`,
```
1. The Vizro `app` object is a WSGI application that exposes the underlying Flask app; this will be used by Gunicorn.
- 2. Enable the same app to still be run using the built-in Flask server with `python app.py` for development purposes.
+ 1. Enable the same app to still be run using the built-in Flask server with `python app.py` for development purposes.
To run using Gunicorn with four worker processes, execute
+
```bash
gunicorn app:app --workers 4
```
+
in the command line. For more Gunicorn configuration options, refer to [Gunicorn documentation](https://docs.gunicorn.org/).
!!! warning "In production"
-
- If your dashboard uses [dynamic data](data.md#dynamic-data) that can be refreshed while the dashboard is running then you should [configure your data manager cache](data.md#configure-cache) to use a backend that supports multiple processes.
+ If your dashboard uses [dynamic data](data.md#dynamic-data) that can be refreshed while the dashboard is running then you should [configure your data manager cache](data.md#configure-cache) to use a back end that supports multiple processes.
## Deployment
@@ -149,6 +149,6 @@ Internally, `app = Vizro()` contains a Flask app in `app.dash.server`. However,
[`Vizro`][vizro.Vizro] accepts `**kwargs` that are passed through to `Dash`. This enables you to configure the underlying Dash app using the same [arguments that are available](https://dash.plotly.com/reference#dash.dash) in `Dash`. For example, in a deployment context, these arguments may be useful:
-- `url_base_pathname`: serve your Vizro app at a specific path rather than at the domain root. For example, if you host your dashboard at http://www.example.com/my_dashboard/ then you would set `url_base_pathname="/my_dashboard/"` or an environment variable `DASH_URL_BASE_PATHNAME="/my_dashboard/"`.
+- `url_base_pathname`: serve your Vizro app at a specific path rather than at the domain root. For example, if you host your dashboard at `http://www.example.com/my_dashboard/` then you would set `url_base_pathname="/my_dashboard/"` or an environment variable `DASH_URL_BASE_PATHNAME="/my_dashboard/"`.
- `serve_locally`: set to `False` to [serve Dash component libraries from a Content Delivery Network (CDN)](https://dash.plotly.com/external-resources#serving-dash's-component-libraries-locally-or-from-a-cdn), which reduces load on the server and can improve performance. Vizro uses [jsDeliver](https://www.jsdelivr.com/) as a CDN for CSS and JavaScript sources.
- `assets_external_path`: when `serve_locally=False`, you can also set `assets_external_path` or an environment variable `DASH_ASSETS_EXTERNAL_PATH` to [serve your own assets from a CDN](https://dash.plotly.com/external-resources#load-assets-from-a-folder-hosted-on-a-cdn).
diff --git a/vizro-core/docs/pages/user-guides/selectors.md b/vizro-core/docs/pages/user-guides/selectors.md
index 10481d2ba..a1bd4be20 100644
--- a/vizro-core/docs/pages/user-guides/selectors.md
+++ b/vizro-core/docs/pages/user-guides/selectors.md
@@ -6,10 +6,7 @@ The [`Filter`][vizro.models.Filter] or the [`Parameter`][vizro.models.Parameter]
## Categorical selectors
-Within the categorical selectors, a clear distinction exists between multi-option and single-option selectors.
-For instance, the [`Checklist`][vizro.models.Checklist] functions as a multi-option selector by default while
-the [`RadioItem`][vizro.models.RadioItems] serves as a single-option selector by default. However, the
-[`Dropdown`][vizro.models.Dropdown] can function as both a multi-option or single-option selector.
+Within the categorical selectors, a clear distinction exists between multi-option and single-option selectors. For instance, the [`Checklist`][vizro.models.Checklist] functions as a multi-option selector by default while the [`RadioItem`][vizro.models.RadioItems] serves as a single-option selector by default. However, the [`Dropdown`][vizro.models.Dropdown] can function as both a multi-option or single-option selector.
For more information, refer to the API reference of the selector, or the documentation of its underlying Dash component:
@@ -18,15 +15,12 @@ For more information, refer to the API reference of the selector, or the documen
- [`RadioItems`][vizro.models.RadioItems] based on [`dcc.RadioItems`](https://dash.plotly.com/dash-core-components/radioitems)
!!! note
-
- When configuring the `options` of the categorical selectors, you can either provide:
+ When configuring the `options` of the categorical selectors, you can either give:
- a list of values `options = ['Value A', 'Value B', 'Value C']`
- or a dictionary of label-value mappings `options=[{'label': 'True', 'value': True}, {'label': 'False', 'value': False}]`
- The later is required if you want to provide different display labels to your option values or in case you want to
- provide boolean values as options. In this case, you need to provide a string label for your boolean values as
- boolean values cannot be displayed properly as labels in the underlying Dash components.
+ The later is required if you want to provide different display labels to your option values or in case you want to provide boolean values as options. In this case, you need to provide a string label for your boolean values as boolean values cannot be displayed properly as labels in the underlying Dash components.
## Numerical selectors
@@ -36,11 +30,7 @@ For more information, refer to the API reference of the selector, or the documen
- [`RangeSlider`][vizro.models.RangeSlider] based on [`dcc.RangeSlider`](https://dash.plotly.com/dash-core-components/rangeslider)
!!! note
-
- When configuring the [`Slider`][vizro.models.Slider] and the [`RangeSlider`][vizro.models.RangeSlider] with float values, and using `step` with an integer value, you may notice
- unexpected behavior, such as the drag value being outside its indicated marks.
- To our knowledge, this is a current bug in the underlying [`dcc.Slider`](https://dash.plotly.com/dash-core-components/slider) and
- [`dcc.RangeSlider`](https://dash.plotly.com/dash-core-components/rangeslider) component, which you can circumvent by adapting the `step` size accordingly.
+ When configuring the [`Slider`][vizro.models.Slider] and the [`RangeSlider`][vizro.models.RangeSlider] with float values, and using `step` with an integer value, you may notice unexpected behavior, such as the drag value being outside its indicated marks. To our knowledge, this is a current bug in the underlying [`dcc.Slider`](https://dash.plotly.com/dash-core-components/slider) and [`dcc.RangeSlider`](https://dash.plotly.com/dash-core-components/rangeslider) component, which you can circumvent by adapting the `step` size as needed.
## Temporal selectors
@@ -49,7 +39,6 @@ For more information, refer to the API reference of the selector, or the documen
- [`DatePicker`][vizro.models.DatePicker] based on [`dmc.DateRangePicker`](https://www.dash-mantine-components.com/components/datepicker#daterangepicker) and [`dmc.DatePicker`](https://www.dash-mantine-components.com/components/datepicker)
!!! note
-
When the [`DatePicker`][vizro.models.DatePicker] is configured with `range=True` (the default), the underlying component is `dmc.DateRangePicker`. When `range=False` the underlying component is `dmc.DatePicker`.
When configuring the [`DatePicker`][vizro.models.DatePicker] make sure to provide your dates for `min`, `max` and `value` arguments in `"yyyy-mm-dd"` format or as `datetime` type (for example, `datetime.datetime(2024, 01, 01)`).
diff --git a/vizro-core/docs/pages/user-guides/table.md b/vizro-core/docs/pages/user-guides/table.md
index 19197c465..80e8e53dc 100755
--- a/vizro-core/docs/pages/user-guides/table.md
+++ b/vizro-core/docs/pages/user-guides/table.md
@@ -2,46 +2,32 @@
This guide shows you how to visualize tables in Vizro.
-There are two ways to visualize tables in Vizro, using either [AG Grid](#ag-grid) or [Dash DataTable](#dash-datatable).
-In general, [AG Grid](#ag-grid) is Vizro's recommended table implementation, but sometimes it may make sense to use the [Dash DataTable](#dash-datatable) instead.
+There are two ways to visualize tables in Vizro, using either [AG Grid](#ag-grid) or [Dash DataTable](#dash-datatable). In general, [AG Grid](#ag-grid) is Vizro's recommended table implementation, but sometimes it may make sense to use the [Dash DataTable](#dash-datatable) instead.
## Choose between AG Grid and Dash DataTable
-Vizro offers two models - the [`AgGrid`][vizro.models.AgGrid] model and the [`Table`][vizro.models.Table] model - for the above two approaches respectively.
-They both visualize tabular data in similar ways.
+Vizro offers two models - the [`AgGrid`][vizro.models.AgGrid] model and the [`Table`][vizro.models.Table] model - for the above two approaches respectively. They both visualize tabular data in similar ways.
-The main difference between the two is that the [`AgGrid`][vizro.models.AgGrid] model is based on Plotly's [Dash AG Grid](https://dash.plotly.com/dash-ag-grid) component,
-while the [`Table`][vizro.models.Table] model is based on the [Dash DataTable](https://dash.plotly.com/datatable) component.
-
-Both approaches have similar base features, and are configurable in similar ways. However, the AG Grid offers more advanced features out-of-the-box, is more customizable
-and also ships a powerful enterprise version. This is why it is Vizro's recommended table implementation. At the same time, the Dash DataTable can be used if developers are
-already familiar with it, or if some custom functionality is easier to implement using the Dash DataTable.
+The main difference between the two is that the [`AgGrid`][vizro.models.AgGrid] model is based on Plotly's [Dash AG Grid](https://dash.plotly.com/dash-ag-grid) component, while the [`Table`][vizro.models.Table] model is based on the [Dash DataTable](https://dash.plotly.com/datatable) component.
+Both approaches have similar base features, and are configurable in similar ways. However, the AG Grid offers more advanced features out-of-the-box, is more customizable and also ships a powerful enterprise version. This is why it is Vizro's recommended table implementation. At the same time, the Dash DataTable can be used if developers are already familiar with it, or if some custom functionality is easier to implement using the Dash DataTable.
## AG Grid
-[AG Grid](https://www.ag-grid.com/) is an interactive table/grid component designed for viewing, editing, and exploring large datasets. It
-is Vizro's recommended table implementation.
+[AG Grid](https://www.ag-grid.com/) is an interactive table/grid component designed for viewing, editing, and exploring large datasets. It is Vizro's recommended table implementation.
-The Vizro [`AgGrid`][vizro.models.AgGrid] model is based on the [Dash AG Grid](https://dash.plotly.com/dash-ag-grid), which is in turn based the
-original [Javascript implementation](https://www.ag-grid.com/).
+The Vizro [`AgGrid`][vizro.models.AgGrid] model is based on the [Dash AG Grid](https://dash.plotly.com/dash-ag-grid), which is in turn based the original [Javascript implementation](https://www.ag-grid.com/).
### Basic usage
To add a [`AgGrid`][vizro.models.AgGrid] to your page, do the following:
-1. Insert the [`AgGrid`][vizro.models.AgGrid] model into the `components` argument of the
-[`Page`][vizro.models.Page] model.
-2. Enter the `dash_ag_grid` function under the `figure` argument (imported via `from vizro.tables import dash_ag_grid`).
-
-The Vizro version of this AG Grid differs in one way from the original Dash AG Grid: it requires the user to pass a pandas DataFrame as the source of data.
-As explained in [our guide to using data in Vizro](data.md), this must be entered under the argument `data_frame`. Most other [parameters of the Dash AG Grid](https://dash.plotly.com/dash-ag-grid/reference) can be entered as keyword arguments.
-Note that some defaults are set for some arguments (for example, for `columnDefs`) to help with styling and usability.
-Sometimes a parameter may not work because it requires a callback to function. In that case you can try [creating a custom AG Grid callable](custom-tables.md).
+1. Insert the [`AgGrid`][vizro.models.AgGrid] model into the `components` argument of the [`Page`][vizro.models.Page] model.
+1. Enter the `dash_ag_grid` function under the `figure` argument (imported via `from vizro.tables import dash_ag_grid`).
+The Vizro version of this AG Grid differs in one way from the original Dash AG Grid: it requires the user to pass a pandas DataFrame as the source of data. As explained in [our guide to using data in Vizro](data.md), this must be entered under the argument `data_frame`. Most other [parameters of the Dash AG Grid](https://dash.plotly.com/dash-ag-grid/reference) can be entered as keyword arguments. Note that some defaults are set for some arguments (for example, for `columnDefs`) to help with styling and usability. Sometimes a parameter may not work because it requires a callback to function. In that case you can try [creating a custom AG Grid callable](custom-tables.md).
!!! example "Basic Dash AG Grid"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -59,29 +45,28 @@ Sometimes a parameter may not work because it requires a callback to function. I
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
# See from_yaml example
pages:
- - components:
- - figure:
- _target_: dash_ag_grid
- data_frame: gapminder
- type: ag_grid
- title: Default Dash AG Grid
+ - components:
+ - figure:
+ _target_: dash_ag_grid
+ data_frame: gapminder
+ type: ag_grid
+ title: Default Dash AG Grid
```
- === "Result"
- [![AGGrid]][AGGrid]
- [AGGrid]: ../../assets/user_guides/table/aggrid.png
+ === "Result"
+ [![AGGrid]][aggrid]
### Enable pagination
-Pagination is a visual alternative to using vertical scroll. It can also improve loading time if you have many rows.
-You can turn it on by setting `dashGridOptions={"pagination": True}`.
-!!! example "Basic Dash AG Grid"
+Pagination is a visual alternative to using vertical scroll. It can also improve loading time if you have many rows. You can turn it on by setting `dashGridOptions={"pagination": True}`.
+!!! example "Basic Dash AG Grid"
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -99,37 +84,34 @@ You can turn it on by setting `dashGridOptions={"pagination": True}`.
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
# See from_yaml example
pages:
- - components:
- - figure:
- _target_: dash_ag_grid
- data_frame: gapminder
- dashGridOptions:
- pagination: true
- type: ag_grid
- title: Dash AG Grid with pagination
+ - components:
+ - figure:
+ _target_: dash_ag_grid
+ data_frame: gapminder
+ dashGridOptions:
+ pagination: true
+ type: ag_grid
+ title: Dash AG Grid with pagination
```
- === "Result"
- [![AGGrid]][AGGrid]
- [AGGrid]: ../../assets/user_guides/table/aggrid-pagination.png
+ === "Result"
+ [![AGGrid]][aggrid]
### Formatting columns
#### Numbers
-One of the most common tasks when working with tables is to format the columns so that displayed numbers are more readable.
-To do this, you can use the native functionality of [value formatters](https://dash.plotly.com/dash-ag-grid/value-formatters)
-or the Vizro pre-defined [custom cell data types](https://dash.plotly.com/dash-ag-grid/cell-data-types#providing-custom-cell-data-types) as shown below.
+One of the most common tasks when working with tables is to format the columns so that displayed numbers are more readable. To do this, you can use the native functionality of [value formatters](https://dash.plotly.com/dash-ag-grid/value-formatters) or the Vizro pre-defined [custom cell data types](https://dash.plotly.com/dash-ag-grid/cell-data-types#providing-custom-cell-data-types) as shown below.
The available custom cell types for Vizro are `dollar`, `euro`, `percent` and `numeric`.
-To use these, define your desired `` alongside the chosen `cellDataType` in
-the `columnDefs` argument of your `dash_ag_grid` function:
+To use these, define your desired `` alongside the chosen `cellDataType` in the `columnDefs` argument of your `dash_ag_grid` function:
```py
columnDefs = [{"field": "", "cellDataType": "euro"}]
@@ -138,7 +120,6 @@ columnDefs = [{"field": "", "cellDataType": "euro"}]
In the example below we select and format some columns of the gapminder data.
!!! example "AG Grid with formatted columns"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -168,6 +149,7 @@ In the example below we select and format some columns of the gapminder data.
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -190,33 +172,23 @@ In the example below we select and format some columns of the gapminder data.
type: ag_grid
title: Example of AG Grid with formatted columns
```
- === "Result"
- [![AGGrid2]][AGGrid2]
- [AGGrid2]: ../../assets/user_guides/table/formatted_aggrid.png
+ === "Result"
+ [![AGGrid2]][aggrid2]
#### Dates
-For the [`AgGrid`][vizro.models.AgGrid] model to sort and filter dates correctly, the date must either be of
-string format `yyyy-mm-dd` (see [Dash AG Grid docs](https://dash.plotly.com/dash-ag-grid/date-filters#example:-date-filter))
-or a pandas datetime object. Any pandas datetime column will be transformed into the `yyyy-mm-dd` format automatically.
+For the [`AgGrid`][vizro.models.AgGrid] model to sort and filter dates correctly, the date must either be of string format `yyyy-mm-dd` (see [Dash AG Grid docs](https://dash.plotly.com/dash-ag-grid/date-filters#example:-date-filter)) or a pandas datetime object. Any pandas datetime column will be transformed into the `yyyy-mm-dd` format automatically.
#### Objects and strings
-No specific formatting is available for custom objects and strings, however you can make use of [Value Formatters](https://dash.plotly.com/dash-ag-grid/value-formatters)
-to format displayed strings automatically.
-
+No specific formatting is available for custom objects and strings, however you can make use of [Value Formatters](https://dash.plotly.com/dash-ag-grid/value-formatters) to format displayed strings automatically.
### Styling and changing the AG Grid
-As mentioned above, all [parameters of the Dash AG Grid](https://dash.plotly.com/dash-ag-grid/reference) can be entered as keyword arguments. Below you can find
-an example of a styled AG Grid where some conditional formatting is applied, and where the columns are editable, but
-not filterable or resizable. There are more ways to alter the grid beyond this showcase. AG Grid, like any other Vizro
-component, can be customized using custom CSS. You can find information in
-the [guide to overwriting CSS properties](custom-css.md#overwrite-css-for-selected-components).
+As mentioned above, all [parameters of the Dash AG Grid](https://dash.plotly.com/dash-ag-grid/reference) can be entered as keyword arguments. Below you can find an example of a styled AG Grid where some conditional formatting is applied, and where the columns are editable, but not filterable or resizable. There are more ways to alter the grid beyond this showcase. AG Grid, like any other Vizro component, can be customized using custom CSS. You can find information in the [guide to overwriting CSS properties](custom-css.md#overwrite-css-for-selected-components).
!!! example "Styled and modified Dash AG Grid"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -284,6 +256,7 @@ the [guide to overwriting CSS properties](custom-css.md#overwrite-css-for-select
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -299,28 +272,28 @@ the [guide to overwriting CSS properties](custom-css.md#overwrite-css-for-select
- field: year
- field: lifeExp
valueFormatter:
- function: "d3.format('.1f')(params.value)"
+ function: d3.format('.1f')(params.value)
- field: gdpPercap
valueFormatter:
- function: "d3.format('$,.1f')(params.value)"
+ function: d3.format('$,.1f')(params.value)
cellStyle:
styleConditions:
- condition: params.value < 1045
style:
- backgroundColor: "#ff9222"
+ backgroundColor: '#ff9222'
- condition: params.value >= 1045 && params.value <= 4095
style:
- backgroundColor: "#de9e75"
+ backgroundColor: '#de9e75'
- condition: params.value > 4095 && params.value <= 12695
style:
- backgroundColor: "#aaa9ba"
+ backgroundColor: '#aaa9ba'
- condition: params.value > 12695
style:
- backgroundColor: "#00b4ff"
+ backgroundColor: '#00b4ff'
- field: pop
type: rightAligned
valueFormatter:
- function: "d3.format(',.0f')(params.value)"
+ function: d3.format(',.0f')(params.value)
defaultColDef:
resizable: false
filter: false
@@ -329,10 +302,9 @@ the [guide to overwriting CSS properties](custom-css.md#overwrite-css-for-select
type: ag_grid
title: Example of a Dash AG Grid
```
- === "Result"
- [![AGGrid3]][AGGrid3]
- [AGGrid3]: ../../assets/user_guides/table/styled_aggrid.png
+ === "Result"
+ [![AGGrid3]][aggrid3]
If the available arguments are not sufficient, there is always the option to [create a custom AG Grid callable](custom-tables.md).
@@ -348,19 +320,14 @@ The Vizro [`Table`][vizro.models.Table] model is based on the [Dash DataTable](h
To add a [`Table`][vizro.models.Table] to your page, do the following:
-1. Insert the [`Table`][vizro.models.Table] model into the `components` argument of the
-[`Page`][vizro.models.Page] model.
-2. Enter the `dash_data_table` function under the `figure` argument (imported via `from vizro.tables import dash_data_table`).
-
+1. Insert the [`Table`][vizro.models.Table] model into the `components` argument of the [`Page`][vizro.models.Page] model.
+1. Enter the `dash_data_table` function under the `figure` argument (imported via `from vizro.tables import dash_data_table`).
-The Vizro version of this table differs in one way from the original table: it requires the user to pass a pandas DataFrame as the source of data.
-As explained in [our guide to using data in Vizro](data.md), this must be entered under the argument `data_frame`.
+The Vizro version of this table differs in one way from the original table: it requires the user to pass a pandas DataFrame as the source of data. As explained in [our guide to using data in Vizro](data.md), this must be entered under the argument `data_frame`.
-All other [parameters of the Dash DataTable](https://dash.plotly.com/datatable/reference) can be entered as keyword arguments. Note that we are
-setting some defaults for some arguments to help with styling.
+All other [parameters of the Dash DataTable](https://dash.plotly.com/datatable/reference) can be entered as keyword arguments. Note that we are setting some defaults for some arguments to help with styling.
!!! example "Dash DataTable"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -380,31 +347,29 @@ setting some defaults for some arguments to help with styling.
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_: dash_data_table
- data_frame: gapminder_2007
- title: Dash DataTable
- type: table
- title: Example of a Dash DataTable
+ - components:
+ - figure:
+ _target_: dash_data_table
+ data_frame: gapminder_2007
+ title: Dash DataTable
+ type: table
+ title: Example of a Dash DataTable
```
- === "Result"
- [![Table]][Table]
- [Table]: ../../assets/user_guides/table/table.png
+ === "Result"
+ [![Table]][table]
### Styling and changing the Dash DataTable
-As mentioned above, all [parameters of the Dash DataTable](https://dash.plotly.com/datatable/reference) can be entered as keyword arguments. Below you can find
-an example of a styled table where some conditional formatting is applied. There are many more ways to alter the table beyond this showcase.
+As mentioned above, all [parameters of the Dash DataTable](https://dash.plotly.com/datatable/reference) can be entered as keyword arguments. Below you can find an example of a styled table where some conditional formatting is applied. There are many more ways to alter the table beyond this showcase.
!!! example "Styled Dash DataTable"
-
=== "app.py"
```{.python pycafe-link}
import vizro.models as vm
@@ -467,6 +432,7 @@ an example of a styled table where some conditional formatting is applied. There
Vizro().build(dashboard).run()
```
+
=== "app.yaml"
```yaml
# Still requires a .py to add data to the data manager and parse YAML configuration
@@ -504,12 +470,12 @@ an example of a styled table where some conditional formatting is applied. There
backgroundColor: dodgerblue
color: white
- if:
- filter_query: "{lifeExp} < 55"
+ filter_query: '{lifeExp} < 55'
column_id: lifeExp
- backgroundColor: "#85144b"
+ backgroundColor: '#85144b'
color: white
- if:
- filter_query: "{gdpPercap} > 10000"
+ filter_query: '{gdpPercap} > 10000'
column_id: gdpPercap
backgroundColor: green
color: white
@@ -524,26 +490,20 @@ an example of a styled table where some conditional formatting is applied. There
title: Dash DataTable
```
- === "Result"
- [![Table2]][Table2]
- [Table2]: ../../assets/user_guides/table/styled_table.png
+ === "Result"
+ [![Table2]][table2]
If the available arguments are not sufficient, there is always the option to create a [custom Dash DataTable](custom-tables.md).
-
## Add title, header, and footer
-The [`Table`][vizro.models.Table] and the [`AgGrid`][vizro.models.AgGrid] models accept a `title`, `header` and
-`footer` argument. This is useful for providing context to the data being displayed, or for adding a description of
-the data.
+The [`Table`][vizro.models.Table] and the [`AgGrid`][vizro.models.AgGrid] models accept a `title`, `header` and `footer` argument. This is useful for providing context to the data being displayed, or for adding a description of the data.
- **title**: Displayed as an [H3 header](https://dash.plotly.com/dash-html-components/h3), useful for summarizing the main topic or insight of the component.
- **header**: Accepts markdown text, ideal for extra descriptions, subtitles, or detailed data insights.
- **footer**: Accepts markdown text, commonly used for citing data sources, providing information on the last update, or adding disclaimers.
-
-
### Formatted AgGrid
!!! example "Formatted AgGrid"
@@ -571,30 +531,29 @@ the data.
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_: dash_ag_grid
- data_frame: gapminder_2007
- dashGridOptions:
- pagination: true
- title: Gapminder Data Insights
- header: |
- #### An Interactive Exploration of Global Health, Wealth, and Population
- footer: |
- SOURCE: **Plotly gapminder data set, 2024**
- type: ag_grid
- title: Formatted AgGrid
+ - components:
+ - figure:
+ _target_: dash_ag_grid
+ data_frame: gapminder_2007
+ dashGridOptions:
+ pagination: true
+ title: Gapminder Data Insights
+ header: |
+ #### An Interactive Exploration of Global Health, Wealth, and Population
+ footer: |
+ SOURCE: **Plotly gapminder data set, 2024**
+ type: ag_grid
+ title: Formatted AgGrid
```
- === "Result"
- [![FormattedGrid]][FormattedGrid]
-
- [FormattedGrid]: ../../assets/user_guides/components/formatted_aggrid.png
+ === "Result"
+ [![FormattedGrid]][formattedgrid]
### Formatted DataTable
@@ -623,24 +582,32 @@ the data.
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_: dash_data_table
- data_frame: gapminder_2007
- title: Gapminder Data Insights
- header: |
- #### An Interactive Exploration of Global Health, Wealth, and Population
- footer: |
- SOURCE: **Plotly gapminder data set, 2024**
- type: table
- title: Formatted DataTable
+ - components:
+ - figure:
+ _target_: dash_data_table
+ data_frame: gapminder_2007
+ title: Gapminder Data Insights
+ header: |
+ #### An Interactive Exploration of Global Health, Wealth, and Population
+ footer: |
+ SOURCE: **Plotly gapminder data set, 2024**
+ type: table
+ title: Formatted DataTable
```
- === "Result"
- [![FormattedTable]][FormattedTable]
- [FormattedTable]: ../../assets/user_guides/components/formatted_table.png
+ === "Result"
+ [![FormattedTable]][formattedtable]
+
+[aggrid]: ../../assets/user_guides/table/aggrid.png
+[aggrid2]: ../../assets/user_guides/table/formatted_aggrid.png
+[aggrid3]: ../../assets/user_guides/table/styled_aggrid.png
+[formattedgrid]: ../../assets/user_guides/components/formatted_aggrid.png
+[formattedtable]: ../../assets/user_guides/components/formatted_table.png
+[table]: ../../assets/user_guides/table/table.png
+[table2]: ../../assets/user_guides/table/styled_table.png
diff --git a/vizro-core/docs/pages/user-guides/tabs.md b/vizro-core/docs/pages/user-guides/tabs.md
index 09154177e..1811d0cac 100755
--- a/vizro-core/docs/pages/user-guides/tabs.md
+++ b/vizro-core/docs/pages/user-guides/tabs.md
@@ -1,8 +1,6 @@
# How to use tabs
-[`Tabs`][vizro.models.Tabs] organize and separate groups of related content in a dashboard, letting users switch between different sections or views.
-They are essentially a way of putting multiple [`Containers`][vizro.models.Container] in the same screen space, and letting the user switch between them.
-`Containers` enable the grouping of page components into sections and subsections. See our [user guide on `Containers`](container.md) for more information.
+[`Tabs`][vizro.models.Tabs] organize and separate groups of related content in a dashboard, letting users switch between different sections or views. They are essentially a way of putting multiple [`Containers`][vizro.models.Container] in the same screen space, and letting the user switch between them. `Containers` enable the grouping of page components into sections and subsections. See our [user guide on `Containers`](container.md) for more information.