我正在尝试制作一个网页,其中包含由 AjaxDataSource 对象提供支持的绘图。但是,我想要一个可用于更改此图的 xrange 的 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_ajax()
函数以了解完整的实现:https://github.com/hhprogram/PyramidSite/blob/master/webgraphing/views/ajaxView.py
当我运行它并更改相应的“开始”文本输入框时。 CustomJS 相应地运行,根据我看到的警报,它正在捕获正确的新数据(假设您输入了 ISO 格式的日期,如 YYYY-mm-dd),但它无法更新绘图轴范围(即绘图没有'根本没有改变)。我将如何实现? (我想维护绘图以具有底层 AjaxDataSources,而不使用 Bokeh 服务器 - 如果运行 Bokeh 服务器,我已经知道如何实现这种类型的轴更改功能。)
最佳答案
对于任何好奇的人,发现我的问题。认为主要问题是我没有将我想用来控制绘图 xrange 的小部件和实际绘图本身放在同一个布局对象中。因此,当我在绘图对象上调用组件时,它不包含小部件。然后,当我将小部件包含在绘图中时,它就起作用了。请参阅以下更新和更新的 github 存储库:
(感谢这篇文章对我有很大帮助:Flask + Bokeh AjaxDataSource)
完整文件:https://github.com/hhprogram/PyramidSite/blob/master/webgraphing/views/ajaxView.py )
代码片段:
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)
关于javascript - Bokeh:用于调整 x 轴范围的 CustomJS TextInput 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48692991/