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()