Closed BalaNagendraReddy closed 2 months ago
Hi @BalaNagendraReddy and thanks for the question.
You seem to be looking for the "Parametrize data loading" feature that has been enabled since vizro>=0.1.17
.
More on how to configure it can be found here in the Vizro docs.
Hi @petar-qb ,
Thanks for your reply.
Expected Behavior: When a user selects an option from the radio buttons, the corresponding file should be loaded, and the vm.AgGrid DataTable should be updated with the relevant columns. This updated DataTable should then be passed to the appropriate page components.
Iam expecting to do this using callbacks.
Here is an example where you select between "Old iris dataset" and "New iris dataset" by selecting a RadioButton value. Based on the selected value in the RadioButton, a new dataset is loaded into the Graph. To develop this example, I used the "Parameterize Data Load" feature I mentioned in the comment above.
Let us know if this can help you develop your dashboard. 😃
from vizro import Vizro
import pandas as pd
import vizro.plotly.express as px
import vizro.models as vm
from vizro.managers import data_manager
def mock_loading_old_iris_dataset():
return px.data.iris()[:75]
def mock_loading_new_iris_dataset():
return px.data.iris()[75:]
def load_iris_data(source_file="old"):
if source_file == "old":
return mock_loading_old_iris_dataset()
else:
return mock_loading_new_iris_dataset()
data_manager["iris"] = load_iris_data
page = vm.Page(
title="Update the chart on page refresh",
components=[
vm.Graph(id="graph", figure=px.scatter("iris", x="sepal_length", y="petal_width", color="species"))
],
controls=[
vm.Parameter(
targets=["graph.data_frame.source_file"],
selector=vm.RadioItems(
title="Select dataset",
options=[
{"label": "Old Iris dataset", "value": "old"},
{"label": "New Iris dataset", "value": "new"},
],
value="old"
),
)
],
)
dashboard = vm.Dashboard(pages=[page])
if __name__ == "__main__":
Vizro().build(dashboard).run()
Hi @petar-qb ,
I have nearly 30 options, and based on the selected input, the corresponding file should be displayed in Dash AG Grid format. For reference, I am attaching the code. I hope this clarifies my request.
import vizro.models as vm
import pandas as pd
import dash_bootstrap_components as dbc
from vizro import Vizro
from vizro.tables import dash_ag_grid
from dash import callback, Output, Input
from typing import Literal
dropdown_options = [{'label': 'File1', 'value': 'File1.csv'},{'label': 'File2', 'value': 'File2.csv' }, {'label': 'File3', 'value': 'file3.csv'}, {'label': 'File4', 'value': 'file4.csv'}]
class MyCard(vm.VizroBaseModel):
"""New custom component `CustomHTML`."""
type: Literal["MyCard"] = "MyCard"
def build(self):
return dbc.Card(
children= [
dbc.DropdownMenu(
label= "Select File",
children= dbc.RadioItems(options=dropdown_options, value=dropdown_options[0]['value'], id = "select-file"),
direction="down",
align_end = False,
className="m-1",
size ="sm",
toggle_style= {"fontSize": "12px","fontWeight": "bold", "borderRadius":"5px"},
toggleClassName="fst-italic border border-dark",
),
dbc.CardBody(id = "grid-table", children = [], style={'margin': '10px 10px 0px 10px'}),
],
)
@callback(Output("card", "children"),
Output("__input_grid-table", "figure"),
Input("select-file", "value"))
def display_grid_table(value):
print(value)
df = pd.read_csv(value)
defaultColDef = {
"flex": 1,
"minWidth": 100,
"floatingFilter": True,
"initialWidth": 100,
"wrapHeaderText": True,
"autoHeaderHeight": True,
"checkboxSelection": {
"function": 'params.column == params.columnApi.getAllDisplayedColumns()[0]'
},
"headerCheckboxSelection": {
"function": 'params.column == params.columnApi.getAllDisplayedColumns()[0]'
},
}
# Iam expecting the below table to be returned
table = dash_ag_grid(
id = "data_table",
data_frame=df,
columnDefs= [{"field": i,
'minWidth': 120,
'maxWidth':200,
"cellRenderer": "DynamicTooltip"} for i in df.columns],
defaultColDef=defaultColDef,
enableEnterpriseModules=True,
dashGridOptions={"animateRows": False,
"pagination": True,
"paginationPageSize": 100,
"rowSelection": "multiple",
"suppressRowClickSelection": True,
"enableCellTextSelection": True,
"rowHeight": 25,
"textAlignment": "center",
"tooltipShowDelay": 10,
},
className = "ag-theme-custom-theme",
),
return f"selected File: {value}", table
vm.Page.add_type("components", MyCard)
page = vm.Page(
title="Default Dash AG Grid",
components=[
MyCard(),
vm.AgGrid(id = "grid-table", figure=dash_ag_grid(data_frame=pd.DataFrame())),
vm.Card(id="card", text="Filename"),
]
)
dashboard = vm.Dashboard(pages=[page])
Vizro().build(dashboard).run()
Hi @BalaNagendraReddy
To make your dashboard to work you should apply a few tiny changes in your code. Here is the working example:
import vizro.models as vm
import pandas as pd
import dash_bootstrap_components as dbc
from vizro import Vizro
from vizro.tables import dash_ag_grid
from dash import callback, Output, Input
from typing import Literal
dropdown_options = [{'label': 'File1', 'value': 'File1.csv'}, {'label': 'File2', 'value': 'File2.csv'},
{'label': 'File3', 'value': 'file3.csv'}, {'label': 'File4', 'value': 'file4.csv'}]
class MyCard(vm.VizroBaseModel):
"""New custom component `CustomHTML`."""
type: Literal["MyCard"] = "MyCard"
def build(self):
return dbc.Card(
children=[
dbc.DropdownMenu(
label="Select File",
children=dbc.RadioItems(options=dropdown_options, value=dropdown_options[0]['value'],
id="select-file"),
direction="down",
align_end=False,
className="m-1",
size="sm",
toggle_style={"fontSize": "12px", "fontWeight": "bold", "borderRadius": "5px"},
toggleClassName="fst-italic border border-dark",
),
dbc.CardBody(id="grid-table", children=[], style={'margin': '10px 10px 0px 10px'}),
],
)
@callback(Output("card", "children"),
Output("grid-table", "children"),
Input("select-file", "value"))
def display_grid_table(value):
print(value)
df = pd.read_csv(value)
defaultColDef = {
"flex": 1,
"minWidth": 100,
"floatingFilter": True,
"initialWidth": 100,
"wrapHeaderText": True,
"autoHeaderHeight": True,
"checkboxSelection": {
"function": 'params.column == params.columnApi.getAllDisplayedColumns()[0]'
},
"headerCheckboxSelection": {
"function": 'params.column == params.columnApi.getAllDisplayedColumns()[0]'
},
}
# Iam expecting the below table to be returned
table = dash_ag_grid(
id="data_table",
data_frame=df,
columnDefs=[{"field": i,
'minWidth': 120,
'maxWidth': 200,
"cellRenderer": "DynamicTooltip"} for i in df.columns],
defaultColDef=defaultColDef,
enableEnterpriseModules=True,
dashGridOptions={"animateRows": False,
"pagination": True,
"paginationPageSize": 100,
"rowSelection": "multiple",
"suppressRowClickSelection": True,
"enableCellTextSelection": True,
"rowHeight": 25,
"textAlignment": "center",
"tooltipShowDelay": 10,
},
className="ag-theme-custom-theme",
)()
return f"selected File: {value}", table
vm.Page.add_type("components", MyCard)
page = vm.Page(
title="Default Dash AG Grid",
components=[
MyCard(),
vm.AgGrid(id="grid-table", figure=dash_ag_grid(data_frame=pd.DataFrame())),
vm.Card(id="card", text="Filename"),
]
)
dashboard = vm.Dashboard(pages=[page])
Vizro().build(dashboard).run()
Also, you can change the dash_ag_grid
className
to "ag-theme-custom-theme ag-theme-quartz-dark ag-theme-vizro"
to make it work with the theme changes.
However, there is a more native way to achieve this use-case in Vizro. Here's an example:
import pandas as pd
import vizro.models as vm
from vizro import Vizro
from vizro.tables import dash_ag_grid
from dash import callback, Output, Input
from vizro.managers import data_manager
from vizro.models.types import capture
def load_data_from_file_system(file_name=None):
if file_name is None:
return pd.DataFrame()
return pd.read_csv(file_name)
data_manager["ag_grid_data_data_manager_key"] = load_data_from_file_system
@callback(
Output("card", "children"),
Input("file-selector-id", "value")
)
def update_card_text(file_name):
return f'Selected file: "{file_name}"'
@capture("ag_grid")
def my_custom_dash_ag_grid(data_frame, **kwargs):
kwargs["columnDefs"] = [
{
"field": col,
'minWidth': 120,
'maxWidth': 200,
"cellRenderer": "DynamicTooltip"
} for col in data_frame.columns
]
vizro_ag_grid_object = dash_ag_grid(data_frame=data_frame, **kwargs)
return vizro_ag_grid_object()
page = vm.Page(
title="Default Dash AG Grid",
layout=vm.Layout(grid=[
[0, -1, -1, -1],
*[[1, 1, 1, 1]] * 11,
]),
components=[
vm.Card(id="card", text="Filename"),
vm.AgGrid(
id="grid-table",
figure=my_custom_dash_ag_grid(
data_frame="ag_grid_data_data_manager_key",
id="data_table",
defaultColDef={
"flex": 1,
"minWidth": 100,
"floatingFilter": True,
"initialWidth": 100,
"wrapHeaderText": True,
"autoHeaderHeight": True,
"checkboxSelection": {
"function": 'params.column == params.columnApi.getAllDisplayedColumns()[0]'
},
"headerCheckboxSelection": {
"function": 'params.column == params.columnApi.getAllDisplayedColumns()[0]'
},
},
enableEnterpriseModules=True,
dashGridOptions={
"animateRows": False,
"pagination": True,
"paginationPageSize": 100,
"rowSelection": "multiple",
"suppressRowClickSelection": True,
"enableCellTextSelection": True,
"rowHeight": 25,
"textAlignment": "center",
"tooltipShowDelay": 10,
},
# TODO: Consider changing/concatenating the classname with this one -> "ag-theme-quartz-dark ag-theme-vizro",
className="ag-theme-custom-theme",
)
),
],
controls=[
vm.Parameter(
targets=["grid-table.data_frame.file_name"],
# TODO: Or use this selector instead of the Dropdown
# selector=vm.RadioItems(
# id="file-selector-id",
# title="Select a file",
# options=[
# {'label': 'File1', 'value': 'File1.csv'},
# {'label': 'File2', 'value': 'File2.csv'},
# {'label': 'File3', 'value': 'file3.csv'},
# {'label': 'File4', 'value': 'file4.csv'}
# ]
# ),
selector=vm.Dropdown(
id="file-selector-id",
title="Select a file",
multi=False,
options=[
{'label': 'File1', 'value': 'File1.csv'},
{'label': 'File2', 'value': 'File2.csv'},
{'label': 'File3', 'value': 'file3.csv'},
{'label': 'File4', 'value': 'file4.csv'}
]
),
)
]
)
dashboard = vm.Dashboard(pages=[page])
Vizro().build(dashboard).run()
You can find more about:
Hi @petar-qb ,
It worked as expected.
Thank you for your help in resolving the issue. Your expertise and quick action made a big difference, and I truly appreciate the time and effort you put into solving it.
Thanks again for your support!
Hi @petar-qb ,
Description:
When selecting the first option in the dropdown, the grid column widths are set correctly as expected. However, after selecting an additional file to concatenate the data, the width of the first three columns (which are set to 150px) resets to the default width.
Steps to Reproduce:
Select the first option from the dropdown. Verify that the first three columns have a width of 150px. Select an additional file to concatenate. Observe that the width of the first three columns reverts to the default width.
Expected Behavior:
The width of the first three columns should remain at 150px even after adding more files.
Actual Behavior:
The column widths change to the default width after selecting additional files.
import vizro.models as vm
import pandas as pd
import dash_bootstrap_components as dbc
from vizro import Vizro
from vizro.tables import dash_ag_grid
from dash import callback, Output, Input
from typing import Literal
dropdown_options = [{'label': 'File1', 'value': 'file1.csv'}, {'label': 'File2', 'value': 'file2.csv'},
{'label': 'File3', 'value': 'file3.csv'}, {'label': 'File4', 'value': 'file4.csv'}]
class Dropdown(vm.VizroBaseModel):
"""New custom component `CustomHTML`."""
type: Literal["MyCard"] = "MyCard"
def build(self):
return dbc.Card(
children=[
dbc.DropdownMenu(
label="Select File",
children=dbc.Checklist(options=dropdown_options, value=[], id="select-file"),
direction="down",
align_end=False,
className="m-1",
size="sm",
toggle_style={"fontSize": "12px", "fontWeight": "bold", "borderRadius": "5px"},
toggleClassName="fst-italic border border-dark",
),
],
)
@callback(Output("grid-table", "children"),
Input("select-file", "value"))
def display_grid_table(selected_files):
all_files_df = pd.DataFrame()
if selected_files:
for file_name in selected_files:
df = pd.read_csv(file_name)
all_files_df=pd.concat([all_files_df, df], ignore_index=True)
cols = all_files_df.columns.tolist()
first_three_cols = ['col1', 'col2', 'col3']
rem_cols = [col for col in cols if col not in first_three_cols]
format_df = all_files_df[first_three_cols + rem_cols]
defaultColDef = {
"flex": 1,
"floatingFilter": True,
"wrapHeaderText": True,
"autoHeaderHeight": True,
}
# Iam expecting the below table to be returned
table = dash_ag_grid(
id="data-table",
data_frame = format_df,
rowData= format_df.to_dict("records"),
columnDefs=[{"headerName": x, "field": x} for x in format_df.columns],
columnSize="sizeToFit",
defaultColDef=defaultColDef,
columnSizeOptions={
'defaultMinWidth': 70,
'columnLimits': [{'key': 'col1', 'minWidth': 150}, {'key': 'col2', 'minWidth': 150}, {'key': 'col3', 'minWidth': 150}],
},
enableEnterpriseModules=True,
dashGridOptions = {"animateRows": False, "domLayout": "autoHeight", "textAlignment": "center"},
style = {"height": None},
)()
return table
vm.Page.add_type("components", Dropdown)
page = vm.Page(
title="Default Dash AG Grid",
layout = vm.Layout(grid = [[0, 1, 1, 1, 1]], row_min_height="250px", row_gap = "20px"),
components=[
Dropdown(),
vm.AgGrid(id="grid-table", figure=dash_ag_grid(data_frame=pd.DataFrame())),
]
)
dashboard = vm.Dashboard(pages=[page])
Vizro().build(dashboard).run()
Hi @BalaNagendraReddy
Does it work as expected if you apply the following change?
columnSize="sizeToFit"
to -> columnSize="responsiveSizeToFit",
(edited) Also, what Vizro version do you use?
Hi @petar-qb ,
Tried that option still facing same issue.
Iam using the vizro version of 0.1.18
Hi @BalaNagendraReddy
And what if you remove the line "flex": 1
from defaultColDef
? Does it work then?
Hi @petar-qb ,
Thank you it's working as expected, after removing the "flex": 1.
Question
Based on the user selection from RadioItems or Checklist. I want to display that particular csv file in AgGrid format mainly using vm.AgGrid.
Sample Code.