Skip to content
Draft
Show file tree
Hide file tree
Changes from 65 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
f838f24
Initial commit with some changes already:
maxschulz-COL Oct 23, 2025
0463bc7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 23, 2025
2b67e42
Some notes
maxschulz-COL Oct 23, 2025
052f67f
New breakthrough with type
maxschulz-COL Oct 23, 2025
c169712
Type does not fix wrong validation
maxschulz-COL Oct 27, 2025
e227e99
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 27, 2025
7587ae5
Write proper tests
maxschulz-COL Oct 27, 2025
1c3bab0
Clean up app.py
maxschulz-COL Oct 27, 2025
bb426a8
Merge branch 'mm_latest' of github.com:mckinsey/vizro into mm_latest
maxschulz-COL Oct 27, 2025
be72ff0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 27, 2025
3dc8dff
Refactor type handling in VizroBaseModel to respect custom component …
maxschulz-COL Oct 27, 2025
535e814
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 27, 2025
02d71c8
First addition of MM
maxschulz-COL Oct 28, 2025
93d1d12
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 28, 2025
0b8f25a
Build in the tree mechanism
maxschulz-COL Oct 28, 2025
7fff354
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 28, 2025
745ceb5
Add in private attribute to check if it gets lost on copy
maxschulz-COL Oct 28, 2025
54ccf3f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 28, 2025
bcd4cea
Some notes
maxschulz-COL Oct 29, 2025
a0408ca
Add basic tree tests
maxschulz-COL Oct 29, 2025
1524ed1
Fix the issue of model copying
maxschulz-COL Oct 29, 2025
cd95f51
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2025
8a7dc2f
Add proper tests to check idempotency
maxschulz-COL Oct 29, 2025
80e09fc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2025
19ca1f6
Clean-up
maxschulz-COL Oct 29, 2025
cbab0e9
Merge branch 'mm_latest' of github.com:mckinsey/vizro into mm_latest
maxschulz-COL Oct 29, 2025
d2df87a
Check for private attribute loosing and JSON schema
maxschulz-COL Oct 29, 2025
1a1ba96
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2025
e2b23bd
Summarize Fake Vizro creation
maxschulz-COL Oct 29, 2025
558db74
Merge branch 'mm_latest' of github.com:mckinsey/vizro into mm_latest
maxschulz-COL Oct 29, 2025
706d226
Initial ideas for CLAUDE.md
maxschulz-COL Oct 30, 2025
ff9f8b7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 30, 2025
520884e
Building in the Forward Reference issue
maxschulz-COL Oct 30, 2025
08bcc8d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 30, 2025
c62fcb4
Update TODOs
maxschulz-COL Oct 30, 2025
0712576
Merge branch 'main' into mm_latest
maxschulz-COL Oct 30, 2025
a5c3fbf
Additional notes
maxschulz-COL Oct 30, 2025
dff25a8
Build in forward refs further
maxschulz-COL Oct 30, 2025
77ef0a0
First work on cicular dep issue
maxschulz-COL Oct 30, 2025
c8ce772
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 30, 2025
8c848e5
Remove guidance file to get them from main
maxschulz-COL Oct 30, 2025
aa02376
Merge branch 'main' into mm_latest
maxschulz-COL Oct 30, 2025
c37ca44
Todo
maxschulz-COL Oct 30, 2025
b049825
Remove __pydantic_init_subclass__ to get around circular dependency i…
maxschulz-COL Oct 31, 2025
0d66612
First "working" dashboard
maxschulz-COL Oct 31, 2025
f5e391a
Make all Vizro models fields into a discriminated unions
maxschulz-COL Oct 31, 2025
fdd1d3b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 31, 2025
e21a8c9
Move everything to typing
maxschulz-COL Oct 31, 2025
38771ff
Merge branch 'mm_latest' of github.com:mckinsey/vizro into mm_latest
maxschulz-COL Oct 31, 2025
2da8b33
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 31, 2025
661ac0d
Custom components work without add_type!
maxschulz-COL Oct 31, 2025
7e8f230
Dashboard successfully validates
maxschulz-COL Oct 31, 2025
f784a97
Dashboard renders although not fully functional
maxschulz-COL Oct 31, 2025
d92fd1f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 31, 2025
2820792
ToDos
maxschulz-COL Oct 31, 2025
12e9411
Merge branch 'mm_latest' of github.com:mckinsey/vizro into mm_latest
maxschulz-COL Oct 31, 2025
51e3181
Merge branch 'main' into mm_latest
maxschulz-COL Nov 3, 2025
52fe528
Check for custom component in tree
maxschulz-COL Nov 3, 2025
ca76bc6
Add custom components also to tree
maxschulz-COL Nov 3, 2025
c612d91
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 3, 2025
b69ca54
Add models to tree in FIlter model
maxschulz-COL Nov 3, 2025
2042782
Add remaining later built components
maxschulz-COL Nov 4, 2025
0916173
Merge branch 'main' into mm_latest
maxschulz-COL Nov 4, 2025
fb5804f
Updated models.py list
maxschulz-COL Nov 4, 2025
b46dbc5
Working on current container bug
maxschulz-COL Nov 4, 2025
ad94f03
Add container to scratch app
maxschulz-COL Dec 3, 2025
fa3a013
Comment out container addition
maxschulz-COL Dec 9, 2025
947c2e8
Merge branch 'main' into mm_latest
maxschulz-COL Dec 10, 2025
9a04cae
Merge now works!!
maxschulz-COL Dec 10, 2025
ee2f39e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2025
81e31ec
Add some test for Container problem
maxschulz-COL Dec 10, 2025
a35a5e7
Merge branch 'mm_latest' of github.com:mckinsey/vizro into mm_latest
maxschulz-COL Dec 10, 2025
a6ae7db
Revert linting bug
maxschulz-COL Dec 10, 2025
ef598a0
Next plan for MM
maxschulz-COL Dec 11, 2025
735b98c
First time dev dashboard starting!
maxschulz-COL Dec 15, 2025
3e6f1a8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 15, 2025
b26658d
Merge branch 'main' into mm_latest
maxschulz-COL Dec 15, 2025
d3c9e83
Fixing ID and pre_build creation
maxschulz-COL Dec 16, 2025
d031d48
Private attr saving works
maxschulz-COL Dec 19, 2025
5618659
Remove models dict completely
maxschulz-COL Dec 19, 2025
6ac3152
Move the tree building to the build method
maxschulz-COL Dec 19, 2025
92b13d5
Commit outstanding ToDos
maxschulz-COL Dec 19, 2025
5fbc0a8
Some notes getting back
maxschulz-COL Jan 14, 2026
b56f6ed
Merge branch 'main' into mm_latest
maxschulz-COL Jan 14, 2026
2661f79
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 40 additions & 39 deletions vizro-core/examples/dev/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ def my_custom_table(data_frame=None, chosen_columns: Optional[list[str]] = None)
class TooltipNonCrossRangeSlider(vm.RangeSlider):
"""Custom numeric multi-selector `TooltipNonCrossRangeSlider`."""

type: Literal["other_range_slider"] = "other_range_slider"
type: Literal["custom_component"] = "custom_component"

def build(self):
"""Extend existing component by calling the super build and update properties."""
Expand All @@ -1005,14 +1005,14 @@ def build(self):
return range_slider_build_obj


vm.Filter.add_type("selector", TooltipNonCrossRangeSlider)
# vm.Filter.add_type("selector", TooltipNonCrossRangeSlider)


# 2. Create new custom component
class Jumbotron(vm.VizroBaseModel):
"""New custom component `Jumbotron`."""

type: Literal["jumbotron"] = "jumbotron"
type: Literal["custom_component"] = "custom_component"
title: str
subtitle: str
text: str
Expand All @@ -1022,7 +1022,7 @@ def build(self):
return html.Div([html.H2(self.title), html.H3(self.subtitle), html.P(self.text)])


vm.Page.add_type("components", Jumbotron)
# vm.Page.add_type("components", Jumbotron)

custom_components = vm.Page(
title="Custom Components",
Expand Down Expand Up @@ -1093,53 +1093,54 @@ def multiple_cards(data_frame: pd.DataFrame, n_rows: Optional[int] = 1) -> html.


# DASHBOARD -------------------------------------------------------------------
components = [graphs, ag_grid, table, cards, figure, button, containers, tabs, tooltip]
components = [tabs] # graphs, ag_grid, table, cards, figure, button, containers, tooltip
controls = [filters, parameters, selectors, controls_in_containers]
actions = [export_data_action]
layout = [grid_layout, flex_layout]
extensions = [custom_charts, custom_tables, custom_figures, custom_components]

dashboard = vm.Dashboard(
title="Vizro Features",
pages=[home, *components, *controls, *actions, *layout, *extensions],
navigation=vm.Navigation(
nav_selector=vm.NavBar(
items=[
vm.NavLink(label="Homepage", pages=["Homepage"], icon="Home"),
vm.NavLink(
label="Features",
pages={
"Components": [
"Graphs",
"AG Grid",
"Table",
"Cards",
"Figure",
"Button",
"Containers",
"Tabs",
"Tooltip",
],
"Controls": ["Filters", "Parameters", "Selectors", "Controls in containers"],
"Layout": ["Grid layout", "flex-layout"],
"Actions": ["Export data"],
"Extensions": [
"Custom Charts",
"Custom Tables",
"Custom Components",
"Custom Figures",
],
},
icon="Library Add",
),
]
)
),
pages=[*components], # home, *controls, *actions, *layout, *extensions
# navigation=vm.Navigation(
# nav_selector=vm.NavBar(
# items=[
# vm.NavLink(label="Homepage", pages=["Homepage"], icon="Home"),
# vm.NavLink(
# label="Features",
# pages={
# "Components": [
# "Graphs",
# "AG Grid",
# "Table",
# "Cards",
# "Figure",
# "Button",
# "Containers",
# "Tabs",
# "Tooltip",
# ],
# "Controls": ["Filters", "Parameters", "Selectors", "Controls in containers"],
# "Layout": ["Grid layout", "flex-layout"],
# "Actions": ["Export data"],
# "Extensions": [
# "Custom Charts",
# "Custom Tables",
# "Custom Components",
# "Custom Figures",
# ],
# },
# icon="Library Add",
# ),
# ]
# )
# ),
)


if __name__ == "__main__":
# Move app definition outside of __main__ block for the HF demo to work
dashboard = vm.Dashboard.model_validate(dashboard, context={"build_tree": True})
app = Vizro().build(dashboard)
app.dash.layout.children.append(
dbc.NavLink(
Expand Down
219 changes: 111 additions & 108 deletions vizro-core/examples/scratch_dev/app.py
Original file line number Diff line number Diff line change
@@ -1,128 +1,131 @@
"""Dev app to try things out."""

import vizro.plotly.express as px
from typing import Literal

import vizro.models as vm
import vizro.plotly.express as px
from dash import html
from vizro import Vizro
import vizro.actions as va
from vizro.figures import kpi_card, kpi_card_reference
import pandas as pd
import dash_bootstrap_components as dbc
from vizro.managers import data_manager

df = px.data.iris()
data_manager["iris"] = df


# 2. Create new custom component
class Jumbotron(vm.VizroBaseModel):
"""New custom component `Jumbotron`."""

type: Literal["custom_component"] = "custom_component"
title: str
subtitle: str
text: str

def build(self):
"""Build the new component based on Dash components."""
return html.Div([html.H2(self.title), html.H3(self.subtitle), html.P(self.text)])

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

gapminder = px.data.gapminder()
class CustomCard(vm.VizroBaseModel):
"""New custom component `Card`."""

type: Literal["custom_component"] = "custom_component"
title: str
description: str

def build(self):
"""Build the new component based on Dash components."""
return html.Div(
[
html.Div(
[
html.H4(self.title, style={"margin": "0 0 10px 0"}),
html.P(self.description, style={"margin": "0"}),
],
style={
"border": "1px solid #ddd",
"border-radius": "8px",
"padding": "16px",
"background-color": "#f9f9f9",
},
)
]
)


page = vm.Page(
title="Test page",
title="My first dashboard",
components=[
vm.Card(
text="Lorem Ipsum is simply dummy text. ",
header="### This is card header",
footer="##### This is card footer",
description="Tooltip",
),
vm.Card(
header="## This is card header",
text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. "
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.",
description="Tooltip",
),
vm.Card(
text="Card with text and header and footer",
header="#### This is card header",
footer="##### This is card footer",
description="Tooltip",
),
vm.Card(
text="### Card with just text title",
description="Tooltip",
vm.Graph(figure=px.scatter(df, x="sepal_length", y="petal_width", color="species")),
vm.Graph(figure=px.histogram(df, x="sepal_width", color="species")),
Jumbotron(
title="Custom component",
subtitle="This is a subtitle",
text="This is the main body of text of the Jumbotron.",
),
vm.Card(
text="Card without header",
footer="This is card footer",
description="Tooltip",
Jumbotron(
title="Custom component 2",
subtitle="This is a subtitle",
text="This is the main body of text of the Jumbotron.",
),
vm.Card(
text="Regular card with only text: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry. ",
description="Tooltip",
),
vm.Graph(figure=px.bar(gapminder, x="country", y="pop", color="continent")),
vm.Card(
text="Card with action: Filter Europe",
actions=va.set_control(control="filter-id-1", value="Europe"),
),
vm.Card(
text="Navigate to page",
href="/dummy-page",
CustomCard(
title="Custom card",
description="This is a description of the custom card.",
),
],
controls=[vm.Filter(id="filter-id-1", column="continent", selector=vm.RadioItems())],
layout=vm.Grid(
grid=[
[0, 1, 2, 3],
[4, 5, 7, 8],
[6, 6, -1, -1],
[6, 6, -1, -1],
]
),
controls=[
vm.Filter(column="species"),
],
)

page_2 = vm.Page(title="Dummy page", components=[vm.Card(text="This is plain old card.")])
dashboard = vm.Dashboard(pages=[page])

page_3 = vm.Page(
title="KPI indicator cards",
components=[
vm.Figure(
figure=kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference (pos)",
)
),
vm.Figure(
figure=kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference with icon",
icon="Shopping Cart",
)
),
vm.Figure(
figure=kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference (reverse color)",
reverse_color=True,
)
),
vm.Figure(
figure=kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI with icon",
icon="Shopping Cart",
)
),
vm.Figure(
figure=kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI with formatting",
value_format="${value:.2f}",
)
),
vm.Figure(
figure=kpi_card(data_frame=df_kpi, value_column="Actual", title="KPI with value"),
),
],
layout=vm.Grid(grid=[[0, 1, 2], [3, 4, 5]]),
)
# Same configuration as JSON
# dashboard_config = {
# "type": "dashboard",
# "pages": [
# {
# "type": "page",
# "title": "My first dashboard",
# "components": [
# {
# "type": "graph",
# "figure": {
# "_target_": "scatter",
# "data_frame": "iris",
# "x": "sepal_length",
# "y": "petal_width",
# "color": "species",
# },
# },
# {
# "type": "graph",
# "figure": {
# "_target_": "histogram",
# "data_frame": "iris",
# "x": "sepal_width",
# "color": "species",
# },
# },
# ],
# "controls": [
# {
# "type": "filter",
# "column": "species",
# }
# ],
# }
# ],
# }

dashboard = vm.Dashboard(pages=[page, page_2, page_3])
# dashboard = vm.Dashboard.model_validate(dashboard_config)

if __name__ == "__main__":
Vizro(external_stylesheets=[dbc.themes.BOOTSTRAP]).build(dashboard).run()
dashboard = vm.Dashboard.model_validate(dashboard, context={"build_tree": True})
app = Vizro().build(dashboard)
assert all(
dashboard._tree[model.id].data is model
for model in [dashboard] + dashboard.pages + [comp for page in dashboard.pages for comp in page.components]
)
dashboard._tree.print(repr="{node.kind} -> {node.data.type} (id={node.data.id})")
app.run()
3 changes: 2 additions & 1 deletion vizro-core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ dependencies = [
"black",
"autoflake",
"packaging",
"python-box"
"python-box",
"nutree"
]
description = "Vizro is a low-code framework for building high-quality data visualization apps."
dynamic = ["version"]
Expand Down
12 changes: 6 additions & 6 deletions vizro-core/src/vizro/managers/_model_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ def __init__(self):
# TODO: Consider storing "page_id" or "parent_model_id" and make searching helper methods easier?
@_state_modifier
def __setitem__(self, model_id: ModelID, model: Model):
if model_id in self.__models:
raise DuplicateIDError(
f"Model with id={model_id} already exists. Models must have a unique id across the whole dashboard. "
f"If you are working from a Jupyter Notebook, please either restart the kernel, or "
f"use 'from vizro import Vizro; Vizro._reset()`."
)
# if model_id in self.__models:
# raise DuplicateIDError(
# f"Model with id={model_id} already exists. Models must have a unique id across the whole dashboard. "
# f"If you are working from a Jupyter Notebook, please either restart the kernel, or "
# f"use 'from vizro import Vizro; Vizro._reset()`."
# )
self.__models[model_id] = model

@_state_modifier
Expand Down
Loading
Loading