Search code examples
pythonplotlyplotly-dashcytoscape

Can I make a node clickable in dash as a hyperlink?


I have this code (from here) and it generates a network as expected:

import dash
import dash_core_components as 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__)
    
    app.layout = html.Div([
        html.P("Dash Cytoscape:"),
        cyto.Cytoscape(
            id='cytoscape',
            elements=[
                {'data': {'id': 'ca', 'label': 'Canada'}}, 
                {'data': {'id': 'on', 'label': 'Ontario'}}, 
                {'data': {'id': 'qc', 'label': 'Quebec'}},
                {'data': {'source': 'ca', 'target': 'on'}}, 
                {'data': {'source': 'ca', 'target': 'qc'}}
            ],
            layout={'name': 'breadthfirst'},
            style={'width': '1000px', 'height': '1000px'}
        )
    ])
    
    if __name__ == '__main__':
       app.run_server()

I'm just wondering, would someone know if I'm able to/how to edit this code so that I can click on a node, and it's a hyperlink to a webpage (e.g. in this case could just be the wikipedia page for each node).


Solution

  • You could create a callback which sets the href property of a dcc.Location component based on the clicked node:

    app = dash.Dash(__name__)
    
    app.layout = html.Div(
        [
            dcc.Location(id="location"),
            cyto.Cytoscape(
                id="cytoscape",
                elements=[
                    {"data": {"id": "ca", "label": "Canada"}},
                    {"data": {"id": "on", "label": "Ontario"}},
                    {"data": {"id": "qc", "label": "Quebec"}},
                    {"data": {"source": "ca", "target": "on"}},
                    {"data": {"source": "ca", "target": "qc"}},
                ],
                layout={"name": "breadthfirst"},
                style={"width": "1000px", "height": "1000px"},
            ),
        ]
    )
    
    
    @app.callback(
        Output("location", "href"),
        Input("cytoscape", "tapNodeData"),
        prevent_initial_call=True,
    )
    def navigate_to_url(node_data):
        return f"https://en.wikipedia.org/wiki/{node_data['label']}"