mirror of
https://github.com/fhswf/aki_prj23_transparenzregister.git
synced 2025-05-13 16:08:45 +02:00
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:
parent
e7278c047e
commit
0d4d1324d0
@ -31,7 +31,7 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
width: 31%;
|
width: 31%;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.networkx_style .filter-wrapper .filter-wrapper-item .dropdown_style {
|
.networkx_style .filter-wrapper .filter-wrapper-item .dropdown_style {
|
||||||
|
@ -8,6 +8,7 @@ import pandas as pd
|
|||||||
import plotly.graph_objects as go
|
import plotly.graph_objects as go
|
||||||
from cachetools import TTLCache, cached
|
from cachetools import TTLCache, cached
|
||||||
from dash import Input, Output, callback, dash_table, dcc, html
|
from dash import Input, Output, callback, dash_table, dcc, html
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
from aki_prj23_transparenzregister.utils.networkx.network_2d import (
|
from aki_prj23_transparenzregister.utils.networkx.network_2d import (
|
||||||
create_2d_graph,
|
create_2d_graph,
|
||||||
@ -64,7 +65,6 @@ def update_table(
|
|||||||
@cached(TTLCache(20, ttl=600))
|
@cached(TTLCache(20, ttl=600))
|
||||||
def _update_figure( # noqa: PLR0913
|
def _update_figure( # noqa: PLR0913
|
||||||
selected_metric: str,
|
selected_metric: str,
|
||||||
switch_value: bool,
|
|
||||||
switch_edge_annotation_value: bool,
|
switch_edge_annotation_value: bool,
|
||||||
c_relation_filter_value: frozenset[str],
|
c_relation_filter_value: frozenset[str],
|
||||||
p_relation_filter_value: frozenset[str],
|
p_relation_filter_value: frozenset[str],
|
||||||
@ -78,7 +78,6 @@ def _update_figure( # noqa: PLR0913
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
selected_metric: Selected Value
|
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
|
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
|
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
|
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
|
Network Graph(Plotly Figure): Plotly Figure in 3 or 2D
|
||||||
"""
|
"""
|
||||||
_ = c_relation_filter_value, p_relation_filter_value
|
_ = 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(
|
graph, metrics, nodes, edges = update_graph_data(
|
||||||
person_relation_type=p_relation_filter_value,
|
person_relation_type=p_relation_filter_value,
|
||||||
company_relation_type=c_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)
|
table_dict, table_columns = update_table(metric_dropdown_value, metrics)
|
||||||
|
|
||||||
if switch_value:
|
if dims == 2: # noqa: PLR2004
|
||||||
return (
|
return (
|
||||||
table_dict,
|
table_dict,
|
||||||
table_columns,
|
table_columns,
|
||||||
@ -148,10 +149,9 @@ def layout() -> list[html]:
|
|||||||
top_companies_dict, top_companies_columns, figure = _update_figure(
|
top_companies_dict, top_companies_columns, figure = _update_figure(
|
||||||
"None",
|
"None",
|
||||||
False,
|
False,
|
||||||
False,
|
|
||||||
selected_company_relation_types,
|
selected_company_relation_types,
|
||||||
selected_person_relation_types,
|
selected_person_relation_types,
|
||||||
"Spring",
|
"Spring (3d)",
|
||||||
1,
|
1,
|
||||||
"degree",
|
"degree",
|
||||||
)
|
)
|
||||||
@ -199,14 +199,15 @@ def layout() -> list[html]:
|
|||||||
html.Div(
|
html.Div(
|
||||||
className="filter-wrapper",
|
className="filter-wrapper",
|
||||||
id="company_dropdown",
|
id="company_dropdown",
|
||||||
# style="visibility: hidden;",
|
|
||||||
children=[
|
children=[
|
||||||
html.Div(
|
html.Div(
|
||||||
className="filter-wrapper-item",
|
className="filter-wrapper-item",
|
||||||
children=[
|
children=[
|
||||||
html.H5(
|
html.H5(
|
||||||
className="filter-description",
|
className="filter-description",
|
||||||
children=["Company Relation Type Filter:"],
|
children=[
|
||||||
|
"Show selected relations Company to Company:"
|
||||||
|
],
|
||||||
),
|
),
|
||||||
dcc.Dropdown(
|
dcc.Dropdown(
|
||||||
company_relation_types,
|
company_relation_types,
|
||||||
@ -220,11 +221,12 @@ def layout() -> list[html]:
|
|||||||
),
|
),
|
||||||
html.Div(
|
html.Div(
|
||||||
className="filter-wrapper-item",
|
className="filter-wrapper-item",
|
||||||
# style="visibility: visible;",
|
|
||||||
children=[
|
children=[
|
||||||
html.H5(
|
html.H5(
|
||||||
className="filter-description",
|
className="filter-description",
|
||||||
children=["Person Relation Type Filter:"],
|
children=[
|
||||||
|
"Show selected relations Company to Person:"
|
||||||
|
],
|
||||||
),
|
),
|
||||||
dcc.Dropdown(
|
dcc.Dropdown(
|
||||||
person_relation_types,
|
person_relation_types,
|
||||||
@ -266,20 +268,25 @@ def layout() -> list[html]:
|
|||||||
),
|
),
|
||||||
dcc.Dropdown(
|
dcc.Dropdown(
|
||||||
[
|
[
|
||||||
"Spring",
|
"Spring (2d)",
|
||||||
|
"Spring (3d)",
|
||||||
# "Bipartite",
|
# "Bipartite",
|
||||||
"Circular",
|
"Circular (2d)",
|
||||||
"Kamada Kawai",
|
"Circular (3d)",
|
||||||
|
"Kamada Kawai (2d)",
|
||||||
|
"Kamada Kawai (3d)",
|
||||||
# "Planar",
|
# "Planar",
|
||||||
"Random",
|
"Random (2d)",
|
||||||
"Shell (only 2D)",
|
"Random (3d)",
|
||||||
|
"Shell (2d)",
|
||||||
# "Spectral",
|
# "Spectral",
|
||||||
"Spiral (only 2D)",
|
"Spiral (2d)",
|
||||||
# "Multipartite"
|
# "Multipartite"
|
||||||
],
|
],
|
||||||
"Spring",
|
"Spring (3d)",
|
||||||
id="dropdown_layout",
|
id="dropdown_layout",
|
||||||
className="dropdown_style",
|
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(
|
html.Div(
|
||||||
className="filter-wrapper-item",
|
className="filter-wrapper-item",
|
||||||
children=[
|
children=[
|
||||||
@ -370,15 +344,7 @@ def update_graph_data(
|
|||||||
person_relation_type: frozenset[str] | None = None,
|
person_relation_type: frozenset[str] | None = None,
|
||||||
company_relation_type: frozenset[str] | None = None,
|
company_relation_type: frozenset[str] | None = None,
|
||||||
) -> tuple[nx.Graph, pd.DataFrame, dict, list]:
|
) -> tuple[nx.Graph, pd.DataFrame, dict, list]:
|
||||||
"""_summary_.
|
"""_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_
|
|
||||||
"""
|
|
||||||
person_df = get_all_person_relations()
|
person_df = get_all_person_relations()
|
||||||
company_df = get_all_company_relations()
|
company_df = get_all_company_relations()
|
||||||
|
|
||||||
@ -400,7 +366,6 @@ def update_graph_data(
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
Input("dropdown", "value"),
|
Input("dropdown", "value"),
|
||||||
Input("switch", "on"),
|
|
||||||
# Input("switch_node_annotation", "on"),
|
# Input("switch_node_annotation", "on"),
|
||||||
Input("switch_edge_annotation", "on"),
|
Input("switch_edge_annotation", "on"),
|
||||||
Input("dropdown_company_relation_filter", "value"),
|
Input("dropdown_company_relation_filter", "value"),
|
||||||
@ -414,7 +379,6 @@ def update_graph_data(
|
|||||||
)
|
)
|
||||||
def update_figure( # noqa: PLR0913
|
def update_figure( # noqa: PLR0913
|
||||||
selected_metric: str,
|
selected_metric: str,
|
||||||
switch_value: bool,
|
|
||||||
switch_edge_annotation_value: bool,
|
switch_edge_annotation_value: bool,
|
||||||
c_relation_filter_value: list[str],
|
c_relation_filter_value: list[str],
|
||||||
p_relation_filter_value: list[str],
|
p_relation_filter_value: list[str],
|
||||||
@ -428,7 +392,6 @@ def update_figure( # noqa: PLR0913
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
selected_metric: Selected Value
|
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
|
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
|
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
|
p_relation_filter_value: Variable with String value of Relation Type for Persons
|
||||||
@ -440,9 +403,10 @@ def update_figure( # noqa: PLR0913
|
|||||||
Returns:
|
Returns:
|
||||||
Network Graph: Plotly Figure in 3D or 2D
|
Network Graph: Plotly Figure in 3D or 2D
|
||||||
"""
|
"""
|
||||||
|
if not layout:
|
||||||
|
return dash.no_update
|
||||||
return _update_figure(
|
return _update_figure(
|
||||||
selected_metric,
|
selected_metric,
|
||||||
switch_value,
|
|
||||||
switch_edge_annotation_value,
|
switch_edge_annotation_value,
|
||||||
frozenset(c_relation_filter_value),
|
frozenset(c_relation_filter_value),
|
||||||
frozenset(p_relation_filter_value),
|
frozenset(p_relation_filter_value),
|
||||||
|
@ -45,11 +45,11 @@ def create_2d_graph( # noqa PLR0913
|
|||||||
# pos = nx.planar_layout(graph)
|
# pos = nx.planar_layout(graph)
|
||||||
case "Random":
|
case "Random":
|
||||||
pos = nx.random_layout(graph)
|
pos = nx.random_layout(graph)
|
||||||
case "(Shell only 2D)":
|
case "Shell":
|
||||||
pos = nx.shell_layout(graph)
|
pos = nx.shell_layout(graph)
|
||||||
# case "Spectral":
|
# case "Spectral":
|
||||||
# pos = nx.spectral_layout(graph)
|
# pos = nx.spectral_layout(graph)
|
||||||
case "(Spiral only 2D)":
|
case "Spiral":
|
||||||
pos = nx.spiral_layout(graph)
|
pos = nx.spiral_layout(graph)
|
||||||
# case "Multipartite":
|
# case "Multipartite":
|
||||||
# pos = nx.multipartite_layout(graph)
|
# pos = nx.multipartite_layout(graph)
|
||||||
|
@ -5,8 +5,10 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pytest
|
import pytest
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from aki_prj23_transparenzregister.ui.pages import home
|
from aki_prj23_transparenzregister.ui.pages import home
|
||||||
|
from aki_prj23_transparenzregister.ui.session_handler import SessionHandler
|
||||||
|
|
||||||
|
|
||||||
def test_import() -> None:
|
def test_import() -> None:
|
||||||
@ -14,7 +16,6 @@ def test_import() -> None:
|
|||||||
assert home is not None
|
assert home is not None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.tim()
|
|
||||||
def test_person_relation_type_filter() -> None:
|
def test_person_relation_type_filter() -> None:
|
||||||
with patch(
|
with patch(
|
||||||
"aki_prj23_transparenzregister.ui.pages.home.get_all_person_relations"
|
"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"]
|
assert list(home.person_relation_type_filter()) == ["Eigentümer", "Inhaber"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.tim()
|
|
||||||
def test_company_relation_type_filter() -> None:
|
def test_company_relation_type_filter() -> None:
|
||||||
with patch(
|
with patch(
|
||||||
"aki_prj23_transparenzregister.ui.pages.home.get_all_company_relations"
|
"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"]
|
assert list(home.company_relation_type_filter()) == ["Eigentümer", "Inhaber"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.tim()
|
|
||||||
def test_update_table() -> None:
|
def test_update_table() -> None:
|
||||||
metrics = pd.DataFrame(
|
metrics = pd.DataFrame(
|
||||||
[
|
[
|
||||||
@ -192,3 +191,17 @@ def test_update_graph_data() -> None:
|
|||||||
frozenset({"HAFTENDER_GESELLSCHAFTER"}), frozenset("GESCHAEFTSFUEHRER")
|
frozenset({"HAFTENDER_GESELLSCHAFTER"}), frozenset("GESCHAEFTSFUEHRER")
|
||||||
)
|
)
|
||||||
assert graph_result is not None
|
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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user