RadioButtonGroup on_click behaviour

Working with a figure and a RadioButtonGroup, I have callback functions for both which should result in a change in the figure/RBG when a change in the RBG/figure occurs, respectively.

However, when the figure callback is triggered and changes the value of the RBG, the BRG callback is triggered as well (i.e the RBG callback is triggered not when the button is clicked but when it’s value changes).

How do I trigger the RBG callback only if the buttons are clicked on?

#Create RBG
cZone = RadioButtonGroup (
labels=cZoneList,
active=-1,
)

rbgCallback = CustomJS(args=dict(source=geosource),code="""
console.log(‘rbgCallback event’)
console.log(cb_obj)
“”")

#Create figure object.
p = figure(title = ‘USA Climate Zone Map’, plot_height = 450 , plot_width = 800, toolbar_location = “below”, tools=select_tools)
p.add_tools(hover)
p.add_tools(tap)

figureCallback = CustomJS(args=dict(source=geosource, rbg=cZone),code="""
console.log(‘Tap event’)
var n = source.selected.indices.length
console.log(n)
if (n>0) {
rbg.active = source.selected.indices[0]
} else {
rbg.active = -1
}
“”")

#on event
p.js_on_event(‘tap’, figureCallback)
cZone.js_on_click(rbgCallback)

#show
layout = column(p, cZone)
show(layout)

``

Capture.PNG

It is obvious that your figureCallback will trigger RBG callback as you are setting its “active” property in that callback.

It could help a lot if you explained what are you trying to achieve?

Do you want to select a patch in your map when RBG is clicked and vice versa?

Currently your code:

p.js_on_event(‘tap’, figureCallback)

``

will trigger the figureCallback even if no patch is clicked on the map e.g. also when you click on white area on the plot.

With that respect you could be possibly better off switching to:

geosource.selected.js_on_change(‘indices’, figureCallback)

``

where you could set your button in RBG and have your current figureCallback only reset the RGB when geosource.selected.indices is empty (a click on white area on the plot)

···

On Friday, March 15, 2019 at 11:04:47 AM UTC+1, Noam Naveh wrote:

Working with a figure and a RadioButtonGroup, I have callback functions for both which should result in a change in the figure/RBG when a change in the RBG/figure occurs, respectively.

However, when the figure callback is triggered and changes the value of the RBG, the BRG callback is triggered as well (i.e the RBG callback is triggered not when the button is clicked but when it’s value changes).

How do I trigger the RBG callback only if the buttons are clicked on?

#Create RBG
cZone = RadioButtonGroup (
labels=cZoneList,
active=-1,
)

rbgCallback = CustomJS(args=dict(source=geosource),code=“”"
console.log(‘rbgCallback event’)
console.log(cb_obj)
“”")

#Create figure object.
p = figure(title = ‘USA Climate Zone Map’, plot_height = 450 , plot_width = 800, toolbar_location = “below”, tools=select_tools)
p.add_tools(hover)
p.add_tools(tap)

figureCallback = CustomJS(args=dict(source=geosource, rbg=cZone),code=“”"
console.log(‘Tap event’)
var n = source.selected.indices.length
console.log(n)
if (n>0) {
rbg.active = source.selected.indices[0]
} else {
rbg.active = -1
}
“”")

#on event
p.js_on_event(‘tap’, figureCallback)
cZone.js_on_click(rbgCallback)

#show
layout = column(p, cZone)
show(layout)

``

Tony thank you for clarifying this is now solved -

#Match map and radiobuttons selctor via JS callback function
geosourceCallback= CustomJS(args=dict(source=geosource, rbg=cZone),code=“”"
// if condition to prevent loop of events between the callback func’s
if (source.selected.indices[0] != rbg.active) {
console.log(‘Figure call back event’)
var n = source.selected.indices.length
if (n>0) {
rbg.active = source.selected.indices[0]
} else {
rbg.active = -1
}
}
“”")

rbgCallback = CustomJS(args=dict(source=geosource),code=“”"
// if condition to prevent loop of events between the callback func’s
if (source.selected.indices[0] != cb_obj.active && cb_obj.active != -1) {
console.log(‘rbgCallback event’)
source.selected.indices[0] = cb_obj.active
source.change.emit()
}
“”")

geosource.selected.js_on_change(‘indices’, geosourceCallback)
cZone.js_on_change(‘active’, rbgCallback)

``

(slightly straying perhaps)

whilst this is working fine and there are no ‘loops’ within the callback functions, i still don’t understand the .emit() functionality here - I had to introduce it for the rbgCallback (otherwise the figure won’t update), however the geosourceCallback seems to function just fine without.

thanks

···

On Friday, March 15, 2019 at 4:34:52 PM UTC, tony halik wrote:

It is obvious that your figureCallback will trigger RBG callback as you are setting its “active” property in that callback.

It could help a lot if you explained what are you trying to achieve?

Do you want to select a patch in your map when RBG is clicked and vice versa?

Currently your code:

p.js_on_event(‘tap’, figureCallback)

``

will trigger the figureCallback even if no patch is clicked on the map e.g. also when you click on white area on the plot.

With that respect you could be possibly better off switching to:

geosource.selected.js_on_change(‘indices’, figureCallback)

``

where you could set your button in RBG and have your current figureCallback only reset the RGB when geosource.selected.indices is empty (a click on white area on the plot)

On Friday, March 15, 2019 at 11:04:47 AM UTC+1, Noam Naveh wrote:

Working with a figure and a RadioButtonGroup, I have callback functions for both which should result in a change in the figure/RBG when a change in the RBG/figure occurs, respectively.

However, when the figure callback is triggered and changes the value of the RBG, the BRG callback is triggered as well (i.e the RBG callback is triggered not when the button is clicked but when it’s value changes).

How do I trigger the RBG callback only if the buttons are clicked on?

#Create RBG
cZone = RadioButtonGroup (
labels=cZoneList,
active=-1,
)

rbgCallback = CustomJS(args=dict(source=geosource),code=“”"
console.log(‘rbgCallback event’)
console.log(cb_obj)
“”")

#Create figure object.
p = figure(title = ‘USA Climate Zone Map’, plot_height = 450 , plot_width = 800, toolbar_location = “below”, tools=select_tools)
p.add_tools(hover)
p.add_tools(tap)

figureCallback = CustomJS(args=dict(source=geosource, rbg=cZone),code=“”"
console.log(‘Tap event’)
var n = source.selected.indices.length
console.log(n)
if (n>0) {
rbg.active = source.selected.indices[0]
} else {
rbg.active = -1
}
“”")

#on event
p.js_on_event(‘tap’, figureCallback)
cZone.js_on_click(rbgCallback)

#show
layout = column(p, cZone)
show(layout)

``

In general if you modify the data source (like in your case) you need to use: source.change.emit()

Exceptions are:
source.data = new_data => replacing not a part (like in your case) but entire source data

source.stream(new_data)** => appending** to existing source data

···

On Monday, March 18, 2019 at 2:22:45 PM UTC+1, Noam Naveh wrote:

Tony thank you for clarifying this is now solved -

#Match map and radiobuttons selctor via JS callback function
geosourceCallback= CustomJS(args=dict(source=geosource, rbg=cZone),code=“”"
// if condition to prevent loop of events between the callback func’s
if (source.selected.indices[0] != rbg.active) {
console.log(‘Figure call back event’)
var n = source.selected.indices.length
if (n>0) {
rbg.active = source.selected.indices[0]
} else {
rbg.active = -1
}
}
“”")

rbgCallback = CustomJS(args=dict(source=geosource),code=“”"
// if condition to prevent loop of events between the callback func’s
if (source.selected.indices[0] != cb_obj.active && cb_obj.active != -1) {
console.log(‘rbgCallback event’)
source.selected.indices[0] = cb_obj.active
source.change.emit()
}
“”")

geosource.selected.js_on_change(‘indices’, geosourceCallback)
cZone.js_on_change(‘active’, rbgCallback)

``

(slightly straying perhaps)

whilst this is working fine and there are no ‘loops’ within the callback functions, i still don’t understand the .emit() functionality here - I had to introduce it for the rbgCallback (otherwise the figure won’t update), however the geosourceCallback seems to function just fine without.

thanks

On Friday, March 15, 2019 at 4:34:52 PM UTC, tony halik wrote:

It is obvious that your figureCallback will trigger RBG callback as you are setting its “active” property in that callback.

It could help a lot if you explained what are you trying to achieve?

Do you want to select a patch in your map when RBG is clicked and vice versa?

Currently your code:

p.js_on_event(‘tap’, figureCallback)

``

will trigger the figureCallback even if no patch is clicked on the map e.g. also when you click on white area on the plot.

With that respect you could be possibly better off switching to:

geosource.selected.js_on_change(‘indices’, figureCallback)

``

where you could set your button in RBG and have your current figureCallback only reset the RGB when geosource.selected.indices is empty (a click on white area on the plot)

On Friday, March 15, 2019 at 11:04:47 AM UTC+1, Noam Naveh wrote:

Working with a figure and a RadioButtonGroup, I have callback functions for both which should result in a change in the figure/RBG when a change in the RBG/figure occurs, respectively.

However, when the figure callback is triggered and changes the value of the RBG, the BRG callback is triggered as well (i.e the RBG callback is triggered not when the button is clicked but when it’s value changes).

How do I trigger the RBG callback only if the buttons are clicked on?

#Create RBG
cZone = RadioButtonGroup (
labels=cZoneList,
active=-1,
)

rbgCallback = CustomJS(args=dict(source=geosource),code=“”"
console.log(‘rbgCallback event’)
console.log(cb_obj)
“”")

#Create figure object.
p = figure(title = ‘USA Climate Zone Map’, plot_height = 450 , plot_width = 800, toolbar_location = “below”, tools=select_tools)
p.add_tools(hover)
p.add_tools(tap)

figureCallback = CustomJS(args=dict(source=geosource, rbg=cZone),code=“”"
console.log(‘Tap event’)
var n = source.selected.indices.length
console.log(n)
if (n>0) {
rbg.active = source.selected.indices[0]
} else {
rbg.active = -1
}
“”")

#on event
p.js_on_event(‘tap’, figureCallback)
cZone.js_on_click(rbgCallback)

#show
layout = column(p, cZone)
show(layout)

``