I have a d3 chart that is using d3.drag()
to gather data on user mouse placement. Everytime the user drags on the chart I want to update the value of my cell to be watched with a viewof
.
My problem is I can’t figure out what the best way to get the new cell.value
out of the callback scope. In normal JS development I would set up an observable, but, I figure there is a way to do it in a notebook without starting observable-ception.
The following is an example notebook of what I am talking about.
https://beta.observablehq.com/@nstrayer/how-to-get-data-out-of-internal-callback
1 Like
We’re hoping to add pleasant support for mutable-and-reactive values shortly, that should make patterns like these more obvious and straightforward to write — but in the meantime, you can already do it, because you can change the value of your view.
Instead of:
//const to_return = svg.node();
//to_return.value = [];
//yield to_return;
Try something like this:
const to_return = svg.node();
to_return.value = data; // Or whatever you want your updated value to be.
to_return.dispatchEvent(new CustomEvent("input"));
This works because viewof
cells are designed to update themselves and their values whenever they hear an "input"
event. It’s the API for manually telling a view: update!
3 Likes
Right—I don’t think you need mutation for a case like this. It’s a natural fit for viewof
where you have a DOM element that is your display (your view) and a corresponding JavaScript value. The only thing you need to implement a custom view is to dispatch an input event and assign to element.value.
Here’s an example of dragging in a canvas that exposes the drawn stroke:
https://beta.observablehq.com/@mbostock/draw-me
(This one requires a mouse… I should probably update it to use d3-drag but it’s nice to have no dependencies.)
2 Likes
Here’s a “Draw Me” example using d3-drag:
1 Like
All of these worked wonderfully! Thanks a ton. I knew I had seen something about a dispatching new event method but couldn’t remember where or how.