holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.68k stars 508 forks source link

.param.watch onlychanged flag not working as expected #5363

Open diehl opened 1 year ago

diehl commented 1 year ago

ALL software version info

PyDeck 0.8 Panel 1.2.0 Jupyter Notebook 7

Description of expected behavior and the observed behavior

Defining a watcher on a DeckGL pane that is monitoring click state with the onlychanged flag set to False is not producing what I believe is the expected behavior, which is that the callback function will get executed regardless of whether the click state changes or not. In other words, the callback function will execute with every click.

The key line of code to instantiate this in the following demo is:

map.param.watch(callback,['click_state'],onlychanged=False)

Complete, minimal, self-contained example code that reproduces the issue

Jupyter notebook example: https://gist.github.com/diehl/42f3801272587ce6ea60004dd17b7d8e

Screenshots or screencasts of the bug in action

The following screencast shows the example in action. The intent here was to realize code that allows the user to toggle the highlighted geometry on and off with a click. What actually occurs is that the visibility toggle only happens if the user moves the mouse pointer to a new location prior to each click. The video highlights that when multiple clicks occur in the same location, the subsequent clicks do not toggle visibility. I expected that with onlychanged=False the toggle would occur with each click, regardless of whether or not the click state changed. Strangely enough, there are also some more infrequent cases, as shown in the video, that even with a move to a new mouse location, a click doesn't toggle visibility. Maybe I'm misunderstanding how .param.watch should behave?

https://github.com/holoviz/panel/assets/349843/2c7fcda7-1632-4742-ac60-98c3ddbf6f59

philippjfr commented 1 year ago

The issue here comes down to the fact that while Param will trigger new events, Bokeh will not send a new event if the value of a property hasn't changed. The way we could address this is to use explicit BokehEvents for sending the click state rather than updating a property.

diehl commented 1 year ago

@philippjfr That makes sense. Is there a direct way to trigger callbacks based on clicks as opposed to a click state change? That is ultimately what I want but I could not figure out how to do that from the documentation. This was my attempt to get there via an indirect path.

MarcSkovMadsen commented 1 year ago

An alternative to sending explicit BokehEvents would be to add a unique value to the click parameter value on the js side. That is what I've been doing in the panel extensions I manage.

This is a general issue which would be really nice to have a solution or a best practice for handling.

diehl commented 1 year ago

@MarcSkovMadsen In the interim, is there a direct way to trigger callbacks based on clicks as opposed to a click state change? I'm not seeing an obvious way to accomplish this from the documentation.