"""Example to show dashboard configuration.""" import pandas as pd import vizro.models as vm from vizro import Vizro import vizro.plotly.express as px from dash import get_asset_url, html import dash_bootstrap_components as dbc from vizro.models.types import capture from vizro.tables import dash_ag_grid from utils.helper import categorize_price, convert_price_to_numeric, columnDefs from vizro.figures import kpi_card # Custom charts are required because of the post-update calls @capture("graph") def bar(data_frame, top_n=20, **kwargs): data_top = data_frame.head(top_n) fig = px.bar(data_top, **kwargs) fig.update_layout(title=f"Top {top_n} Games by {kwargs['x']}", yaxis_title="", yaxis_autorange="reversed") return fig @capture("graph") def scatter(data_frame, top_n=20, **kwargs): data_top = data_frame.head(top_n) fig = px.scatter(data_top, **kwargs) fig.update_layout( title=f"Top {top_n} games by {kwargs['y']}. Each bubble represents a single game. The bigger the bubble, the more players." ) return fig @capture("graph") def treemap(data_frame, top_n=20, **kwargs): data_top = data_frame.head(top_n) fig = px.treemap(data_top, **kwargs) fig.update_traces(root_color="lightgrey") fig.update_layout(title=f"Top {top_n} games by {kwargs['values']}. The bigger the square, the more players.") return fig # Tidy data set players = pd.read_csv( "https://raw.githubusercontent.com/plotly/Figure-Friday/refs/heads/main/2025/week-5/Steam%20Top%20100%20Played%20Games%20-%20List.csv" ) players["Price Category"] = players["Price"].apply(categorize_price) players["Price Numeric"] = players["Price"].apply(convert_price_to_numeric) players["Current Players"] = pd.to_numeric(players["Current Players"].str.replace(",", "")) players["Peak Today"] = pd.to_numeric(players["Peak Today"].str.replace(",", "")) tabs = vm.Tabs( tabs=[ vm.Container( title="Bar", components=[ vm.Graph( id="bar", figure=bar( players, y="Name", x="Current Players", title="Current Players by Game", orientation="h", color="Price Numeric", ), ) ], ), vm.Container( title="Treemap", components=[ vm.Graph( id="treemap", figure=treemap( players, path=[px.Constant("All"), "Name"], values="Current Players", color="Price Numeric" ), ) ], ), vm.Container( title="Bubble", components=[ vm.Graph( id="bubble", figure=scatter( players, x="Price Numeric", y="Current Players", size="Current Players", size_max=50, opacity=0.5, color="Price Numeric", ), ) ], ), ], ) players_page = vm.Page( title="Total Players 🎮", layout=vm.Layout(grid=[[0, 1, 2, 3, 4]] + [[5, 5, 5, 5, 5]] * 5), components=[ vm.Figure( id="kpi-1", figure=kpi_card( data_frame=players[players["Price Category"] == "Free To Play"], value_column="Current Players", value_format="{value:,}", icon="groups", title="Free to play", ), ), vm.Figure( id="kpi-2", figure=kpi_card( data_frame=players[players["Price Category"] == "Less than £15"], value_column="Current Players", value_format="{value:,}", icon="group", title="Less than £15", ), ), vm.Figure( id="kpi-3", figure=kpi_card( data_frame=players[players["Price Category"] == "£15-£30"], value_column="Current Players", value_format="{value:,}", icon="person", title="£15-£30", ), ), vm.Figure( id="kpi-4", figure=kpi_card( data_frame=players[players["Price Category"] == "£30-£45"], value_column="Current Players", value_format="{value:,}", icon="people", title="£30-£45", ), ), vm.Figure( id="kpi-5", figure=kpi_card( data_frame=players[players["Price Category"] == "More than 45£"], value_column="Current Players", value_format="{value:,}", icon="groups", title="More than 45£", ), ), tabs, ], controls=[ vm.Parameter( targets=[ "bar.x", "treemap.values", "bubble.y", "kpi-1.value_column", "kpi-2.value_column", "kpi-3.value_column", "kpi-4.value_column", "kpi-5.value_column", ], selector=vm.RadioItems( options=["Current Players", "Peak Today"], title="Select metric in all charts", ), ), vm.Parameter( targets=["bar.top_n", "bubble.top_n", "treemap.top_n"], selector=vm.Slider(min=10, max=50, step=5, value=20, title="Select top N:"), ), vm.Filter( column="Price Category", selector=vm.Checklist( options=["Free To Play", "Less than £15", "£15-£30", "£30-£45", "More than 45£"], title="Select price category:", ), ), vm.Filter(column="Name", selector=vm.Dropdown(title="Select game:")), ], ) games_page = vm.Page( title="Most played games 👾", components=[ vm.AgGrid( figure=dash_ag_grid(players, columnDefs=columnDefs, dashGridOptions={"rowHeight": 56, "pagination": True}) ) ], ) dashboard = vm.Dashboard( title="Figure Friday - Week 5", pages=[players_page, games_page], navigation=vm.Navigation( nav_selector=vm.NavBar( items=[ vm.NavLink(label="Players", pages=["Total Players 🎮"], icon="Person Play"), vm.NavLink(label="Games", pages=["Most played games 👾"], icon="Stadia Controller"), ] ) ), ) 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()