def input_tab(): output_file("bokeh_app/output/text_input.html") text_input = TextAreaInput(value="Voer je review hier in :)", rows=6, title="Sentiment tester") text_input.on_change("value", input_handler) tab = Panel(child=column(text_input, toggle), title='Tester') return tab
class Toxicity: def __init__(self, protocol): self.protocol = protocol # link to Protocol tab so we can info in the protocol tab self.source = ColumnDataSource(data=dict(mrn=[])) self.source.selected.on_change('indices', self.source_listener) # self.source.on_change('data', self.update_toxicity_grades_from_table) self.data = [ ] # This will keep all data from query, self.source may display a subset self.clear_source_selection_button = Button(label='Clear Selection', button_type='primary', width=150) self.clear_source_selection_button.on_click( self.clear_source_selection) self.protocol_select = Select(value='All Data', options=['All Data', 'None'], title='Protocol:') self.protocol_select.on_change('value', self.protocol_ticker) self.update_protocol_options() self.display_by = RadioGroup(labels=[ 'Display by Institutional ROI', 'Display by Physician ROI' ], active=0) self.display_by.on_change('active', self.display_by_ticker) self.physician = Select(value='', options=[''], title='Physician:', width=150) self.physician.on_change('value', self.physician_ticker) self.roi = Select(value='', options=[''], title='Institutional ROI:') self.roi.on_change('value', self.roi_ticker) self.mrn_input_count = 0 self.toxicity_grade_input_count = 0 self.mrn_input = TextAreaInput(value='', title="MRN Input:", rows=30, cols=25, max_length=2000) self.mrn_input.on_change('value', self.mrn_input_ticker) self.toxicity_grade_input = TextAreaInput( value='', title="Toxicity Grade Input:", rows=30, cols=5, max_length=500) self.toxicity_grade_input.on_change('value', self.toxicity_input_ticker) self.update_button = Button(label='Update', button_type='primary', width=425) self.update_button.on_click(self.update_toxicity_grades) self.update_update_button_status() self.columns = ['mrn', 'roi_name', 'toxicity_grade'] relative_widths = [1, 1, 1, 1] column_widths = [int(250. * rw) for rw in relative_widths] table_columns = [ TableColumn(field=c, title=c, width=column_widths[i]) for i, c in enumerate(self.columns) ] table_columns.insert( 1, TableColumn(field='protocol', title='protocol', width=column_widths[0])) table_columns.insert( 1, TableColumn(field='physician', title='physician', width=column_widths[0] / 3)) self.table = DataTable(source=self.source, columns=table_columns, width=800, editable=True, height=600) self.update_physicians() note = Div( text= '<b>NOTE</b>: MRNs input below that are not in the table to the left will be ' 'ignored on update.') self.layout = column( self.protocol_select, row(self.display_by, self.physician, self.roi), row( self.table, Spacer(width=50), column(note, self.update_button, self.clear_source_selection_button, row(self.mrn_input, self.toxicity_grade_input)))) def source_listener(self, attr, old, new): new.sort() mrns = [self.source.data['mrn'][x] for x in new] self.mrn_input.value = '\n'.join(mrns) toxicities = [str(self.source.data['toxicity_grade'][x]) for x in new] toxicities = [['NULL', t][t.isdigit()] for t in toxicities] self.toxicity_grade_input.value = '\n'.join(toxicities) def update_source(self): cnx = DVH_SQL() if self.display_by.active == 1: # Display by Physician ROI uids_physician = cnx.get_unique_values( 'Plans', 'study_instance_uid', "physician = '%s'" % self.physician.value) condition = ["physician_roi = '%s'" % self.roi.value] if uids_physician: condition.append("study_instance_uid in ('%s')" % "', '".join(uids_physician)) else: # Display by Institutional ROI condition = ["institutional_roi = '%s'" % self.roi.value] if self.physician.value != 'Any': uids_physician = cnx.get_unique_values( 'Plans', 'study_instance_uid', "physician = '%s'" % self.physician.value) if uids_physician: condition.append("study_instance_uid in ('%s')" % "', '".join(uids_physician)) condition = ' AND '.join(condition) self.data = cnx.query('DVHs', ', '.join(self.columns + ['study_instance_uid']), condition, bokeh_cds=True, order_by='mrn') cnx.close() for col in ['protocol', 'physician']: self.data[col] = self.get_sql_values_based_on_source( 'Plans', col, return_list=True) self.clean_toxicity_grades() if self.protocol_select.value == 'All Data': self.source.data = self.data else: self.source.data = self.get_data_filtered_by_protocol() def get_data_filtered_by_protocol(self): selected_protocol = self.protocol_select.value if selected_protocol == 'No Protocol': selected_protocol = '' protocols = self.get_sql_values_based_on_source('Plans', 'protocol') if not protocols: return self.data new_data = {key: [] for key in list(self.data)} for i in range(len(self.data['mrn'])): if (selected_protocol == 'Any Protocol' and protocols[self.data['study_instance_uid'][i]]) or \ (not selected_protocol and not protocols[self.data['study_instance_uid'][i]]) or\ (selected_protocol and selected_protocol in protocols[self.data['study_instance_uid'][i]]): for key in list(self.data): new_data[key].append(self.data[key][i]) return new_data def clean_toxicity_grades(self): # Replace any toxicity grade values of -1 to None. Stored in SQL as integer, but integer columns can't have NULL for i, value in enumerate(self.data['toxicity_grade']): if value == -1: self.data['toxicity_grade'][i] = None def update_protocol_options(self): options = ['All Data', 'Any Protocol', 'No Protocol' ] + self.get_protocols() self.protocol_select.options = options if self.protocol_select.value not in options: self.protocol_select.value = options[0] def get_sql_values_based_on_source(self, sql_table, sql_column, return_list=False): cnx = DVH_SQL() uids = self.data['study_instance_uid'] data = cnx.query(sql_table, 'study_instance_uid, %s' % sql_column, "study_instance_uid in ('%s')" % "', '".join(uids)) if data: return_data = {line[0]: line[1] for line in data} if return_list: return [ return_data[uid] for uid in self.data['study_instance_uid'] ] else: return return_data return [] def update_physicians(self): physicians = DVH_SQL().get_unique_values('Plans', 'physician') if self.display_by.active == 0: physicians.insert(0, 'Any') self.physician.options = physicians if self.physician.value not in physicians: self.physician.value = physicians[0] def protocol_ticker(self, attr, old, new): self.update_source() def physician_ticker(self, attr, old, new): self.update_source() self.update_rois() def roi_ticker(self, attr, old, new): self.update_source() def update_rois(self): cnx = DVH_SQL() if self.display_by.active == 1: # Display by Physician ROI uids_physician = cnx.get_unique_values( 'Plans', 'study_instance_uid', "physician = '%s'" % self.physician.value) condition = "study_instance_uid in ('%s')" % "', '".join( uids_physician) rois = cnx.get_unique_values('DVHs', 'physician_roi', condition) else: # Display by Institutional ROI rois = cnx.get_unique_values('DVHs', 'institutional_roi') cnx.close() self.roi.options = rois if self.roi.value not in rois: self.roi.value = rois[0] def display_by_ticker(self, attr, old, new): self.roi.title = ['Institutional ROI:', 'Physician ROI:'][new] self.update_physicians() self.update_rois() @staticmethod def get_protocols(condition=None): return DVH_SQL().get_unique_values('Plans', 'protocol', condition, ignore_null=True) def update_toxicity_grades(self): if self.update_button.label == 'Update': mrns = parse_text_area_input_to_list(self.mrn_input.value, delimeter=None) toxicities = parse_text_area_input_to_list( self.toxicity_grade_input.value, delimeter=None) cnx = DVH_SQL() for i, mrn in enumerate(mrns): if mrn in self.data['mrn']: index = self.data['mrn'].index(mrn) uid = self.data['study_instance_uid'][index] roi_name = self.data['roi_name'][index] cnx.update( 'DVHs', 'toxicity_grade', toxicities[i], "study_instance_uid = '%s' and roi_name = '%s'" % (uid, roi_name)) update_plan_toxicity_grades(cnx, uid) cnx.close() self.update_source() self.clear_source_selection() self.toxicity_grade_input.value = '' self.protocol.update_source( ) # update the table in the Protocol tab since it has toxicity grades in it def mrn_input_ticker(self, attr, old, new): count = len(parse_text_area_input_to_list(new)) self.mrn_input.title = "MRN Input%s:" % ( ['', ' (count = %d)' % count][count > 0]) self.mrn_input_count = count self.update_update_button_status() def toxicity_input_ticker(self, attr, old, new): toxicity_grades = parse_text_area_input_to_list(new, delimeter=None) count = len(toxicity_grades) self.toxicity_grade_input.title = "Toxicity Grade Input%s:" % ( ['', ' (count = %d)' % count][count > 0]) self.toxicity_grade_input_count = count self.update_update_button_status() self.validate_toxicity_grade_input(toxicity_grades) def update_update_button_status(self): if not self.mrn_input_count and not self.toxicity_grade_input_count: self.update_button.label = "Need data to update" self.update_button.button_type = 'default' elif self.mrn_input_count != self.toxicity_grade_input_count: self.update_button.label = 'Input data row count mismatch' self.update_button.button_type = 'default' else: self.update_button.label = 'Update' self.update_button.button_type = 'primary' def validate_toxicity_grade_input(self, toxicity_grades): validated_data = [['NULL', grade][grade.isdigit() and grade > -1] for grade in toxicity_grades] # remove non-int > -1 for i, x in enumerate(validated_data): if x.isdigit(): validated_data[i] = str( int(x)) # clean, convert to string (removes leading zeros) self.toxicity_grade_input.value = '\n'.join(validated_data) # if 'NULL' in validated_data: # label = self.update_button.label # button_type = self.update_button.button_type # self.update_button.label = 'Invalid grade detected. Setting to None.' # self.update_button.button_type = 'danger' # time.sleep(1) # self.update_button.label = label # self.update_button.button_type = button_type def clear_source_selection(self): self.source.selected.indices = []
class Protocol: def __init__(self): note = Div( text="<b>NOTE</b>: Each plan may only have one protocol assigned. " "Updating database will overwrite any existing data.", width=700) self.update_checkbox = CheckboxGroup( labels=["Only update plans in table."], active=[0]) self.toxicity = [] # Will be used to link to Toxicity tab self.source = ColumnDataSource(data=dict(mrn=[''])) self.source.selected.on_change('indices', self.source_listener) self.clear_source_selection_button = Button(label='Clear Selection', button_type='primary', width=150) self.clear_source_selection_button.on_click( self.clear_source_selection) self.protocol = Select(value='', options=[''], title='Protocols:') self.physician = Select(value='', options=[''], title='Physician:', width=150) self.date_filter_by = Select( value='None', options=['None', 'sim_study_date', 'import_time_stamp'], title='Date Filter Type:', width=150) self.date_filter_by.on_change('value', self.date_ticker) self.date_start = DatePicker(title='Start Date:', width=200) self.date_start.on_change('value', self.date_ticker) self.date_end = DatePicker(title='End Date:', width=200) self.date_end.on_change('value', self.date_ticker) self.update_protocol_options() self.update_physician_options() self.protocol_input = TextInput(value='', title='Protocol for MRN Input:') self.update_button = Button(label='Need MRNs to Update', button_type='default', width=150) self.update_button.on_click(self.update_db) self.mrn_input = TextAreaInput(value='', title='MRN Input:', rows=30, cols=25, max_length=2000) self.mrn_input.on_change('value', self.mrn_input_ticker) self.columns = [ 'mrn', 'protocol', 'physician', 'tx_site', 'sim_study_date', 'import_time_stamp', 'toxicity_grades' ] relative_widths = [1, 0.8, 0.5, 1, 0.75, 1, 0.8] column_widths = [int(250. * rw) for rw in relative_widths] table_columns = [ TableColumn(field=c, title=c, width=column_widths[i]) for i, c in enumerate(self.columns) ] self.table = DataTable(source=self.source, columns=table_columns, width=800, editable=True, height=600) self.protocol.on_change('value', self.protocol_ticker) self.physician.on_change('value', self.physician_ticker) self.update_source() self.layout = column( row(self.protocol, self.physician), row(self.date_filter_by, Spacer(width=30), self.date_start, Spacer(width=30), self.date_end), note, row( self.table, Spacer(width=30), column(self.update_checkbox, row(self.protocol_input, self.update_button), self.clear_source_selection_button, self.mrn_input))) def source_listener(self, attr, old, new): mrns = [self.source.data['mrn'][x] for x in new] self.mrn_input.value = '\n'.join(mrns) def update_source(self): condition = [] if self.protocol.value not in self.protocol.options[0:3]: condition.append("protocol = '%s'" % self.protocol.value) elif self.protocol.value == self.protocol.options[1]: condition.append("protocol != ''") elif self.protocol.value == self.protocol.options[2]: condition.append("protocol = ''") if self.physician.value != self.physician.options[0]: condition.append("physician = '%s'" % self.physician.value) if self.date_filter_by.value != 'None': if self.date_start.value: condition.append( "%s >= '%s'::date" % (self.date_filter_by.value, self.date_start.value)) if self.date_end.value: condition.append( "%s >= '%s'::date" % (self.date_filter_by.value, self.date_end.value)) condition = ' AND '.join(condition) columns = ', '.join(self.columns + ['study_instance_uid']) data = DVH_SQL().query('Plans', columns, condition, order_by='mrn', bokeh_cds=True) self.source.data = data def update_protocol_options(self): options = ['All Data', 'Any Protocol', 'No Protocol' ] + self.get_protocols() self.protocol.options = options if self.protocol.value not in options: self.protocol.value = options[0] @property def mrns_to_add(self): return parse_text_area_input_to_list(self.mrn_input.value, delimeter=None) @staticmethod def get_protocols(condition=None): return DVH_SQL().get_unique_values('Plans', 'protocol', condition, ignore_null=True) def update_physician_options(self): physicians = ['Any'] + DVH_SQL().get_unique_values( 'Plans', 'physician') self.physician.options = physicians if self.physician.value not in physicians: self.physician.value = physicians[0] def protocol_ticker(self, attr, old, new): self.update_source() def physician_ticker(self, attr, old, new): self.update_source() def date_ticker(self, attr, old, new): self.update_source() def update_db(self): if 0 in self.update_checkbox.active: condition = "mrn in ('%s')" % "', '".join(self.mrns_to_add) else: uids = [] for i, mrn in enumerate(self.mrns_to_add): if mrn in self.source.data['mrn']: index = self.source.data['mrn'].index(mrn) uids.append(self.source.data['study_instance_uid'][index]) condition = "study_instance_uid in ('%s')" % "', '".join(uids) DVH_SQL().update( 'Plans', 'protocol', self.protocol_input.value.replace("'", "").replace("\"", "").replace( "\\", ""), condition) self.update_source() self.clear_source_selection() self.protocol_input.value = '' self.update_protocol_options() self.toxicity.update_protocol_options() self.toxicity.update_source() def clear_source_selection(self): self.source.selected.indices = [] def add_toxicity_tab_link(self, toxicity): self.toxicity = toxicity def mrn_input_ticker(self, attr, old, new): self.update_update_button_status() def update_update_button_status(self): if self.mrns_to_add: self.update_button.label = 'Update' self.update_button.button_type = 'primary' else: self.update_button.label = 'Need MRNs to Update' self.update_button.button_type = 'default'
def graph(): def reading_config(path): #Reading the configuration file file = open(path, "r") #dictio=yaml.full_load(file) dictio = yaml.load(file, Loader=yaml.FullLoader) file.close() #Exctraction of the sensors part and the database part dictio_sensors = dictio['sensors'] dictio_database = dictio['database'] #Transformation in DataFrame to allow an easy read df_sensors = pd.DataFrame(dictio_sensors) df_databases = pd.DataFrame(dictio_database) list_sensor_name = [] for i in range(0, df_sensors.shape[1]): list_sensor_name.append(df_sensors.loc['name_sensor'][i]) L = [] L.append(df_sensors.loc['Registre'][0]) list_registre_name = L[len(L) - 1] L_influx = [] L_influx.append(df_databases.loc['name'][i]) L_influx.append(df_databases.loc['username'][i]) L_influx.append(df_databases.loc['password'][i]) L_influx.append(df_databases.loc['ip'][i]) L_influx.append(df_databases.loc['port'][i]) return (list_sensor_name, list_registre_name, L_influx) def make_dataset(capteur_list, text_input_start, text_input_end, nom_capteur, L_influx): xs = [] ys = [] colors = [] labels = [] client = DataFrameClient(host=L_influx[3], port=L_influx[4], username=L_influx[1], password=L_influx[2]) client.switch_database(L_influx[0]) #Granularity to avoid to display too much points on the figure end = datetime.strptime(text_input_end, "%Y-%m-%d %H:%M:%S") start = datetime.strptime(text_input_start, "%Y-%m-%d %H:%M:%S") ecartSecondes = (end - start).total_seconds() if ecartSecondes < 86401: groupby = None elif ecartSecondes > 86401 and ecartSecondes < 5000000: groupby = '1m' elif ecartSecondes > 5000000 and ecartSecondes < 77000000: groupby = '15m' else: groupby = '1h' #print(ecartSecondes, groupby) #Construction of vectors x and y for each register to be displayed for elt in capteur_list: if groupby == None: requete = "SELECT " + '"' + elt + '"' + " FROM measure WHERE time >= " + "'" + text_input_start + "'" + " AND " + "time <= " + "'" + text_input_end + "'" + " AND " + "ID=" + "'" + nom_capteur + "'" datasets = client.query(requete) df = pd.DataFrame(datasets['measure']) df = df.rename_axis('Date') df.index = df.index.astype('datetime64[ns]') client.close() #Convert data in list of lists a = [] b = [] for i in range(df.shape[0]): a.append(df[elt][i]) b.append(df.index[i]) xs.append(a) ys.append(b) colors.append(capteur_color[capteur_list.index(elt)]) labels.append(elt) else: requete = "SELECT MEAN(" + '"' + elt + '"' + ") FROM measure WHERE time >= " + "'" + text_input_start + "'" + " AND " + "time <= " + "'" + text_input_end + "'" + " AND " + "ID=" + "'" + nom_capteur + "'" + " GROUP BY time(" + groupby + ") fill(0)" datasets = client.query(requete) df = pd.DataFrame(datasets['measure']) df = df.rename_axis('Date') df.index = df.index.astype('datetime64[ns]') client.close() #Conversion des données en liste de liste a = [] b = [] for i in range(df.shape[0]): a.append(df['mean'][i]) b.append(df.index[i]) xs.append(a) ys.append(b) colors.append(capteur_color[capteur_list.index(elt)]) labels.append(elt) #Construction of the source of the figure new_src = ColumnDataSource(data={ 'x': xs, 'y': ys, 'color': colors, 'label': labels }) return new_src def make_plot(src): # Blank plot with correct labels p = figure(plot_width=1000, plot_height=700, title='Graph of the registers', x_axis_type="datetime", x_axis_label='Date', y_axis_label='Unit', output_backend='webgl') p.multi_line('y', 'x', color='color', legend='label', line_width=3, source=src) # Hover tool with next line policy hover = HoverTool(tooltips=[('Capteur', '@label')], line_policy='next') # Add the hover tool and styling p.add_tools(hover) # Styling p = style(p) return p # Update function takes three default parameters def update(attr, old, new): #clear_plot(old) # Get the list of carriers for the graph capteur_to_plot = [ capteur_selection.labels[i] for i in capteur_selection.active ] l = text_input.value L_text = [] for val in l.split('\n'): L_text.append(val) text_input_start = L_text[1] text_input_end = L_text[4] nom_capteur = select.value # Make a new dataset based on the selected sensors new_src = make_dataset(capteur_to_plot, text_input_start, text_input_end, nom_capteur, L_influx) # Update the source used the quad glpyhs src.data.update(new_src.data) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p #Select """ WARNING : you need to change the path to your config file to run this code """ (available_name, available_capteur, L_influx) = reading_config( "/home/rsm/Desktop/Arnaud_Debar/bokehapp_final/config/config.yml") select = Select(title="Select one sensor:", value=available_name[0], options=available_name) select.on_change('value', update) available_capteur.sort() #capteur_color=Category20_20 capteur_color = [] for val in cc.glasbey_hv: capteur_color.append(plt.colors.to_hex(val)) #capteur_color.sort() #Capteur to plot capteur_selection = CheckboxGroup(labels=available_capteur, active=[0, 1]) capteur_selection.on_change('active', update) #Date input text_input = TextAreaInput( value='Start:\n2019-08-08 18:20:00\n \nEnd:\n2019-08-09 10:27:00\n ', rows=5, title="Date: Year-Month-Day Hour:Minute:Second") text_input.on_change('value', update) l = text_input.value L_text_input = [] for val in l.split('\n'): L_text_input.append(val) initial_text_input_start = L_text_input[1] initial_text_input_end = L_text_input[4] #Initial register display initial_capteur = [ capteur_selection.labels[i] for i in capteur_selection.active ] #Make the initial dataset src = make_dataset(initial_capteur, initial_text_input_start, initial_text_input_end, available_name[0], L_influx) #Make the plot p = make_plot(src) # Add style to the plot p = style(p) # Put control in a single element controls = WidgetBox(select, capteur_selection, text_input) layout = row(controls, p) tab = Panel(child=layout, title='Summary Graph') return tab
t = (disk_source.data['peri'][disk_source.data['dist'] > 0]) hist, edges = np.histogram(t, bins=100) hist = np.cumsum(hist) / hist.sum() disk_line.data = {'x': edges[:-1], 'y': hist} p2.xaxis.axis_label = labels_dict['peri'] p2.yaxis.axis_label = "" _ = np.seterr(**old_set) def _customJS(fname, source, script="download.js"): return CustomJS(args=dict(source=source, fname=fname), code=open(join(dirname(__file__), script)).read()) sql_query.on_change('value', query_change) sql_query2.on_change('value', query_change) log_axes.on_change('active', scale_axes) x_col.on_change('value', column_change) y_col.on_change('value', column_change) plot_type.on_change('value', create_line_plot) button_dmo_sub = Button(label="Download DMO Query", button_type="primary") button_dmo_all = Button(label="Download DMO Catalog", button_type="primary") button_disk_sub = Button(label="Download Disk Query", button_type="danger") button_disk_all = Button(label="Download Disk Catalog", button_type="danger") button_dmo_all.callback = _customJS('pelvis_dmo_all.csv', dmo_data) button_dmo_sub.callback = _customJS('pelvis_dmo_query.csv', dmo_source) button_disk_all.callback = _customJS('pelvis_disk_all.csv', disk_data) button_disk_sub.callback = _customJS('pelvis_disk_query.csv', disk_source) button_list = [
def table(): def reading_config(path): #Reading the configuration file file = open(path, "r") #dictio=yaml.full_load(file) dictio = yaml.load(file, Loader=yaml.FullLoader) file.close() #Exctraction of the sensors part and the database part dictio_sensors = dictio['sensors'] dictio_database = dictio['database'] #Transformation in DataFrame to allow an easy read df_sensors = pd.DataFrame(dictio_sensors) df_databases = pd.DataFrame(dictio_database) list_sensor_name = [] for i in range(0, df_sensors.shape[1]): list_sensor_name.append(df_sensors.loc['name_sensor'][i]) L = [] L.append(df_sensors.loc['Registre'][0]) list_registre_name = L[len(L) - 1] L_influx = [] L_influx.append(df_databases.loc['name'][i]) L_influx.append(df_databases.loc['username'][i]) L_influx.append(df_databases.loc['password'][i]) L_influx.append(df_databases.loc['ip'][i]) L_influx.append(df_databases.loc['port'][i]) return (list_sensor_name, list_registre_name, L_influx) def make_dataset(capteur_list, text_input_start, text_input_end, nom_capteur, L_influx): client = DataFrameClient(host=L_influx[3], port=L_influx[4], username=L_influx[1], password=L_influx[2]) client.switch_database(L_influx[0]) src = pd.DataFrame() for elt in capteur_list: requete = "SELECT " + '"' + elt + '"' + " FROM measure WHERE time >= " + "'" + text_input_start + "'" + " AND " + "time <= " + "'" + text_input_end + "'" + " AND " + "ID=" + "'" + nom_capteur + "'" datasets = client.query(requete) df = pd.DataFrame(datasets['measure']) df = df.rename_axis('Date') df.index = df.index.astype('datetime64[ns]') src = pd.concat([df, src], axis=1) client.close() src['Date'] = src.index Index = [i for i in range(0, df.shape[0])] src.index = Index cols = src.columns.tolist() cols = cols[-1:] + cols[:-1] src = src[cols] return (src) def make_table(source, src): table_columns = [ TableColumn(field='Date', title='Date', formatter=DateFormatter(format="%m/%d/%Y %H:%M:%S")) ] colonne = src.columns colonne = colonne.delete(0) table_columns += [TableColumn(field=col, title=col) for col in colonne] liste = [k for k in range(0, 10)] longueur = src.shape[0] for k in range(longueur - 10, longueur): liste.append(k) view1 = CDSView(source=source, filters=[IndexFilter(indices=liste)]) #table_source = ColumnDataSource(src) datatable = DataTable(source=source, columns=table_columns, width=1200, height=1000, view=view1) #print(datatable.fit_columns) return datatable # Update function takes three default parameters def update(attr, old, new): capteur_to_plot = [ capteur_selection.labels[i] for i in capteur_selection.active ] l = text_input.value L_text = [] for val in l.split('\n'): L_text.append(val) text_input_start = L_text[1] text_input_end = L_text[4] nom_capteur = select.value new_src = make_dataset(capteur_to_plot, text_input_start, text_input_end, nom_capteur, L_influx) new_source = ColumnDataSource(new_src) dictio = {} for i in range(0, len(new_src.columns)): dictio[new_src.columns[i]] = new_src[new_src.columns[i]] source.data = dictio table_columns = [ TableColumn(field='Date', title='Date', formatter=DateFormatter(format="%m/%d/%Y %H:%M:%S")) ] colonne = new_src.columns colonne = colonne.delete(0) table_columns += [TableColumn(field=col, title=col) for col in colonne] datatable.columns = table_columns liste = [k for k in range(0, 10)] longueur = new_src.shape[0] for k in range(longueur - 10, longueur): liste.append(k) view1 = CDSView(source=new_source, filters=[IndexFilter(indices=liste)]) datatable.view = view1 #Select """ WARNING : you need to change the path to your config file to run this code """ (available_name, available_capteur, L_influx ) = reading_config("/home/rsm/Desktop/bokehapp_final/config/config.yml") select = Select(title="Select one sensor:", value=available_name[0], options=available_name) select.on_change('value', update) available_capteur.sort() #Capteur to plot capteur_selection = CheckboxGroup(labels=available_capteur, active=[0]) capteur_selection.on_change('active', update) text_input = TextAreaInput( value='Start:\n2019-08-08 18:20:00\n \nEnd:\n2019-08-08 18:27:00\n ', rows=5, title="Date: Year-Month-Day Hour:Minute:Second") text_input.on_change('value', update) initial_capteur = [ capteur_selection.labels[i] for i in capteur_selection.active ] l = text_input.value L_text_input = [] for val in l.split('\n'): L_text_input.append(val) initial_text_input_start = L_text_input[1] initial_text_input_end = L_text_input[4] src = make_dataset(initial_capteur, initial_text_input_start, initial_text_input_end, available_name[0], L_influx) source = ColumnDataSource(src) #Make the plot datatable = make_table(source, src) #Download part button = Button(label='Download', button_type='success') button.callback = CustomJS(args=dict(source=source), code=open(join(dirname(__file__), "download.js")).read()) #text_banner = Paragraph(text='To download the displayed data, please indicate the name you want to give to the file in the box below. The file will be automatically created in CSV format in the "Folder_CSV" folder as soon as you click on the "Download" button', width=250, height=130) #path_input=TextInput(value="Name", title="Name of the file :") # Put control in a single element controls = WidgetBox(select, capteur_selection, text_input, button) layout = row(controls, datatable) tab = Panel(child=layout, title='Summary Table') return tab