I am attempting to add a Bokeh DataTable object via Flexx. Because it uses a ColumnDataSource, I assume that we can make it work very similarly to the BokehWidget for plots. Just as we create a figure, we can create a DataTable from a ColumnDataSource:
x_table = [randint(0, 100) for i in range(10)]
y_table = [randint(0, 100) for i in range(10)]
total = np.sum([x_table, y_table], axis = 0)
self.datatable_source = ColumnDataSource(dict(x=x_table, y=y_table, total = total))
datatable_columns = [TableColumn(field="x", title="x"),
TableColumn(field="y", title="y"),
TableColumn(field="total", title="total")]
self.data_table= DataTable(source=self.datatable_source,
# columns=datatable_columns,
width=600, height=600, editable = True)
I have created a modified BokehWidget object which works very similarly to the BokehWidget for plots:
def make_bokeh_widget_from_data_table(data_table, **kwargs):
ns = {}
exec("from bokeh.models.widgets import DataTable", ns, ns) # noqa - dont trigger e.g. PyInstaller
exec("from bokeh.embed import components", ns, ns) # noqa - dont trigger e.g. PyInstaller
DataTableClone, components = ns["DataTable"], ns["components"]
# Set plot prop
if not isinstance(data_table, DataTableClone):
raise ValueError('plot must be a Bokeh plot object.')
# The sizing_mode is fixed by default, but that's silly in this context
# if plot.sizing_mode == 'fixed':
# plot.sizing_mode = 'stretch_both'
# Get components and apply to widget
script, div = components(data_table)
script = '\n'.join(script.strip().split('\n')[1:-1])
widget = BokehWidgetAdapted(**kwargs)
widget.set_table_components(
dict(script=script, div=div, id=data_table.ref['id']))
return widget
class BokehWidgetAdapted(BokehWidget):
@classmethod
def from_data_table(cls, data_table, **kwargs):
""" Create a BokehWidget using a Bokeh plot.
"""
return make_bokeh_widget_from_data_table(data_table, **kwargs)
table = event.Attribute(doc="""The JS-side of the Bokeh plot object.""")
def _render_dom(self):
return None
@event.action
def set_table_components(self, d):
""" Set the plot using its script/html components.
"""
global window
# Embed div
self.node.innerHTML = d.div # We put trust in d.div
# "exec" code
el = window.document.createElement('script')
el.innerHTML = d.script
self.node.appendChild(el)
# Get plot from id in next event-loop iter
def gettable():
self._table = window.Bokeh.index[d.id]
self.__resize_table()
window.setTimeout(gettable, 10)
@event.reaction('size')
def __resize_table(self, *events):
if self.table and self.parent:
if self.table.resize_layout:
self.table.resize_layout()
elif self.table.resize:
self.table.resize() # older
else:
self.table.model.document.resize() # older still
To get these widgets working, the bokeh-tables.js, bokeh-widgets.js and bokeh-mathjax.js files are associated using app.assets.associate_asset. We can then try to add the Bokeh DataTable object:
This partially works! The table is rendered on the page, but the data is blank and no errors are thrown. Is there something I am missing here? I think this would be a great widget to add to Flexx to have support for tables via Bokeh. I think it should be extendable to most Bokeh widgets such as buttons, checkboxes, etc.
I am attempting to add a Bokeh DataTable object via Flexx. Because it uses a ColumnDataSource, I assume that we can make it work very similarly to the BokehWidget for plots. Just as we create a figure, we can create a DataTable from a ColumnDataSource:
I have created a modified BokehWidget object which works very similarly to the BokehWidget for plots:
To get these widgets working, the bokeh-tables.js, bokeh-widgets.js and bokeh-mathjax.js files are associated using app.assets.associate_asset. We can then try to add the Bokeh DataTable object:
This partially works! The table is rendered on the page, but the data is blank and no errors are thrown. Is there something I am missing here? I think this would be a great widget to add to Flexx to have support for tables via Bokeh. I think it should be extendable to most Bokeh widgets such as buttons, checkboxes, etc.