You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Expected Behaviour: Programitcally selecting the row in a DataTable should scroll the row into view. This works with a ColumnDataSource, but does not work with an AjaxDataSource. Previous discussion of this issue can be found here. The specific behaviour that I ultimately want, is that when table data is updated, I want the last new data to be in the Users view, which means scrolling to the last row in the table.
Observed Behaviour: The row is not selected, the table does not scroll to row.
bokeh version: 1.3.4
browser Chrome: Version 76.0.3809.132 (Official Build) (64-bit)
host OS: Ubuntu 18.04
python: Python 3.6.8 (default, Aug 20 2019, 17:12:48) [GCC 8.3.0] on linux
Minimal Code:
Because the issue is only seen with an AjaxDataSource, there are two pieces of code, one for the Flask server providing the data, and the other being the bokeh code. Start the flask server in one terminal, and the bokeh code in another. The minimal code supports testing both "append/replace" modes of the AjaxDataSource, as commented in the source.
Flask server:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
from flask import Flask, jsonify
from flask_cors import CORS,cross_origin
# install cors: pip3 install -U flask-cors
app = Flask(__name__)
CORS(app, support_credentials=True)
PAGE_URL = "/test"
MODE = ["append", "replace"][1] # change index 0/1 to get different modes
G = { # globals...
"table": {"a": []},
}
@app.route(PAGE_URL + "/table", methods=['POST', 'OPIONS'])
@cross_origin(supports_credentials=True)
def url__table_data():
# Ajax URL, add a timestamp to the data stream, either whole table (replace) or last item (append)
G["table"]["a"].append("{}".format(time.time()))
if MODE == "append": return jsonify({"a": [G["table"]["a"][-1]]})
else: return jsonify(G["table"])
# Ajax URL: http://127.0.0.1:6800/test/table
app.run(host="0.0.0.0", port=6800, debug=False)
The bopkeh code uses two different methods to try and select the last row of the DataTable. One is a callback when the source data changes, and the other is thru a button that the user can press. Neither method causes the last row to be selected.
The bokeh code:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from bokeh.layouts import layout, column
from bokeh.models.widgets import Div, DataTable, TableColumn
from bokeh.models import AjaxDataSource, CustomJS
from bokeh.models.widgets.buttons import Button
from bokeh.io import show
MODE = ["append", "replace"][1] # change index 0/1 to get different modes
source = AjaxDataSource(data=dict(a=[]), data_url="http://127.0.0.1:6800/test/table",
polling_interval=1000, mode=MODE)
# The GOAL of this callback is to scroll the DataTable to the last row,
# every time the datatable gets new data...
callback = CustomJS(args=dict(source=source),
code="""
var last_row_idx = source.get_length();
if (last_row_idx) source.selected.indices = [last_row_idx - 1];
//console.log("ads", cb_obj, source, (last_row_idx - 1));
""")
source.js_on_change("data", callback)
columns = [TableColumn(field=c) for c in source.data.keys()]
dt_table = DataTable(source=source, columns=columns, selectable=True, scroll_to_selection=True)
button = Button()
button.js_on_click(CustomJS(args=dict(source=source), code="""
var last_row_idx = source.get_length();
if (last_row_idx) source.selected.indices = [last_row_idx - 1];
//console.log("Button", cb_obj, source, (last_row_idx - 1));
"""))
doc_layout = layout()
doc_layout.children.append(column(Div(text="""<h1>Hello World!</h1><p>Using an AjaxDataSource.</p>""")))
doc_layout.children.append(column(button, dt_table))
show(doc_layout)
Note that the issue does not occur with a ColumnDataSource, only with an AjaxDataSource.
I have used the console output in the above example to inspect the source.selected.indices and indeed this value is updated by the callbacks above (both button and the data change callback). But it seems that this does not trigger the table to scroll. Also note that I triedd adding a source.selected.change.emit(); to manually trigger the table to scroll, but that also did nothing.
The workaround, as discussed in the above linked discussion, is to call SlickGrid directly, but I have yet to get to trying that out... (TODO).
The text was updated successfully, but these errors were encountered:
Expected Behaviour: Programitcally selecting the row in a DataTable should scroll the row into view. This works with a ColumnDataSource, but does not work with an AjaxDataSource. Previous discussion of this issue can be found here. The specific behaviour that I ultimately want, is that when table data is updated, I want the last new data to be in the Users view, which means scrolling to the last row in the table.
Observed Behaviour: The row is not selected, the table does not scroll to row.
bokeh version: 1.3.4
browser Chrome: Version 76.0.3809.132 (Official Build) (64-bit)
host OS: Ubuntu 18.04
python: Python 3.6.8 (default, Aug 20 2019, 17:12:48) [GCC 8.3.0] on linux
Minimal Code:
Because the issue is only seen with an AjaxDataSource, there are two pieces of code, one for the Flask server providing the data, and the other being the bokeh code. Start the flask server in one terminal, and the bokeh code in another. The minimal code supports testing both "append/replace" modes of the AjaxDataSource, as commented in the source.
Flask server:
The bopkeh code uses two different methods to try and select the last row of the DataTable. One is a callback when the source data changes, and the other is thru a button that the user can press. Neither method causes the last row to be selected.
The bokeh code:
Note that the issue does not occur with a ColumnDataSource, only with an AjaxDataSource.
I have used the
console
output in the above example to inspect thesource.selected.indices
and indeed this value is updated by the callbacks above (both button and the data change callback). But it seems that this does not trigger the table to scroll. Also note that I triedd adding asource.selected.change.emit();
to manually trigger the table to scroll, but that also did nothing.The workaround, as discussed in the above linked discussion, is to call SlickGrid directly, but I have yet to get to trying that out... (TODO).
The text was updated successfully, but these errors were encountered: