import vizro.actions as va
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.actions._abstract_action import _AbstractAction
from typing import Literal, Any
tips = px.data.tips()
# This works already:
page = vm.Page(
title="Cross-filter from graph",
components=[
vm.Graph(
title="Click on a tile to use that tile's sex and day to filter table",
figure=px.density_heatmap(tips, x="day", y="sex", category_orders={"day": ["Thur", "Fri", "Sat", "Sun"]}),
actions=[
va.set_control(control="day_filter", value="x"),
va.set_control(control="sex_filter", value="y"),
],
),
vm.AgGrid(id="tips_table", figure=dash_ag_grid(tips)), # (1)!
],
controls=[
vm.Filter(id="day_filter", column="day", targets=["tips_table"]),
vm.Filter(id="sex_filter", column="sex", targets=["tips_table"]),
], # (2)!
)
# Doing the same thing from AgGrid does not, but it would be nice if we could enable it.
pivot = tips.pivot_table(
index='sex',
columns='day',
aggfunc='size',
fill_value=0
).reindex(columns=["Thur", "Fri", "Sat", "Sun"]).reset_index()
# Make new model just to define a different action trigger for now.
class AgGridAlternativeTrigger(vm.AgGrid):
actions: Any # Lazy hack
@property
def _action_triggers(self):
return {"__default__": f"{self._inner_component_id}.cellClicked"}
# In reality this wouldn't be a different action, it would be built into set_control.
# We want to somehow detect that we're in pivot table mode here - maybe do by checking "rowSelection": {"enableClickSelection": False}
class set_control_from_pivot_table(_AbstractAction):
value: Literal["row", "column"]
control: str
def function(self, _trigger):
if self.value == "row":
return _trigger["rowId"]
elif self.value == "column":
return _trigger["colId"]
@property
def outputs(self):
return self.control
page_2 = vm.Page(
title="Cross-filter from table",
components=[
AgGridAlternativeTrigger(
id="pivot",
title="Click on a tile to use that tile's sex and day to filter table",
figure=dash_ag_grid(pivot, dashGridOptions={
# Need to disable clickSelection or UX is confusing. Also good to have CSS to stop user
# clicking in sex column - see assets folder.
# This could be used to signal we want to use set_control with cellClicked rather
# than rowSelection
# Only set this when mode="pivot":
"rowSelection": {
"enableClickSelection": False,
},
# Might as well always set this, regardless of mode. Use df.columns[0].name for sex.
"getRowId": "params.data.sex"
},
),
actions=[
# value="column" and "row" are good, like "x"/"y" for graph.
set_control_from_pivot_table(control="day_filter2", value="column"),
set_control_from_pivot_table(control="sex_filter2", value="row"),
],
),
vm.AgGrid(id="tips_table2", figure=dash_ag_grid(tips)), # (1)!
],
controls=[
vm.Filter(id="day_filter2", column="day", targets=["tips_table2"]),
vm.Filter(id="sex_filter2", column="sex", targets=["tips_table2"]),
], # (2)!
)
dashboard = vm.Dashboard(pages=[page, page_2])
Vizro().build(dashboard).run()