Below is a simple dash app that makes use of the wonderful visdcc code written by @jimmybow
It has a dcc.Dropdown
component used to search nodes and a visdcc
component to display the network graph.
The goal is to
- allow the user to click on a node (or select it from the dropdown) and have it centered
- when the user clicks elsewhere on the canvas (off of a node), return the view to its original state
Point 1 works.
However, Point 2 only works if the user has previously clicked on a node; it does not work when the user has previously selected a node via dropdown as the update_dropdown
callback is (inexplicably to me) not called.
My guess is that when using the dropdown I must also somehow select the node in the graph, perhaps using the selectNodes()
method from the vis.js API, but this method is not supported by visdcc
.
Any advice on how to overcome this hurdle would be much appreciated
# -*- coding: utf-8 -*-
import dash
import visdcc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash()
nodes = [
{ 'id': 1, 'label': 'Node 1' },
{ 'id': 2, 'label': 'Node 2' },
{ 'id': 3, 'label': 'Node 3' },
{ 'id': 4, 'label': 'Node 4' },
{ 'id': 5, 'label': 'Node 5' },
]
edges = [
{ 'from': 1, 'to': 3 },
{ 'from': 1, 'to': 2 },
{ 'from': 2, 'to': 4 },
{ 'from': 2, 'to': 5 },
{ 'from': 3, 'to': 3 },
]
data = {
'nodes': nodes,
'edges': edges
}
app.layout = html.Div([
dcc.Dropdown(
id='node-search',
options=[{'label':node['label'],'value':node['id']} for node in nodes],
placeholder="Search",
searchable=True,
clearable=True,),
visdcc.Network(
id = 'net',
data = data,
options = dict(height= '600px', width= '100%')),
])
@app.callback(
Output('node-search', 'value'),
Input('net', 'selection'))
def update_dropdown(x):
if not x or len(x['nodes']) == 0:
return None
return str(x['nodes'][0])
@app.callback(
Output('net', 'fit'),
Input('node-search', 'value'))
def update_graph(node):
if not node:
return {'animation':True}
return {'nodes': [node], 'animation':True}
if __name__ == '__main__':
app.run_server(debug=True)