Hmm, right, sorry to have mislead you. In fact, you initial code does send view updates to the UI - it’s just that the DataTable does not pick them up. It’s mentioned in this comment in the linked issue: Changing CDSView filters' attributes does not trigger rendering · Issue #7273 · bokeh/bokeh · GitHub
Here’s how I’d write it:
import numpy.random as rand
from bokeh.io import curdoc
from bokeh.models import RangeSlider, WidgetBox, ColumnDataSource, TableColumn, CDSView, DataTable, BooleanFilter, \
CustomJS
CHAR_LIST = ['WATCHER', 'IRONCLAD', 'THE_SILENT', 'DEFECT']
run_index_random = {
'character': rand.choice(CHAR_LIST, 100),
'ascencion_level': rand.randint(0, 20, 100),
'victory': rand.choice([True, False], 100),
'floor_reached': rand.randint(1, 56, 100),
}
run_index_cds = ColumnDataSource(data=run_index_random)
def range_to_booleans(rng):
bot, top = rng
return [bot <= asc <= top for asc in run_index_cds.data['ascencion_level']]
init_range = (5, 20)
asc_filter = BooleanFilter(range_to_booleans(init_range), tags=['asc_filter'])
run_index_view = CDSView(source=run_index_cds, filters=[asc_filter])
run_index_columns = [TableColumn(field=x, title=x) for x in run_index_cds.column_names]
run_index_table = DataTable(source=run_index_cds, view=run_index_view, columns=run_index_columns)
def asc_filter_change(attr, old, new):
bot, top = new
asc_filter.booleans = [True if bot <= asc <= top else False
for asc in run_index_cds.data['ascencion_level']]
# Ascension filter
asc_slider = RangeSlider(start=0, end=20, step=1, value=init_range, title="Ascension")
asc_slider.on_change('value', asc_filter_change)
asc_filter.js_on_change('booleans', CustomJS(args=dict(cds=run_index_cds),
code="cds.change.emit()"))
curdoc().add_root(WidgetBox(children=[asc_slider, run_index_table]))
The essential part is that js_on_change
- it basically makes the DataTable
think that the actual data has changed when the slider’s value changes.