簡體   English   中英

如何使用 Dash Cytoscape cola.js 但在 Python 中為每個邊緣指定 edgeLength

[英]How do you specify edgeLength for each edge using Dash Cytoscape cola.js but in Python

我正在嘗試使用 Dash Cytoscape 創建一個物理直接網絡圖。 我嘗試過使用 Cose、Cose-Bilkent 和現在的可樂,但我的問題是我無法讓邊緣長度清楚地與重量成正比。

在 Cola 的 JS 中,您可以在“edgeLength”的布局參數中設置為 function 例如 function(e){ return params.edgeLengthVal / e.data('weight'); },但在 Python 中我無法找到替代方案。 傳遞定義的 function 不起作用,將 dict 傳遞給 layout 或為數據 dict 中的每個元素指定 EdgeLength 也不起作用。

如果我能實現這樣的目標,但在 Python 中,那將是理想的。 我想在 Python 中執行此操作,因為這是一系列 Dash 圖之一,它們是完全內置於 Python 中的更大項目的一部分,而且我不熟悉 JS。

import json

import dash
import dash_html_components as html

import dash_cytoscape as cyto
cyto.load_extra_layouts()
app = dash.Dash(__name__)
server = app.server

app.scripts.config.serve_locally = True
app.css.config.serve_locally = True

# Load Data
with open('data.json', 'r') as f:
    elements = json.loads(f.read())

nodes = [{"data":{"id":"1",'name':'1','score':1},"group": "nodes"},
         {"data":{"id":"2",'name':'2','score':0.1},"group": "nodes"},
         {"data":{"id":"3",'name':'3','score':0.1},"group": "nodes"},
         {"data":{"id":"4",'name':'4','score':0.1},"group": "nodes"}]

edges = [
    {"data":{"id":"1-2","source":"1","target":"2","weight":1},"group": "edges"},
    {"data":{"id":"1-3","source":"1","target":"3","weight":0.1},"group": "edges"},
    {"data":{"id":"1-4","source":"1","target":"4","weight":0.1},"group": "edges"},
    {"data":{"id":"2-3","source":"2","target":"3","weight":0.1},"group": "edges"},
    {"data":{"id":"2-4","source":"2","target":"4","weight":0.1},"group": "edges"},
    {"data":{"id":"3-4","source":"3","target":"4","weight":0.1,"edgeLength":20000},"group": "edges"}
]
elements = nodes + edges
print(elements)


with open('cy-style_2.json', 'r') as f:
    stylesheet = json.loads(f.read())

def length(edge):
    distance = 100/edge['data']['weight']
    return distance

# App
app.layout = html.Div([
    cyto.Cytoscape(
        id='cytoscape',
        elements=elements,
        stylesheet=stylesheet,
        style={
            'width': '100%',
            'height': '100%',
            'position': 'absolute',
            'left': 0,
            'top': 0,
            'z-index': 999

        },
        layout={
            'name': 'cola',
            'EdgeLength': length,
            'maxSimulationTime': 8000,
            'convergenceThreshold': 0.001,
            'nodeOverlap': 20,
            'refresh': 20,
            'fit': True,
            'padding': 30,
            'randomize': True,
            'componentSpacing': 100,
            'nodeRepulsion': 400000,
            'edgeElasticity': 100000,
            'nestingFactor': 5,
            'gravity': 80,
            'numIter': 1000,
            'initialTemp': 200,
            'coolingFactor': 0.95,
            'minTemp': 1.0
        }
    )
])
print(app.layout)
if __name__ == '__main__':
    app.run_server(debug=True)

也許這會有所幫助: https://github.com/cytoscape/ipycytoscape/issues/82

否則,這將在單擊節點時解決您的問題(但不拖動它)

nodes = [
     {"data":{"id":"1",'name':'1','score':1,'href':'www.mywebsite.com'},"group": "nodes"},
     {"data":{"id":"2",'name':'2','score':0.1,'href':'www.mywebsite.com'},"group": "nodes"},
     {"data":{"id":"3",'name':'3','score':0.1,'href':'www.mywebsite.com'},"group": "nodes"},
     {"data":{"id":"4",'name':'4','score':0.1,'href':'www.mywebsite.com'},"group": "nodes"}
]

然后添加一個回調

@app.callback(Output('cytoscape', 'layout'),
          [Input('cytoscape', 'tapNode')],
          [State('cytoscape', 'layout')])
def open_link_at_node_click(data, layout):
    """
        Open (default) web-browser
    """
    import sys
    import subprocess
    import webbrowser
    # Mac
    if sys.platform == 'darwin':
        subprocess.Popen(['open', data['data']['href']])
    # Linux & Windows
    else:
        webbrowser.open_new_tab(data['data']['href'])
    return {'name': layout}

即使不是目的,這里也會強制刷新布局。 但是,它可以解決問題。 一種方法是找到更好的“輸出”,例如隱藏的 div。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM