Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Fix bug that prevented custom tables/grids with column referral #439

Merged
merged 22 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3d2403b
Adressing bug and adding tests
maxschulz-COL Apr 26, 2024
747837a
Fix remaining unit tests
maxschulz-COL Apr 26, 2024
425c773
Linting
maxschulz-COL Apr 26, 2024
e8c4ace
CHangelog
maxschulz-COL Apr 26, 2024
794eed8
Merge branch 'main' into bug/missing_DF_435
maxschulz-COL Apr 26, 2024
a18d2cc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 26, 2024
df41457
Merge branch 'main' into bug/missing_DF_435
maxschulz-COL May 2, 2024
a3bf131
Different example
maxschulz-COL May 2, 2024
4c39246
TBR Removing DF breaks filter persistence on page change
maxschulz-COL May 2, 2024
7d4e6c9
Revert "TBR Removing DF breaks filter persistence on page change"
maxschulz-COL May 2, 2024
a35f6c7
Final comments and linting
maxschulz-COL May 2, 2024
2143987
Merge branch 'main' into bug/missing_DF_435
maxschulz-COL May 7, 2024
b5fadca
Merge branch 'main' into bug/missing_DF_435
maxschulz-COL May 7, 2024
be60463
Merge main
maxschulz-COL May 10, 2024
30c75dd
Merge branch 'bug/missing_DF_435' of github.com:mckinsey/vizro into b…
maxschulz-COL May 10, 2024
1bdd2c1
Fix tests after changes in main
maxschulz-COL May 10, 2024
300ef3f
Change back dev example
maxschulz-COL May 10, 2024
5a531cb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 10, 2024
2f1a92b
Revert "Change back dev example"
maxschulz-COL May 11, 2024
b30dd5a
Merge origin
maxschulz-COL May 11, 2024
bccea7e
Fix non running integration tests by adding if clause
maxschulz-COL May 11, 2024
542fe78
Linting
maxschulz-COL May 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!--
A new scriv changelog fragment.

Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Highlights ✨

- A bullet item for the Highlights ✨ category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))

-->
<!--
### Removed

- A bullet item for the Removed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))

-->
<!--
### Added

- A bullet item for the Added category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))

-->
<!--
### Changed

- A bullet item for the Changed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))

-->
<!--
### Deprecated

- A bullet item for the Deprecated category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))

-->

### Fixed

- Fix bug that [prevented referring to columns in custom grids/tables](https://github.com/mckinsey/vizro/issues/435) ([#439](https://github.com/mckinsey/vizro/pull/439))

<!--
### Security

- A bullet item for the Security category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))

-->
2 changes: 1 addition & 1 deletion vizro-core/src/vizro/models/_components/ag_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def build(self):
# here) must have the same setting as the object that is built by the on-page-load mechanism using
# with the user settings and rendered finally. Otherwise the grid is not rendered correctly.
# Hence be careful when editing the line below.
html.Div(self.__call__(data_frame=pd.DataFrame()), id=self.id, className="table-container"),
html.Div(self.__call__(), id=self.id, className="table-container"),
maxschulz-COL marked this conversation as resolved.
Show resolved Hide resolved
],
id=f"{self.id}_outer",
color="grey",
Expand Down
2 changes: 1 addition & 1 deletion vizro-core/src/vizro/models/_components/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def build(self):
html.Div(
[
html.H3(self.title, className="table-title") if self.title else None,
html.Div(self.__call__(data_frame=pd.DataFrame()), id=self.id),
html.Div(self.__call__(), id=self.id),
maxschulz-COL marked this conversation as resolved.
Show resolved Hide resolved
],
className="table-container",
id=f"{self.id}_outer",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Unit tests for vizro.models.AgGrid."""

import pandas as pd
import pytest
from asserts import assert_component_equal
from dash import dcc, html
Expand Down Expand Up @@ -117,15 +116,15 @@ def test_pre_build_actions_underlying_ag_grid_id(self, ag_grid_with_id, filter_i


class TestBuildAgGrid:
def test_ag_grid_build_mandatory_only(self, standard_ag_grid):
def test_ag_grid_build_mandatory_only(self, standard_ag_grid, gapminder):
ag_grid = vm.AgGrid(id="text_ag_grid", figure=standard_ag_grid)
ag_grid.pre_build()
ag_grid = ag_grid.build()
expected_ag_grid = dcc.Loading(
[
None,
html.Div(
dash_ag_grid(data_frame=pd.DataFrame(), id="__input_text_ag_grid")(),
dash_ag_grid(data_frame=gapminder, id="__input_text_ag_grid")(),
id="text_ag_grid",
className="table-container",
),
Expand All @@ -137,7 +136,7 @@ def test_ag_grid_build_mandatory_only(self, standard_ag_grid):

assert_component_equal(ag_grid, expected_ag_grid)

def test_ag_grid_build_with_underlying_id(self, ag_grid_with_id_and_conf, filter_interaction_action):
def test_ag_grid_build_with_underlying_id(self, ag_grid_with_id_and_conf, filter_interaction_action, gapminder):
ag_grid = vm.AgGrid(id="text_ag_grid", figure=ag_grid_with_id_and_conf, actions=[filter_interaction_action])
ag_grid.pre_build()
ag_grid = ag_grid.build()
Expand All @@ -147,7 +146,7 @@ def test_ag_grid_build_with_underlying_id(self, ag_grid_with_id_and_conf, filter
None,
html.Div(
dash_ag_grid(
data_frame=pd.DataFrame(), id="underlying_ag_grid_id", dashGridOptions={"pagination": True}
data_frame=gapminder, id="underlying_ag_grid_id", dashGridOptions={"pagination": True}
)(),
id="text_ag_grid",
className="table-container",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Unit tests for vizro.models.Table."""

import pandas as pd
import pytest
from asserts import assert_component_equal
from dash import dcc, html
Expand Down Expand Up @@ -118,15 +117,15 @@ def test_pre_build_actions_underlying_table_id(self, dash_data_table_with_id, fi


class TestBuildTable:
def test_table_build_mandatory_only(self, standard_dash_table):
def test_table_build_mandatory_only(self, standard_dash_table, gapminder):
table = vm.Table(id="text_table", figure=standard_dash_table)
table.pre_build()
table = table.build()
expected_table = dcc.Loading(
html.Div(
[
None,
html.Div(dash_data_table(id="__input_text_table", data_frame=pd.DataFrame())(), id="text_table"),
html.Div(dash_data_table(id="__input_text_table", data_frame=gapminder)(), id="text_table"),
],
className="table-container",
id="text_table_outer",
Expand All @@ -137,7 +136,7 @@ def test_table_build_mandatory_only(self, standard_dash_table):

assert_component_equal(table, expected_table)

def test_table_build_with_underlying_id(self, dash_data_table_with_id, filter_interaction_action):
def test_table_build_with_underlying_id(self, dash_data_table_with_id, filter_interaction_action, gapminder):
table = vm.Table(id="text_table", figure=dash_data_table_with_id, actions=[filter_interaction_action])
table.pre_build()
table = table.build()
Expand All @@ -146,7 +145,7 @@ def test_table_build_with_underlying_id(self, dash_data_table_with_id, filter_in
html.Div(
[
None,
html.Div(dash_data_table(id="underlying_table_id", data_frame=pd.DataFrame())(), id="text_table"),
html.Div(dash_data_table(id="underlying_table_id", data_frame=gapminder)(), id="text_table"),
],
className="table-container",
id="text_table_outer",
Expand Down
76 changes: 66 additions & 10 deletions vizro-core/tests/unit/vizro/tables/test_dash_ag_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import vizro.models as vm
from asserts import assert_component_equal
from dash import dcc, html
from pandas import Timestamp
from vizro.models.types import capture
from vizro.tables import dash_ag_grid

Expand All @@ -14,6 +15,26 @@
"date": pd.to_datetime(["2021/01/01", "2021/01/02", "2021/01/03"]),
}
)
column_defs = [{"field": "cat"}, {"field": "int"}, {"field": "float"}, {"field": "date"}]
row_data_date_converted = [
{"cat": "a", "int": 4, "float": 7.3, "date": "2021-01-01"},
{"cat": "b", "int": 5, "float": 8.2, "date": "2021-01-02"},
{"cat": "c", "int": 6, "float": 9.1, "date": "2021-01-03"},
]
row_data_date_raw = [
{"cat": "a", "date": Timestamp("2021-01-01 00:00:00"), "float": 7.3, "int": 4},
{"cat": "b", "date": Timestamp("2021-01-02 00:00:00"), "float": 8.2, "int": 5},
{"cat": "c", "date": Timestamp("2021-01-03 00:00:00"), "float": 9.1, "int": 6},
]
default_col_defs = {
"filter": True,
"filterParams": {"buttons": ["apply", "reset"], "closeOnApply": True},
"flex": 1,
"minWidth": 70,
"resizable": True,
"sortable": True,
}
style = {"height": "100%"}


class TestDashAgGrid:
Expand All @@ -22,17 +43,14 @@ def test_dash_ag_grid(self):
assert_component_equal(
grid,
dag.AgGrid(
columnDefs=[{"field": "cat"}, {"field": "int"}, {"field": "float"}, {"field": "date"}],
rowData=[
{"cat": "a", "int": 4, "float": 7.3, "date": "2021-01-01"},
{"cat": "b", "int": 5, "float": 8.2, "date": "2021-01-02"},
{"cat": "c", "int": 6, "float": 9.1, "date": "2021-01-03"},
],
columnDefs=column_defs,
rowData=row_data_date_converted,
defaultColDef=default_col_defs,
style=style,
),
keys_to_strip={"className", "defaultColDef", "dashGridOptions", "style"},
keys_to_strip={"className", "dashGridOptions"},
)
# we could test other properties such as defaultColDef,
# but this would just test our chosen defaults, and no functionality really
# skipping only dashGridOptions as this is mostly our defaults for data formats, and would crowd the tests


class TestCustomDashAgGrid:
Expand All @@ -58,7 +76,45 @@ def custom_ag_grid(data_frame):
[
None,
html.Div(
dag.AgGrid(id="__input_custom_ag_grid", columnDefs=[], rowData=[]),
dag.AgGrid(id="__input_custom_ag_grid", columnDefs=column_defs, rowData=row_data_date_raw),
id=id,
className="table-container",
),
],
id=f"{id}_outer",
color="grey",
parent_className="loading-container",
)

assert_component_equal(custom_grid, expected_grid)

def test_custom_dash_ag_grid_column_referral(self):
"""Tests whether a custom created grid can be correctly built in vm.AgGrid.

This test focuses on the case that the custom grid includes column referrals on presumed data knowledge.
"""
id = "custom_ag_grid"

@capture("ag_grid")
def custom_ag_grid(data_frame):
data_frame["cat"] # access "existing" column
return dag.AgGrid(
columnDefs=[{"field": col} for col in data_frame.columns],
rowData=data_frame.to_dict("records"),
)

grid_model = vm.AgGrid(
id=id,
figure=custom_ag_grid(data_frame=data),
)
grid_model.pre_build()
custom_grid = grid_model.build()

expected_grid = dcc.Loading(
[
None,
html.Div(
dag.AgGrid(id="__input_custom_ag_grid", columnDefs=column_defs, rowData=row_data_date_raw),
id=id,
className="table-container",
),
Expand Down
73 changes: 61 additions & 12 deletions vizro-core/tests/unit/vizro/tables/test_dash_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@
"date": pd.to_datetime(["2021/01/01", "2021/01/02", "2021/01/03"]),
}
)
columns = [
{"id": "cat", "name": "cat"},
{"id": "int", "name": "int"},
{"id": "float", "name": "float"},
{"id": "date", "name": "date"},
]
data_in_table = [
{"cat": "a", "int": 4, "float": 7.3, "date": pd.Timestamp("2021-01-01 00:00:00")},
{"cat": "b", "int": 5, "float": 8.2, "date": pd.Timestamp("2021-01-02 00:00:00")},
{"cat": "c", "int": 6, "float": 9.1, "date": pd.Timestamp("2021-01-03 00:00:00")},
]


class TestDashDataTable:
Expand All @@ -21,17 +32,8 @@ def test_dash_data_table(self):
assert_component_equal(
table,
dash_table.DataTable(
columns=[
{"id": "cat", "name": "cat"},
{"id": "int", "name": "int"},
{"id": "float", "name": "float"},
{"id": "date", "name": "date"},
],
data=[
{"cat": "a", "int": 4, "float": 7.3, "date": pd.Timestamp("2021-01-01 00:00:00")},
{"cat": "b", "int": 5, "float": 8.2, "date": pd.Timestamp("2021-01-02 00:00:00")},
{"cat": "c", "int": 6, "float": 9.1, "date": pd.Timestamp("2021-01-03 00:00:00")},
],
columns=columns,
data=data_in_table,
style_as_list_view=True,
style_data={"border_bottom": "1px solid var(--border-subtle-alpha-01)", "height": "40px"},
style_header={
Expand Down Expand Up @@ -70,7 +72,54 @@ def custom_dash_data_table(data_frame):

custom_table = table.build()

expected_table_object = custom_dash_data_table(data_frame=pd.DataFrame())()
expected_table_object = dash_table.DataTable(
columns=columns,
data=data_in_table,
)
expected_table_object.id = "__input_" + id

expected_table = dcc.Loading(
html.Div(
[
None,
html.Div(expected_table_object, id=id),
],
className="table-container",
id=f"{id}_outer",
),
color="grey",
parent_className="loading-container",
)

assert_component_equal(custom_table, expected_table)

def test_custom_dash_data_table_column_referral(self):
"""Tests whether a custom created table callable can be correctly built in vm.Table.

This test focuses on the case that the custom grid include column referrals on presumed data knowledge.
"""
id = "custom_dash_data_table"

@capture("table")
def custom_dash_data_table(data_frame):
data_frame["cat"] # access "existing" column
return dash_table.DataTable(
columns=[{"name": col, "id": col} for col in data_frame.columns],
data=data_frame.to_dict("records"),
)

table = vm.Table(
id=id,
figure=custom_dash_data_table(data_frame=data),
)
table.pre_build()

custom_table = table.build()

expected_table_object = dash_table.DataTable(
columns=columns,
data=data_in_table,
)
expected_table_object.id = "__input_" + id

expected_table = dcc.Loading(
Expand Down
Loading