如何使用点击的散景图边缘的相应数据打开URL

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

我正在尝试打开一个URL,其中的参数对应于使用Bokeh渲染的networkx图形的边缘。我能够使用带有工具提示的HoverTool来加载与我需要的URL匹配的图像,该URL是一个模板,其中填充了我图形的Edge数据中的参数('color'和'weight')。这是一个简化的例子:

import networkx as nx

from bokeh.io import show, output_file
from bokeh.models import Plot, Range1d, MultiLine, Circle, TapTool, OpenURL, HoverTool
from bokeh.models.graphs import from_networkx, EdgesAndLinkedNodes
from bokeh.palettes import Spectral4

tooltips = """
<div id="picture" style="width : 550px; position: fixed; left: 250px; top: 80px">
    <div>
        <img
            src="http://localhost/@color/@weight/" alt="http://localhost/@color/@weight/" height=300
            border="2"
        ></img>
    </div>
</div>
"""

G = nx.Graph()
G.add_node('X', color='color of node')
G.add_edge('Y', 'X', weight=6, color="blue")
G.add_edge('Z', 'X', weight=3, color="yellow")
G.add_edge('Y', 'Z', weight=7, color="red")

plot = Plot(plot_width=800, plot_height=800,
            x_range=Range1d(-1.1,1.1), y_range=Range1d(-1.1,1.1))

graph_renderer = from_networkx(G, nx.circular_layout, scale=1, center=(0,0))
graph_renderer.node_renderer.glyph = Circle(size=15, fill_color=Spectral4[0])
graph_renderer.node_renderer.selection_glyph = Circle(size=15, fill_color=Spectral4[2])
graph_renderer.node_renderer.hover_glyph = Circle(size=15, fill_color=Spectral4[1])
graph_renderer.edge_renderer.glyph = MultiLine(line_color="#CCCCCC", line_alpha=0.8, line_width=5)
graph_renderer.edge_renderer.selection_glyph = MultiLine(line_color=Spectral4[2], line_width=5)
graph_renderer.edge_renderer.hover_glyph = MultiLine(line_color=Spectral4[1], line_width=5)
graph_renderer.selection_policy = EdgesAndLinkedNodes()
graph_renderer.inspection_policy = EdgesAndLinkedNodes()

plot.renderers.append(graph_renderer)

url = "http://localhost/@color/@weight/@index"
plot.add_tools(HoverTool(tooltips=tooltips), TapTool(callback=OpenURL(url=url)))

output_file("example.html")

show(plot)

例如,悬停边缘,工具提示中加载的图像是:

http://localhost/blue/6

现在,我的目标是在单击边缘时在新选项卡中打开此URL。我正在使用带有OpenURL回调的TapTool。这次,url模板填充了来自最近节点而不是边缘的信息。例如,它试图打开:

http://localhost/color%20of%20node/???/X

有没有办法按照我打算使用的方式使用OpenURL?

我猜我的一个选择是在TapTool中创建一个自定义JS回调而不是使用OpenURL。我能够获得点击字形的x和y位置,但我不知道如何从点击的边缘检索数据信息以构建带有“颜色”和“权重”数据的URL。任何想法如何实现这一目标?

python bokeh
1个回答
2
投票

您可以将您的url传递给JS回调并使用open()方法打开它,如下例所示。单击节点将打印回调对象cb_obj,回调数据cb_data和其他信息到Developers Tools控制台,例如在谷歌浏览器中。此外,将打印所选索引和相应的数据值。请注意,在执行此JS回调之前,将首先应用graph_renderer.selection_policy。我希望它有所帮助

import networkx as nx

from bokeh.io import show, output_file
from bokeh.models import Plot, Range1d, MultiLine, Circle, TapTool, OpenURL, HoverTool, CustomJS
from bokeh.models.graphs import from_networkx, EdgesAndLinkedNodes
from bokeh.palettes import Spectral4

tooltips = """
<div id="picture" style="width : 550px; position: fixed; left: 250px; top: 80px">
    <div>
        <img
            src="http://localhost/@color/@weight/" alt="http://localhost/@color/@weight/" height=300
            border="2"
        ></img>
    </div>
</div> """

G = nx.Graph()
G.add_node('X', color = 'color of node')
G.add_edge('Y', 'X', weight = 6, color = "blue")
G.add_edge('Z', 'X', weight = 3, color = "yellow")
G.add_edge('Y', 'Z', weight = 7, color = "red")

plot = Plot(x_range = Range1d(-1.1, 1.1), y_range = Range1d(-1.1, 1.1))

graph_renderer = from_networkx(G, nx.circular_layout, scale = 1, center = (0, 0))
graph_renderer.node_renderer.glyph = Circle(size = 15, fill_color = Spectral4[0])
graph_renderer.node_renderer.selection_glyph = Circle(size = 15, fill_color = Spectral4[2])
graph_renderer.node_renderer.hover_glyph = Circle(size = 15, fill_color = Spectral4[1])
graph_renderer.edge_renderer.glyph = MultiLine(line_color = "#CCCCCC", line_alpha = 0.8, line_width = 5)
graph_renderer.edge_renderer.selection_glyph = MultiLine(line_color = Spectral4[2], line_width = 5)
graph_renderer.edge_renderer.hover_glyph = MultiLine(line_color = Spectral4[1], line_width = 5)
graph_renderer.selection_policy = EdgesAndLinkedNodes()
graph_renderer.inspection_policy = EdgesAndLinkedNodes()

plot.renderers.append(graph_renderer)

url = "http://localhost/@color/@weight/@index"
code = ''' 
//open(url);
console.log(cb_obj); 
console.log(cb_data); 
console.log(cb_data.source.selected.indices);
console.log(cb_data.source.data);
selected = cb_data.source.selected.indices
if (selected.length > 0)
    for (index in selected)
        console.log('index: ' + selected[index] + ', value: ' + cb_data.source.data.index[selected[index]])
console.log(''); '''
callback_tap_tool = CustomJS(args = dict(url = url), code = code)
plot.add_tools(HoverTool(tooltips = tooltips), TapTool(callback = callback_tap_tool))

output_file("example.html")

show(plot)
© www.soinside.com 2019 - 2024. All rights reserved.