diff --git a/src/aki_prj23_transparenzregister/ui/company_elements.py b/src/aki_prj23_transparenzregister/ui/company_elements.py index ec1c283..7555e0b 100644 --- a/src/aki_prj23_transparenzregister/ui/company_elements.py +++ b/src/aki_prj23_transparenzregister/ui/company_elements.py @@ -11,7 +11,10 @@ from sqlalchemy.orm import Session from aki_prj23_transparenzregister.ui import data_elements, finance_elements from aki_prj23_transparenzregister.ui.networkx_dash import networkx_component +from aki_prj23_transparenzregister.utils.networkx.network_2d import create_2d_graph +from aki_prj23_transparenzregister.utils.networkx.network_base import initialize_network from aki_prj23_transparenzregister.utils.networkx.networkx_data import ( + create_edge_and_node_list_for_company, find_company_relations, ) @@ -378,14 +381,17 @@ def network_layout(selected_company_id: int) -> html.Div: """ person_relations, company_relations = find_company_relations(selected_company_id) # Create Edge and Node List from data - # nodes, edges = create_edge_and_node_list_for_company(company_relations) + nodes, edges = create_edge_and_node_list_for_company(company_relations) # Initialize the Network and receive the Graph and a DataFrame with Metrics # print(nodes) + # print(edges) # print(pd.DataFrame(edges)) - # graph, metrics = initialize_network(nodes=nodes, edges=edges) - # metric = None - # figure = create_2d_graph(graph, nodes, edges, metrics, metric) + if nodes != {}: + graph, metrics = initialize_network(nodes=nodes, edges=edges) + metric = "None" + figure = create_2d_graph(graph, nodes, edges, metrics, metric, layout="Spring", edge_annotation=True, node_annotation=False, edge_thickness=1) # selected_company_id # print(company_relations) - return networkx_component(selected_company_id) - # return html.Div([f"Netzwerk von Unternehmen mit ID: {selected_company_id}"]) + return html.Div( children=[dcc.Graph(figure=figure, id="company-graph", className="graph-style")]) + # return networkx_component(selected_company_id) + return html.Div([html.H3(f"Leider gibt es keine Verbindungen vom Unternehmen mit ID: {selected_company_id}")]) diff --git a/src/aki_prj23_transparenzregister/ui/pages/home.py b/src/aki_prj23_transparenzregister/ui/pages/home.py index e6f5f12..f7fa2a8 100644 --- a/src/aki_prj23_transparenzregister/ui/pages/home.py +++ b/src/aki_prj23_transparenzregister/ui/pages/home.py @@ -66,7 +66,7 @@ graph, metrics = initialize_network(nodes=nodes, edges=edges) metric = "None" layout = "Spring" switch_node_annotaion_value = False -switch_edge_annotaion_value = True +switch_edge_annotaion_value = False egde_thickness = 1 network = create_3d_graph(graph, nodes, edges, metrics, metric, layout, switch_node_annotaion_value, switch_edge_annotaion_value, egde_thickness) @@ -119,6 +119,28 @@ layout = html.Div( html.H1(className="header", children=["Social Graph"]), html.Div( className="filter-wrapper", + children=[ + html.Div( + className="filter-wrapper-item", + children=[ + html.H5( + className="filter-description", + children=["Data Source:"], + ), + dcc.Dropdown( + ["Company Data only", "Person Data only", "Company & Person Data"], + "Company Data only", + id="dropdown_data_soruce_filter", + className="dropdown_style", + ), + ], + ), + ], + ), + html.Div( + className="filter-wrapper", + id= "company_dropdown", + # style="display: inline;", children=[ html.Div( className="filter-wrapper-item", @@ -137,6 +159,7 @@ layout = html.Div( ), html.Div( className="filter-wrapper-item", + # style="display: None;", children=[ html.H5( className="filter-description", @@ -184,12 +207,12 @@ layout = html.Div( # "Bipartite", "Circular", "Kamada Kawai", - "Planar", + # "Planar", "Random", - "Shell", - "Spectral", - "Spiral", - "Multipartite" + "Shell (only 2D)", + # "Spectral", + "Spiral (only 2D)", + # "Multipartite" ], "Spring", id="dropdown_layout", @@ -292,19 +315,22 @@ def update_graph_data( # Get Data person_df = get_all_person_relations() company_df = get_all_company_relations() + # print(company_df) person_relation = filter_relation_type(person_df, person_relation_type) company_relation = filter_relation_type(company_df, company_relation_type) # company_relation = filter_relation_with_more_than_one_connection(company_relation, "id_company_to", "id_company_from") - + # print(company_relation) + # print(len(company_relation)) # Create Edge and Node List from data - nodes, edges = create_edge_and_node_list(person_relation, company_relation) - # node_count = len(nodes) - # edge_count = len(edges) + nodes_tmp, edges_tmp = create_edge_and_node_list(person_relation, company_relation) + node_count = len(nodes_tmp) + edge_count = len(edges_tmp) + # print(edges_tmp) - graph, metrics = initialize_network(nodes=nodes, edges=edges) - return graph, metrics + graph, metrics = initialize_network(nodes=nodes_tmp, edges=edges_tmp) + return graph, metrics, nodes_tmp, edges_tmp @callback( @@ -351,7 +377,9 @@ def update_figure( # print(selected_value) # print(metrics) # print(graph) - graph, metrics = update_graph_data(person_relation_type= p_relation_filter_value, company_relation_type= c_relation_filter_value) + graph, metrics, nodes, edges = update_graph_data(person_relation_type= p_relation_filter_value, company_relation_type= c_relation_filter_value) + node_count = len(nodes) + edge_count = len(edges) if switch_value: @@ -373,4 +401,22 @@ def update_table(metric_dropdown_value: str) -> dict: columns =[{"name": i, "id": i} for i in table_df.columns] # print(columns) - return table_df.to_dict("records") \ No newline at end of file + return table_df.to_dict("records") + + +@callback( +Output("company_dropdown", "style"), +[ + Input("dropdown_data_soruce_filter", "value"), +], +) +def update_Dropdown(datasource_value: str) -> str: + style = "" + match datasource_value: + case "Company Data only": + style = "display: inline" + case "Person Data only": + style = "display: none" + case "Company & Person Data": + style = "display: inline" + return style \ No newline at end of file diff --git a/src/aki_prj23_transparenzregister/utils/networkx/network_2d.py b/src/aki_prj23_transparenzregister/utils/networkx/network_2d.py index c4a1cd8..21ad91d 100644 --- a/src/aki_prj23_transparenzregister/utils/networkx/network_2d.py +++ b/src/aki_prj23_transparenzregister/utils/networkx/network_2d.py @@ -35,11 +35,11 @@ def create_2d_graph( # pos = nx.planar_layout(graph) case "Random": pos = nx.random_layout(graph) - case "Shell": + case "Shell only 2D)": pos = nx.shell_layout(graph) # case "Spectral": # pos = nx.spectral_layout(graph) - case "Spiral": + case "Spiral only 2D)": pos = nx.spiral_layout(graph) # case "Multipartite": # pos = nx.multipartite_layout(graph) @@ -60,15 +60,15 @@ def create_2d_graph( x1, y1 = pos[edge[1]] edge_x.append(x0) edge_x.append(x1) - edge_x.append(None) + # edge_x.append(None) edge_y.append(y0) edge_y.append(y1) - edge_y.append(None) + # edge_y.append(None) - edge_weight_x.append(x0 + ((x1 - x0) / 2)) - edge_weight_y.append(y0 + ((y1 - y0) / 2)) - edge_weight_y.append(None) + edge_weight_x.append(((x1 + x0) / 2)) + edge_weight_y.append(((y1 + y0) / 2)) + # edge_weight_y.append(None) # Add the Edges to the scatter plot according to their Positions. edge_trace = go.Scatter( x=edge_x, @@ -82,10 +82,10 @@ def create_2d_graph( x=edge_weight_x, y=edge_weight_y, mode="text", - marker_size=1, + marker_size=0.5, text=[0.45, 0.7, 0.34], textposition="top center", - hovertemplate="weight: %{text}", + hovertemplate="Relation: %{text}", ) # Getting the Positions from NetworkX and assign it to the variables. @@ -139,6 +139,7 @@ def create_2d_graph( edge_type_list.append(row["type"]) edge_weights_trace.text = edge_type_list + # print(edge_type_list) if node_annotation: print("Test") diff --git a/src/aki_prj23_transparenzregister/utils/networkx/network_3d.py b/src/aki_prj23_transparenzregister/utils/networkx/network_3d.py index 4f53a5d..e0067ad 100644 --- a/src/aki_prj23_transparenzregister/utils/networkx/network_3d.py +++ b/src/aki_prj23_transparenzregister/utils/networkx/network_3d.py @@ -54,6 +54,11 @@ def create_3d_graph( node_y = [] node_z = [] + # Initialize Position Variables for the Description Text of the edges. + edge_weight_x = [] + edge_weight_y = [] + edge_weight_z = [] + # Getting the Positions from NetworkX and assign them to the variables. for edge in graph.edges(): x0, y0, z0 = pos[edge[0]] @@ -67,6 +72,11 @@ def create_3d_graph( edge_z.append(z0) edge_z.append(z1) + + # Calculate edge mid + edge_weight_x.append((x0+x1)/2) + edge_weight_y.append((y0+y1)/2) + edge_weight_z.append((z0+z1)/2) # Add the Edges to the scatter plot according to their Positions. edge_trace = go.Scatter3d( @@ -78,6 +88,18 @@ def create_3d_graph( hoverinfo="none", ) + # Add the Edgedescriptiontext to the scatter plot according to its Position. + edge_weights_trace = go.Scatter3d( + x=edge_weight_x, + y=edge_weight_y, + z=edge_weight_z, + mode="text", + marker_size=1, + text=[0.45, 0.7, 0.34], + textposition="top center", + hovertemplate="weight: %{text}", + ) + # Getting the Positions from NetworkX and assign it to the variables. for node in graph.nodes(): x, y, z = pos[node] @@ -163,6 +185,14 @@ def create_3d_graph( edge_colors.append("rgb(255,105,180)") edge_trace.line = {"color": edge_colors, "width": edge_thickness} + # Add Relation_Type as a Description for the edges. + if edge_annotation: + edge_type_list = [] + for row in edges: + edge_type_list.append(row["type"]) + + edge_weights_trace.text = edge_type_list + # Return the Plotly Figure - data = [edge_trace, node_trace] + data = [edge_trace,edge_weights_trace, node_trace] return go.Figure(data=data, layout=layout)