Skip to content

Commit

Permalink
[Feat] Add reverse_color argument to kpi_card_reference (#995)
Browse files Browse the repository at this point in the history
  • Loading branch information
huong-li-nguyen authored Feb 5, 2025
1 parent 9e2fca0 commit a554f25
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 98 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!--
A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Highlights ✨
- A bullet item for the Highlights ✨ category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Removed
- A bullet item for the Removed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
### Added

- Add `reverse_color` argument to `kpi_card_reference`, enabling color inversion based on delta values. ([#995](https://github.com/mckinsey/vizro/pull/995))

<!--
### Changed
- A bullet item for the Changed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Deprecated
- A bullet item for the Deprecated category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Fixed
- A bullet item for the Fixed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Security
- A bullet item for the Security category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
Binary file modified vizro-core/docs/assets/user_guides/figure/kpi_cards.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 18 additions & 3 deletions vizro-core/docs/pages/user-guides/figure.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,19 @@ As described in the [API reference](../API-reference/figure-callables.md) and il
title="KPI reference with icon",
icon="shopping_cart",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference (reverse color)",
reverse_color=True
),
]

# Create a layout with four rows and columns. The KPI cards are positioned in the first eight cells, while the remaining cells are empty.
# Create a layout with four rows and columns. The KPI cards are positioned in the first nine cells, while the remaining cells are empty.
page = vm.Page(
title="KPI cards",
layout=vm.Layout(grid=[[0, 1, 2, 3], [4, 5, 6, 7], [-1, -1, -1, -1], [-1, -1, -1, -1]]),
layout=vm.Layout(grid=[[0, 1, 2, 3], [4, 5, 6, 7], [8, -1, -1, -1], [-1, -1, -1, -1]]),

components=[vm.Figure(figure=figure) for figure in example_cards + example_reference_cards],
controls=[vm.Filter(column="Category")],
Expand Down Expand Up @@ -245,11 +252,19 @@ As described in the [API reference](../API-reference/figure-callables.md) and il
title: KPI reference with icon
icon: shopping_cart
type: figure
- figure:
_target_: kpi_card_reference
data_frame: df_kpi
value_column: Actual
reference_column: Reference
title: KPI reference (reverse color)
reverse_color: true
type: figure
controls:
- column: Category
type: filter
layout:
grid: [[0, 1, 2, 3], [4, 5, 6, 7], [-1, -1, -1, -1], [-1, -1, -1, -1]]
grid: [[0, 1, 2, 3], [4, 5, 6, 7], [8, -1, -1, -1], [-1, -1, -1, -1]]
title: KPI cards
```

Expand Down
93 changes: 64 additions & 29 deletions vizro-core/examples/scratch_dev/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,76 @@
import pandas as pd
import vizro.models as vm
from vizro import Vizro
from vizro.figures import kpi_card_reference

# For more information, refer to the API reference for kpi_card and kpi_card_reference
from vizro.figures import kpi_card, kpi_card_reference

df_kpi = pd.DataFrame({"Actual": [100, 200, 700], "Reference": [100, 300, 500], "Category": ["A", "B", "C"]})

page = vm.Page(
title="KPI card I",
components=[
vm.Figure(
figure=kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference with icon",
icon="folder_check_2",
)
)
],
)
example_cards = [
kpi_card(data_frame=df_kpi, value_column="Actual", title="KPI with value"),
kpi_card(data_frame=df_kpi, value_column="Actual", title="KPI with aggregation", agg_func="median"),
kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI with formatting",
value_format="${value:.2f}",
),
kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI with icon",
icon="shopping_cart",
),
]

page_two = vm.Page(
title="KPI card II",
components=[
vm.Figure(
figure=kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference with icon",
icon="folder_check",
)
)
],
example_reference_cards = [
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference (pos)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
agg_func="median",
title="KPI reference (neg)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference with formatting",
value_format="{value:.2f}€",
reference_format="{delta:+.2f}€ vs. last year ({reference:.2f}€)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference with icon",
icon="shopping_cart",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference (reverse color)",
reverse_color=True,
),
]

# Create a layout with four rows and columns. The KPI cards are positioned in the first nine cells, while the remaining cells are empty.
page = vm.Page(
title="KPI cards",
layout=vm.Layout(grid=[[0, 1, 2, 3], [4, 5, 6, 7], [8, -1, -1, -1], [-1, -1, -1, -1]]),
components=[vm.Figure(figure=figure) for figure in example_cards + example_reference_cards],
controls=[vm.Filter(column="Category")],
)

dashboard = vm.Dashboard(pages=[page, page_two], navigation=vm.Navigation(nav_selector=vm.NavBar()))
dashboard = vm.Dashboard(pages=[page])

if __name__ == "__main__":
Vizro().build(dashboard).run()
96 changes: 73 additions & 23 deletions vizro-core/examples/scratch_dev/yaml_version/dashboard.yaml
Original file line number Diff line number Diff line change
@@ -1,27 +1,77 @@
# Still requires a .py to register data connector in Data Manager and parse yaml configuration
# See yaml_version example
pages:
- title: "Page with subsections"
- components:
- figure:
_target_: kpi_card
data_frame: df_kpi
value_column: Actual
title: KPI with value
type: figure
- figure:
_target_: kpi_card
data_frame: df_kpi
value_column: Actual
title: KPI with aggregation
agg_func: median
type: figure
- figure:
_target_: kpi_card
data_frame: df_kpi
value_column: Actual
title: KPI with formatting
value_format: ${value:.2f}
type: figure
- figure:
_target_: kpi_card
data_frame: df_kpi
value_column: Actual
title: KPI with icon
icon: shopping_cart
type: figure
- figure:
_target_: kpi_card_reference
data_frame: df_kpi
value_column: Actual
reference_column: Reference
title: KPI reference (pos)
type: figure
- figure:
_target_: kpi_card_reference
data_frame: df_kpi
value_column: Actual
reference_column: Reference
agg_func: median
title: KPI reference (neg)
type: figure
- figure:
_target_: kpi_card_reference
data_frame: df_kpi
value_column: Actual
reference_column: Reference
title: KPI reference with formatting
value_format: "{value:.2f}€"
reference_format: "{delta:+.2f}€ vs. last year ({reference:.2f}€)"
type: figure
- figure:
_target_: kpi_card_reference
data_frame: df_kpi
value_column: Actual
reference_column: Reference
title: KPI reference with icon
icon: shopping_cart
type: figure
- figure:
_target_: kpi_card_reference
data_frame: df_kpi
value_column: Actual
reference_column: Reference
title: KPI reference (reverse color)
reverse_color: true
type: figure
controls:
- column: Category
type: filter
layout:
grid: [[0, 1]]
components:
- type: container
title: "Container I"
components:
- type: graph
figure:
_target_: scatter
data_frame: iris
x: sepal_width
y: sepal_length
color: species
- type: container
title: "Container II"
components:
- type: graph
figure:
_target_: box
data_frame: iris
x: species
y: sepal_length
color: species
grid: [[0, 1, 2, 3], [4, 5, 6, 7], [8, -1, -1, -1], [-1, -1, -1, -1]]
title: KPI cards
10 changes: 9 additions & 1 deletion vizro-core/src/vizro/figures/_kpi_cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def kpi_card_reference( # noqa: PLR0913
agg_func: str = "sum",
title: Optional[str] = None,
icon: Optional[str] = None,
reverse_color: bool = False,
) -> dbc.Card:
"""Creates a styled KPI (Key Performance Indicator) card displaying a value in comparison to a reference value.
Expand Down Expand Up @@ -118,6 +119,11 @@ def kpi_card_reference( # noqa: PLR0913
title: KPI title displayed on top of the card. If not provided, it defaults to the capitalized `value_column`.
icon: Name of the icon from the [Google Material Icon Library](https://fonts.google.com/icons) to be displayed
on the left side of the KPI title. If not provided, no icon is displayed.
reverse_color: If `False`, a positive delta will be colored positively (e.g., blue) and a negative delta
negatively (e.g., red). If `True`, the colors will be inverted: a positive delta will be colored
negatively (e.g., red) and a negative delta positively (e.g., blue). Defaults to `False`.
Returns:
A Dash Bootstrap Components card (`dbc.Card`) containing the formatted KPI value and reference.
Expand All @@ -133,6 +139,8 @@ def kpi_card_reference( # noqa: PLR0913
value, reference = data_frame[[value_column, reference_column]].agg(agg_func)
delta = value - reference
delta_relative = delta / reference if reference else np.nan
pos_color, neg_color = ("color-neg", "color-pos") if reverse_color else ("color-pos", "color-neg")
footer_class = pos_color if delta > 0 else neg_color if delta < 0 else ""

header = dbc.CardHeader(
[
Expand All @@ -153,6 +161,6 @@ def kpi_card_reference( # noqa: PLR0913
reference_format.format(value=value, reference=reference, delta=delta, delta_relative=delta_relative)
),
],
className="color-pos" if delta > 0 else "color-neg" if delta < 0 else "",
className=footer_class,
)
return dbc.Card([header, body, footer], className="card-kpi")
Loading

0 comments on commit a554f25

Please sign in to comment.