Javascript 在bokeh服务器配置中,如何将x,y坐标从客户端浏览器输入服务器

Javascript 在bokeh服务器配置中,如何将x,y坐标从客户端浏览器输入服务器,javascript,python,bokeh,Javascript,Python,Bokeh,我有一个名为getcoords.py的bokeh服务器应用程序。我使用以下命令启动服务器:bokeh-serve-getcoords.py。我有HoverTool和CustomJS回调函数。此外,我还有一个quadglyph,其中on\u change配置为触发服务器端的selected事件。每当我点击四元组字形时,就会执行onTab功能。当我点击glyph时,我希望以某种方式与客户端通信并获取指针坐标。代码如下: import bokeh import bokeh.plotting p =

我有一个名为getcoords.py的bokeh服务器应用程序。我使用以下命令启动服务器:
bokeh-serve-getcoords.py
。我有
HoverTool
CustomJS
回调函数。此外,我还有一个
quad
glyph
,其中
on\u change
配置为触发服务器端的
selected
事件。每当我点击
四元组
字形时,就会执行
onTab
功能。当我点击glyph时,我希望以某种方式与客户端通信并获取指针坐标。代码如下:

import bokeh
import bokeh.plotting

p = bokeh.plotting.figure(plot_height=200,x_range=(0,10),y_range=(0,10))
imquad = p.quad(top=[8], bottom=[2], left=[2], right=[8])

sourceXY = bokeh.models.ColumnDataSource(data=dict(x = [0], y = [0]))

callback_hover = bokeh.models.CustomJS(args=dict(sourceXY=sourceXY), code="""
    console.log('Coords:'+sourceXY.data['x'] +','+sourceXY.data['y'])
    sourceXY.data['x'] = [cb_data['geometry'].x];
    sourceXY.data['y'] = [cb_data['geometry'].y];
    sourceXY.trigger('change');
    """)
def onHover(attr, old, new):
    print "Hover"

counter = 0

def onTab(attr, old, new):
    global counter
    print "Tap on quad. Coordinates:",sourceXY.data['x'], sourceXY.data['y']
    sourceXY.data['x'], sourceXY.data['y'] = [counter],[counter]
    counter += 1
    sourceXY.trigger('data',None,None)
    # unselecting imquad to keep triggering on_change:
    new['1d']['indices'] = []

imquad.data_source.on_change('selected',onTab)

hover_tool = bokeh.models.HoverTool(callback=callback_hover)
tap_tool   = bokeh.models.TapTool()
p.add_tools(tap_tool)
p.add_tools(hover_tool)

bokeh.io.curdoc().add_root(p)
下面是显示
JavaScript
控制台日志的浏览器屏幕截图。坐标:0,0 1,1 2,2 3,3 4,4对应于在四字形上单击一次的时刻,并且这些值从服务器发送到客户端浏览器。javascript
CustomJS
代码首先显示sourceXY的值,然后用x和y数据坐标替换它。移动鼠标时,sourceXY将使用这些坐标进行更新,只要不点击,这些坐标将在JS控制台中显示一次

这是服务器端控制台的屏幕截图。每次点击四字形时,都会执行onTab(attr、old、new)例程。首先,它显示存储在sourceXY中的值,然后分配一个全局计数器值,该值在每次执行例程时增加一个。下面是我希望能够从客户端读取sourceXY的值,但我一直无法做到这一点

wirelessprv-XX-XXX-XXX-XXX:GetCoords pablo$ bokeh serve getcoords.py 
2017-02-25 21:26:00,899 Starting Bokeh server version 0.12.4
2017-02-25 21:26:00,911 Starting Bokeh server on port 5006 with applications at paths ['/getcoords']
2017-02-25 21:26:00,912 Starting Bokeh server with process id: 36965
2017-02-25 21:26:01,267 200 GET /getcoords (::1) 85.38ms
2017-02-25 21:26:01,785 WebSocket connection opened
2017-02-25 21:26:01,788 ServerConnection created
Tap on quad. Coordinates: [0] [0]
Tap on quad. Coordinates: [0] [0]
Tap on quad. Coordinates: [1] [1]
Tap on quad. Coordinates: [2] [2]
Tap on quad. Coordinates: [3] [3]
我尝试的是创建一个名为sourceXY的
ColumnDataSource
,它在
CustomJS
客户端中更新。然后,当我点击图示符时,服务器端的python代码读取尚未更新的服务器端
ColumnDataSource
的值,然后修改它以测试服务器到客户端的通信。这部分工作得很好,因为客户端能够读取从服务器发送的x和y。 我想知道是否有办法将保存在
ColumnDataSource
中的坐标(或点击时的坐标本身)从客户端获取到服务器端。
欢迎提出任何建议和意见。谢谢。

我找到了一种从服务器到客户端更新坐标值的方法。我从
HoverTool
CustomJS
javascript回调中找到了更新
TextInput
模型的解决方案。我将把我的解决方案放在这里,以防有人能从中受益

import bokeh
import bokeh.plotting

p = bokeh.plotting.figure(plot_height=200,x_range=(0,10),y_range=(0,10))
imquad = p.quad(top=[8], bottom=[2], left=[2], right=[8])

textxy = bokeh.models.TextInput(title="xy val", value='')

callback_hover = bokeh.models.CustomJS(args=dict(textxy=textxy), code="""
    textxy.value = cb_data['geometry'].x + ',' + cb_data['geometry'].y;
    console.log(textxy.value);
    """)

def onTab(attr, old, new):
    print "tap:",textxy.value
    # unselecting imquad to keep triggering on_change:
    new['1d']['indices'] = []

imquad.data_source.on_change('selected',onTab)

hover_tool = bokeh.models.HoverTool(callback=callback_hover)
tap_tool   = bokeh.models.TapTool()
p.add_tools(tap_tool)
p.add_tools(hover_tool)

bokeh.io.curdoc().add_root(p)
每当我点击
四元组
字形时,控制台的输出显示正确的坐标:

wirelessprv-XXX-XXX-XXX-XXX:GetCoords pablo$ bokeh serve getcoords.py 
2017-02-26 18:09:44,189 Starting Bokeh server version 0.12.4
2017-02-26 18:09:44,199 Starting Bokeh server on port 5006 with applications at paths ['/getcoords']
2017-02-26 18:09:44,199 Starting Bokeh server with process id: 42626
2017-02-26 18:09:46,841 200 GET /getcoords (::1) 68.90ms
2017-02-26 18:09:47,282 WebSocket connection opened
2017-02-26 18:09:47,283 ServerConnection created
tap: 3.3528435714104643,3.925695345068399
tap: 5.715666419702689,6.670813794893257
tap: 6.649805685306592,3.341627589786514
tap: 7.913641162300107,2.407119181335499
tap: 7.913641162300107,7.66372897887246
更新Bokeh的新版本。在0.12.16测试

为了使这种方法有效,需要将TextInput模型添加到客户端布局中。在此处,它作为行的一部分添加并禁用:

import bokeh
import bokeh.plotting

p = bokeh.plotting.figure(plot_height=200,x_range=(0,10),y_range=(0,10))
imquad = p.quad(top=[8], bottom=[2], left=[2], right=[8])

textxy = bokeh.models.TextInput(title="xy val", value='',disabled=True)

callback_hover = bokeh.models.CustomJS(args=dict(textxy=textxy), code="""
    textxy.value = cb_data['geometry'].x + ',' + cb_data['geometry'].y;
    console.log(textxy.value);
    """)

def onTab(attr, old, new):
    print "tap:",textxy.value

imquad.data_source.on_change('selected',onTab)

hover_tool = bokeh.models.HoverTool(callback=callback_hover)
tap_tool   = bokeh.models.TapTool()
p.add_tools(tap_tool)
p.add_tools(hover_tool)
layout = bokeh.layouts.row(p,textxy)

bokeh.io.curdoc().add_root(layout)
应该提到的是,
bokeh.models.Div
模型可以以相同的方式发送在
CustomJS
回调函数中更新的x,y坐标