Javascript Bokeh:CustomJS TextInput回调以调整x轴范围

Javascript Bokeh:CustomJS TextInput回调以调整x轴范围,javascript,python,ajax,bokeh,Javascript,Python,Ajax,Bokeh,我正在尝试制作一个网页,它有一个由AjaxDataSource对象驱动的绘图。但是,我希望有一个TextInput小部件,可以用来更改此绘图的范围。下面是一个片段: source = AjaxDataSource(data={"time": [], "temperature": [], "id": []}, data_url='http://localhost:6543/AJAXdata', poll

我正在尝试制作一个网页,它有一个由AjaxDataSource对象驱动的绘图。但是,我希望有一个TextInput小部件,可以用来更改此绘图的范围。下面是一个片段:

source = AjaxDataSource(data={"time": [], "temperature": [], "id": []},
                        data_url='http://localhost:6543/AJAXdata',
                        polling_interval=100,
                        mode='append')
livePlot = figure(x_axis_type="datetime",
                  x_range=[startDt, endDt],
                  y_range=(0,25),
                  y_axis_label='Temperature (Celsius)',
                  title="Sea Surface Temperature at 43.18, -70.43",
                  plot_width=800)
livePlot.line("time", "temperature", source=source)
....
updateStartJS = CustomJS(args=dict(xrange=livePlot.x_range), code="""
    var startStr = cb_obj.value
    alert(startStr)
    var newStartMilliSeconds = Date.parse(startStr)
    alert(newStartMilliSeconds)
    alert(xrange)
    alert(xrange.start)
    xrange.start = newStartMilliSeconds
    alert(xrange.start)
    xrange.change.emit();
""")
startInput = TextInput(value=startDt.strftime(dateFmt), callback=updateStartJS)
有关完整的实现,请参阅此文件和
bokeh\u ajax()
函数:


当我运行它并更改相应的“开始”文本输入框时。CustomJS相应地运行,并且根据我看到的警报,它捕获了正确的新数据(假设您输入了ISO格式的日期,如YYYY-mm-dd),但它无法更新绘图轴范围(即绘图根本没有更改)。我将如何实现这一点?(我想维护绘图,使其也具有底层AjaxDataSources,而不使用bokeh服务器-如果运行bokeh服务器,我已经知道如何实现这种类型的轴更改功能。)

任何好奇的人都可以找到我的问题。我想主要的问题是我没有把我想要用来控制plot xrange和实际plot本身的小部件放在同一个布局对象中。因此,当我在plot对象上调用组件时,它不包括小部件。然后,当我将小部件与绘图一起包含时,它工作了。请参阅以下更新和更新的github repo:

(这篇文章对我的帮助很大:)

完整文件:)

代码段:

source = AjaxDataSource(data={"time": [], "temperature": [], "id": []},
                        data_url='http://localhost:6543/AJAXdata',
                        polling_interval=100,
                        mode='append')
livePlot = figure(x_axis_type="datetime",
                  x_range=[startDt, endDt],
                  y_range=(0,25),
                  y_axis_label='Temperature (Celsius)',
                  title="Sea Surface Temperature at 43.18, -70.43",
                  plot_width=800)
livePlot.line("time", "temperature", source=source)
jsResources = INLINE.render_js()
cssResources = INLINE.render_css()

updateStartJS = CustomJS(args=dict(plotRange=livePlot.x_range), code="""
    var newStart = Date.parse(cb_obj.value)
    plotRange.start = newStart
    plotRange.change.emit()
""")

updateEndJS = CustomJS(args=dict(plotRange=livePlot.x_range), code="""
    var newEnd = Date.parse(cb_obj.value)
    plotRange.end = newEnd
    plotRange.change.emit()
""")

startInput = TextInput(value=startDt.strftime(dateFmt), title="Enter Date in format: YYYY-mm-dd")
startInput.js_on_change('value', updateStartJS)
endInput = TextInput(value=endDt.strftime(dateFmt), title="Enter Date in format: YYYY-mm-dd")
endInput.js_on_change('value', updateEndJS)
textWidgets = row(startInput, endInput)
# NOTE: this is important. Need to have the widgets and plot within same object that is the argument for components() method
layout =  column(textWidgets, livePlot)
script, div = components(layout)