mirror of
https://github.com/fhswf/aki_prj23_transparenzregister.git
synced 2025-05-14 12:58:46 +02:00
Added 2d and 3d network to dash
This commit is contained in:
parent
e45f3a3b98
commit
bcb6df8e5d
@ -1,18 +1,20 @@
|
|||||||
.networkx_style {
|
.networkx_style {
|
||||||
float: right;
|
float: right;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-left: 20px;
|
margin-left: 10px;
|
||||||
|
margin-right: 20px;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
border-color: blue;
|
border-color: blue;
|
||||||
width: 45%;
|
width: 57%;
|
||||||
height: 500px;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top_companytable_style {
|
.top_companytable_style {
|
||||||
float: left;
|
float: left;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-right: 20px;
|
margin-left: 20px;
|
||||||
|
margin-right: 10px;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
width: 45%;
|
width: 37%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
@ -3,14 +3,32 @@ import dash
|
|||||||
import networkx as nx
|
import networkx as nx
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import plotly.graph_objects as go
|
import plotly.graph_objects as go
|
||||||
from dash import Input, Output, callback, html
|
from dash import Input, Output, callback, html, dcc, dash_table, ctx
|
||||||
|
import dash_daq as daq
|
||||||
|
|
||||||
|
|
||||||
from aki_prj23_transparenzregister.utils.networkx.networkx_data import (
|
from aki_prj23_transparenzregister.utils.networkx.networkx_data import (
|
||||||
find_all_company_relations,
|
find_all_company_relations,
|
||||||
find_top_companies,
|
find_top_companies,
|
||||||
|
get_all_person_relations,
|
||||||
|
get_all_company_relations,
|
||||||
|
filter_relation_type,
|
||||||
|
filter_relation_with_more_than_one_connection,
|
||||||
|
create_edge_and_node_list
|
||||||
|
)
|
||||||
|
from aki_prj23_transparenzregister.utils.networkx.network_3d import (
|
||||||
|
initialize_network,
|
||||||
|
create_3d_graph,
|
||||||
|
)
|
||||||
|
|
||||||
|
from aki_prj23_transparenzregister.utils.networkx.network_2d import (
|
||||||
|
create_2d_graph,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Get Data
|
||||||
|
person_relation = filter_relation_type(get_all_person_relations(), "HAFTENDER_GESELLSCHAFTER")
|
||||||
|
company_relation = filter_relation_with_more_than_one_connection(get_all_company_relations(), "id_company_to", "id_company_from")
|
||||||
|
|
||||||
dash.register_page(
|
dash.register_page(
|
||||||
__name__,
|
__name__,
|
||||||
@ -29,99 +47,14 @@ dash.register_page(
|
|||||||
def networkGraph(EGDE_VAR: None) -> go.Figure:
|
def networkGraph(EGDE_VAR: None) -> go.Figure:
|
||||||
# find_all_company_relations()
|
# find_all_company_relations()
|
||||||
|
|
||||||
edges = []
|
graph, metrices = initialize_network(nodes = nodes, edges = edges)
|
||||||
for index, row in find_all_company_relations().iterrows():
|
# print(graph)
|
||||||
edges.append([row["company_name"], row["connected_company_name"]])
|
metric = None
|
||||||
network_graph = nx.Graph()
|
network = create_3d_graph(graph, nodes, edges, metrices, metric)
|
||||||
network_graph.add_edges_from(edges)
|
|
||||||
pos = nx.spring_layout(network_graph)
|
|
||||||
|
|
||||||
# edges trace
|
company_relation_type_filter = get_all_person_relations()["relation_type"].unique()
|
||||||
edge_x = []
|
print(company_relation_type_filter)
|
||||||
edge_y = []
|
person_relation_type_filter = get_all_company_relations()["relation_type"].unique()
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
df = find_top_companies()
|
df = find_top_companies()
|
||||||
@ -130,44 +63,122 @@ with open("src/aki_prj23_transparenzregister/ui/assets/network_graph.html") as f
|
|||||||
|
|
||||||
|
|
||||||
layout = html.Div(
|
layout = html.Div(
|
||||||
children=[
|
# children=[
|
||||||
# NOTE lib dir created by NetworkX has to be placed in assets
|
# # NOTE lib dir created by NetworkX has to be placed in assets
|
||||||
html.Iframe(
|
# # html.Iframe(
|
||||||
src="assets/network_graph.html",
|
# # src="assets/network_graph.html",
|
||||||
style={"height": "100vh", "width": "100vw"},
|
# # style={"height": "100vh", "width": "100vw"},
|
||||||
allow="*",
|
# # allow="*",
|
||||||
)
|
# # )
|
||||||
]
|
# ]
|
||||||
# children = html.Div(
|
children = html.Div(
|
||||||
# children=[
|
children=[
|
||||||
# html.Div(
|
html.Div(
|
||||||
# className="top_companytable_style",
|
className="top_companytable_style",
|
||||||
# children=[
|
children=[
|
||||||
# html.Title(title="Top Ten Unternehmen", style={"align": "mid"}),
|
html.Title(title="Top Ten Unternehmen", style={"align": "mid"}),
|
||||||
# dash_table.DataTable(df.to_dict('records'), [{"name": i, "id": i} for i in df.columns])
|
dash_table.DataTable(df.to_dict('records'), [{"name": i, "id": i} for i in df.columns])
|
||||||
# ]
|
]
|
||||||
# ),
|
),
|
||||||
# html.Div(
|
html.Div(
|
||||||
# className="networkx_style",
|
className="networkx_style",
|
||||||
# children=[
|
children=[
|
||||||
# html.Header(title="Social Graph"),
|
html.Header(title="Social Graph"),
|
||||||
# dcc.Dropdown(['eigenvector', 'degree', 'betweeness', 'closeness'], 'eigenvector', id='demo-dropdown'),
|
"Company Relation Type Filter:",
|
||||||
# "Text",
|
dcc.Dropdown(company_relation_type_filter, company_relation_type_filter[0], id='dropdown_companyrelation_filter'),
|
||||||
# dcc.Input(id="EGDE_VAR", type="text", value="K", debounce=True),
|
"Person Relation Type Filter:",
|
||||||
# # dcc.Dropdown(['eigenvector', 'degree', 'betweeness', 'closeness'], 'eigenvector', id='metric-dropdown'),
|
dcc.Dropdown(person_relation_type_filter, person_relation_type_filter[0], id='dropdown_personrelation_filter'),
|
||||||
# dcc.Graph(id="my-graph"),
|
"Choose Graph Metric:",
|
||||||
# ]
|
dcc.Dropdown(['None','eigenvector', 'degree', 'betweeness', 'closeness'], 'None', id='dropdown'),
|
||||||
# )
|
# "Text",
|
||||||
# ]
|
# dcc.Input(id="EGDE_VAR", type="text", value="K", debounce=True),
|
||||||
# )
|
daq.BooleanSwitch(id='switch', on=False),
|
||||||
|
# html.Div(id='switch'),
|
||||||
|
# dcc.Dropdown(['eigenvector', 'degree', 'betweeness', 'closeness'], 'eigenvector', id='metric-dropdown'),
|
||||||
|
# dcc.Graph(id="my-graph"),
|
||||||
|
dcc.Graph(figure = network, id='my-graph'),
|
||||||
|
# html.Div(id='my-graph'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
Output("my-graph", "figure"),
|
Output("my-graph", "figure"),
|
||||||
# Input('metric-dropdown', 'value'),
|
# Input('metric-dropdown', 'value'),
|
||||||
[Input("EGDE_VAR", "value")],
|
[Input("dropdown", "value"),
|
||||||
|
Input("switch", "on"),
|
||||||
|
Input("dropdown_companyrelation_filter", "value"),
|
||||||
|
Input("dropdown_personrelation_filter", "value")],
|
||||||
|
prevent_initial_call=True,
|
||||||
|
allow_duplicate=True
|
||||||
)
|
)
|
||||||
def update_output(EGDE_VAR: None) -> None:
|
def update_figure(selected_value, on, c_relation_filter, p_relation_filter):
|
||||||
|
triggered_id = ctx.triggered_id
|
||||||
|
|
||||||
|
|
||||||
find_top_companies()
|
find_top_companies()
|
||||||
return networkGraph(EGDE_VAR)
|
|
||||||
|
if selected_value == "None":
|
||||||
|
metric = None
|
||||||
|
else:
|
||||||
|
metric = selected_value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if triggered_id == 'switch':
|
||||||
|
|
||||||
|
if on:
|
||||||
|
return update_mode(on, selected_value)
|
||||||
|
else:
|
||||||
|
return create_3d_graph(graph, nodes, edges, metrices, metric)
|
||||||
|
elif triggered_id == 'dropdown':
|
||||||
|
|
||||||
|
if on:
|
||||||
|
return update_mode(on, selected_value)
|
||||||
|
else:
|
||||||
|
return create_3d_graph(graph, nodes, edges, metrices, metric)
|
||||||
|
|
||||||
|
# print(c_relation_filter)
|
||||||
|
# print(p_relation_filter)
|
||||||
|
# if triggered_id == 'dropdown_companyrelation_filter' or triggered_id == 'dropdown_personrelation_filter':
|
||||||
|
# print("Hallo")
|
||||||
|
# print(selected_value)
|
||||||
|
# graph, metrices = update_graph_data(person_relation_type= p_relation_filter, company_relation_type= c_relation_filter)
|
||||||
|
# if on:
|
||||||
|
# return update_mode(on, selected_value)
|
||||||
|
# else:
|
||||||
|
# return create_3d_graph(graph, nodes, edges, metrices, metric)
|
||||||
|
# print(metrices)
|
||||||
|
# print(graph)
|
||||||
|
|
||||||
|
def update_mode(value, metric):
|
||||||
|
|
||||||
|
if metric == "None":
|
||||||
|
metric = None
|
||||||
|
if value == True:
|
||||||
|
return create_2d_graph(graph, nodes, edges, metrices, metric)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def update_graph_data(person_relation_type = "HAFTENDER_GESELLSCHAFTER", company_relation_type = "GESCHAEFTSFUEHRER"):
|
||||||
|
# Get Data
|
||||||
|
person_df = get_all_person_relations()
|
||||||
|
company_df = get_all_company_relations()
|
||||||
|
|
||||||
|
person_relation = filter_relation_type(person_df, person_relation_type)
|
||||||
|
company_relation = filter_relation_type(company_df, company_relation_type)
|
||||||
|
print(company_relation)
|
||||||
|
|
||||||
|
# company_relation = filter_relation_with_more_than_one_connection(company_relation, "id_company_to", "id_company_from")
|
||||||
|
# print(company_relation)
|
||||||
|
#Create Edge and Node List from data
|
||||||
|
nodes, edges = create_edge_and_node_list(person_relation, company_relation)
|
||||||
|
# print(edges)
|
||||||
|
|
||||||
|
graph, metrices = initialize_network(nodes = nodes, edges = edges)
|
||||||
|
return graph, metrices
|
||||||
|
|
128
src/aki_prj23_transparenzregister/utils/networkx/network_2d.py
Normal file
128
src/aki_prj23_transparenzregister/utils/networkx/network_2d.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import networkx as nx
|
||||||
|
import pandas as pd
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
|
||||||
|
def initialize_network(edges: list, nodes: list):
|
||||||
|
# create edges from dataframe
|
||||||
|
df_edges = pd.DataFrame(edges)
|
||||||
|
graph = nx.from_pandas_edgelist(df_edges, source="from", target="to", edge_attr="type")
|
||||||
|
|
||||||
|
# update node attributes from dataframe
|
||||||
|
nx.set_node_attributes(graph, nodes)
|
||||||
|
|
||||||
|
metrices = pd.DataFrame(columns=["degree", "eigenvector", "betweeness", "closeness", "pagerank"])
|
||||||
|
|
||||||
|
metrices["eigenvector"] = nx.eigenvector_centrality(graph).values()
|
||||||
|
metrices["degree"] = nx.degree_centrality(graph).values()
|
||||||
|
metrices["betweeness"] = nx.betweenness_centrality(graph).values()
|
||||||
|
metrices["closeness"] = nx.closeness_centrality(graph).values()
|
||||||
|
metrices["pagerank"] = nx.pagerank(graph).values()
|
||||||
|
|
||||||
|
return graph, metrices
|
||||||
|
|
||||||
|
def create_2d_graph(graph, nodes, edges,metrices, metric):
|
||||||
|
edge_x = []
|
||||||
|
edge_y = []
|
||||||
|
|
||||||
|
pos = nx.spring_layout(graph)
|
||||||
|
|
||||||
|
edge_weight_x = []
|
||||||
|
edge_weight_y = []
|
||||||
|
G = graph
|
||||||
|
for edge in G.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_weight_x.append(x1 + x1 - x0)
|
||||||
|
# edge_weight_y.append(y1 + y1 - y0)
|
||||||
|
# edge_weight_x.append(x0 + x0 - x1)
|
||||||
|
# edge_weight_y.append(y0 + y0 - y1)
|
||||||
|
edge_weight_x.append(x0 + ((x1 - x0) / 2))
|
||||||
|
edge_weight_y.append(y0 + ((y1 - y0) / 2))
|
||||||
|
|
||||||
|
edge_trace = go.Scatter(
|
||||||
|
x=edge_x, y=edge_y,
|
||||||
|
line=dict(width=0.5, color='#888'),
|
||||||
|
hoverinfo='none',
|
||||||
|
mode='lines')
|
||||||
|
|
||||||
|
edge_weights_trace = go.Scatter(x=edge_weight_x,y= edge_weight_y, mode='text',
|
||||||
|
marker_size=1,
|
||||||
|
text=[0.45, 0.7, 0.34],
|
||||||
|
textposition='top center',
|
||||||
|
hovertemplate='weight: %{text}<extra></extra>')
|
||||||
|
|
||||||
|
|
||||||
|
node_x = []
|
||||||
|
node_y = []
|
||||||
|
for node in G.nodes():
|
||||||
|
x, y = pos[node]
|
||||||
|
node_x.append(x)
|
||||||
|
node_y.append(y)
|
||||||
|
|
||||||
|
node_trace = go.Scatter(
|
||||||
|
x=node_x, y=node_y,
|
||||||
|
mode='markers',
|
||||||
|
hoverinfo='text',
|
||||||
|
marker=dict(
|
||||||
|
showscale=True,
|
||||||
|
colorscale='YlGnBu',
|
||||||
|
reversescale=True,
|
||||||
|
color=[],
|
||||||
|
size=10,
|
||||||
|
colorbar=dict(
|
||||||
|
thickness=15,
|
||||||
|
title='Node Connections',
|
||||||
|
xanchor='left',
|
||||||
|
titleside='right'
|
||||||
|
),
|
||||||
|
line_width=2))
|
||||||
|
|
||||||
|
#Set Color by using the nodes DataFrame with its Color Attribute. The sequence matters!
|
||||||
|
colors = list(nx.get_node_attributes(graph, "color").values())
|
||||||
|
|
||||||
|
node_names = []
|
||||||
|
for key, value in nodes.items():
|
||||||
|
|
||||||
|
if 'name' in value.keys():
|
||||||
|
node_names.append(value["name"])
|
||||||
|
else:
|
||||||
|
node_names.append(value["firstname"] + " " + value["lastname"])
|
||||||
|
|
||||||
|
|
||||||
|
node_trace.marker.color = colors
|
||||||
|
node_trace.text = node_names
|
||||||
|
|
||||||
|
if metric != None:
|
||||||
|
node_trace.marker.size = list(metrices[metric]*500)
|
||||||
|
# print(list(metrices[metric]*500))
|
||||||
|
|
||||||
|
|
||||||
|
edge_type_list = []
|
||||||
|
|
||||||
|
for row in edges:
|
||||||
|
edge_type_list.append(row["type"])
|
||||||
|
|
||||||
|
edge_weights_trace.text = edge_type_list
|
||||||
|
|
||||||
|
return go.Figure(data=[edge_trace, edge_weights_trace, node_trace],
|
||||||
|
layout=go.Layout(
|
||||||
|
title='<br>Network graph made with Python',
|
||||||
|
titlefont_size=16,
|
||||||
|
showlegend=False,
|
||||||
|
hovermode='closest',
|
||||||
|
margin=dict(b=20,l=5,r=5,t=40),
|
||||||
|
annotations=[ dict(
|
||||||
|
text="Python code: <a href='https://plotly.com/ipython-notebooks/network-graphs/'> https://plotly.com/ipython-notebooks/network-graphs/</a>",
|
||||||
|
showarrow=False,
|
||||||
|
xref="paper", yref="paper",
|
||||||
|
x=0.005, y=-0.002 ) ],
|
||||||
|
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
|
||||||
|
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
|
||||||
|
)
|
142
src/aki_prj23_transparenzregister/utils/networkx/network_3d.py
Normal file
142
src/aki_prj23_transparenzregister/utils/networkx/network_3d.py
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import networkx as nx
|
||||||
|
import pandas as pd
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
|
||||||
|
def initialize_network(edges: list, nodes: list):
|
||||||
|
# create edges from dataframe
|
||||||
|
df_edges = pd.DataFrame(edges)
|
||||||
|
graph = nx.from_pandas_edgelist(df_edges, source="from", target="to", edge_attr="type")
|
||||||
|
|
||||||
|
# update node attributes from dataframe
|
||||||
|
nx.set_node_attributes(graph, nodes)
|
||||||
|
|
||||||
|
metrices = pd.DataFrame(columns=["degree", "eigenvector", "betweeness", "closeness", "pagerank"])
|
||||||
|
|
||||||
|
metrices["eigenvector"] = nx.eigenvector_centrality(graph).values()
|
||||||
|
metrices["degree"] = nx.degree_centrality(graph).values()
|
||||||
|
metrices["betweeness"] = nx.betweenness_centrality(graph).values()
|
||||||
|
metrices["closeness"] = nx.closeness_centrality(graph).values()
|
||||||
|
metrices["pagerank"] = nx.pagerank(graph).values()
|
||||||
|
|
||||||
|
return graph, metrices
|
||||||
|
|
||||||
|
def create_3d_graph(graph, nodes, edges,metrices, metric):
|
||||||
|
edge_x = []
|
||||||
|
edge_y = []
|
||||||
|
edge_z = []
|
||||||
|
|
||||||
|
# 3d spring layout
|
||||||
|
pos = nx.spring_layout(graph, dim=3, seed=779)
|
||||||
|
|
||||||
|
for edge in graph.edges():
|
||||||
|
x0, y0, z0 = pos[edge[0]]
|
||||||
|
x1, y1, z1 = pos[edge[1]]
|
||||||
|
|
||||||
|
edge_x.append(x0)
|
||||||
|
edge_x.append(x1)
|
||||||
|
|
||||||
|
edge_y.append(y0)
|
||||||
|
edge_y.append(y1)
|
||||||
|
|
||||||
|
edge_z.append(z0)
|
||||||
|
edge_z.append(z1)
|
||||||
|
|
||||||
|
edge_trace=go.Scatter3d(x=edge_x,
|
||||||
|
y=edge_y,
|
||||||
|
z=edge_z,
|
||||||
|
mode='lines',
|
||||||
|
line=dict(color='rgb(125,125,125)', width=1),
|
||||||
|
hoverinfo='none'
|
||||||
|
)
|
||||||
|
|
||||||
|
node_x = []
|
||||||
|
node_y = []
|
||||||
|
node_z = []
|
||||||
|
|
||||||
|
for node in graph.nodes():
|
||||||
|
x, y, z = pos[node]
|
||||||
|
node_x.append(x)
|
||||||
|
node_y.append(y)
|
||||||
|
node_z.append(z)
|
||||||
|
|
||||||
|
node_trace=go.Scatter3d(x=node_x,
|
||||||
|
y=node_y,
|
||||||
|
z=node_z,
|
||||||
|
mode='markers',
|
||||||
|
name='actors',
|
||||||
|
marker=dict(symbol='circle',
|
||||||
|
size=6,
|
||||||
|
color="blue",
|
||||||
|
colorscale='Viridis',
|
||||||
|
line=dict(color='rgb(50,50,50)', width=0.5)
|
||||||
|
),
|
||||||
|
# text=labels,
|
||||||
|
hoverinfo='text'
|
||||||
|
)
|
||||||
|
|
||||||
|
axis=dict(showbackground=False,
|
||||||
|
showline=False,
|
||||||
|
zeroline=False,
|
||||||
|
showgrid=False,
|
||||||
|
showticklabels=False,
|
||||||
|
title=''
|
||||||
|
)
|
||||||
|
|
||||||
|
layout = go.Layout(
|
||||||
|
title="Social Graph",
|
||||||
|
|
||||||
|
showlegend=False,
|
||||||
|
scene=dict(
|
||||||
|
xaxis=dict(axis),
|
||||||
|
yaxis=dict(axis),
|
||||||
|
zaxis=dict(axis),
|
||||||
|
),
|
||||||
|
margin=dict(
|
||||||
|
t=10
|
||||||
|
),
|
||||||
|
hovermode='closest',
|
||||||
|
annotations=[
|
||||||
|
dict(
|
||||||
|
showarrow=False,
|
||||||
|
text="Companies (Blue) & Person (Red) Relation",
|
||||||
|
xref='paper',
|
||||||
|
yref='paper',
|
||||||
|
x=0,
|
||||||
|
y=0.1,
|
||||||
|
xanchor='left',
|
||||||
|
yanchor='bottom',
|
||||||
|
font=dict(
|
||||||
|
size=14
|
||||||
|
)
|
||||||
|
)
|
||||||
|
], )
|
||||||
|
|
||||||
|
#Set Color by using the nodes DataFrame with its Color Attribute. The sequence matters!
|
||||||
|
colors = list(nx.get_node_attributes(graph, "color").values())
|
||||||
|
|
||||||
|
node_names = []
|
||||||
|
for key, value in nodes.items():
|
||||||
|
|
||||||
|
if 'name' in value.keys():
|
||||||
|
node_names.append(value["name"])
|
||||||
|
else:
|
||||||
|
node_names.append(value["firstname"] + " " + value["lastname"])
|
||||||
|
|
||||||
|
node_trace.marker.color = colors
|
||||||
|
node_trace.text = node_names
|
||||||
|
|
||||||
|
if metric != None:
|
||||||
|
node_trace.marker.size = list(metrices[metric]*500)
|
||||||
|
print("Test")
|
||||||
|
|
||||||
|
edge_colors = []
|
||||||
|
for row in edges:
|
||||||
|
if row["type"] == "HAFTENDER_GESELLSCHAFTER":
|
||||||
|
edge_colors.append('rgb(255,0,0)')
|
||||||
|
else:
|
||||||
|
edge_colors.append('rgb(255,105,180)')
|
||||||
|
edge_trace.line = dict(color=edge_colors, width=2)
|
||||||
|
|
||||||
|
|
||||||
|
data=[edge_trace, node_trace]
|
||||||
|
return go.Figure(data=data, layout=layout)
|
@ -1,6 +1,18 @@
|
|||||||
from aki_prj23_transparenzregister.utils.sql import connector, entities
|
from aki_prj23_transparenzregister.utils.sql import connector, entities
|
||||||
from aki_prj23_transparenzregister.config.config_providers import JsonFileConfigProvider
|
from aki_prj23_transparenzregister.config.config_providers import JsonFileConfigProvider
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
from sqlalchemy.orm import aliased
|
||||||
|
import pandas as pd
|
||||||
|
from sqlalchemy import func, text
|
||||||
|
from aki_prj23_transparenzregister.utils.sql.connector import get_session
|
||||||
|
|
||||||
|
session = get_session(JsonFileConfigProvider("secrets.json"))
|
||||||
|
|
||||||
|
# Alias for Company table for the base company
|
||||||
|
to_company = aliased(entities.Company, name="to_company")
|
||||||
|
|
||||||
|
# Alias for Company table for the head company
|
||||||
|
from_company = aliased(entities.Company, name="from_company")
|
||||||
|
|
||||||
def find_all_company_relations() -> pd.DataFrame:
|
def find_all_company_relations() -> pd.DataFrame:
|
||||||
"""_summary_
|
"""_summary_
|
||||||
@ -44,5 +56,137 @@ def find_top_companies() -> pd.DataFrame:
|
|||||||
companies_df["Platzierung"] = [1,2,3,4,5]
|
companies_df["Platzierung"] = [1,2,3,4,5]
|
||||||
companies_df["Umsatz M€"] = [1,2,3,4,5]
|
companies_df["Umsatz M€"] = [1,2,3,4,5]
|
||||||
companies_df = companies_df[['Platzierung', 'company_name', 'Umsatz M€']]
|
companies_df = companies_df[['Platzierung', 'company_name', 'Umsatz M€']]
|
||||||
print(companies_df)
|
# print(companies_df)
|
||||||
return companies_df
|
return companies_df
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_company_relations():
|
||||||
|
# Query to fetch relations between companies
|
||||||
|
relations_company_query = (
|
||||||
|
session.query(
|
||||||
|
to_company.id.label("id_company_to"),
|
||||||
|
to_company.name.label("name_company_to"),
|
||||||
|
entities.CompanyRelation.relation.label("relation_type"),
|
||||||
|
from_company.name.label("name_company_from"),
|
||||||
|
from_company.id.label("id_company_from"),
|
||||||
|
)
|
||||||
|
.join(
|
||||||
|
entities.CompanyRelation,
|
||||||
|
entities.CompanyRelation.company_id == to_company.id,
|
||||||
|
)
|
||||||
|
.join(
|
||||||
|
from_company,
|
||||||
|
entities.CompanyRelation.company2_id == from_company.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
str(relations_company_query)
|
||||||
|
company_relations = pd.read_sql_query(str(relations_company_query), session.bind)
|
||||||
|
|
||||||
|
company_relations['id_company_from'] = company_relations['id_company_from'].apply(lambda x: f"c_{x}")
|
||||||
|
company_relations['id_company_to'] = company_relations['id_company_to'].apply(lambda x: f"c_{x}")
|
||||||
|
|
||||||
|
return company_relations
|
||||||
|
|
||||||
|
def get_all_person_relations():
|
||||||
|
relations_person_query = (
|
||||||
|
session.query(
|
||||||
|
entities.Company.id.label("id_company"),
|
||||||
|
entities.Company.name.label("name_company"),
|
||||||
|
entities.PersonRelation.relation.label("relation_type"),
|
||||||
|
entities.Person.id.label("id_person"),
|
||||||
|
entities.Person.lastname.label("lastname"),
|
||||||
|
entities.Person.firstname.label("firstname"),
|
||||||
|
entities.Person.date_of_birth.label("date_of_birth"),
|
||||||
|
)
|
||||||
|
.join(
|
||||||
|
entities.PersonRelation,
|
||||||
|
entities.PersonRelation.company_id == entities.Company.id,
|
||||||
|
)
|
||||||
|
.join(
|
||||||
|
entities.Person,
|
||||||
|
entities.PersonRelation.person_id == entities.Person.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
person_relations = pd.read_sql_query(str(relations_person_query), session.bind)
|
||||||
|
|
||||||
|
person_relations['id_company'] = person_relations['id_company'].apply(lambda x: f"c_{x}")
|
||||||
|
person_relations['id_person'] = person_relations['id_person'].apply(lambda x: f"p_{x}")
|
||||||
|
|
||||||
|
|
||||||
|
return person_relations
|
||||||
|
|
||||||
|
|
||||||
|
def filter_relation_type(df: pd.DataFrame, selected_relation_type):
|
||||||
|
df = df.loc[df["relation_type"] == selected_relation_type]
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
def filter_relation_with_more_than_one_connection(df: pd.DataFrame, id_column_name_to, id_column_name_from):
|
||||||
|
# print(df.columns.values)
|
||||||
|
tmp_df = pd.DataFrame(columns= df.columns.values)
|
||||||
|
# print(tmp_df)
|
||||||
|
for _index, row in df.iterrows():
|
||||||
|
count = 0
|
||||||
|
id = row[id_column_name_to]
|
||||||
|
for _index_sub, row_sub in df.iterrows():
|
||||||
|
if id == row_sub[id_column_name_to]:
|
||||||
|
count = count + 1
|
||||||
|
if id == row_sub[id_column_name_from]:
|
||||||
|
count = count + 1
|
||||||
|
if count > 1:
|
||||||
|
break
|
||||||
|
|
||||||
|
if count > 1:
|
||||||
|
# tmp_df = pd.concat([tmp_df, pd.DataFrame(row)])+
|
||||||
|
tmp_df.loc[len(tmp_df)] = row
|
||||||
|
# print(row)
|
||||||
|
count = 0
|
||||||
|
else:
|
||||||
|
count = 0
|
||||||
|
continue
|
||||||
|
# print(tmp_df)
|
||||||
|
count = 0
|
||||||
|
return tmp_df
|
||||||
|
|
||||||
|
|
||||||
|
def create_edge_and_node_list(person_relations: pd.DataFrame, company_relations:pd.DataFrame):
|
||||||
|
nodes = {}
|
||||||
|
edges = []
|
||||||
|
|
||||||
|
COLOR_COMPANY = "blue"
|
||||||
|
COLOR_PERSON = "red"
|
||||||
|
|
||||||
|
# Iterate over person relations
|
||||||
|
for _index, row in person_relations.iterrows():
|
||||||
|
if node:= nodes.get(row['id_company']) is None:
|
||||||
|
nodes[row['id_company']] = {
|
||||||
|
"id": row['id_company'],
|
||||||
|
'name': row['name_company'],
|
||||||
|
'color': COLOR_COMPANY
|
||||||
|
}
|
||||||
|
if node:= nodes.get(row['id_person']) is None:
|
||||||
|
nodes[row['id_person']] = {
|
||||||
|
"id": row['id_person'],
|
||||||
|
'firstname': row['firstname'],
|
||||||
|
'lastname': row['lastname'],
|
||||||
|
'date_of_birth': row['date_of_birth'],
|
||||||
|
'color': COLOR_PERSON
|
||||||
|
}
|
||||||
|
edges.append({'from': row['id_person'], 'to': row['id_company'], 'type': row['relation_type']})
|
||||||
|
|
||||||
|
for _index, row in company_relations.iterrows():
|
||||||
|
if node:= nodes.get(row['id_company_from']) is None:
|
||||||
|
nodes[row['id_company_from']] = {
|
||||||
|
"id": row['id_company_from'],
|
||||||
|
'name': row['name_company_from'],
|
||||||
|
'color': COLOR_COMPANY
|
||||||
|
}
|
||||||
|
if node:= nodes.get(row['id_company_to']) is None:
|
||||||
|
nodes[row['id_company_to']] = {
|
||||||
|
"id": row['id_company_to'],
|
||||||
|
'name': row['name_company_to'],
|
||||||
|
'color': COLOR_COMPANY
|
||||||
|
}
|
||||||
|
edges.append({'from': row['id_company_from'], 'to': row['id_company_to'], 'type': row['relation_type']})
|
||||||
|
return nodes, edges
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user