
Hello,
I currently work on a program to analyse some data through a standalone html created in bokeh. I would like to give the user the option to load xy-data from a csv/txt file through a JS callback. I am currently doing the following and I am not sure, why it is not working.
import bokeh
import pandas as pd
from bokeh import events
from bokeh.io import show, output_file
from bokeh.plotting import figure, output_file, show
from bokeh.models.widgets import Button
from bokeh.layouts import Column
from bokeh.models import HoverTool, CustomJS,AjaxDataSource, ColumnDataSource
output_file('jsreadcsv.html')
d = {'x': [1000,20000], 'y': [0,1]}
df=pd.DataFrame(data=d)
source=ColumnDataSource(df)
js_upload2 = CustomJS(args=dict(source=source), code="""
var xydat=source.data;
var input = document.createElement('input');
input.type = 'file';
delimiter = '\t'
input.onchange = e => {
for(i=xydat['x'].length-1; i >= 0; i--){
xydat['x'].splice(i,1);
xydat['y'].splice(i,1);
}
// getting a hold of the file reference
var file = e.target.files[0];
// setting up the reader
var reader = new FileReader();
reader.readAsText(file,'UTF-8');
// here we tell the reader what to do when it's done reading...
reader.onload = readerEvent => {
var content = readerEvent.target.result; // this is the content!
///console.log( content );
var lines = content.split('\\n')
for(i=10; i < lines.length; i++){
line = lines[i].split('\\t')
xydat['x'].push(parseFloat(line[0]))
xydat['y'].push(parseFloat(line[1]))
}
/// Find maximum and normalise data
max_y=0.0
for(i=0; i < xydat['y'].length; i++){
if(xydat['y'][i] > max_y){
max_y = xydat['y'][i];
}
}
for(i=0; i < xydat['y'].length; i++){
xydat['y'][i] = xydat['y'][i] / max_y;
}
console.log(xydat['x'])
console.log(xydat['y'])
source.change.emit();
}
}
input.click();
""")
Button_load = Button(name='loadfile')
Button_load.js_on_click(js_upload2)
p=figure(plot_width = 950, plot_height = 600,x_axis_label = 'x', y_axis_label = 'y', tools=['pan,wheel_zoom, reset'], )
p.line(x='x', y='y', color='black', source=source)
layout = Column(Button_load,p)
show(layout)
I am really not sure why it does not work. I get a “inconsistent column length in the JS console”. I don’t understand why.
Thank you very much for your help in advance!
Daniel
. Unfortunately, I don’t think it directly applies to my case 

