Spaces:
Running
Running
File size: 4,399 Bytes
487a9ac 42ee455 b699ae9 42ee455 3787474 42ee455 c777272 42ee455 b699ae9 42ee455 76bf90c 42ee455 b07f575 8d0380b 3052245 8d0380b b07f575 22b0b94 b699ae9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
"""App configuration for dashboard."""
from typing import Union
import dash_bootstrap_components as dbc
import vizro.models as vm
from chart_groups import ALL_CHART_GROUP, CHART_GROUPS, ChartGroup, IncompletePage
from custom_components import FlexContainer, Markdown
from dash import get_asset_url, html
from vizro import Vizro
def make_chart_card(page: Union[vm.Page, IncompletePage]) -> vm.Card:
"""Makes a card with svg icon, linked to the right page if page is complete.
Args:
page: page to make card for
Returns: card with svg icon, linked to the right page if page is complete.
"""
# There's one SVG per chart title, so that e.g. pages distribution-butterfly and deviation-butterfly, which both
# have title "Butterfly", correspond to butterfly.svg.
# Incomplete pages have page.path = "" so won't be linked to here.
svg_name = page.title.lower().replace(" ", "-")
return vm.Card(
text=f"""
![](assets/images/charts/{svg_name}.svg#chart-icon)
#### {page.title}
""",
href=page.path,
)
def make_homepage_container(chart_group: ChartGroup) -> vm.Container:
"""Makes a container with cards for each completed and incomplete chart in chart_group.
Args:
chart_group: group of charts to make container for.
Returns: container with cards for each chart in chart_group.
"""
# Pages are sorted in title's alphabetical order and deduplicated so that e.g. pages distribution-butterfly and
# deviation-butterfly, which both have title "Butterfly", correspond to a single card.
return vm.Container(
title=chart_group.name,
layout=vm.Layout(grid=[[0, 1, 1]], col_gap="40px"),
components=[
Markdown(text=chart_group.intro_text, classname="intro-text"),
FlexContainer(
components=[
make_chart_card(page)
for page in sorted(
_remove_duplicates(chart_group.pages + chart_group.incomplete_pages),
key=lambda page: page.title,
)
],
),
],
)
def _remove_duplicates(pages: list[Union[vm.Page, IncompletePage]]) -> list[Union[vm.Page, IncompletePage]]:
# Deduplicate pages that have the same title. Using reversed means that the page that is kept is the first one
# in the dashboard. This will be the one that the card on the homepage links to.
return list({page.title: page for page in reversed(pages)}.values())
def make_navlink(chart_group: ChartGroup) -> vm.NavLink:
"""Makes a navlink with icon and links to every complete page within chart_group.
Args:
chart_group: chart_group to make a navlink for.
Returns: navlink for chart_group.
"""
# Pages are sorted in alphabetical order within each chart group.
return vm.NavLink(
label=chart_group.name,
pages={chart_group.name: [page.id for page in sorted(chart_group.pages, key=lambda page: page.title)]},
icon=chart_group.icon,
)
homepage = vm.Page(
title="Overview",
components=[
vm.Tabs(tabs=[make_homepage_container(chart_group) for chart_group in [ALL_CHART_GROUP, *CHART_GROUPS]]),
],
)
# TODO: consider whether each chart group should have its own individual homepage,
# e.g. at http://localhost:8050/deviation/. This could just repeat the content of the tab from the homepage and would
# work nicely with the hierarchical navigation.
dashboard = vm.Dashboard(
# ALL_CHART_GROUP.pages has duplicated pages, e.g. both distribution-butterfly and deviation-butterfly.
title="Visual vocabulary",
pages=[homepage, *ALL_CHART_GROUP.pages],
navigation=vm.Navigation(
nav_selector=vm.NavBar(
items=[
vm.NavLink(label="Overview", pages=[homepage.id], icon="Home"),
]
+ [make_navlink(chart_group) for chart_group in CHART_GROUPS]
)
),
)
app = Vizro().build(dashboard)
app.dash.layout.children.append(
dbc.NavLink(
["Made with ", html.Img(src=get_asset_url("logo.svg"), id="banner", alt="Vizro logo"), "vizro"],
href="https://github.com/mckinsey/vizro",
target="_blank",
className="anchor-container",
)
)
server = app.dash.server
if __name__ == "__main__":
app.run(port=8051)
|