Closed szt-ableton closed 4 months ago
Hello @szt-ableton and thank you for your comments and for asking this excellent question!
What you describe is something we would call a parameter interaction. It's not natively built into vizro yet as an action but will be in future. You can already achieve what you need a couple of ways though.
Approach 1 below does what you described: use a custom action to update a graph when you click on a cell of the AgGrid. I've added cellClicked
data into a vm.Card
just so you can easily see what information is available there.
Approach 2 does things a bit differently:
Currently I think the easiest/only way to do Approach 2 is by using a pure Dash callback rather than action (but let's discuss this when you're back from holiday @petar-qb).
In my mind there are actually a couple of advantages of Approach 2:
This is a topic we're very actively discussing now so I am very curious why you would like to take the first approach instead of updating a parameter - please can you explain?
FYI @Joseph-Perkins @maxschulz-COL
import json
from dash import Output, Input, callback
from dash.exceptions import PreventUpdate
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.models.types import capture
from vizro.tables import dash_ag_grid
df = px.data.iris()
graph = vm.Graph(id="graph", figure=px.box(df, x="petal_width", color="species"))
@capture("action")
def f(data):
# Put the JSON dump of data in ``` to show it as code in markdown
code_markdown = f"```\n{json.dumps(data, indent=2)}\n```"
# graph() is basically a shortcut for saying "re-run the vm.Graph's figure function but with x=data["colId"]
# The data used will be *unfiltered* df
return graph(x=data["colId"]), code_markdown
page = vm.Page(
title="Demo",
components=[
vm.AgGrid(
figure=dash_ag_grid(id="grid", data_frame=df),
actions=[vm.Action(function=f(), inputs=["grid.cellClicked"], outputs=["graph.figure", "card.children"])],
),
graph,
vm.Card(id="card", text="Click on a cell on the grid and the box plot will show that column"),
],
controls=[
vm.Parameter(targets=["graph.x"], selector=vm.RadioItems(id="radio", options=list(df.columns[:4]))),
vm.Filter(column="species"),
],
)
dashboard = vm.Dashboard(pages=[page])
import json
from dash import Output, Input, callback
from dash.exceptions import PreventUpdate
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.models.types import capture
from vizro.tables import dash_ag_grid
df = px.data.iris()
graph = vm.Graph(id="graph", figure=px.box(df, x="petal_width", color="species"))
@callback(Output("radio", "value"), Output("card", "children"), Input("grid", "cellClicked"))
def g(data):
if data is None:
raise PreventUpdate
code_markdown = f"```\n{json.dumps(data, indent=2)}\n```"
return data["colId"], code_markdown
page = vm.Page(
title="Hi",
components=[
vm.AgGrid(
figure=dash_ag_grid(id="grid", data_frame=df),
),
graph,
vm.Card(id="card", text="Click on a cell on the grid and the box plot will show that column"),
],
controls=[
vm.Parameter(targets=["graph.x"], selector=vm.RadioItems(id="radio", options=list(df.columns[:4]))),
vm.Filter(column="species"),
],
)
dashboard = vm.Dashboard(pages=[page])
Vizro().build(dashboard).run(debug=True)
Hey @antonymilne
thank you so much for the fast and clear answer, it saved me a lot of confusion! Hats off to this project!
As for your question - I did consider manipulating the parameter directly (asked if its possible in the question as well). The reason I focused on Approach 1 is twofold - and none of them about any strong preference:
However, I do see that the arguments you bring for Approach 2 are valid, so I will go with that one! (to avoid overwriting other params and maybe for transparency as well)
Thanks a lot again and wish you some fun bringing these great features to the people!
@szt-ableton Great, thank you for the extra information - that's all very useful feedback!
Just on the dropdown point, this is great to know and we actually had another ask for something similar last week. Are you able to share the code for your custom dropdown menu just to see how you solved it? @lingyielia suggested for the other user to use optionHeight
. if this is a common problem then indeed we might be able to build something in to make this easier to format nicely (maybe it could even automatically choose a right height depending on number of characters). wdyt @huong-li-nguyen?
@maxschulz-COL @Joseph-Perkins this is a great example we should talk about when we discuss the question "should all interactions be done through controls
". My current feeling is definitely yes, though maybe eventually we should add a visible
option to Parameter
/Filter
to make it easier to hide (already easy through CSS though). This would also be how we handle URL query parameters that we don't want to render on screen.
@antonymilne I've also used optionHeight (plus dropdown_build_obj[self.id].style = {"min-width": "150px", "padding": "20px 20px"} for the menu itself.)
Perfect, thank you! I'll close this issue then but please do feel free to open another if you have any more questions 🙂
FYI @szt-ableton we've merged a change that means optionsHeight
should change itself automatically depending on the length of the options. https://github.com/mckinsey/vizro/pull/574. This will be in the next release, 0.1.19, which is probably later this week.
amaaziing!
Question
Hey team, I have a question regarding the use of custom actions. I would like to be able to click on a cell on my AgGrid element, and for the value of the click to update a parameter in the function that builds my graph. However, I am not sure how to target a parameter within a function that builds the Graph component.
Below is an example - where I am able to control the text in a card element ( as in a standard example published by you). Instead, I would like to control specific inputs to my function (the commented out mainfig.question example). To be more clear, basically, I would like this custom action to work as a parameter - being able to change the question input to my custom graph.
How is it possible to target custom graph inputs through custom actions? If that is not possible, is it possible to target the selected parameter somehow?
Thank you so much for the amazing work on this tool, and for the help in advance!
Code/Examples
Other information
No response
Which package?
vizro
Package version
No response
Python version
No response
OS
No response
Code of Conduct