I am trying to debug an issue with the notebook below, and I’m not sure if it’s a problem with my plot implementation or how I’m using mutable values.
I am using a map with mouseover events on the polygons to filter a second data set by the geographic entity. I’m using a mutable ("mutable cd" below) to set this value to be picked up by the filter. This filtering is working, but my mouseover event is firing over and over again. It seems most likely that I am implementing the mouseevent incorrectly, but I haven’t been able to fix it after a few days of troubleshooting, and I’m wondering if it might have to do with how I’m using mutable values.
I’ve already checked out Mike’s excellent workbooks on mutable values and synchronized views, and I refactored my code to use viewof but, while I was able to get the filtering to work, the mouseover issue is still there. I know that I didn’t fully implement the viewof–I couldn’t figure out how to write the input event dispatch from the hover–but on reading more about it, it seems mutable values are probably the way to go anyway. But perhaps this is my mistake!
I’m afraid I haven’t quite gone the whole way through to fixing the linked notebook, but your problem is pretty straightforward:
By using mutable cd, you’ve managed to introduce a circularity into the dataflow of your notebook’s cells. Every time your mouse over a path on the map, you set mutable cd, which causes filterByCD2 to update, which causes filterData to update, which causes quantileFromHistogram to update, which causes nycCD to update, which in turn causes the map to re-render itself.
And when the map re-renders, now you’ve got a new mouseover event, starting the whole cycle again.
The solution is to break the circularity — which you can do either by avoiding mutable in the first place, or by removing the circular chain of linked dependencies.
Yeah, similar things have been a bit tricky for me, and I’m still not sure what the best pattern is – there are several plausible ways you could approach it.
The general pattern I have adopted is to have interactive diagrams only ever use viewof when referencing any variable which might ever change in response to user input stemming from interaction with that diagram (or elsewhere on the page but that you don’t want to force a re-evaluation of the whole diagram cell). But it’s kind of a pain to make sure that changes to those views always trigger events which re-render relevant parts of the diagram as needed – or at any rate, it takes some manual effort instead of just relying on the platform to do it for you.
Overall I’m still not sure I’m entirely satisfied with the way Observable handles data flow and updates for interactive bits (input elements, interactive diagrams, etc.). There’s a bit of a fundamental conflict between immutable graph-based reevaluation vs. dynamic diagrams that pass data bidirectionally. It’s something that takes trying several times to wrap your head around, and I feel like there might be some better possible pattern. (Though I don’t know what that is, exactly… It’s also possible the community will figure out some ways to make this straightforward and trouble-free and easy to explain without needing to change anything about the platform.)
Thanks @jashkenas, this was very helpful! When I tried to generalize my code, I didn’t do a good enough job, and needed to learn how to pass parameters to my filter callback to eliminate the circularity.