def _tap_callback(comptable_cds, div_content, io_generator): """ Javacript function to animate tap events and show component info on the right Parameters ---------- CDS: bokeh.models.ColumnDataSource Data structure containing a limited set of columns from the comp_table div: bokeh.models.Div Target Div element where component images will be loaded io_generator: tedana.io.OutputGenerator Output generating object for this workflow Returns ------- CustomJS: bokeh.models.CustomJS Javascript function that adds the tapping functionality """ return models.CustomJS( args=dict( source_comp_table=comptable_cds, div=div_content, outdir=io_generator.out_dir, ), code=tap_callback_jscode, )
def gen_upd_plot(event): try: ls_tab = [] if inp_gen_upd.label != "Update": cmst_upd = get_dataset() for k in cmst_upd.time_selector: pdf_ts[k] = bmo.ColumnDataSource(data=cmst_upd.get_pandas_df(k)) # Create panel ls_tab.append(create_panel(k)) tabs = bo.layouts.column([ bo.layouts.row([inp_xaxis, inp_yaxis]), bo.layouts.row([bmo.widgets.Tabs(tabs=ls_tab, width=800)]), ]) l.children[-1] = tabs inp_gen_upd.label = "Update" else: cmst_upd = get_dataset() pdf_ts_upd = {} for k in cmst_upd.time_selector: pdf_ts_upd = bmo.ColumnDataSource(data=cmst_upd.get_pandas_df(k)) pdf_ts[k].data.update(pdf_ts_upd.data) dct_buttons[k].callback = bmo.CustomJS(args=dict(source=pdf_ts[k], filename="{}_{}_{}.csv".format(k, inp_time_mean.value, inp_exp.value)), code=open(join(dirname(__file__), "download.js")).read()) hide_spinner() except: div_spinner.text="""
def add_callback(widget, prop): lines = [l1, l2, l3, l4] widget.callback = models.CustomJS(args=dict(widget=widget), code=""" for ( var i = 0; i < %s; i++ ) { var g = eval( 'line' + i ).get( 'glyph' ); g.set( '%s', widget.get( 'value' ) ); window.g = g; } """ % (len(lines), prop)) for i, line in enumerate(lines): widget.callback.args['line%i' % i] = line
def layout(self): source = bkmod.AjaxDataSource(data_url=self.data_url, \ polling_interval=self.interval, mode='replace', method="GET") callback = bkmod.CustomJS(args=dict(source=source), code=""" //console.log(source); var name = cb_obj.attributes.name if(name == "fs"){{ source.fs = cb_obj.value }} if(name == "f"){{ source.f = cb_obj.value }} // set default value var fs = (typeof source.fs === 'undefined') ? 1000 : source.fs; var f = (typeof source.f === 'undefined') ? 5 : source.f; source.data_url = "{}/"+fs+"/"+f; source.get_data('replace'); """.format(self.data_url)) slider_fs = bkmod.widgets.Slider(start=100, end=2000, value=1000, step=50, name="fs", callback=callback) slider_f = bkmod.widgets.Slider(start=1, end=20, value=5, step=1, name="f", callback=callback) #button = bkmod.widgets.Button(label="Update", button_type="success",callback=callback, name="update") #streaming=True source.data = dict(x=[], yn=[], y=[]) fig = bkplt.figure(title="Streaming Example") if self.plot == "line": fig.line('x','y', source=source, legend="sine", \ line_color="orange", line_width=4) fig.line('x', 'yn', legend="sine noise", alpha=0.1, source=source) if self.plot == "scatter": fig.line('x','y', source=source, legend="sine", \ line_color="orange", line_width=4) fig.scatter('x', 'yn', legend="sine noise", alpha=0.05, source=source) script, div = bkembed.components(bk.layouts.layout([[slider_fs,slider_f],\ [fig]], responsive=False, sizing_mode="scale_width")\ , bkres.INLINE) plot = {"title": self.title, "plot": div, "script": script} return plot
def table_widget(entry): from bokeh.models import ColumnDataSource from bokeh.models.widgets import DataTable, TableColumn entry_dict = copy(entry.__dict__) print(entry_dict.keys()) # Note: iterate over old dict, not the copy that is changing for k, v in entry.__dict__.items(): if k == "id" or k == "_sa_instance_state": del entry_dict[k] # use _units keys to rename corresponding quantity if k[-6:] == "_units": prop = k[:-6] new_key = "{} [{}]".format(prop, entry_dict[k]) del entry_dict[k] entry_dict[new_key] = entry_dict.pop(prop) # order entry dict entry_dict = OrderedDict([(k, entry_dict[k]) for k in sorted(list(entry_dict.keys()))]) data = dict( labels=[str(k) for k in entry_dict], values=[str(v) for v in entry_dict.values()], ) source = ColumnDataSource(data) columns = [ TableColumn(field="labels", title="Properties"), TableColumn(field="values", title="Values"), ] data_table = DataTable( source=source, columns=columns, width=500, height=570, index_position=None, fit_columns=False, ) json_str = json.dumps(entry_dict, indent=2) btn_download_table.callback = bmd.CustomJS( args=dict(string=json_str, filename=entry_dict["name"] + ".json"), code=download_js, ) return widgetbox(data_table)
def add_updated_local_time_callback(self): """Add callbacks to display the last-updated time in the browser-local timezone. """ # Unfortunately, getting the timezone to show in the users's local time # (instead of the server timezone) was tricky - the only thing that # "knows" the local time is the browser, which means the updated time # display string has to be updated via a javascript-callback; # unfortunately, getting a javascript callback to fire just once, when # the whole graph is first built (and not when, say, the user clicks a # button) proved problematic - the only way I found was to make use # of a periodic_callback, which modified a value that a javascript # on change callback was watching. # Thanks to _jm and Bryan for their responses on this thread: # https://discourse.bokeh.org/t/how-to-display-last-updated-information-in-local-time/5870 update_time_cds = mdl.ColumnDataSource( data={'t': [self.model.last_update_time()]}) update_text_cb = mdl.CustomJS(args=dict(source=update_time_cds), code=""" var localUpdateTime = new Date(source.data['t'][0]) cb_obj.text = "Updated: " + localUpdateTime.toString(); """) self.updated.js_on_change('text', update_text_cb) periods_holder = [0] def modify_updated_time_placeholder(*args, **kwargs): if not self.updated.text.startswith(self.UPDATE_FETCHING): # print("periodic_callback removed...") self.doc.remove_periodic_callback(periodic_callback) return # Just cycle between values with 1 to 3 trailing "." - this just # makes sure that the value is always changed, so that as soon # as javascript is "available", the javascript "on change" callback # will fire. num_periods = periods_holder[0] # print("periodic_callback fired! {} - {} - {}" # .format(num_periods, args, kwargs)) periods_holder[0] = num_periods + 1 ellipsis = '.' * (num_periods % 3 + 1) self.updated.text = self.UPDATE_FETCHING + ellipsis periodic_callback = self.doc.add_periodic_callback( modify_updated_time_placeholder, 1000)
def table_widget(entry): # disable=redefined-outer-name """Create table widget.""" from bokeh.models import ColumnDataSource from bokeh.models.widgets import DataTable, TableColumn entry_dict = copy(entry.__dict__) # Note: iterate over old dict, not the copy that is changing for k, _v in entry.__dict__.items(): if k in ['id', '_sa_instance_state']: del entry_dict[k] # use _units keys to rename corresponding quantity if k[-6:] == '_units': prop = k[:-6] new_key = '{} [{}]'.format(prop, entry_dict[k]) del entry_dict[k] entry_dict[new_key] = entry_dict.pop(prop) # order entry dict entry_dict = OrderedDict([(k, entry_dict[k]) for k in sorted(list(entry_dict.keys()))]) data = dict( labels=[str(k) for k in entry_dict], values=[str(v) for v in entry_dict.values()], ) source = ColumnDataSource(data) columns = [ TableColumn(field='labels', title='Properties'), TableColumn(field='values', title='Values'), ] data_table = DataTable(source=source, columns=columns, width=500, height=570, index_position=None, fit_columns=False) json_str = json.dumps(entry_dict, indent=2) btn_download_table.callback = bmd.CustomJS(args=dict( string=json_str, filename=entry_dict['name'] + '.json'), code=download_js) return widgetbox(data_table)
def _create_multiline_multiselect_callback( source: bm.ColumnDataSource) -> bm.CustomJS: full_source = bm.ColumnDataSource(source.data) callback: bm.CustomJS = bm.CustomJS( args=dict(source=source, full_source=full_source), code=""" const indices = cb_obj.value.map(x => parseInt(x)); let items = ['xs', 'ys', 'color', 'legend']; for (const item of items) { let full_item = full_source.data[item]; source.data[item].length = 0; for (var i of indices) { source.data[item].push(full_item[i]); } } source.change.emit() """, ) return callback
def create_panel(k): # Create plot p[k] = bpl.figure(tools=[TOOLS,hover],toolbar_location="right") p[k].circle(x=inp_xaxis.value, y=inp_yaxis.value, source = pdf_ts[k], size=12) p[k].xaxis.axis_label = "climate change signal {}".format(inp_xaxis.value) p[k].yaxis.axis_label = "climate change signal {}".format(inp_yaxis.value) # Horizontal line hline = bmo.Span(location=0, dimension='width', line_color='black', line_width=3) vline = bmo.Span(location=0, dimension='height', line_color='black', line_width=3) p[k].renderers.extend([vline, hline]) # Create table columns = [ bmo.widgets.TableColumn(field="index", title="model"), bmo.widgets.TableColumn(field="{}".format(inp_xaxis.value), title="{}".format(inp_xaxis.value.title()), width=65,formatter=bmo.NumberFormatter(format="0.000")), bmo.widgets.TableColumn(field="{}_percentiles".format(inp_xaxis.value), title="{} Perc.".format(inp_xaxis.value.title()), width=70,formatter=bmo.NumberFormatter(format="0.000")), bmo.widgets.TableColumn(field="{}".format(inp_yaxis.value), title="{}".format(inp_yaxis.value.title()), width=65,formatter=bmo.NumberFormatter(format="0.000")), bmo.widgets.TableColumn(field="{}_percentiles".format(inp_yaxis.value), title="{} Perc.".format(inp_yaxis.value.title()), width=70,formatter=bmo.NumberFormatter(format="0.000")), ] data_table = bmo.widgets.DataTable(source=pdf_ts[k], columns=columns, fit_columns=False, selectable='checkbox', height=p[k].plot_height-100, index_position=None) down_button = bmo.widgets.Button(label="Download CSV", button_type="primary") down_button.callback = bmo.CustomJS(args=dict(source=pdf_ts[k], filename="{}_{}_{}.csv".format(k, inp_time_mean.value, inp_exp.value)), code=open(join(dirname(__file__), "download.js")).read()) dct_buttons[k] = down_button l_panel = bo.layouts.row([ bo.layouts.column([p[k]]), bo.layouts.column([down_button, data_table]), ]) panel = bmo.widgets.Panel(child=l_panel, title=time_description[k]) return panel
def build_save_button(self): save_button = mdl.Button(label='Save/Share', button_type="success") # want to have a click call python code (to calculate the url), and # then javascript (to do the dialog) # only way to do this that I found was to chain callbacks, as shown here # (thanks ChesuCR): # https://stackoverflow.com/a/49095082/920545 # We trigger the JS callback on a change to "tags" since that shouldn't # affect anything else js_code = r""" prompt("Copy the following url to save this graph:", url); """ js_callback = mdl.CustomJS(code=js_code) save_button.js_on_change("tags", js_callback) def on_click(): querystr = self.model.to_query_str() # TODO: don't hardcode directory portion host = self.doc.session_context.request.headers['Host'] url = f'http://{host}/covid19?{querystr}' # we could change js_callback.code, but easier to change args js_callback.args = {'url': url} # now trigger the javascript, by changing tags tags = save_button.tags SENTINEL = 'click_toggle' if SENTINEL in tags: tags.remove(SENTINEL) else: tags.append(SENTINEL) # this should trigger the javascript save_button.tags = tags save_button.on_click(on_click) return save_button
# j2sPath="https://www.materialscloud.org/discover/scripts/external/jsmol/j2s", serverURL="detail/static/jsmol/php/jsmol.php", j2sPath="detail/static/jsmol/j2s", script="""set antialiasDisplay ON; load data "cifstring" {} end "cifstring" """.format(cif_str) ## Note: Need PHP server for approach below to work # script="""set antialiasDisplay ON; # load cif::{}; # """.format(get_cif_url(entry.filename)) ) btn_download_cif.callback = bmd.CustomJS(args=dict( string=cif_str, filename=entry.filename), code=download_js) script_source = bmd.ColumnDataSource() applet = JSMol( width=600, height=600, script_source=script_source, info=info, js_url="detail/static/jsmol/JSmol.min.js", ) df_tailcorrection, df_no_tailcorrection = get_results_df() if cof_name in used_block: plot_info_ = plot_info_blocked_pockets
def make_responsive_plot(prot, tag): #output_file("test_deg_def.html", title="line deg") title = tag fig_fit = get_base_plot(prot, title) #fig_fit.set(y_range=bkm.Range1d(-0.1, 1.1)) x_lim = prot.X[-1] + 0.1 X = np.arange(-0.1, x_lim, 0.1) Ys = model_syn(X, prot.N0, prot.tau, prot.offset) Yd = model_deg(X, prot.N0, prot.tau, prot.offset) params_start = [prot.N0, prot.tau, prot.offset, title] params = [prot.N0, prot.tau, prot.offset, title] diff = len(Yd) - len(params) add = [np.nan] * diff params_start += add params += add source = bkm.ColumnDataSource(data=dict( X=X, Ys=Ys, Yd=Yd, params_start=params_start, params=params, )) code = """ var data = source.get('data'); var params_start = data['params_start'] var X = data['X']; var Ys = data['Ys']; var Yd = data['Yd']; var params = data['params']; var title = params[3]; var f = cb_obj.get('value'); if (cb_obj.get('title') == 'N0') {N0 = cb_obj.get('value'); params[0] = N0;}; if (cb_obj.get('title') == 'tau') {tau = cb_obj.get('value'); params[1] = tau; }; if (cb_obj.get('title') == 'offset') {offset = cb_obj.get('value'); params[2] = offset;}; var N0 = parseFloat(params[0]); var tau = parseFloat(params[1]); var offset = parseFloat(params[2]); //console.log(params, 'here parms'); //console.log(N0, 'here N0'); //console.log(tau, 'here tau'); //console.log(offset, 'here offset'); //console.log(Ys, 'here Ys before'); //console.log(Yd, 'here Yd before'); for (i = 0; i < X.length; i++) { Ys[i] = 1 - ((N0 * Math.exp( -X[i]/tau )) + offset) ; } for (i = 0; i < X.length; i++) { Yd[i] = (N0 * Math.exp( -X[i]/tau )) + offset ; } var last_element = X[X.length - 1]; var residual = (N0 * Math.exp( -last_element/tau )) + offset //console.log(Ys, 'here Ys after'); //console.log(Yd, 'here Yd after'); source.trigger('change'); console.log(N0, 'here N0 after'); console.log(tau, 'here tau after'); console.log(offset, 'here offset after'); console.log( tau / Math.log(2) ,'here half life') //$("field_name_1").update(tau/Math.log(2)); //$("field_name_2").update(tau); //$("field_name_3").update(offset); $('#field_name_1').text(Math.round(tau/Math.log(2)* 100)/100); $('#field_name_2').text(Math.round(residual * 100)/100); //$('#field_name_3').text(offset); //document.getElementById("field_name_1").innerHTML = N0; // $( ".hello" ).remove(); //var $new = $('<div class="hello"></div>').appendTo('.insert_body'); //http://stackoverflow.com/questions/247483/http-get-request-in-javascript //function httpGet(theUrl) //{ //var xmlHttp = new XMLHttpRequest(); //xmlHttp.open( "GET", theUrl, false ); // false for synchronous request //xmlHttp.send( null ); //return xmlHttp.responseText; //} //var address = '{web_address}find_intersection?N0='+N0+'&tau='+tau+'&c='+offset //var res = httpGet(address); //console.log(res, 'test'); //if (title == 'Bloodstrem'){ //console.log('new_intersection_bs'); //$("#new_intersection_bs").html('new intersection: '+res); //} //if (title == 'Procyclic'){ // $("#new_intersection_pc").html('new intersection: '+res); //} //res = httpGet(address) //console.log(res, 'test'); //ras = $.get("address"); //req.open('GET', address, false); // //console.log(address); """ #code = code.replace('{web_address}', web_adress) callback = bkm.CustomJS(args=dict(source=source), code=code) sliderN0 = bkm.Slider(start=0, end=1, value=prot.N0, step=.01, title="N0", name='N0', callback=callback) sliderTau = bkm.Slider(start=0.1, end=50, value=prot.tau, step=.01, title="tau", name='tau', callback=callback) sliderOffSet = bkm.Slider(start=0, end=1, value=prot.offset, step=.01, title="offset", name='offset', callback=callback) syn = fig_fit.line(x='X', y='Ys', source=source, color='green') deg = fig_fit.line(x='X', y='Yd', source=source, color='red') legend = Legend(items=[("syn", [syn]), ("deg", [deg])], location=(10, -30)) #fig_fit.legend.location = (0, -30) #layout = vform(fig_fit) #script, div = components(layout) #layout = vform() #script_bar, div_bar = components(layout) #show(layout( #[[fig_fit],[sliderN0],[sliderTau],[sliderOffSet]] #)) fig_fit.add_layout(legend, 'right') #show(layouts.column(fig_fit, sliderN0, sliderTau, sliderOffSet)) script, div = components( layouts.column(fig_fit, sliderN0, sliderTau, sliderOffSet)) return script, div
value="tasmax", options=["tasmin", "tasmax", "pr", "rsds"]) inp_yaxis = bmo.widgets.Select(title="Y-Axis:", value="pr", options=["tasmin", "tasmax", "pr", "rsds"]) inp_xaxis.on_change('value', upd_axis) inp_yaxis.on_change('value', upd_axis) inp_country.on_change('value', upd_lat_lon) # Handle on click_events (unfortunately show spinner with js due to lag otherwise) inp_gen_upd.on_event(bo.events.ButtonClick, gen_upd_plot) inp_gen_upd.js_on_event( bo.events.ButtonClick, bmo.CustomJS(args=dict(div_spinner=div_spinner, spinner_text=spinner_text), code=show_spinner_js)) inputs = bo.layouts.row([ bo.layouts.column([ bo.layouts.row([inp_lat, inp_lon, inp_country]), bo.layouts.row([inp_time_mean, inp_exp]), bo.layouts.row([inp_gen_upd]) ]), bo.layouts.column([ bo.layouts.row([div_spinner]), ]), ]) l = bo.layouts.layout([ bo.layouts.row([div_desc]), inputs,
def generate_plot(data, df_all_prediction): COLORS = d3["Category10"][10] tooltips = f""" <div> <p> <span style="font-size: 12px; color: black;font-family:century gothic;">Nombre de cas : </span> <span style="font-size: 12px; color: {COLORS[0]}; font-weight: bold;font-family:century gothic;">@total_cases</span> <br> <span style="font-size: 12px; color: black;font-family:century gothic;">Nombre de nouveaux cas : </span> <span style="font-size: 12px; color: {COLORS[1]}; font-weight: bold;font-family:century gothic;">@new_cases</span> <br> <span style="font-size: 12px; color: black;font-family:century gothic;">Nombre de deces : </span> <span style="font-size: 12px; color: {COLORS[3]}; font-weight: bold;font-family:century gothic;">@total_deaths</span> <br> <span style="font-size: 12px; color: black;font-family:century gothic;">Nombre nouveaux deces : </span> <span style="font-size: 12px; color: {COLORS[5]}; font-weight: bold;font-family:century gothic;">@new_deaths</span> <br> <span style="font-size: 12px; color: black;font-family:century gothic;">Date : </span> <span style="font-size: 12px; color: black; font-weight: bold;font-family:century gothic;">@date_str</span> </p> </div> """ tooltips_predictions = (f""" <div> <p> <span style="font-size: 12px; color: black;font-family:century gothic;">Prédiction nombre de cas : </span> <span style="font-size: 12px; color: {COLORS[0]}; font-weight: bold;font-family:century gothic;">@median_display</span> <br> <span style="font-size: 12px; color: black;font-family:century gothic;">Date : </span> <span style="font-size: 12px; color: black; font-weight: bold;font-family:century gothic;">""" + """@date_str</span> </p> </div> """) hover = bkm.tools.HoverTool(names=["line_total"], tooltips=tooltips, mode="vline") hover_prediction = bkm.tools.HoverTool( names=["prediction"], tooltips=tooltips_predictions, ) # --- define all DataSource needed --- # source_all = bkm.ColumnDataSource(data) country = "World" source = bkm.ColumnDataSource(get_country(data, country)) source_all_prediction = bkm.ColumnDataSource(df_all_prediction) source_prediction = bkm.ColumnDataSource( get_country(df_all_prediction, country)) date_end_training = np.unique( get_country(df_all_prediction, country)["date_end_train"])[-1] source_prediction_end_date = bkm.ColumnDataSource( get_country(df_all_prediction, country)[get_country( df_all_prediction, country).date_end_train == date_end_training]) slider = bkm.Slider( start=0, end=len( np.unique( get_country(df_all_prediction, country)["date_end_train"])) - 1, value=0, step=1, title="Days dropped for prediction", ) # ----------- # p = bkp.figure( y_axis_type="linear", x_axis_type="datetime", sizing_mode="stretch_both", title=f"Covid 19 evolution: {country}", x_axis_label="date", y_axis_label="Total number of Covid 19 cases", tools=[hover, "pan", "wheel_zoom", "reset"], x_range=[ get_country(data, country).date.min(), get_country(data, country).date.max() + datetime.timedelta(days=1), ], y_range=[ -get_country(data, country).total_cases.max() * 0.05, get_country(data, country).total_cases.max() * 1.1, ], ) p.yaxis.formatter = bkm.formatters.NumeralTickFormatter(format="0,0") p.xaxis.formatter = bkm.formatters.DatetimeTickFormatter( days=["%d/%m", "%d%a"], months=["%m/%Y", "%b %Y"]) p.add_tools(hover_prediction) p.toolbar.active_drag = None # p.toolbar.active_scroll = p.select_one(bkm.WheelZoomTool) y_extra_range_max = np.max([ np.max(get_country(data, country).new_cases.values), np.max(get_country(data, country).total_deaths.values), ]) p.extra_y_ranges = { "Number of deaths": bkm.Range1d(start=-0.05 * y_extra_range_max, end=1.1 * y_extra_range_max) } p.add_layout( bkm.LinearAxis( y_range_name="Number of deaths", axis_label="New Covid 19 cases", formatter=bkm.formatters.NumeralTickFormatter(format="0,0"), ), "right", ) # --- plot total cases --- # p.line( source=source, x="date", y="total_cases", name="line_total", color=COLORS[0], legend_label="total cases", muted_alpha=0.1, ) p.circle(source=source, x="date", y="total_cases", color=COLORS[0], muted_alpha=0.1) # --- plot new cases --- # p.vbar( source=source, x="date", top="new_cases", color=COLORS[1], width=50e6, alpha=0.5, name="bar", y_range_name="Number of deaths", legend_label="new cases", muted_alpha=0.1, ) # --- plot total death --- # p.line( source=source, x="date", y="total_deaths", color=COLORS[3], y_range_name="Number of deaths", name="line_death", legend_label="total deaths", muted_alpha=0.1, ) p.circle( source=source, x="date", y="total_deaths", color=COLORS[3], y_range_name="Number of deaths", muted_alpha=0.1, ) # --- plot new death --- # p.vbar( source=source, x="date", top="new_deaths", color=COLORS[5], width=50e6, alpha=0.5, y_range_name="Number of deaths", legend_label="new deaths", muted_alpha=0.1, ) button_click_count = bkm.ColumnDataSource({"clicks": [0]}) select = bkm.Select(title="Country: ", value=country, options=list(data.location.unique())) button_log = bkm.Button(label="Log Scale", button_type="primary") # --- Predictions --- # median_prediction = p.line( source=source_prediction_end_date, x="date", y="median", line_color=COLORS[0], name="prediction", ) prediction_cases_line = p.line( source=source_prediction_end_date, x="date", y="derivative", color=COLORS[1], y_range_name="Number of deaths", ) band_low = bkm.Band( source=source_prediction_end_date, base="date", lower="25%", upper="median", fill_color=COLORS[0], level="underlay", fill_alpha=0.1, line_width=0.5, line_color="black", ) band_high = bkm.Band( source=source_prediction_end_date, base="date", lower="median", upper="75%", fill_color=COLORS[0], level="underlay", fill_alpha=0.1, line_width=0.5, line_color="black", ) median_prediction.visible = False prediction_cases_line.visible = False band_low.visible = False band_high.visible = False p.add_layout(band_low) p.add_layout(band_high) button_prediction = bkm.Button(label="Show predictions", button_type="primary") # -- Callback -- # callback = bkm.CustomJS( args=dict( source=source, source_all=source_all, select=select, x_range=p.x_range, y_range_left=p.y_range, y_range_right=p.extra_y_ranges["Number of deaths"], title=p.title, button_click_count=button_click_count, slider=slider, source_all_prediction=source_all_prediction, source_prediction=source_prediction, source_prediction_end_date=source_prediction_end_date, median_prediction=median_prediction, band_low=band_low, prediction_cases_line=prediction_cases_line, band_high=band_high, ), code=""" var country = select.value var date = source_all.data['date'] var date_str = source_all.data['date_str'] var location = source_all.data['location'] var total_cases = source_all.data['total_cases'] var new_cases = source_all.data['new_cases'] var total_deaths = source_all.data['total_deaths'] var new_deaths = source_all.data['new_deaths'] var new_date = [] var new_date_str = [] var new_total_cases = [] var new_new_cases = [] var new_total_deaths = [] var new_new_deaths = [] for(var i=0; i < date.length; i++){ if(location[i]==country){ new_date.push(date[i]); new_date_str.push(date_str[i]) new_total_cases.push(total_cases[i]); new_new_cases.push(new_cases[i]); new_total_deaths.push(total_deaths[i]); new_new_deaths.push(new_deaths[i]); } } source.data['date']=new_date; source.data['date_str']=new_date_str; source.data['total_cases']=new_total_cases; source.data['new_cases']=new_new_cases; source.data['total_deaths']=new_total_deaths; source.data['new_deaths']=new_new_deaths; const new_cases_no_Nan = new_new_cases.filter(function (value) { return !Number.isNaN(value); }); const cases_no_Nan = new_total_cases.filter(function (value) { return !Number.isNaN(value); }); y_range_right.setv({"start": -0.05*Math.max.apply(Math, new_cases_no_Nan.concat(new_total_deaths)), "end": 1.1*Math.max.apply(Math, new_cases_no_Nan.concat(new_total_deaths))}) y_range_left.setv({"start": -0.05*Math.max.apply(Math, cases_no_Nan), "end": 1.1*Math.max.apply(Math, cases_no_Nan)}) x_range.setv({"start": Math.min.apply(Math, new_date), "end": 1.0001*Math.max.apply(Math, new_date)}) title.text = "Evolution du nombre de cas en " + country source.change.emit(); // change value of predictions button_click_count.data.clicks = 0 median_prediction.visible = false band_low.visible = false band_high.visible = false prediction_cases_line.visble = false var date_end_prediction = source_all_prediction.data['date_end_train'] var location = source_all_prediction.data['location'] var date = source_all_prediction.data['date'] var date_str = source_all_prediction.data['date_str'] var quantile_1 = source_all_prediction.data['25%'] var quantile_2 = source_all_prediction.data['median'] var quantile_3 = source_all_prediction.data['75%'] var new_cases = source_all_prediction.data['derivative'] var median_prediction = source_all_prediction.data['median_display'] var new_date = [] var new_date_str = [] var new_date_end_prediction = [] var new_quantile_1 = [] var new_quantile_2 = [] var new_quantile_3 = [] var new_new_cases = [] var new_median_prediction = [] for(var i=0; i < quantile_1.length; i++){ if(location[i]==country){ new_date.push(date[i]) new_date_str.push(date_str[i]) new_date_end_prediction.push(date_end_prediction[i]) new_quantile_1.push(quantile_1[i]); new_quantile_2.push(quantile_2[i]); new_quantile_3.push(quantile_3[i]); new_new_cases.push(new_cases[i]); new_median_prediction.push(median_prediction[i]); } } source_prediction.data['date']=new_date source_prediction.data['date_str']=new_date_str source_prediction.data['date_end_train']=new_date_end_prediction source_prediction.data['25%']=new_quantile_1; source_prediction.data['median']=new_quantile_2; source_prediction.data['75%']=new_quantile_3; source_prediction.data['derivative']=new_new_cases; source_prediction.data['median_display']=new_median_prediction; var n = new_date.length var max_date = Math.max.apply(Math, new_date_end_prediction) var new_date_bis = [] var new_date_str_bis = [] var new_date_end_prediction_bis = [] var new_quantile_1_bis = [] var new_quantile_2_bis = [] var new_quantile_3_bis = [] var new_new_cases_bis = [] var new_median_prediction_bis = [] for(var i=0; i < n; i++){ if(new_date_end_prediction[i]==max_date){ new_date_bis.push(new_date[i]) new_date_str_bis.push(new_date_str[i]) new_date_end_prediction_bis.push(new_date_end_prediction[i]) new_quantile_1_bis.push(new_quantile_1[i]); new_quantile_2_bis.push(new_quantile_2[i]); new_quantile_3_bis.push(new_quantile_3[i]); new_new_cases_bis.push(new_new_cases[i]); new_median_prediction_bis.push(new_median_prediction[i]); } } var n = new_date_bis.length var max_date = Math.max.apply(Math, new_date_end_prediction_bis) source_prediction_end_date.data['date']=new_date_bis source_prediction_end_date.data['date_str']=new_date_str_bis source_prediction_end_date.data['date_end_train']=new_date_end_prediction_bis source_prediction_end_date.data['25%']=new_quantile_1_bis; source_prediction_end_date.data['median']=new_quantile_2_bis; source_prediction_end_date.data['75%']=new_quantile_3_bis; source_prediction_end_date.data['derivative']=new_new_cases_bis; source_prediction_end_date.data['median_display']=new_median_prediction_bis; source_prediction.change.emit(); source_prediction_end_date.change.emit() const unique = (value, index, self) => { return self.indexOf(value) === index } // change slider value slider.setv({"end": new_date_end_prediction.filter(unique).length - 1, "value": 0}) """, ) callback_button = bkm.CustomJS( args=dict(y_axis=p.left, title=p.title), code=""" console.log(y_axis) y_axis = LogAxis() """, ) select.js_on_change("value", callback) button_log.js_on_click(callback_button) callback_button = bkm.CustomJS( args=dict( source=source, source_prediction=source_prediction, source_all_prediction=source_all_prediction, source_prediction_end_date=source_prediction_end_date, select=select, button_prediction=button_prediction, median_prediction=median_prediction, band_low=band_low, prediction_cases_line=prediction_cases_line, band_high=band_high, button_click_count=button_click_count, x_range=p.x_range, y_range_left=p.y_range, y_range_right=p.extra_y_ranges["Number of deaths"], ), code=""" // function to get unique value of an array const unique = (value, index, self) => { return self.indexOf(value) === index } var date = source.data['date']; var total_cases = source.data['total_cases']; var new_cases = source.data['new_cases']; var total_deaths = source.data['total_deaths']; var date_prediction = source_prediction.data['date']; var total_cases_prediction = source_prediction.data['75%']; const new_cases_no_Nan = new_cases.filter(function (value) { return !Number.isNaN(value); }); const cases_no_Nan = total_cases.filter(function (value) { return !Number.isNaN(value); }); var country = select.value button_click_count.data.clicks ++ var show_prediction = (button_click_count.data.clicks % 2) == 1 var locations_predicted = source_all_prediction.data['location'].filter(unique) if (locations_predicted.includes(country) == false){ window.alert("This country doesn't have prediction: Available countries are: " + locations_predicted); } else{ if (show_prediction == true){ median_prediction.visible = true band_low.visible = true band_high.visible = true prediction_cases_line.visble = true const y_range_right_values = [].concat([].slice.call(new_cases_no_Nan), [].slice.call(total_deaths)) y_range_left.setv({"start": -0.05*Math.max.apply(Math, total_cases_prediction), "end": 1.1 * Math.max.apply(Math, total_cases_prediction)}) y_range_right.setv({"start": -0.05*Math.max.apply(Math, y_range_right_values) * Math.max.apply(Math, total_cases_prediction) / Math.max.apply(Math, cases_no_Nan), "end": 1.1*Math.max.apply(Math, y_range_right_values) * Math.max.apply(Math, total_cases_prediction) / Math.max.apply(Math, cases_no_Nan)}) x_range.setv({"start": Math.min.apply(Math, date_prediction), "end": 1.0001*Math.max.apply(Math, date_prediction)}) } else{ median_prediction.visible = false band_low.visible = false band_high.visible = false prediction_cases_line.visble = false const y_range_right_values = [].concat([].slice.call(new_cases_no_Nan), [].slice.call(total_deaths)) y_range_left.setv({"start": -0.05*Math.max.apply(Math, cases_no_Nan), "end": 1.1*Math.max.apply(Math, cases_no_Nan)}) y_range_right.setv({"start": -0.05*Math.max.apply(Math, y_range_right_values), "end": 1.1*Math.max.apply(Math, y_range_right_values)}) x_range.setv({"start": Math.min.apply(Math, date), "end": 1.0001*Math.max.apply(Math, date)}) } } """, ) button_prediction.js_on_click(callback_button) callback_slider = bkm.CustomJS( args=dict( source=source, source_prediction=source_prediction, source_all_prediction=source_all_prediction, source_prediction_end_date=source_prediction_end_date, select=select, prediction_cases_line=prediction_cases_line, slider=slider, button_click_count=button_click_count, x_range=p.x_range, y_range_left=p.y_range, y_range_right=p.extra_y_ranges["Number of deaths"], ), code=""" // function to get unique value of an array const unique = (value, index, self) => { return self.indexOf(value) === index } var slider_value = slider.value var country = select.value var date_prediction = source_prediction.data['date'] var date_str = source_prediction.data['date_str'] var date_end_prediction = source_prediction.data['date_end_train'] var quantile_1 = source_prediction.data['25%']; var quantile_2 = source_prediction.data['median'] var quantile_3 = source_prediction.data['75%'] var new_cases = source_prediction.data['derivative']; var median_prediction = source_prediction.data['median_display'] var unique_end_prediction = date_end_prediction.filter(unique) var show_prediction = (button_click_count.data.clicks % 2) == 1 var locations_predicted = source_all_prediction.data['location'].filter(unique) if (show_prediction == true && locations_predicted.includes(country)){ var new_date_prediction = [] var new_date_str = [] var new_date_end_prediction = [] var new_quantile_1 = [] var new_quantile_2 = [] var new_quantile_3 = [] var new_new_cases = [] var new_median_prediction = [] for(var i=0; i < quantile_1.length; i++){ if(date_end_prediction[i]==unique_end_prediction[slider.end - slider_value]){ new_date_prediction.push(date_prediction[i]) new_date_str.push(date_str[i]) new_date_end_prediction.push(date_end_prediction[i]) new_quantile_1.push(quantile_1[i]); new_quantile_2.push(quantile_2[i]); new_quantile_3.push(quantile_3[i]); new_new_cases.push(new_cases[i]); new_median_prediction.push(median_prediction[i]); } } source_prediction_end_date.data['date']=new_date_prediction source_prediction_end_date.data['date_str']=new_date_str source_prediction_end_date.data['date_end_train']=new_date_end_prediction source_prediction_end_date.data['25%']=new_quantile_1; source_prediction_end_date.data['median']=new_quantile_2; source_prediction_end_date.data['75%']=new_quantile_3; source_prediction_end_date.data['derivative']=new_new_cases; source_prediction_end_date.data['median_display']=new_median_prediction; source_prediction_end_date.change.emit(); var date_prediction = source_prediction_end_date.data['date']; var total_cases_prediction = source_prediction_end_date.data['75%']; const new_cases_no_Nan = new_cases.filter(function (value) { return !Number.isNaN(value); }); const cases_no_Nan = quantile_2.filter(function (value) { return !Number.isNaN(value); }); // y_range_left.setv({"start": -0.05*Math.max.apply(Math, total_cases_prediction), "end": 1.1*Math.max.apply(Math, total_cases_prediction)}) // x_range.setv({"start": Math.min.apply(Math, date_prediction), "end": 1.0001*Math.max.apply(Math, date_prediction)}) } """, ) slider.js_on_change("value", callback_slider) p.legend.location = "top_left" p.legend.click_policy = "mute" return select, button_prediction, slider, p