from pathlib import Path
from typing import Literal
import vizro.plotly.express as px
from dash import clientside_callback, ClientsideFunction, dcc, html, Input, Output, State, get_asset_url
from vizro import Vizro
import vizro.models as vm
from vizro.models.types import capture
UNDERLYING_HIST_CHART_ID = "underlying_hist_chart"
df = px.data.iris()
# Custom figure that returns dcc.Graph with a histogram figure.
# It takes a display_mode_bar parameter from the UI Dashboard to show/hide the mode bar.
@capture("figure")
def plot_histogram(data_frame, display_mode_bar=True):
fig = px.histogram(data_frame, x="sepal_width", color="species")
return dcc.Graph(
id=UNDERLYING_HIST_CHART_ID,
figure=fig,
config={
"displayModeBar": display_mode_bar,
},
)
# clientside callback hack that updates the "dcc.Graph" even though it's not created using the "vm.Graph" component.
clientside_callback(
ClientsideFunction(namespace="dashboard", function_name="update_graph_theme"),
output=[
Output(UNDERLYING_HIST_CHART_ID, "figure"),
Output(UNDERLYING_HIST_CHART_ID, "style")
],
inputs=[
Input(UNDERLYING_HIST_CHART_ID, "figure"),
Input("theme-selector", "value"),
State("vizro_themes", "data"),
],
)
# Custom Vizro component that serves two images but only one is visible based on the theme.
# See the "hack" of showing/hiding the content based on selected theme within the "assets/custom.css".
class ThemedImage(vm.VizroBaseModel):
"""New custom component `ThemedImage`."""
type: Literal["themed_image"] = "themed_image"
src_dark: str
src_light: str
def build(self):
assets_url_dark = get_asset_url(self.src_dark)
assets_url_light = get_asset_url(self.src_light)
return html.Div(
id=self.id,
children=[
html.Img(id=f"my_image_dark", src=assets_url_dark),
html.Img(id=f"my_image_light", src=assets_url_light)
]
)
# Enabling custom component to be used within the "vm.Page.components".
vm.Page.add_type("components", ThemedImage)
page = vm.Page(
title="Vizro on PyCafe",
components=[
ThemedImage(src_dark="google-dark.png", src_light="google-light.png"),
vm.Graph(id="scatter_chart", figure=px.scatter(df, x="sepal_length", y="petal_width", color="species")),
vm.Figure(id="hist_chart", figure=plot_histogram(data_frame=df)),
],
controls=[
vm.Filter(column="species"), vm.Filter(column="petal_length"), vm.Filter(column="sepal_width"),
vm.Parameter(
targets=["hist_chart.display_mode_bar"],
selector=vm.RadioItems(
id="display_mode_bar",
options=[{"label": "True", "value": True}, {"label": "False", "value": False}],
value=True,
)
)
],
)
dashboard = vm.Dashboard(pages=[page])
Vizro().build(dashboard).run()