使用 Dash Cytoscape 在回调中更改节点标签

Change label of node within callback using Dash Cytoscape

我用 Dash Cytoscapes 创建了一些节点。我的最终目标是在单击节点后应该出现一个滑块。通过使用此滑块选择一个值,节点的标签应更新为所选值。由于我无法在单击节点后显示滑块,因此我将其永久显示在节点下方。希望你有一些想法来实现我的愿望。

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

app = dash.Dash(__name__)

app.layout = html.Div([
        cyto.Cytoscape(  
        id='node-callback-event',
        layout={'name': 'preset'},
        style={'width': '100%', 'height': '2000px', 'display': 'block'},
        elements=[
            {
                'data': {'id': 'root', 'label': 'test label'},
                'position': {'x': 750, 'y': 750},
                'locked': True
            }
        ]
    ),
        html.Label('Slider'),
        dcc.Slider(
            id='slider-update-value',
            min=0,
            max=100,
            value=0,
            step=0.01,
            tooltip = {"placement": "bottom", 'always_visible': False },
            included=False,
            updatemode='drag',
        ),
    ], 
    style={'padding': 1, 'flex': 1})

@app.callback(Output('node-callback-event', 'elements'),
              Input('node-callback-event', 'tapNodeData'),
              Input('slider-update-value', 'value'))
def displayTapNodeData(node, probability):
    if node:
        node['label'] += str(probability)


# how to assign the value to the nodes label? 

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

您可以将滑块包裹在 div 元素中,默认情况下您可以使用 hidden 属性 :

隐藏它
html.Div(id='slider', hidden=True, children=[
    html.Label('Slider'),
    dcc.Slider(
        id='slider-update-value',
        # options...
    )
])

然后在使用 tapNodeDataselectedNodeData 事件选择节点时更新 属性,我在这里使用 selectedNodeData 因为当您取消选择节点时另一个不会被触发(即。如果你想隐藏滑块):

@app.callback(
    Output('slider', 'hidden'),
    Input('node-callback-event', 'selectedNodeData'))
def displaySlider(data):
    return False if data else True

现在,给定滑块的 Input value,您想更新 Cytoscape elements,给定当前所选节点的 StatetapNodeDataselectedNodeData):

@app.callback(Output('node-callback-event', 'elements'),
            Input('slider-update-value', 'value'),
            State('node-callback-event', 'elements'),
            State('node-callback-event', 'selectedNodeData'))
def updateNodeLabel(value, elements, selected):
    if selected:
        # Update only the selected element(s)
        ids = [nodeData['id'] for nodeData in selected]
        nodes = ((i,n) for i,n in enumerate(elements) if n['data']['id'] in ids)
        for i, node in nodes:
            elements[i]['data']['label'] = 'test-' + str(value)
    return elements

@see Cytoscape callbacks and events