🏠 back to Observable

Scoping problems (probably a Newbie error)

I create a chart, include an event listener that updates a variable used by the chart and repaints the chart. The problem is that when the chart is updated with a separate variable elsewhere, the updated value from the listener is lost and reverts to the original.

percentileTheory = {
const svg = d3.create(“svg”)
.attr(“viewBox”, [0, 0, width, height]);

svg.on(“mousedown”, (event) => {
meanDiff = zScale.invert(d3.pointer(event)[0]);
mouseDragging = true;
paint();
})

function paint() {
//modifies the svg using meanDiff
}

return svg.node();
}

if I define meanDiff inside the chart

let meanDiff = 0.8;

it works fine for the initial paint and updates correctly for the dragging. However, when an input option changes a value (not related to meanDiff), the chart reverts to the original value of meanDiff. All attempts to define meanDiff outside the scope of the chart produces an error when I try to assign a new value to meanDiff inside the mouse down function. How do I save the new value of meanDiff?

One way to directly have what you want is using the mutable keyword - https://observablehq.com/@observablehq/introduction-to-mutable-state. But it’s not very recommended, and another way could be to create an .update() method in your svg chart, and call it when the input option changes a value, without direct dependency between the input cell and the svg cell.

See A bit confused about 'mutable', etc for more about the different ways of synchronizing the states of two “views”

See also another thread about the same problem: how to control cell updating in response to value changes in dependency cells?

mutable got it working. I see its dangers and I will continue exploring ways to avoid it. I already had an update() function [mine is paint()] but I hadn’t been able to make that work. Your helpful references got me exploring on the right track and I will continue. thanks.

1 Like