"Selectable" attribute to DataTable: how to use 'checkbox' option?

Hi there,

I’m interested in the ‘selectable’ attribute of the DataTable. As per the documentation below, it appears to be possible to set this attribute so that row selection can be done using check boxes, rather than by clicking on and highlighting the row itself. Per http://bokeh.pydata.org/en/latest/docs/reference/models/widgets.tables.html :

selectable
property type: Either ( Bool , Enum ( Enumeration(checkbox) ) )

Whether a table’s rows can be selected or not. Using checkbox is
equivalent to True, but makes selection visible through a checkbox
for each row, instead of highlighting rows. Multiple selection is
allowed and can be achieved by either clicking multiple checkboxes (if
enabled) or using Shift + click on rows.

However, I haven’t managed to get this functionality to work. My first naive instinct would be to set data_table.selectable = “checkbox”. However, since ‘selectable’ should not be a string, but be either a Bool, or an Enum ( Enumeration(checkbox), my next attempt was the below:

···

from datetime import date
from random import randint
from bokeh.core.enums import enumeration
from bokeh.core.properties import Enum
from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn

output_file(“data_table.html”)

data = dict(
dates=[date(2014, 3, i+1) for i in range(10)],
downloads=[randint(0, 100) for i in range(10)],
)
source = ColumnDataSource(data)

columns = [
TableColumn(field=“dates”, title=“Date”, formatter=DateFormatter()),
TableColumn(field=“downloads”, title=“Downloads”),
]

my_enumeration = enumeration(“checkbox”)
my_Enum = Enum( my_enumeration )

data_table = DataTable(source=source, columns=columns, width=400, height=280)
data_table.selectable = my_Enum

show(widgetbox(data_table))


However, as can be seen by running this code (adapted only slightly from http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/widgets.html#data-table ), this produces an error:

Traceback (most recent call last):
File “dt_test.py”, line 32, in
data_table.selectable = my_Enum
File “/usr/local/lib/python2.7/dist-packages/bokeh/core/has_props.py”, line 274, in setattr
super(HasProps, self).setattr(name, value)
File “/usr/local/lib/python2.7/dist-packages/bokeh/core/property/descriptors.py”, line 495, in set
self._internal_set(obj, value, setter)
File “/usr/local/lib/python2.7/dist-packages/bokeh/core/property/descriptors.py”, line 713, in _internal_set
value = self.property.prepare_value(obj, self.name, value)
File “/usr/local/lib/python2.7/dist-packages/bokeh/core/property/bases.py”, line 290, in prepare_value
raise e
ValueError: expected an element of either Bool or Enum(‘checkbox’), got <bokeh.core.properties.Enum object at 0x7f287fcca1d0>

This feels like it should be obvious, but has me rather stumped: as fas as I can see, the above approach to creating an Enum ( Enumeration ( xxxx ) ) is the same procedure followed throughout the codebase for other attributes which are defined with an enumeration (eg, those listed at bokeh.core.enums — Bokeh 2.4.2 Documentation). However, after a number of attempts and a lot of playing around with Enum and enumerate, I’ve not been able to find anything that works.

It’s the end of the day here, so I expect I am simply misunderstanding something/making a simple error; I’m sure someone can advise.

Any guidance? Has anyone succeeded with checkbox selection on a data table? (I am using bokeh 0.12.6, Python 2.7.6)

Many thanks,
Sarah

I have not use the Enum(‘checkbox’) but it’s definitely possible to link a table source and a checkboxgroup.

from datetime import date
from random import randint
from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource, CustomJS, CheckboxGroup, Button
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn

output_file(“data_table.html”)

data = dict(
dates=[date(2014, 3, i+1) for i in range(10)],
downloads=[randint(0, 100) for i in range(10)],
)
source = ColumnDataSource(data)

columns = [
TableColumn(field=“dates”, title=“Date”, formatter=DateFormatter()),
TableColumn(field=“downloads”, title=“Downloads”),
]

data_table = DataTable(source=source, columns=columns, width=400, height=280,selectable=True)
checkbox = CheckboxGroup(labels=[str(i) for i in data[‘dates’]],active=)
button = Button(label=“Log”)

source_code = “”"
var inds = cb_obj.selected[‘1d’].indices;

checkbox.active = inds;

checkbox.change.emit()
“”"

checkbox_code = “”"
source.selected[‘1d’].indices = cb_obj.active;
“”"

button_code = “”"
console.log(‘checkbox’,checkbox.active);
console.log(‘source’,source.selected[‘1d’].indices);
“”"

source.callback = CustomJS(args=dict(checkbox=checkbox),code=source_code)

checkbox.callback = CustomJS(args=dict(table=data_table,source=source),code=checkbox_code)

button.callback = CustomJS(args=dict(table=data_table,checkbox=checkbox,source=source),code=button_code)

show(widgetbox(data_table,checkbox,button))

``

Although I don’t know how to make the checkboxes highlight the corresponding selected rows like when the table is clicked.

Hi Sebastien,

Thanks for the response! I may be able to do something with that, if there’s no luck to be had with the ‘selectable’ attribute of the Data Table itself.

However, I think the last bit, making the checkboxes highlight the corresponding selected rows like when the table is clicked, is pretty much what I’m after. I need a fairly flexible way to select a number of rows from the data table, so I can display the relevant data in other plot objects. However, the data table can be sorted, etc, and I can’t see that there was ever a resolution to the question at https://github.com/bokeh/bokeh/issues/3564 .

I had hoped that the selectable[‘checkbox’] option might be a magic bullet, but unless anyone has further comments I might have to look into alternatic approaches.

···

On Saturday, July 22, 2017 at 6:54:04 AM UTC+10, Sébastien Roche wrote:

I have not use the Enum(‘checkbox’) but it’s definitely possible to link a table source and a checkboxgroup.

from datetime import date
from random import randint
from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource, CustomJS, CheckboxGroup, Button
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn

output_file(“data_table.html”)

data = dict(
dates=[date(2014, 3, i+1) for i in range(10)],
downloads=[randint(0, 100) for i in range(10)],
)
source = ColumnDataSource(data)

columns = [
TableColumn(field=“dates”, title=“Date”, formatter=DateFormatter()),
TableColumn(field=“downloads”, title=“Downloads”),
]

data_table = DataTable(source=source, columns=columns, width=400, height=280,selectable=True)
checkbox = CheckboxGroup(labels=[str(i) for i in data[‘dates’]],active=)
button = Button(label=“Log”)

source_code = “”"
var inds = cb_obj.selected[‘1d’].indices;

checkbox.active = inds;

checkbox.change.emit()
“”"

checkbox_code = “”"
source.selected[‘1d’].indices = cb_obj.active;
“”"

button_code = “”"
console.log(‘checkbox’,checkbox.active);
console.log(‘source’,source.selected[‘1d’].indices);
“”"

source.callback = CustomJS(args=dict(checkbox=checkbox),code=source_code)

checkbox.callback = CustomJS(args=dict(table=data_table,source=source),code=checkbox_code)

button.callback = CustomJS(args=dict(table=data_table,checkbox=checkbox,source=source),code=button_code)

show(widgetbox(data_table,checkbox,button))

``

Although I don’t know how to make the checkboxes highlight the corresponding selected rows like when the table is clicked.

Note that in my code it doesn’t matter if you sort the table by clicking on headers because rows are referred by indice (the # column) which is not static.
And the table highlight is only a visual problem, both clicking the table or checkboxes will result in the same data being “selected” in the ColumnDataSource so that wouldn’t be a problem for selecting data to display in other plots.

I owe you an apology, Sebastien: I read your reply too quickly, and didn’t fully appreciate what you’d done. I have tested your code today, and you’re right: it does work even when columns are sorted. In fact, it may be close to exactly what I want - many thanks! I will do some further investigations, and report back once I have an implementation I’m happy with.

Thanks again for your quick and helpful response - much appreciated!
Sarah

···

On Monday, July 24, 2017 at 11:26:04 PM UTC+10, Sébastien Roche wrote:

Note that in my code it doesn’t matter if you sort the table by clicking on headers because rows are referred by indice (the # column) which is not static.
And the table highlight is only a visual problem, both clicking the table or checkboxes will result in the same data being “selected” in the ColumnDataSource so that wouldn’t be a problem for selecting data to display in other plots.

Hi

I’m interested in that feature too. Could anyone provide a sample code please?

Thanks
BG

···

Le vendredi 21 juillet 2017 09:13:32 UTC-3, Sarah Hegarty a écrit :

Hi there,

I’m interested in the ‘selectable’ attribute of the DataTable. As per the documentation below, it appears to be possible to set this attribute so that row selection can be done using check boxes, rather than by clicking on and highlighting the row itself. Per http://bokeh.pydata.org/en/latest/docs/reference/models/widgets.tables.html :

selectable
property type: Either ( Bool , Enum ( Enumeration(checkbox) ) )

Whether a table’s rows can be selected or not. Using checkbox is
equivalent to True, but makes selection visible through a checkbox
for each row, instead of highlighting rows. Multiple selection is
allowed and can be achieved by either clicking multiple checkboxes (if
enabled) or using Shift + click on rows.

However, I haven’t managed to get this functionality to work. My first naive instinct would be to set data_table.selectable = “checkbox”. However, since ‘selectable’ should not be a string, but be either a Bool, or an Enum ( Enumeration(checkbox), my next attempt was the below:


from datetime import date
from random import randint
from bokeh.core.enums import enumeration
from bokeh.core.properties import Enum
from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn

output_file(“data_table.html”)

data = dict(
dates=[date(2014, 3, i+1) for i in range(10)],
downloads=[randint(0, 100) for i in range(10)],
)
source = ColumnDataSource(data)

columns = [
TableColumn(field=“dates”, title=“Date”, formatter=DateFormatter()),
TableColumn(field=“downloads”, title=“Downloads”),
]

my_enumeration = enumeration(“checkbox”)
my_Enum = Enum( my_enumeration )

data_table = DataTable(source=source, columns=columns, width=400, height=280)
data_table.selectable = my_Enum

show(widgetbox(data_table))


However, as can be seen by running this code (adapted only slightly from http://bokeh.pydata.org/en/latest/docs/user_guide/interaction/widgets.html#data-table ), this produces an error:

Traceback (most recent call last):
File “dt_test.py”, line 32, in
data_table.selectable = my_Enum
File “/usr/local/lib/python2.7/dist-packages/bokeh/core/has_props.py”, line 274, in setattr
super(HasProps, self).setattr(name, value)
File “/usr/local/lib/python2.7/dist-packages/bokeh/core/property/descriptors.py”, line 495, in set
self._internal_set(obj, value, setter)
File “/usr/local/lib/python2.7/dist-packages/bokeh/core/property/descriptors.py”, line 713, in _internal_set
value = self.property.prepare_value(obj, self.name, value)
File “/usr/local/lib/python2.7/dist-packages/bokeh/core/property/bases.py”, line 290, in prepare_value
raise e
ValueError: expected an element of either Bool or Enum(‘checkbox’), got <bokeh.core.properties.Enum object at 0x7f287fcca1d0>

This feels like it should be obvious, but has me rather stumped: as fas as I can see, the above approach to creating an Enum ( Enumeration ( xxxx ) ) is the same procedure followed throughout the codebase for other attributes which are defined with an enumeration (eg, those listed at http://bokeh.pydata.org/en/latest/docs/reference/core/enums.html). However, after a number of attempts and a lot of playing around with Enum and enumerate, I’ve not been able to find anything that works.

It’s the end of the day here, so I expect I am simply misunderstanding something/making a simple error; I’m sure someone can advise.

Any guidance? Has anyone succeeded with checkbox selection on a data table? (I am using bokeh 0.12.6, Python 2.7.6)

Many thanks,
Sarah

Any luck on code so that we can select a datatable row and get a plot generated for the same? Thanks,harsh