添加 URL 超链接到单击 plotly dash 时返回的文本

Add in URL hyperlink to text returned upon click in plotly dash

此代码使用 plotly dash 按预期生成网络:

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

dash_elements = [{'data': {'id': '6840', 'label': '6840'}, 'classes': 'black'}, {'data': {'id': '7431', 'label': '7431'}, 'classes': 'red'}, {'data': {'source': '6840', 'target': '7431'}}, {'data': {'id': '6640', 'label': '6640'}, 'classes': 'black'}, {'data': {'id': '5217', 'label': '5217'}, 'classes': 'black'}, {'data': {'source': '6640', 'target': '5217'}}, {'data': {'id': '823', 'label': '823'}, 'classes': 'black'}, {'data': {'id': '7431', 'label': '7431'}, 'classes': 'red'}, {'data': {'source': '823', 'target': '7431'}}]

app = dash.Dash(__name__)

styles = {
    'pre': {
        'border': 'thin lightgrey solid',
        'overflowX': 'scroll'
    }
}


default_stylesheet=[
    # Class Selectors
    {
        'selector':'.black',
        #'selector': 'node',
        'style': {
            'background-color': '#000000',
            'label': 'data(label)'
        },
    },

    {
        'selector':'.red',
        #'selector':'node',
        'style': {
            'background-color': '#FF0000',
            'label': 'data(label)'
        },
    },
]


app.layout = html.Div([
    #html.P("Dash Cytoscape:"),
    cyto.Cytoscape(
        id='cytoscape-event-callbacks-2',
        elements = dash_elements,
        layout={'name': 'breadthfirst'},
        #layout={'name': 'preset'},
        style={'width': '1000px', 'height': '1000px'},
        stylesheet = default_stylesheet
        
        
        
    ),
    html.P(id='cytoscape-tapNodeData-output'),
    html.P(id='cytoscape-tapEdgeData-output'),
    html.P(id='cytoscape-mouseoverNodeData-output'),
    html.P(id='cytoscape-mouseoverEdgeData-output')
])

@app.callback(Output('page-content', 'children'),
              Input('cytoscape-event-callbacks-2', 'tapNodeData'))

#app.callback(Output('url', 'children'),
# Input('cytoscape-event-callbacks-2', 'tapNodeData'))


def displayTapNodeData(data):
    if data:
        return "https://www.ncbi.nlm.nih.gov/gene/" + str(data['label'])

    
    

@app.callback(Output('cytoscape-tapEdgeData-output', 'children'),
              Input('cytoscape-event-callbacks-2', 'tapEdgeData'))

def displayTapEdgeData(data):
    if data:
        return "There is a physical interaction between " + \
               str(data['source']) + " and " + str(data['target'])

    
    

@app.callback(Output('cytoscape-mouseoverNodeData-output', 'children'),
              Input('cytoscape-event-callbacks-2', 'mouseoverNodeData'))

def displayTapNodeData(data):
    if data:
        return "https://www.ncbi.nlm.nih.gov/gene/" + str(data['label'])


@app.callback(Output('cytoscape-mouseoverEdgeData-output', 'children'),
              Input('cytoscape-event-callbacks-2', 'mouseoverEdgeData'))



def displayTapEdgeData(data):
    if data:
        return "There is a physical interaction between " + \
               str(data['source']) + " and " + str(data['target'])

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

输出:

当我单击一个节点时,如预期的那样,左下角的文本出现 URL 以查找有关该节点的更多信息。

我只想将该文本变成超链接。

我可以查看示例文档来执行此操作 here 并且我可以使用此示例代码。

我不清楚我对自己的代码进行了哪些更改以合并此内容,我已经将我尝试过的尝试注释掉了,我认为我会输入 tapNodeData 并且输出会成为 url.

如果有人可以演示如何将点击返回的内容转换为 URL,我将不胜感激。

节点选择后URLlink秒返回活动

您可以只使用 Dash html.A 组件,不是吗?:

import dash
from dash import dcc
from dash import html
import dash_cytoscape as cyto
from dash.dependencies import Input, Output, State
import plotly.express as px

dash_elements = [
    {"data": {"id": "6840", "label": "6840"}, "classes": "black"},
    {"data": {"id": "7431", "label": "7431"}, "classes": "red"},
    {"data": {"source": "6840", "target": "7431"}},
    {"data": {"id": "6640", "label": "6640"}, "classes": "black"},
    {"data": {"id": "5217", "label": "5217"}, "classes": "black"},
    {"data": {"source": "6640", "target": "5217"}},
    {"data": {"id": "823", "label": "823"}, "classes": "black"},
    {"data": {"id": "7431", "label": "7431"}, "classes": "red"},
    {"data": {"source": "823", "target": "7431"}},
]

app = dash.Dash(__name__)

styles = {"pre": {"border": "thin lightgrey solid", "overflowX": "scroll"}}


default_stylesheet = [
    # Class Selectors
    {
        "selector": ".black",
        #'selector': 'node',
        "style": {"background-color": "#000000", "label": "data(label)"},
    },
    {
        "selector": ".red",
        #'selector':'node',
        "style": {"background-color": "#FF0000", "label": "data(label)"},
    },
]


app.layout = html.Div(
    [
        # html.P("Dash Cytoscape:"),
        cyto.Cytoscape(
            id="cytoscape-event-callbacks-2",
            elements=dash_elements,
            layout={"name": "breadthfirst"},
            # layout={'name': 'preset'},
            style={"width": "1000px", "height": "1000px"},
            stylesheet=default_stylesheet,
        ),
        html.P(id="cytoscape-tapNodeData-output"),
        html.P(id="cytoscape-tapEdgeData-output"),
        html.P(id="cytoscape-mouseoverNodeData-output"),
        html.P(id="cytoscape-mouseoverEdgeData-output"),
        html.Div([], id="page-content"),
    ]
)


@app.callback(
    Output("page-content", "children"),
    Input("cytoscape-event-callbacks-2", "tapNodeData"),
)
def displayTapNodeDataLink(data):
    if data:
        url = f"https://www.ncbi.nlm.nih.gov/gene/{data['label']}"
        return html.A(url, href=url, target="_blank")


@app.callback(
    Output("cytoscape-tapEdgeData-output", "children"),
    Input("cytoscape-event-callbacks-2", "tapEdgeData"),
)
def displayTapEdgeData(data):
    if data:
        return (
            "There is a physical interaction between "
            + str(data["source"])
            + " and "
            + str(data["target"])
        )


@app.callback(
    Output("cytoscape-mouseoverNodeData-output", "children"),
    Input("cytoscape-event-callbacks-2", "mouseoverNodeData"),
)
def displayTapNodeData(data):
    if data:
        return "https://www.ncbi.nlm.nih.gov/gene/" + str(data["label"])


@app.callback(
    Output("cytoscape-mouseoverEdgeData-output", "children"),
    Input("cytoscape-event-callbacks-2", "mouseoverEdgeData"),
)
def displayTapEdgeData(data):
    if data:
        return (
            "There is a physical interaction between "
            + str(data["source"])
            + " and "
            + str(data["target"])
        )


if __name__ == "__main__":
    app.run_server(debug=True, dev_tools_hot_reload=True)

我还添加了参数 target="_blank",这使得单击 URL 在新选项卡中打开。我个人觉得大部分时间真的很烦人,但尤其是在 Dash 应用程序中,link 在同一个选项卡中打开,然后离开该应用程序。但是,这当然是主观的,取决于您!

在选择节点时在一个回调中返回 stylesheethtml.A url 作为多个输出

(optional change which interactively indicates which node was most recently clicked on)

另外,我在这里更新了它,如果您碰巧想要这种行为,最近被点击的节点会改变颜色:

import dash
import dash_cytoscape as cyto
import plotly.express as px

from dash import dcc
from dash import html
from dash import no_update
from dash.dependencies import Input
from dash.dependencies import Output
from dash.dependencies import State


dash_elements = [
    {"data": {"id": "6840", "label": "6840"}, "classes": "node-6840"},
    {"data": {"id": "7431", "label": "7431"}, "classes": "node-7431"},
    {"data": {"source": "6840", "target": "7431"}},
    {"data": {"id": "6640", "label": "6640"}, "classes": "node-6640"},
    {"data": {"id": "5217", "label": "5217"}, "classes": "node-5217"},
    {"data": {"source": "6640", "target": "5217"}},
    {"data": {"id": "823", "label": "823"}, "classes": "node-823"},
    {"data": {"id": "7431", "label": "7431"}, "classes": "node-7431"},
    {"data": {"source": "823", "target": "7431"}},
]

app = dash.Dash(__name__)

styles = {"pre": {"border": "thin lightgrey solid", "overflowX": "scroll"}}


default_stylesheet = [
    # Class Selectors
    {
        "selector": "node",
        "style": {"background-color": "#000000", "label": "data(label)"},
    },
]


app.layout = html.Div(
    [
        # html.P("Dash Cytoscape:"),
        cyto.Cytoscape(
            id="cytoscape-event-callbacks-2",
            elements=dash_elements,
            layout={"name": "breadthfirst"},
            # layout={'name': 'preset'},
            style={"width": "750px", "height": "750px"},
            stylesheet=default_stylesheet,
        ),
        html.P(id="cytoscape-tapNodeData-output"),
        html.P(id="cytoscape-tapEdgeData-output"),
        html.P(id="cytoscape-mouseoverNodeData-output"),
        html.P(id="cytoscape-mouseoverEdgeData-output"),
        html.Div([], id="page-content"),
        html.Br(),
    ],
    style={"margin": "5%"},
)


@app.callback(
    [
        Output("page-content", "children"),
        Output("cytoscape-event-callbacks-2", "stylesheet"),
    ],
    Input("cytoscape-event-callbacks-2", "tapNodeData"),
)
def displayTapNodeDataLink(data):
    if data:
        stylesheet = [
            {"selector": "node", "style": {"label": "data(label)"},},
            {
                "selector": f".node-{data['id']}",
                "style": {"background-color": "red", "label": "data(label)",},
            },
        ]
        url = f"https://www.ncbi.nlm.nih.gov/gene/{data['label']}"
        return [html.A(url, href=url, target="_blank")], stylesheet
    else:
        return no_update, default_stylesheet


@app.callback(
    Output("cytoscape-tapEdgeData-output", "children"),
    Input("cytoscape-event-callbacks-2", "tapEdgeData"),
)
def displayTapEdgeData(data):
    if data:
        return (
            "There is a physical interaction between "
            + str(data["source"])
            + " and "
            + str(data["target"])
        )


@app.callback(
    Output("cytoscape-mouseoverNodeData-output", "children"),
    Input("cytoscape-event-callbacks-2", "mouseoverNodeData"),
)
def displayTapNodeData(data):
    if data:
        return "https://www.ncbi.nlm.nih.gov/gene/" + str(data["label"])


@app.callback(
    Output("cytoscape-mouseoverEdgeData-output", "children"),
    Input("cytoscape-event-callbacks-2", "mouseoverEdgeData"),
)
def displayTapEdgeData(data):
    if data:
        return (
            "There is a physical interaction between "
            + str(data["source"])
            + " and "
            + str(data["target"])
        )


if __name__ == "__main__":
    app.run_server(debug=True, dev_tools_hot_reload=True)