Example needed for datatable

Hi all,

Can someone please provide an example below.
when we click on a data table row , it should create another data table.

Thanks,

For a Bokeh server application? For standalone (static HTML, no server) output? What should happen if the user multi-selects? Where does the data for the other table come from? The question is too broad and vague and underspecified. In general the Discourse is for getting help with specific technical questions (similar to SO) and not a code-writing site. The best way to utilize the expertise here is to make some minimal attempt to code what you are looking for, so that you can then ask targeted questions about particular issues.

1 Like

@Bryan, I was trying as below, when i click on any row of the table, it should just print same row only in another datatable so datasource remains same. With below code if click on any row nothing is generated.

from bokeh.models import DataTable, TableColumn, ColumnDataSource, Div, CustomJS
from bokeh.layouts import row
from bokeh.plotting import show
from bokeh.plotting import figure, show
from bokeh.plotting import curdoc

x = [2, 4, 8]
y = [3, 6, 9]

cds = ColumnDataSource(data={'x': x, 'y': y})

columns = [
    TableColumn(field='x', title='X'),
    TableColumn(field='y', title='Y'),
]
main_fig = DataTable(source=cds, columns=columns, width=400, height=400)

child_fig = DataTable(source=cds, columns=columns, width=400, height=400)

my_row = row(main_fig, Div())

change_child_callback = CustomJS(args=dict(my_row=my_row, x=x, y=y, child_fig=child_fig), code="""
  console.log(cb_obj.indices)
  var children = [...my_row.children]
  children[1] = child_fig[cb_obj.indices[0]]
  my_row.children = children 
  """)

cds.selected.js_on_change('indices', change_child_callback)

source = ColumnDataSource(data=dict({'x': x, 'y':y}))

show(my_row)

Hi @Bryan, It took me some time to implement but finally got it after going thru some bokeh documentation. Sharing code as below.

from bokeh.models import DataTable, TableColumn, ColumnDataSource, Div, CustomJS
from bokeh.layouts import row,Column
from bokeh.plotting import show
from bokeh.io import show
from bokeh.models import ColumnDataSource, HoverTool, DataTable, TableColumn, CDSView, CustomJS, IndexFilter
from bokeh.models import HTMLTemplateFormatter

from bokeh.plotting import figure

## data for main table
x = ['AP', 'BF', 'TCS', 'INFY', 'SBI', 'IPL']
y = [4, 8, 2, 7, 4, 6]
status = ['Completed','Completed','Completed','Completed','Completed','Failed']
color =  ['#90EE90','#90EE90','#90EE90','#90EE90','#90EE90','#FF7F7F']

template="""
<div style="background:<%=color%>"; color="white";>
<%= value %></div>
"""

formater =  HTMLTemplateFormatter(template=template)

## data for child table
a = [3, 4, 8, 5, 9, 3,3, 4, 8, 5, 9, 3,3, 4, 8, 5, 9, 3,3, 4, 8, 5, 9, 3]
b = [7, 8, 2, 7, 4, 6,7, 8, 2, 7, 4, 6,7, 8, 2, 7, 4, 6,7, 8, 2, 7, 4, 6]
c = [9, 8, 2, 7, 4, 6,9, 8, 2, 7, 4, 6,9, 8, 2, 7, 4, 6,9, 8, 2, 7, 4, 6]
d = ['AP', 'SBI', 'TCS', 'BF', 'INFY', 'BF','AP', 'SBI', 'IPL', 'BF', 'INFY', 'BF','AP', 'SBI', 'TCS', 'BF', 'INFY', 
     'BF','AP', 'SBI', 'IPL', 'BF', 'INFY', 'BF']

### main table datasource
cds = ColumnDataSource(data={'x': x, 'y': y, 'color':color})    

## child table data source
dt_ds = ColumnDataSource(data={'a': a, 'b': b, 'c':c, 'd':d})   

## coulmns of main data table
columns = [
    TableColumn(field='x', title='X',formatter=formater),
    TableColumn(field='y', title='Y',formatter=formater),
          ]

## columns of child data table
columns1 = [
    TableColumn(field='a', title='A'),
    TableColumn(field='b', title='B'),
    TableColumn(field='c', title='C'),
    TableColumn(field='d', title='D'),
          ]

## child datatable
dt = DataTable(source=dt_ds,columns=columns1, width=1000,height=300,
                       view=CDSView(source=dt_ds,filters=[IndexFilter(indices=[])]))

## main datatable 
source_main = DataTable(source=cds, columns=columns, width=400, height=200)


## Callback on main data source
cds.selected.js_on_change('indices',
                           CustomJS(args=dict(cds=cds,view=dt.view),
                                    code="""\
                                        const {indices} = cb_obj;
                                        if (indices.length > 0) {
                                            const idx = indices[0];
                                            const word = cds.data['x'][idx]
                                            console.log(word)
                                            const GroupFilter = Bokeh.Models('GroupFilter');
                                            view.filters = [new GroupFilter({column_name: 'd', group: word})];
                                        } else {
                                            const IndexFilter = Bokeh.Models('IndexFilter');
                                            view.filters = [new IndexFilter({indices: []})];
                                        }
                                        view.source.change.emit();
                                    """))


## for representation purpose

layout = Column(source_main, dt)
show(layout)
1 Like

Hi @Bryan, I am running above solution on Jupyter notebook. I don’t want second table to appear until i click on some row from first table. Any suggestion on how to achieve this.
Currently when i execute the above code second table column structure is also appearing even before click event.

Thanks.

I was able to fix it using dt.visible=False before click event and added dt.visible=true in call back code.

1 Like