Simplification of layout selection (#384)

Removed the 2d/3d toggle and added that option into the layout dropdown.

---------

Co-authored-by: KM-R <129882581+KM-R@users.noreply.github.com>
This commit is contained in:
Philipp Horstenkamp 2023-11-14 22:31:30 +01:00 committed by GitHub
parent e7278c047e
commit 0d4d1324d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 69 deletions

View File

@ -31,7 +31,7 @@
display: inline-block;
padding: 10px;
width: 31%;
vertical-align: top;
}
.networkx_style .filter-wrapper .filter-wrapper-item .dropdown_style {

View File

@ -8,6 +8,7 @@ import pandas as pd
import plotly.graph_objects as go
from cachetools import TTLCache, cached
from dash import Input, Output, callback, dash_table, dcc, html
from loguru import logger
from aki_prj23_transparenzregister.utils.networkx.network_2d import (
create_2d_graph,
@ -64,7 +65,6 @@ def update_table(
@cached(TTLCache(20, ttl=600))
def _update_figure( # noqa: PLR0913
selected_metric: str,
switch_value: bool,
switch_edge_annotation_value: bool,
c_relation_filter_value: frozenset[str],
p_relation_filter_value: frozenset[str],
@ -78,7 +78,6 @@ def _update_figure( # noqa: PLR0913
Args:
selected_metric: Selected Value
switch_value: True if 2D, False if 3D
switch_edge_annotation_value: True if Edge should have a description, False = No Description
c_relation_filter_value: Variable with String value of Relation Type for Companies
p_relation_filter_value: Variable with String value of Relation Type for Persons
@ -91,7 +90,9 @@ def _update_figure( # noqa: PLR0913
Network Graph(Plotly Figure): Plotly Figure in 3 or 2D
"""
_ = c_relation_filter_value, p_relation_filter_value
dims = 3 if layout.endswith("(3d)") else 2
layout = layout[:-5].strip()
logger.info(f"Plotting full network for layout: {layout} with {dims} dimensions.")
graph, metrics, nodes, edges = update_graph_data(
person_relation_type=p_relation_filter_value,
company_relation_type=c_relation_filter_value,
@ -99,7 +100,7 @@ def _update_figure( # noqa: PLR0913
table_dict, table_columns = update_table(metric_dropdown_value, metrics)
if switch_value:
if dims == 2: # noqa: PLR2004
return (
table_dict,
table_columns,
@ -148,10 +149,9 @@ def layout() -> list[html]:
top_companies_dict, top_companies_columns, figure = _update_figure(
"None",
False,
False,
selected_company_relation_types,
selected_person_relation_types,
"Spring",
"Spring (3d)",
1,
"degree",
)
@ -199,14 +199,15 @@ def layout() -> list[html]:
html.Div(
className="filter-wrapper",
id="company_dropdown",
# style="visibility: hidden;",
children=[
html.Div(
className="filter-wrapper-item",
children=[
html.H5(
className="filter-description",
children=["Company Relation Type Filter:"],
children=[
"Show selected relations Company to Company:"
],
),
dcc.Dropdown(
company_relation_types,
@ -220,11 +221,12 @@ def layout() -> list[html]:
),
html.Div(
className="filter-wrapper-item",
# style="visibility: visible;",
children=[
html.H5(
className="filter-description",
children=["Person Relation Type Filter:"],
children=[
"Show selected relations Company to Person:"
],
),
dcc.Dropdown(
person_relation_types,
@ -266,20 +268,25 @@ def layout() -> list[html]:
),
dcc.Dropdown(
[
"Spring",
"Spring (2d)",
"Spring (3d)",
# "Bipartite",
"Circular",
"Kamada Kawai",
"Circular (2d)",
"Circular (3d)",
"Kamada Kawai (2d)",
"Kamada Kawai (3d)",
# "Planar",
"Random",
"Shell (only 2D)",
"Random (2d)",
"Random (3d)",
"Shell (2d)",
# "Spectral",
"Spiral (only 2D)",
"Spiral (2d)",
# "Multipartite"
],
"Spring",
"Spring (3d)",
id="dropdown_layout",
className="dropdown_style",
placeholder="Select a graph layout",
),
],
),
@ -299,39 +306,6 @@ def layout() -> list[html]:
),
],
),
],
),
html.Div(
className="filter-wrapper",
children=[
html.Div(
className="filter-wrapper-item",
children=[
html.H5(
className="filter-description",
children=["Switch to 2D Diagramm"],
),
html.Div(
className="switch-style",
children=[
daq.BooleanSwitch(id="switch", on=False)
],
),
],
),
# html.Div(
# className="filter-wrapper-item",
# children=[
# html.H5(
# className="filter-description",
# children=["Enable Node Annotation"],
# ),
# html.Div(
# className="switch-style",
# children=[daq.BooleanSwitch(id="switch_node_annotation", on=False)],
# ),
# ],
# ),
html.Div(
className="filter-wrapper-item",
children=[
@ -370,15 +344,7 @@ def update_graph_data(
person_relation_type: frozenset[str] | None = None,
company_relation_type: frozenset[str] | None = None,
) -> tuple[nx.Graph, pd.DataFrame, dict, list]:
"""_summary_.
Args:
person_relation_type (str, optional): _description_. Defaults to "HAFTENDER_GESELLSCHAFTER".
company_relation_type (str, optional): _description_. Defaults to "GESCHAEFTSFUEHRER".
Returns:
tuple[nx.Graph, pd.DataFrame, dict, list]: _description_
"""
"""_summary_."""
person_df = get_all_person_relations()
company_df = get_all_company_relations()
@ -400,7 +366,6 @@ def update_graph_data(
],
[
Input("dropdown", "value"),
Input("switch", "on"),
# Input("switch_node_annotation", "on"),
Input("switch_edge_annotation", "on"),
Input("dropdown_company_relation_filter", "value"),
@ -414,7 +379,6 @@ def update_graph_data(
)
def update_figure( # noqa: PLR0913
selected_metric: str,
switch_value: bool,
switch_edge_annotation_value: bool,
c_relation_filter_value: list[str],
p_relation_filter_value: list[str],
@ -428,7 +392,6 @@ def update_figure( # noqa: PLR0913
Args:
selected_metric: Selected Value
switch_value: True if 2D, False if 3D
switch_edge_annotation_value: True if Edge should have a description, False = No Description
c_relation_filter_value: Variable with String value of Relation Type for Companies
p_relation_filter_value: Variable with String value of Relation Type for Persons
@ -440,9 +403,10 @@ def update_figure( # noqa: PLR0913
Returns:
Network Graph: Plotly Figure in 3D or 2D
"""
if not layout:
return dash.no_update
return _update_figure(
selected_metric,
switch_value,
switch_edge_annotation_value,
frozenset(c_relation_filter_value),
frozenset(p_relation_filter_value),

View File

@ -45,11 +45,11 @@ def create_2d_graph( # noqa PLR0913
# pos = nx.planar_layout(graph)
case "Random":
pos = nx.random_layout(graph)
case "(Shell only 2D)":
case "Shell":
pos = nx.shell_layout(graph)
# case "Spectral":
# pos = nx.spectral_layout(graph)
case "(Spiral only 2D)":
case "Spiral":
pos = nx.spiral_layout(graph)
# case "Multipartite":
# pos = nx.multipartite_layout(graph)

View File

@ -5,8 +5,10 @@ from unittest.mock import patch
import pandas as pd
import pytest
from sqlalchemy.orm import Session
from aki_prj23_transparenzregister.ui.pages import home
from aki_prj23_transparenzregister.ui.session_handler import SessionHandler
def test_import() -> None:
@ -14,7 +16,6 @@ def test_import() -> None:
assert home is not None
@pytest.mark.tim()
def test_person_relation_type_filter() -> None:
with patch(
"aki_prj23_transparenzregister.ui.pages.home.get_all_person_relations"
@ -28,7 +29,6 @@ def test_person_relation_type_filter() -> None:
assert list(home.person_relation_type_filter()) == ["Eigentümer", "Inhaber"]
@pytest.mark.tim()
def test_company_relation_type_filter() -> None:
with patch(
"aki_prj23_transparenzregister.ui.pages.home.get_all_company_relations"
@ -42,7 +42,6 @@ def test_company_relation_type_filter() -> None:
assert list(home.company_relation_type_filter()) == ["Eigentümer", "Inhaber"]
@pytest.mark.tim()
def test_update_table() -> None:
metrics = pd.DataFrame(
[
@ -192,3 +191,17 @@ def test_update_graph_data() -> None:
frozenset({"HAFTENDER_GESELLSCHAFTER"}), frozenset("GESCHAEFTSFUEHRER")
)
assert graph_result is not None
@pytest.fixture()
def _set_session(full_db: Session) -> Generator[None, None, None]:
"""Sets a session for the dash application to be used."""
SessionHandler.session = full_db
yield
SessionHandler.session = None
@pytest.mark.usefixtures("_set_session")
def test_layout() -> None:
"""Checks if layout can be executed."""
home.layout()