Hey,
I cannot really explain this behaviour, might be a bug:
Normal Callbacks works just fine with selecting Nodes. Clientside Callback does not work even though the node has ‘selected’ as classes afterwards. Additionally if you click first on the clientside callback and then on the normal it does not work anymore. Here is a MRE:
from dash import html, Output,State, Input, Dash, no_update ,dcc
import dash_cytoscape as cyto
app = Dash(__name__)
app.layout = html.Div([
cyto.Cytoscape(
id='cytoscape',
style={'width': '100%', 'height': '400px'},
stylesheet = [
{
'selector': 'node',
'style': {
'label': 'data(label)',
'font-size': '50px',
'text-valign': 'center',
'text-halign': 'right',
'color': 'white',
'text-outline-width': '2px',
"text-wrap": "wrap",
'width': 'data(size)',
'height': 'data(size)',
"text-wrap": "wrap"
}},
{'selector': '.selected',
'style': {
'border-width': '8px',
'font-size': '80px',
'font-weight': 'bold',
'text-outline-width': '4px',
'background-image': 'data(url)',
'background-fit': 'cover',
}},
],
elements=[
# Define your nodes here with unique IDs
{'data': {'id': 'node1','size':'150px', 'label': 'Node 1', 'url': 'https://i.scdn.co/image/ab67616d00001e0216aaf05fe82237576a7d0e38'}, 'position': {'x': 50, 'y': 50}},
{'data': {'id': 'node2','size':'150px', 'label': 'Node 2', 'url': 'https://i.scdn.co/image/ab67616d00001e0216aaf05fe82237576a7d0e38'}, 'position': {'x': 150, 'y': 150}},
{'data': {'id': 'node3','size':'150px', 'label': 'Node 3', 'url': 'https://i.scdn.co/image/ab67616d00001e0216aaf05fe82237576a7d0e38'}, 'position': {'x': 250, 'y': 250}},
],
),
html.Button('Normal Callback', id='normal-button'),
html.Button('Client-Side Callback', id='client-button'),
])
@app.callback(
Output('cytoscape', 'elements' ,allow_duplicate=True),
Input('normal-button', 'n_clicks'),
State('cytoscape', 'elements'),
prevent_initial_call = True
)
def update_output(n_clicks, elements):
if n_clicks:
elements[0]['classes'] = 'selected'
print(elements[0])
return elements
app.clientside_callback(
"""
function(n_clicks, elements) {
if (n_clicks) {
elements[0].classes = 'selected';
console.log(elements[0]);
return elements;
}
return dash_clientside.no_update;
}
""",
Output('cytoscape', 'elements'),
Input('client-button', 'n_clicks'),
State('cytoscape', 'elements'),
prevent_initial_call = True
)
if __name__ == '__main__':
app.run_server(debug=True)