I am trying to create a dashboard of data for our university, and have run into a problem with how it is presenting. I am using Bokeh and Python to create somewhat interactive graphs. My checkbox group is not updating when I click a box to select the college for the major. I have tried changing several items, but cannot figure out what I am doing wrong.
My code:
# Available college list
available_colleges = list(df['College'].unique())
source_maj = ColumnDataSource(df)
grouped_maj = df.groupby('Major').sum()
source_maj = ColumnDataSource(grouped_maj)
major = source_maj.data['Major'].tolist()
p_maj = figure(x_range=major, width=1100, height=500)
p_maj.xaxis.major_label_orientation = math.pi/4
color_map = factor_cmap(field_name='Major',
palette=Magma11, factors=level)
p_maj.vbar(x='Major', top='AY2018_19', source=source_maj, width=0.2, color=color_map)
p_maj.title.text ='Enrollment by Major'
p_maj.xaxis.axis_label = 'Major'
p_maj.yaxis.axis_label = 'Enrolled Students'
hover = HoverTool()
hover.tooltips = [
("2019-2020", "@AY2019_20"),
("2018-2019", "@AY2018_19"),
("2017-2018", "@AY2017_18")]
hover.mode = 'vline'
callback = CustomJS(args=dict(source=source_maj), code="""
const labels = cb_obj.labels;
const active = cb_obj.active;
const data = source_maj.data;
const sourceLen = data.combined.length;
const combined = Array(sourceLen).fill(undefined);
if (active.length > 0) {
const selectedColumns = labels.filter((val, ind) => active.includes(ind));
for(let i = 0; i < sourceLen; i++) {
let sum = 0;
for(col of selectedColumns){
sum += Major[col][i];
}
combined[i] = sum;
}
}
Major.combined=combined;
source_maj.change.emit();
""")
colleges_selection = CheckboxGroup(labels=available_colleges, active = [0], callback=callback)
controls = WidgetBox(colleges_selection)
p_maj = row(controls, p_maj)
Data is formated in a csv sheet that is being read
What it looks like, but nothing updates
Any help is greatly appreciated.
You'll probably want to watch the output the browser sends to the javascript console; it'll tell you what's going wrong here.
A couple places to start: your arguments to the CustomJS object bring in the python object 'source_maj' and rename it as 'source', but then in your JS code you refer to it as 'source_maj'. Also, your JS code makes reference to 'Major', but this isn't an object that the JS knows about (i.e. it wasn't brought in with the args).