4 回答
TA贡献2016条经验 获得超9个赞
source.data更改滑块时需要创建一个新的。为此,您还需要一个不可source更改的“备份” ,并作为要包含哪些数据的参考。将两者作为参数传递给回调函数使它们可用于 Javascript 代码。
datesX = pd.date_range(start='1/1/2018', periods=100)
valuesY = pd.DataFrame(np.random.randint(0,25,size=(100, 1)), columns=list('A'))
# keep track of the unchanged, y-axis values
source = ColumnDataSource(data={'x': datesX, 'y': valuesY['A']})
source2 = ColumnDataSource(data={'x': datesX, 'y': valuesY['A']})
# output to static HTML file
output_file('file.html')
hover = HoverTool(
tooltips=[('Timestamp', '@x{%Y-%m-%d %H:%M:%S}'), ('Value', '@y')],
formatters={'x': 'datetime'},)
date_range_slider = DateRangeSlider(
title="Zeitrahmen", start=datesX[0], end=datesX[99],
value=(datesX[0], datesX[99]), step=1, width=300)
# create a new plot with a title and axis labels
p = figure(
title='file1', x_axis_label='Date', y_axis_label='yValue',
y_range=(0, 30), x_axis_type='datetime',
tools="pan, wheel_zoom, box_zoom, reset",
plot_width=600, plot_height=200)
# add a line renderer with legend and line thickness
p.line(x='x', y='y', source=source, line_width=2)
p.add_tools(hover)
callback = CustomJS(args=dict(source=source, ref_source=source2), code="""
// print out array of date from, date to
console.log(cb_obj.value);
// dates returned from slider are not at round intervals and include time;
const date_from = Date.parse(new Date(cb_obj.value[0]).toDateString());
const date_to = Date.parse(new Date(cb_obj.value[1]).toDateString());
const data = source.data;
const ref = ref_source.data;
const from_pos = ref["x"].indexOf(date_from);
// add + 1 if you want inclusive end date
const to_pos = ref["x"].indexOf(date_to);
// re-create the source data from "reference"
data["y"] = ref["y"].slice(from_pos, to_pos);
data["x"] = ref["x"].slice(from_pos, to_pos);
source.change.emit();
""")
date_range_slider.js_on_change('value', callback)
layout = column(p, date_range_slider)
# show the results
show(layout)
TA贡献1790条经验 获得超9个赞
我发现上面的答案不起作用,因为数据的时间戳ref_source与来自散景滑块对象(cb_obj)的解析时间戳不同。
例如,ref_source数据中的时间戳在使用 进行解析时会创建以下输出new Date(source.data.["x"]);:
01/01/2020 02:00:00
来自散景滑块对象的时间戳cb_obj始终为00:00:00。因此使用时无法找到时间戳const from_pos = ref["date"].indexOf(date_from);。
为了正确解析日期,ref_source我创建了一个新数组new_ref并将正确解析的日期添加到该数组中。不过,我必须在这里强调,我不是 JavaScript 专家,我很确定在这里可以更有效地编写代码。
这是我的工作示例:
// print out array of date from, date to
console.log(cb_obj.value);
// dates returned from slider are not at round intervals and include time;
const date_from = Date.parse(new Date(cb_obj.value[0]).toDateString());
const date_to = Date.parse(new Date(cb_obj.value[1]).toDateString());
console.log(date_from, date_to)
// Creating the Data Sources
const data = source.data;
const ref = ref_source.data;
// Creating new Array and appending correctly parsed dates
let new_ref = []
ref["x"].forEach(elem => {
elem = Date.parse(new Date(elem).toDateString());
new_ref.push(elem);
console.log(elem);
})
// Creating Indices with new Array
const from_pos = new_ref.indexOf(date_from);
const to_pos = new_ref.indexOf(date_to) + 1;
// re-create the source data from "reference"
data["y"] = ref["y"].slice(from_pos, to_pos);
data["x"] = ref["x"].slice(from_pos, to_pos);
source.change.emit();
我希望它对你有一点帮助:)
TA贡献1865条经验 获得超7个赞
有趣的问题和讨论。添加以下两行(其中一行直接从文档中提取)允许滑块在不使用 CustomJS 和 js_on_change 函数的情况下工作 - 使用 js_link 函数代替:
date_range_slider.js_link('value', p.x_range, 'start', attr_selector=0) date_range_slider.js_link('value', p.x_range, 'end', attr_selector=1)
TA贡献1825条经验 获得超4个赞
使用 CustonJS 直接更改绘图 x_range 而不是过滤数据源。
callback = CustomJS(args=dict(p=p), code="""
p.x_range.start = cb_obj.value[0]
p.x_range.end = cb_obj.value[1]
p.x_range.change.emit()
""")
date_range_slider.js_on_change('value_throttled', callback)
添加回答
举报