Hi,
I have a last feature in my dashboard that I can seems to get working properly. I have a data table and added the pointdrawtool so the user would be able to remove outliers by clicking on the plot. I tried this separately on a code without the CDSView in it and it deleted the rows from the table when the user clicked on a point and pressed backspace. But when adding that snippet of code to the code below. Its doing weird stuff. Not entirely sure what is happening when the user clears a point from the plot. I have added the code below for anyone who wants to try and see if they understand the issue.
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource, PointDrawTool, BooleanFilter, MultiSelect, CustomJSTransform
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.transform import transform
output_file("data_table.html")
x=[randint(0, 100) for i in range(10)]
y=[randint(0, 100) for i in range(10)]
total = np.sum([x, y], axis = 0)
source = ColumnDataSource(dict(x=x,
y=y,
total = total,
temp_int=['(20, 30]', '(40, 50]', '(20, 30]', '(20, 30]', '(40, 50]', '(20, 30]', '(20, 30]', '(20, 30]', '(20, 30]', '(40, 50]'],
matrix_names=['ras', 'das', 'ras', 'das', 'das', 'bas', 'ras', 'ras', 'ras', 'bas'],
names=['a', 'b', 'c', 'c', 'd', 'd', 'a', 'a', 'c', 'c'],
name_id=['a-5', 'b-1', 'c-1', 'c-1', 'd-1', 'd-1', 'a-2', 'a-5', 'c-2', 'c-2']))
sourceNew = ColumnDataSource(dict(x=x, y=y, total = total))
columns = [
TableColumn(field="x", title="x"),
TableColumn(field="y", title="y"),
TableColumn(field="total", title="total"),
TableColumn(field="temp_int", title="temp_int"),
TableColumn(field="matrix_names", title="matrix_names"),
TableColumn(field="name_id", title="name_id"),
]
TOOLS = "pan,wheel_zoom,box_select,reset"
options = sorted(set(source.data['names']))
initial_value = [options[0]]
b = BooleanFilter([x in initial_value for x in source.data['names']])
ms = MultiSelect(title='MC Experiment:', value=initial_value, options=options)
id_options = sorted(set(i for n, i in zip(source.data['names'], source.data['name_id'])
if n in initial_value))
initial_id_value = id_options#[id_options[0]]
b_id = BooleanFilter([x in initial_id_value for x in source.data['name_id']])
ms_id = MultiSelect(title='ID:', value=initial_id_value, options=id_options)
mn_options = sorted(set(source.data['matrix_names']))
mn_initial_value = [mn_options[0]]
b_mn = BooleanFilter([x in mn_initial_value for x in source.data['matrix_names']])
ms_mn = MultiSelect(title='Matrix Names:', value=mn_initial_value, options = mn_options)
ms.js_on_change('value', CustomJS(args=dict(f=b, source=source, columnName='names', ms_id=ms_id, ms_mn = ms_mn),
code="""\
const val = cb_obj.value;
f.booleans = Array.from(source.data[columnName]).map(d => val.includes(d != null && d.toString()));
// New lines.
const id_options = [...new Set(source.data.name_id.filter((_, idx) => f.booleans[idx]))];
id_options.sort();
ms_id.options = id_options;
ms_id.value = id_options;
const mn_options = [...new Set(source.data.matrix_names.filter((_, idx) => f.booleans[idx]))];
mn_options.sort();
ms_mn.options = mn_options;
ms_mn.value = mn_options;
source.change.emit();
"""))
ms_id.js_on_change('value', CustomJS(args=dict(f=b_id, source=source, columnName='name_id'),
code="""\
const val = cb_obj.value;
f.booleans = Array.from(source.data[columnName]).map(d => val.includes(d != null && d.toString()));
source.change.emit();
"""))
view = CDSView(source=source, filters=[b, b_id, b_mn])
tr = CustomJSTransform(v_func="return xs.map(x => 10 * x);")
fig = figure(plot_width=600, plot_height=600, tools=TOOLS)
plot = fig.scatter('x', transform('y', tr), view=view, source=source, color='red')
draw_tool = PointDrawTool(renderers=[plot])
fig.add_tools(draw_tool)
data_table= DataTable(source=source, columns=columns, view=view, width=600, height=600, editable = True)
source.callback = CustomJS(args=dict(source=source, sourceNew = sourceNew), code="""
var inds = cb_obj.indices;
var d1 = source.data;
var d2 = sourceNew.data;
d2['total'] = [];
console.log(d1['x'], d1['y'], d1['total']);
d2['total'].push(parseInt(d1['x']) + parseInt(d1['y']))
console.log(d2)
source.change.emit();
""")
show(row(column(fig, ms, ms_id, ms_mn), data_table))