diff --git a/src/aki_prj23_transparenzregister/ui/assets/networkx_style.css b/src/aki_prj23_transparenzregister/ui/assets/networkx_style.css new file mode 100644 index 0000000..aaf5f34 --- /dev/null +++ b/src/aki_prj23_transparenzregister/ui/assets/networkx_style.css @@ -0,0 +1,17 @@ +.networkx_style { + float: right; + margin-top: 20px; + margin-left: 20px; + border: 1px solid; + width: 45%; + height: 500px; +} + +.top_companytable_style { + float: left; + margin-top: 20px; + margin-right: 20px; + border: 1px solid; + width: 45%; + height: 100%; +} \ No newline at end of file diff --git a/src/aki_prj23_transparenzregister/ui/company_elements.py b/src/aki_prj23_transparenzregister/ui/company_elements.py index 5379784..f5b4dff 100644 --- a/src/aki_prj23_transparenzregister/ui/company_elements.py +++ b/src/aki_prj23_transparenzregister/ui/company_elements.py @@ -10,6 +10,7 @@ from dash import dash_table, dcc, html 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 COLORS = { "light": "#edefef", @@ -353,4 +354,6 @@ def network_layout(selected_company_id: int) -> html: Returns: The html div to create the network tab of the company page. """ - return html.Div([f"Netzwerk von Unternehmen mit ID: {selected_company_id}"]) + selected_company_id + return networkx_component(selected_company_id) + # return html.Div([f"Netzwerk von Unternehmen mit ID: {selected_company_id}"]) diff --git a/src/aki_prj23_transparenzregister/ui/networkx_dash.py b/src/aki_prj23_transparenzregister/ui/networkx_dash.py index e9b39c0..4eb961a 100644 --- a/src/aki_prj23_transparenzregister/ui/networkx_dash.py +++ b/src/aki_prj23_transparenzregister/ui/networkx_dash.py @@ -1,7 +1,7 @@ import pandas as pd import networkx as nx import plotly.graph_objects as go -from dash import Dash, Input, Output, dcc, html +from dash import Dash, Input, Output, dcc, html, callback from aki_prj23_transparenzregister.config.config_providers import JsonFileConfigProvider from aki_prj23_transparenzregister.utils.sql import connector, entities @@ -32,10 +32,10 @@ def find_company_relations(company_id: int) -> pd.DataFrame: return companies_relations_df # Plotly figure -def networkGraph(EGDE_VAR: None) -> go.Figure: +def networkGraph(company_id: int) -> go.Figure: # df = find_company_relations(test_company) edges = [] - for index, row in find_company_relations(test_company).iterrows(): + for index, row in find_company_relations(company_id).iterrows(): edges.append([row["company_name"], row["connected_company_name"]]) # print(row["company_name"], row["connected_company_name"]) # print(edges) @@ -113,27 +113,36 @@ def networkGraph(EGDE_VAR: None) -> go.Figure: # Dash App -app = Dash(__name__) +# app = Dash(__name__) -app.title = "Dash Networkx" +# app.title = "Dash Networkx" -app.layout = html.Div( +# app.layout = html.Div( +# [ +# html.I("Write your EDGE_VAR"), +# html.Br(), +# dcc.Input(id="EGDE_VAR", type="text", value="K", debounce=True), +# dcc.Graph(id="my-graph"), +# ] +# ) +def networkx_component(company_id: int): + + layout = html.Div( [ - html.I("Write your EDGE_VAR"), - html.Br(), - dcc.Input(id="EGDE_VAR", type="text", value="K", debounce=True), - dcc.Graph(id="my-graph"), + + dcc.Graph(id="my-graph", figure=networkGraph(company_id)), ] -) + ) + return layout + +# callback( +# Output("my-graph", "figure", allow_duplicate=True), +# [Input("EGDE_VAR", "value")], +# prevent_initial_call=True, +# ) +# def update_output() -> None: +# return networkGraph() -@app.callback( - Output("my-graph", "figure"), - [Input("EGDE_VAR", "value")], -) -def update_output(EGDE_VAR: None) -> None: - return networkGraph(EGDE_VAR) - - -if __name__ == "__main__": - app.run(debug=True) +# if __name__ == "__main__": +# app.run(debug=True) diff --git a/src/aki_prj23_transparenzregister/ui/networkx_dash_overall.py b/src/aki_prj23_transparenzregister/ui/networkx_dash_overall.py index b439414..b1ffbc6 100644 --- a/src/aki_prj23_transparenzregister/ui/networkx_dash_overall.py +++ b/src/aki_prj23_transparenzregister/ui/networkx_dash_overall.py @@ -148,14 +148,16 @@ def networkGraph(EGDE_VAR: None) -> go.Figure: app = Dash(__name__) app.title = "Dash Networkx" - +# className="networkx_style" app.layout = html.Div( - [ + + style={'width': '49%'}, + children = [ html.I("Write your EDGE_VAR"), html.Br(), # dcc.Dropdown(['eigenvector', 'degree', 'betweeness', 'closeness'], 'eigenvector', id='metric-dropdown'), dcc.Input(id="EGDE_VAR", type="text", value="K", debounce=True), - dcc.Graph(id="my-graph"), + dcc.Graph(id="my-graph", style={'width': '49%'}), ] ) diff --git a/src/aki_prj23_transparenzregister/ui/pages/home.py b/src/aki_prj23_transparenzregister/ui/pages/home.py index d99af6a..ad0489b 100644 --- a/src/aki_prj23_transparenzregister/ui/pages/home.py +++ b/src/aki_prj23_transparenzregister/ui/pages/home.py @@ -1,6 +1,12 @@ """Content of home page.""" import dash from dash import html +import pandas as pd +import networkx as nx +import plotly.graph_objects as go +from dash import Dash, Input, Output, dcc, html, callback +from aki_prj23_transparenzregister.config.config_providers import JsonFileConfigProvider +from aki_prj23_transparenzregister.utils.sql import connector, entities dash.register_page( __name__, @@ -14,9 +20,177 @@ dash.register_page( ], ) +def find_all_company_relations() -> pd.DataFrame: + session = connector.get_session(JsonFileConfigProvider("./secrets.json")) + query_companies = session.query(entities.Company) #.all() + query_relations = session.query(entities.CompanyRelation) # .all() + + companies_df: pd.DataFrame = pd.read_sql(str(query_companies), session.bind) # type: ignore + companies_relations_df: pd.DataFrame = pd.read_sql(str(query_relations), session.bind) # type: ignore + # print(companies_relations_df) + companies_relations_df = companies_relations_df[["relation_id","company_relation_company2_id"]] + # print(companies_relations_df) + company_name = [] + connected_company_name = [] + + companies_relations_df = companies_relations_df.head() + # print(companies_relations_df) + + for _, row in companies_relations_df.iterrows(): + # print(companies_df.loc[companies_df["company_id"] == row["relation_id"]]["company_name"].values[0]) + # print("TEst") + company_name.append(companies_df.loc[companies_df["company_id"] == row["relation_id"]]["company_name"].values[0]) + + connected_company_name.append(companies_df.loc[companies_df["company_id"] == row["company_relation_company2_id"]]["company_name"].values[0]) + # print(connected_company_name) + + # print(company_name) + companies_relations_df["company_name"] = company_name + companies_relations_df["connected_company_name"] = connected_company_name + # print("Test") + # print(companies_relations_df) + return companies_relations_df + +# Plotly figure +def networkGraph(EGDE_VAR: None) -> go.Figure: + # find_all_company_relations() + + edges = [] + for index, row in find_all_company_relations().iterrows(): + edges.append([row["company_name"], row["connected_company_name"]]) + # print(row["company_name"], row["connected_company_name"]) + # print(edges) + # edges = df[["relation_id","company_relation_company2_id"]] + # edges = [[EGDE_VAR, "B"], ["B", "C"], ["B", "D"]] + network_graph = nx.Graph() + network_graph.add_edges_from(edges) + pos = nx.spring_layout(network_graph) + + # edges trace + edge_x = [] + edge_y = [] + for edge in network_graph.edges(): + x0, y0 = pos[edge[0]] + x1, y1 = pos[edge[1]] + edge_x.append(x0) + edge_x.append(x1) + edge_x.append(None) + edge_y.append(y0) + edge_y.append(y1) + edge_y.append(None) + + edge_trace = go.Scatter( + x=edge_x, + y=edge_y, + line={"color": "black", "width": 1}, + hoverinfo="none", + showlegend=False, + mode="lines", + ) + + # nodes trace + node_x = [] + node_y = [] + text = [] + for node in network_graph.nodes(): + x, y = pos[node] + node_x.append(x) + node_y.append(y) + text.append(node) + + node_trace = go.Scatter( + x=node_x, + y=node_y, + text=text, + mode="markers+text", + showlegend=False, + hoverinfo="none", + marker={"color": "pink", "size": 50, "line": {"color": "black", "width": 1}}, + ) + + # layout + layout = { + "plot_bgcolor": "white", + "paper_bgcolor": "white", + "margin": {"t": 10, "b": 10, "l": 10, "r": 10, "pad": 0}, + "xaxis": { + "linecolor": "black", + "showgrid": False, + "showticklabels": False, + "mirror": True, + }, + "yaxis": { + "linecolor": "black", + "showgrid": False, + "showticklabels": False, + "mirror": True, + }, + } + + print(nx.eigenvector_centrality(network_graph)) + measure_vector = {} + network_metrics_df = pd.DataFrame() + + + measure_vector = nx.eigenvector_centrality(network_graph) + network_metrics_df["eigenvector"] = measure_vector.values() + + measure_vector = nx.degree_centrality(network_graph) + network_metrics_df["degree"] = measure_vector.values() + + measure_vector = nx.betweenness_centrality(network_graph) + network_metrics_df["betweeness"] = measure_vector.values() + + measure_vector = nx.closeness_centrality(network_graph) + network_metrics_df["closeness"] = measure_vector.values() + + # measure_vector = nx.pagerank(network_graph) + # network_metrics_df["pagerank"] = measure_vector.values() + + # measure_vector = nx.average_degree_connectivity(network_graph) + # network_metrics_df["average_degree"] = measure_vector.values() + print(network_metrics_df) + + # figure + return go.Figure(data=[edge_trace, node_trace], layout=layout) + + +# Dash App + + +# app = Dash(__name__) + +# app.title = "Dash Networkx" + layout = html.Div( - [ - html.H1("This is our Home page", style={"margin": 0}), - html.Div("This is our Home page content."), - ] + + children = html.Div( + children=[ + html.Div( + className="top_companytable_style", + children=[ + html.I("Write your EDGE_VAR") + ] + ), + html.Div( + className="networkx_style", + children=[ + html.I("Write your EDGE_VAR"), + html.Br(), + # dcc.Dropdown(['eigenvector', 'degree', 'betweeness', 'closeness'], 'eigenvector', id='metric-dropdown'), + dcc.Input(id="EGDE_VAR", type="text", value="K", debounce=True), + dcc.Graph(id="my-graph"), + ] + ) + ] + ) ) + + +@callback( + Output("my-graph", "figure"), + # Input('metric-dropdown', 'value'), + [Input("EGDE_VAR", "value")], +) +def update_output(EGDE_VAR: None) -> None: + return networkGraph(EGDE_VAR) \ No newline at end of file