是否可以在 dash-cytoscape 的广度优先布局中使用深度排序参数?

问题描述 投票:0回答:1

我正在使用 Dash-Cytoscape 绘制网络,使用

breadthfirst
布局,如此处所述。

我想控制同一级别上元素的出现顺序。 JS API 有

depthSort
参数来实现这一点,但我不知道如何在 Python 中传递前端可以使用的回调。

我尝试过的事情:

  1. "depthSort": lambda a,b: a - b
  2. "depthSort": "(a,b) => a - b"
  3. "depthSort": "function (a,b) { return a - b}"

最小示例:

我想要这个:

   1
3     2

但我得到的是这样的:

   1
2     3
from dash import Dash
import dash_cytoscape as cyto

app = Dash(__name__)

app.layout = cyto.Cytoscape(
    elements=[
        {"data": {"id": "1", "label": "1"}},
        {"data": {"id": "2", "label": "2"}},
        {"data": {"id": "3", "label": "3"}},
        {"data": {"source": "1", "target": "2"}},
        {"data": {"source": "1", "target": "3"}},
    ],
    layout={
        "name": "breadthfirst",
        "roots": ["1"],
        # "depthSort": ?
    },
)

app.run_server(debug=True)

python plotly-dash cytoscape dash-cytoscape
1个回答
0
投票

Python 不支持需要 JS 函数的选项,因为它意味着将函数作为字符串传递,因此需要 Cytoscape.js

eval
uate 任意字符串,这可能是维护者不希望看到的安全原因。

也就是说,Dash 支持客户端回调(JS),因此我们仍然可以在回调中分配函数:

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

app = Dash(__name__)

app.layout = cyto.Cytoscape(
    id="cyto",
    elements=[
        {"data": {"id": "1", "label": "1"}},
        {"data": {"id": "2", "label": "2"}},
        {"data": {"id": "3", "label": "3"}},
        {"data": {"source": "1", "target": "2"}},
        {"data": {"source": "1", "target": "3"}},
    ],
    layout={
        "name": "breadthfirst",
        "roots": ["1"]
    }
)

app.clientside_callback(
    """
    function (id, layout) {
        layout.depthSort = (a, b) => b.data('id') - a.data('id');
        cy.layout(layout).run();
        return layout;
    }
    """,
    Output('cyto', 'layout'),  # update the (dash) cytoscape component's layout
    Input('cyto', 'id'),       # trigger the function when the Cytoscape component loads (1)
    State('cyto', 'layout'),   # grab the layout so we can update it in the function
    prevent_initial_call=False # ensure (1) (needed if True at the app level)
)

app.run_server(debug=True)

注意。我们需要执行

cy.layout(layout).run()
,因为没有添加/删除元素,所以它不会自动运行。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.