Here’s what I recommend using viewof:
The key part is here in the click listener. Here’s a commented version:
.on("click", (event, d) => {
// If the selection is already the current bin (d), then
// revert the selection back to the entire dataset. If
// preferred, you could change this logic to allow the
// user to toggle individual bins on and off.
selection = selection === d ? data : d;
// Now that the selection is set, recompute the fill color
// of the rect elements. By removing the fill attribute for
// unselected bins (i.e., by returning null), these bins will
// inherit the fill attribute of the parent G element, so we
// don’t have to repeat the gray color. Also, note that we
// reference the rect selection explicitly, rather than re-
// selecting elements through the DOM (which is an anti-
// pattern in Observable because it can select DOM elements
// created by other cells, and because the DOM created by
// other cells can be dynamic!).
rect.attr("fill", d => selection === d ? "blue" : null);
// Lastly, update the SVG element’s value property, which is
// how you define the value of a view, and then dispatch an
// input event to tell Observable to re-run any cells that
// reference the view’s value (i.e., selection).
svg.property("value", selection).dispatch("input");
});