Animate the width of a line inside a network graph

Hi @surendraa ,

If you want to perform animation using cyoscape and dash callback, you can replace the dcc.Dropdown with dcc.Interval.

Set Interval value in miliseconds.
Then create callback function use Internal component as Input and Cytoscape component as `Output.

For example you want to animate the edge with red color with interval 1 second.

from dash import Dash, html,dcc,Input,Output,State
import dash_cytoscape as cyto

app = Dash(__name__)

edge_ids = ['BA', 'BC', 'CD', 'DA', 'AD']

directed_edges = [{'data': {'id': src+tgt, 'source': src, 'target': tgt, 'weight': 3}} for src, tgt in edge_ids]

directed_elements = [{'data': {'id': id_}} for id_ in 'ABCD'] + directed_edges

default_stylesheet = [
                {
                    'selector': 'node',
                    'style': {
                        'label': 'data(id)'
                    }
                },
                {
                    'selector': 'edge',
                    'style': {
                        # The default curve style does not work with certain arrows
                        'curve-style': 'bezier'
                    }
                },
                {
                    'selector': '#BA',
                    'style': {
                        'source-arrow-color': 'red',
                        'source-arrow-shape': 'triangle',
                        'line-color': 'red',
                        'width':3,
                    }
                },
                {
                'selector': '#DA',
                'style': {
                        'target-arrow-color': 'blue',
                        'target-arrow-shape': 'triangle',
                        'line-color': 'blue',
                        'width':3,
                    }
                },
                {
                    'selector': '#AD',
                    'style': {
                        'target-arrow-color': 'magenta',
                        'target-arrow-shape': 'triangle',
                        'line-color': 'magenta',
                        'width':3,
                    }
                },
                {
                    'selector': '#BC',
                    'style': {
                        'source-arrow-color': 'green',
                        'source-arrow-shape': 'triangle',
                        'line-color': 'green',
                        'width':3,
                    }
                },
                {
                    'selector': '#CD',
                    'style': {
                        'target-arrow-color': 'black',
                        'target-arrow-shape': 'triangle',
                        'line-color': 'black',
                        'width':3,
                    }
                }
            ]

selectors = [data["selector"] for data in default_stylesheet]

width_list = list(range(3,21,2))

app.layout = html.Div([
        dcc.Interval(id="interval", interval=1000),
        html.Div([
            cyto.Cytoscape(
                id='cytoscape-styling-9',
                layout={'name': 'circle','animate':True,'animationDuration': 500},
                style={'width': '100%', 'height': '400px'},
                elements=directed_elements,
                stylesheet=default_stylesheet
            )
        ])
    ])

@app.callback(
    Output("cytoscape-styling-9","stylesheet"),
    [Input('interval', 'n_intervals')],
    prevent_initial_call=True
    )
def update_weight_value(n_intervals):
    current_index = width_list.index(default_stylesheet[2]['style']['width']) 
    if current_index < len(width_list)-1:
        default_stylesheet[2]['style']['width'] = width_list[current_index+1]
        
    else:
        default_stylesheet[2]['style']['width'] = width_list[0]
    return default_stylesheet


if __name__ == '__main__':
    app.run(debug=True)

It will be displayed like image below.

network_callback_animation

Hope this is solution you are looking for.
Cheers. :slightly_smiling_face:

2 Likes