0
votes

Can someone explain, why this doesn't do anything and how I can print values from inside the callback function? Problem must lay in the callback function. I want my plot to be updated by the date range slider in a standalone html file, but nothing happens, when I change the values of the slider.

import numpy as np
import pandas as pd
from datetime import datetime
from bokeh.models import ColumnDataSource, DatetimeTickFormatter, HoverTool
from bokeh.models.widgets import DateRangeSlider
from bokeh.layouts import layout, column
from bokeh.models.callbacks import CustomJS
from bokeh.plotting import figure, output_file, show, save

datesX = pd.date_range(start='2018-01-02', periods=100)
# valuesY = pd.DataFrame(np.random.randint(0,25,size=(100, 1)), columns=list('A'))
np.random.seed(0)
valuesY  = np.random.rand(100)

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

# output to static HTML file
output_file('file.html')

hover = HoverTool(tooltips=[('Timestamp', '@x{%Y-%m-%d %H:%M:%S}'), ('Value', '@y')], formatters={'@x': 'datetime'})
    
date_range_slider = DateRangeSlider(title="Zeitrahmen", start=datesX[0], end=datesX[99], \
                                        value=(datesX[0], datesX[99]), step=1, width=1000)

# create a new plot with a title and axis labels
p = figure(title='file1', x_axis_label='Date', y_axis_label='yValue',  x_axis_type='datetime', 
               tools="pan, wheel_zoom, box_zoom, reset", plot_width=1000, plot_height=700)

# add a line renderer with legend and line thickness
    
p.line(x='x', y='y', source=source, line_width=2)
p.add_tools(hover)
       
callback = CustomJS(args=dict(source=source), code="""
    var data = source.data;
    var a = cb_obj.value;
    var xmin = a[0];
    var xmax = a[1];
    var x = data['x'];
    var y = data['y'];
    
    for (var i = 0; i < x.length; i++) {
        if (data['x'][i] == xmin){
            startidx = i;       
        }
        if (data['x'][i] == xmax){
            endidx = i;
        }
    }
    
    int j=0;
    while(j <= endidx-startidx){
        x[j] = data['x'][startidx+j];
        y[j] = data['y'][startidx+j];
        j++;
    }

    source.change.emit();
    """)
    
date_range_slider.js_on_change('value', callback)
layout = column(p, date_range_slider)

# show the results
show(layout)
1

1 Answers

0
votes

When developing JS callbacks, it is essential to learn how to view your browser's JavaScript console. This differs by browser so you will have to search how to access the console on whatever specific browser you are using.

Once you can see the console, you will see that your code has an error:

SyntaxError: Unexpected identifier 'j'

because you have int j instead og var j in your callback code. It that is fixed, there is then another error:

ReferenceError: Can't find variable: endidx

It's not really clear what you you actually want to happen, so it's not really possible to try to actually fix the code completely, but hopefully this gives you the information you need to properly do the debugging yourself. Some other tips for debugging:

  • to "print" in console, use console.log(...)

  • you can also add the command debugger in the callback code. If you run the Bokeh script with BOKEH_MINIFIED=no and the browser dev tools window open, then the exectution will stop at that point and you can single step through the code.