Dash: How to make text appear upon clicking a node?

I saw the ‘Click, Hover, Tap’ section of the tutorial described here and I wanted to implement it myself.

I can get the exact example in that tutorial to work as expected no problem, I click a node, and text appears underneath the network.

I then tried to adapt the code for my own network:

dash_elements = [{'data': {'id': '6840', 'label': '6840'}, 'classes': 'black'}, {'data': {'id': '7431', 'label': '7431'}, 'classes': 'red'}, {'data': {'source': '6840', 'target': '7431'}}, {'data': {'id': '6640', 'label': '6640'}, 'classes': 'black'}, {'data': {'id': '5217', 'label': '5217'}, 'classes': 'black'}, {'data': {'source': '6640', 'target': '5217'}}, {'data': {'id': '823', 'label': '823'}, 'classes': 'black'}, {'data': {'id': '7431', 'label': '7431'}, 'classes': 'red'}, {'data': {'source': '823', 'target': '7431'}}]

import dash
from dash import dcc
from dash import html
import dash_cytoscape as cyto
from dash.dependencies import Input, Output
import plotly.express as px

app = dash.Dash(__name__)

styles = {
    'pre': {
        'border': 'thin lightgrey solid',
        'overflowX': 'scroll'
    }
}


default_stylesheet=[
    # Class Selectors
    {
        'selector':'.black',
        #'selector': 'node',
        'style': {
            'background-color': '#000000',
            'label': 'data(label)'
        },
    },

    {
        'selector':'.red',
        #'selector':'node',
        'style': {
            'background-color': '#FF0000',
            'label': 'data(label)'
        },
    },
]


app.layout = html.Div([
    html.P("Dash Cytoscape:"),
    cyto.Cytoscape(
        #id='cytoscape',
        id='cytoscape-event-callbacks-2',
        elements = dash_elements,
        layout={'name': 'breadthfirst'},
        #layout={'name': 'preset'},
        style={'width': '1000px', 'height': '1000px'},
        stylesheet = default_stylesheet
        
        
        
    ),
    html.P(id='cytoscape-tapNodeData-output'),
    html.P(id='cytoscape-tapEdgeData-output'),
    html.P(id='cytoscape-mouseoverNodeData-output'),
    html.P(id='cytoscape-mouseoverEdgeData-output')
])


@app.callback(Output('cytoscape-tapNodeData-output', 'children'),
              Input('cytoscape-event-callbacks-2', 'tapNodeData'))
def displayTapNodeData(data):
    if data:
        return "You recently clicked/tapped the city: " + str(data['label'])


@app.callback(Output('cytoscape-tapEdgeData-output', 'children'),
              Input('cytoscape-event-callbacks-2', 'tapEdgeData'))

def displayTapEdgeData(data):
    if data:
        return "You recently clicked/tapped the edge between " + \
               str(data['source']) + " and " + str(data['target'])


@app.callback(Output('cytoscape-mouseoverNodeData-output', 'children'),
              Input('cytoscape-event-callbacks-2', 'mouseoverNodeData'))

def displayTapNodeData(data):
    if data:
        return "You recently hovered over the city: " + str(data['label'])


@app.callback(Output('cytoscape-mouseoverEdgeData-output', 'children'),
              Input('cytoscape-event-callbacks-2', 'mouseoverEdgeData'))

def displayTapEdgeData(data):
    if data:
        return "You recently hovered over the edge between " + \
               str(data['source']) + " and " + str(data['target'])

if __name__ == '__main__':
   app.run_server()

There is no error:

Dash is running on http://127.0.0.1:8050/

Dash is running on http://127.0.0.1:8050/

Dash is running on http://127.0.0.1:8050/

 * Serving Flask app "__main__" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)
127.0.0.1 - - [24/Oct/2021 13:29:49] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:49] "GET /_dash-layout HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:49] "GET /_dash-dependencies HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:50] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:50] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:50] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:50] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:50] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:51] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2021 13:29:51] "POST /_dash-update-component HTTP/1.1" 200 -

And upon opening the network, the nodes and edges are as expected, but when I click on a node, no text appears, which is my issue.

When I add debug=True to the app.run_server() line, in either the original example or my version, I get an error 48 about a socket already being in use.

Would someone be able to explain to me what the difference is between my code, and the example?

Hi,

I can’t see any reason why your code would not work and you can’t see any errors other than the socket one (which is probably because you are reusing the same port, ie not killing the first app).

Now, your Cytoscape component has a quite large height (1000px) and you won’t be able to see the text below it in any given screen (scrolling won’t roll the page either if the mouse is over the component). Is this the reason why you can’t see anything?