我正在尝试创建一个由AjaxDataSource对象提供支持的绘图的网页。但是,我希望有一个TextInput小部件可用于更改此绘图的xrange。以下是一个片段:
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
当我运行它并更改相应的'开始' textInput框。 CustomJS相应地运行并根据警报我已经看到它正在捕获正确的新数据(假设您输入了像YYYY-mm-dd这样的ISO格式化日期),但是它无法更新绘图轴范围(即绘图没有&# 39; t完全改变)。我该如何实现? (我想维护这些图也有基础AjaxDataSources而不使用散景服务器 - 如果运行散景服务器,我已经知道如何实现这种类型的轴更改功能。)
答案 0 :(得分:1)
对于任何好奇的人,找到了我的问题。认为主要的问题是我没有把我想要用来控制绘图xrange的小部件和实际的绘图本身放在同一个布局对象中。因此,当我在绘图对象上调用组件时,它没有包含小部件。然后,当我将小部件与情节一起包含在内时。请参阅以下更新和更新的github repo:
(感谢这篇文章非常有帮助我: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)