☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

DataCube - changing underlying data using source.change.emit() resulted in Uncaught TypeError

Community Support
wiseleywu
wiseleywu

Hi All,

Previously, I have a functional python script that generates a static html page using DataTable widget. I use CustomJS and js_on_change in order to add ability for user to filter the data in DataTable using dropdown menu, checkboxes, etc. Essentially, based on the filter criteria, I emptied out my subset data object, and run a for loop on my main source data object to obtain data I need and append back into my subset data object. Here’s the sample code, where source is my main data and s is my subset data :

var f = d1.value;
var g = mc1.active.map(a => mc1.labels[a]);
var h = mc2.active.map(b => mc2.labels[b]);
var colNames = Object.keys(s.data);
var t_names =  [];

# remove existing data in subset
for (var i=0; i < colNames.length; i++) {
  var colName = colNames[i];
  s.data[colName] = []
}

# append filtered data back into subset
for (var j=0; j < source.get_length(); j++) {
    if (
         (source.data['column_name_1'][j] == f) & 
         (g.includes(source.data['column_name_2'][j])) &
         (h.includes(source.data['column_name_3'][j])) &
         ((!sa3.active) || (source.data['column_name_4'][j] < cutoff))
       ) {
       var t_name = source.data['column_name_5'][j];
       if (!t_names.includes(t_name)) {t_names.push(t_name)}
       for (var k=0; k < colNames.length; k++) {
          var colName = colNames[k];
          s.data[colName].push(source.data[colName][j])
    }
  }
}
s.change.emit();

Currently, I’m trying out DataCube widget instead. On its own, the widget works fine with static data. As soon as I change my previous code (that dynamically changes data based on user filter input) using DataCube, I got the following traceback:

bokeh-1.4.0.min.js:formatted:4224 Uncaught TypeError: Cannot read property 'slice' of undefined
    at e.getItemMetadata (bokeh-tables-1.4.0.min.js:formatted:10559)
    at appendRowHtml (bokeh-tables-1.4.0.min.js:formatted:6708)
    at renderRows (bokeh-tables-1.4.0.min.js:formatted:6992)
    at render (bokeh-tables-1.4.0.min.js:formatted:7030)
    at SlickGrid.invalidate (bokeh-tables-1.4.0.min.js:formatted:6758)
    at e.t.updateGrid (bokeh-tables-1.4.0.min.js:formatted:742)
    at e.<anonymous> (bokeh-tables-1.4.0.min.js:formatted:703)
    at t.n.emit (bokeh-1.4.0.min.js:formatted:4224)
    at t.emit (bokeh-1.4.0.min.js:formatted:4238)
    at eval (eval at get (bokeh-1.4.0.min.js:formatted:18365), <anonymous>:56:10)

What it’s trying to do is called this.column.slice(1), and I have no idea what this is. This error is caused by the last line of my customJS’s emit function. It doesn’t seem like it’s using the subset data object at all, since I tried adding a columns attribute to the object but still resulted in the same error.

Any idea what might have happened? There are not many documentations and stack overflow topic on DataCube so I’m kinda at a loss.

Thank you for the help!

⌁   Link to post
Bryan
Bryan

DataCube was added by an outside contributor. It probably should have been marked something like “Experimental”, but we have not formally developed such a notion or guidelines for applying it. In any case, it’s not really possible to say much without actual code to execute. If you can provide such complete, minimal example, I am happy to take a quick look it.

⌁   Link to post
wiseleywu
wiseleywu

Hi Bryan, thank you for offering to help!

I have reduced it to a minimal example:

from bokeh.io import output_file, save
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import DataTable, TableColumn, Select, DataCube, GroupingInfo
from bokeh.layouts import column, layout
import pandas as pd

output_file("datacube_example.html")

df = pd.DataFrame({'name':['A','B','C','A','B','C','A','B','C','A','B','C',],
                   'value':[1,2,3,4,5,6,7,8,9,10,11,12]})

# source are where all data are stored, subset are the data being displayed
source = ColumnDataSource(df.to_dict('list'))
subset = ColumnDataSource(df[df.name == 'B'].to_dict('list'))


target = ColumnDataSource(data=dict(row_indices=[], labels=[]))

columns = [
    TableColumn(field='name', title='Name', width=100, sortable=False),
    TableColumn(field='value', title='value', width=100, sortable=False)
]

grouping = [
    GroupingInfo(getter='name', collapsed=False)
]

# data table definition
data_table = DataTable(source=subset,
                       columns=columns,
                       fit_columns=True,
                       header_row=True,
                       index_position=None,
                       reorderable=False)


cube = DataCube(source=subset, columns=columns, grouping=grouping, target=target)


# Experiment Dropdown Menu
d1 = Select(value='B', options=sorted(list(df.name.unique())))

# main js block to fill table with data based on user's selection
c1 = CustomJS(args=dict(source=source, s=subset, d1=d1), code="""
var f = d1.value;
var colNames = Object.keys(s.data);
for (var i=0; i < colNames.length; i++) {
  var colName = colNames[i];
  s.data[colName] = []
}

for (var j=0; j < source.get_length(); j++) {
    if (
         (source.data['name'][j] == f)
       ) {
       for (var k=0; k < colNames.length; k++) {
          var colName = colNames[k];
          s.data[colName].push(source.data[colName][j])
    }
  }
}
s.change.emit();

""")

# dropdown callback
d1.js_on_change('value', c1)


report = layout([
    column(d1),
    column(data_table)  # replace with column(cube) to see the error
    ]
)

save(report)

This will generate a html file. Using column(data_table) generates no error, while using column(cube) will result in the error I mentioned previously as soon as you select a different value in the dropdown menu.

Thanks!

⌁   Link to post

End of archived discussion · Replies are disabled