204 lines
5.3 KiB
Python
204 lines
5.3 KiB
Python
import time
|
|
import webbrowser
|
|
from pathlib import Path
|
|
from threading import Thread
|
|
from typing import cast
|
|
|
|
import dash_cytoscape as cyto
|
|
import lang_main.io
|
|
from dash import Dash, Input, Output, State, dcc, html
|
|
from lang_main.analysis import graphs
|
|
|
|
target = '../results/test_20240529/Pipe-Token_Analysis_Step-1_build_token_graph.pkl'
|
|
p = Path(target).resolve()
|
|
ret = lang_main.io.load_pickle(p)
|
|
tk_graph = cast(graphs.TokenGraph, ret[0])
|
|
tk_graph_filtered = tk_graph.filter_by_edge_weight(150)
|
|
tk_graph_filtered = tk_graph_filtered.filter_by_node_degree(1)
|
|
cyto_data, weight_data = graphs.convert_graph_to_cytoscape(tk_graph_filtered)
|
|
|
|
MIN_WEIGHT = weight_data['min']
|
|
MAX_WEIGHT = weight_data['max']
|
|
|
|
|
|
cyto.load_extra_layouts()
|
|
app = Dash(__name__)
|
|
|
|
my_stylesheet = [
|
|
# Group selectors
|
|
{
|
|
'selector': 'node',
|
|
'style': {
|
|
'shape': 'circle',
|
|
'content': 'data(label)',
|
|
'background-color': '#B10DC9',
|
|
'border-width': 2,
|
|
'border-color': 'black',
|
|
'border-opacity': 1,
|
|
'opacity': 1,
|
|
'color': 'black',
|
|
'text-opacity': 1,
|
|
'font-size': 12,
|
|
'z-index': 9999,
|
|
},
|
|
},
|
|
{
|
|
'selector': 'edge',
|
|
'style': {
|
|
'width': 2,
|
|
'curve-style': 'bezier',
|
|
'line-color': 'grey',
|
|
'line-style': 'solid',
|
|
'line-opacity': 1,
|
|
},
|
|
},
|
|
# Class selectors
|
|
# {'selector': '.red', 'style': {'background-color': 'red', 'line-color': 'red'}},
|
|
# {'selector': '.triangle', 'style': {'shape': 'triangle'}},
|
|
]
|
|
|
|
app.layout = html.Div(
|
|
[
|
|
html.Button('Reset', id='bt-reset'),
|
|
dcc.Dropdown(
|
|
id='layout_choice_internal',
|
|
options=[
|
|
'random',
|
|
'grid',
|
|
'circle',
|
|
'concentric',
|
|
'breadthfirst',
|
|
'cose',
|
|
],
|
|
value='cose',
|
|
clearable=False,
|
|
),
|
|
dcc.Dropdown(
|
|
id='layout_choice_external',
|
|
options=[
|
|
'cose-bilkent',
|
|
'cola',
|
|
'euler',
|
|
'spread',
|
|
'dagre',
|
|
'klay',
|
|
],
|
|
clearable=False,
|
|
),
|
|
dcc.RangeSlider(
|
|
id='weight_slider',
|
|
min=MIN_WEIGHT,
|
|
max=MAX_WEIGHT,
|
|
step=1000,
|
|
),
|
|
cyto.Cytoscape(
|
|
id='cytoscape-graph',
|
|
layout={'name': 'cose'},
|
|
style={'width': '100%', 'height': '600px'},
|
|
stylesheet=my_stylesheet,
|
|
elements=cyto_data,
|
|
zoom=1,
|
|
),
|
|
]
|
|
)
|
|
|
|
|
|
@app.callback(
|
|
Output('cytoscape-graph', 'layout', allow_duplicate=True),
|
|
Input('layout_choice_internal', 'value'),
|
|
prevent_initial_call=True,
|
|
)
|
|
def update_layout_internal(layout_choice):
|
|
return {'name': layout_choice}
|
|
|
|
|
|
@app.callback(
|
|
Output('cytoscape-graph', 'layout', allow_duplicate=True),
|
|
Input('layout_choice_external', 'value'),
|
|
prevent_initial_call=True,
|
|
)
|
|
def update_layout_external(layout_choice):
|
|
return {'name': layout_choice}
|
|
|
|
|
|
@app.callback(
|
|
Output('cytoscape-graph', 'zoom'),
|
|
Output('cytoscape-graph', 'elements'),
|
|
Input('bt-reset', 'n_clicks'),
|
|
prevent_initial_call=True,
|
|
)
|
|
def reset_layout(n_clicks):
|
|
return (1, cyto_data)
|
|
|
|
|
|
# @app.callback(
|
|
# Output('cytoscape-graph', 'stylesheet'),
|
|
# Input('weight_slider', 'value'),
|
|
# State('cytoscape-graph', 'stylesheet'),
|
|
# prevent_initial_call=True,
|
|
# )
|
|
# def select_weight(range_chosen, stylesheet):
|
|
# min_weight, max_weight = range_chosen
|
|
# new_stylesheet = stylesheet.copy()
|
|
# new_stylesheet.append(
|
|
# {
|
|
# 'selector': f'[weight >= {min_weight}]',
|
|
# 'style': {'line-color': 'blue', 'line-style': 'dashed'},
|
|
# }
|
|
# )
|
|
# new_stylesheet.append(
|
|
# {
|
|
# 'selector': f'[weight <= {max_weight}]',
|
|
# 'style': {'line-color': 'blue', 'line-style': 'dashed'},
|
|
# }
|
|
# )
|
|
# return new_stylesheet
|
|
|
|
|
|
# app.layout = html.Div(
|
|
# [
|
|
# cyto.Cytoscape(
|
|
# id='cytoscape-two-nodes',
|
|
# layout={'name': 'preset'},
|
|
# style={'width': '100%', 'height': '400px'},
|
|
# stylesheet=my_stylesheet,
|
|
# elements=[
|
|
# {
|
|
# 'data': {
|
|
# 'id': 'one',
|
|
# 'label': 'Titel 1',
|
|
# },
|
|
# 'position': {'x': 75, 'y': 75},
|
|
# 'grabbable': False,
|
|
# #'locked': True,
|
|
# 'classes': 'red',
|
|
# },
|
|
# {
|
|
# 'data': {'id': 'two', 'label': 'Title 2'},
|
|
# 'position': {'x': 200, 'y': 200},
|
|
# 'classes': 'triangle',
|
|
# },
|
|
# {'data': {'source': 'one', 'target': 'two', 'weight': 2000}},
|
|
# ],
|
|
# )
|
|
# ]
|
|
# )
|
|
|
|
|
|
def _start_webbrowser():
|
|
host = '127.0.0.1'
|
|
port = '8050'
|
|
adress = f'http://{host}:{port}/'
|
|
time.sleep(2)
|
|
webbrowser.open_new(adress)
|
|
|
|
|
|
def main():
|
|
webbrowser_thread = Thread(target=_start_webbrowser, daemon=True)
|
|
webbrowser_thread.start()
|
|
app.run(debug=True)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|