problem changing a mutable value in a function

Hi! I’m attempting to update a mutable state in a mouseover function, which works, but nothing else in the function appears to run. Here is the function, note on the mouseover I would like to change the opacity of some areas and line, which works when I comment out mutable vegadata = out but when I include that, which I want to (it updates a second plot), the selections don’t seem to run.

function mouseEnter(datum) {
  let out = [];
  out.push(datum);

 
  d3.selectAll(".lines").style('opacity', e => {
    return datum.data[0].reporting_unit === e.country ? 1 : 0;
  });

  d3.selectAll(".areas").style('opacity', e => {
    return datum.data[0].reporting_unit === e.country ? .5 : 0;
  });

  d3.selectAll(".areas2").style('opacity', e => {
    return datum.data[0].reporting_unit === e.country ? .5 : 0;
  });

  d3.selectAll(".playerlabel").style('opacity', e => {
    return datum.data[0].reporting_unit === e.country ? 1 : 0;
  });

  mutable vegadata = out;

}

Here’s the notebook for reference. Was a bit cleaner when these were two separate plots, but we decided they should be side by side…

Note the chart updates but the bands not hovered over don’t switch to an opacity of “0”

hmm, so it seems when the mutable value changes the whole cell re-renders and thus any selections in the mouseover function are overwritten by the re-render…

Yes, a common early misunderstanding about mutable is that people forget to think in terms of “cells dependent on other cells re-render”

I’m a bit pressed for time right now, or I would happily dive into your notebook to give more concrete advice, but the general approach to solve this would be on the one hand to refactor some of the cells into fine-grained ones to minimize dependencies on other cells. If mutable then still would trigger the kinds of resets when using cells, the next step is to try to put all code handling and depending on that state in one cell.

someCell = {

  const svg = d3.select(DOM.svg(width, height)); // for example

  let data = ...

  function mouseEnter(datum) {
    /* handle data mutations here */
  }
  
  /*
    other code dependend on data, but careful!
    you are in charge of reactivity again!
  */


  return svg;
}

Good luck! It’s a bit of a balancing act at first to make as much code as possible work with Observable’s reactive cells, but also work with mutability when needed for performance. Once you get the hang of it it is genuinely a lot nicer to work with than raw JavaScript though!

1 Like

Thanks Job, I’ll try some refactoring and partitioning of the code into more cells and see if I can get mutable to cooperate.

1 Like

Good luck! When you manage (or get really stuck again, but let’s stay optimistic) please come back to show the results! :blush:

So I ended up with what I want but abandoned the mutable approach. I did break my code up into more cells but I still ended up with the same issue. My final approach was to kind of go in the opposite direction and put almost everything in one cell. This allowed me to declare variables at the top of the cell and access the values as they are changed in the functions… vegadata (terrible name, oof!) was the mutable variable causing me grief. Anyway, like I said it’s working, though I’m sure there is a better way of going about this. Thanks again for your help!
here’s the notebook as is https://observablehq.com/d/04ba91008569f153

1 Like

Very nice! Hey, if it works it works, right?

Pfft, you should see some of the monstrosities I’ve built :wink: (by which I mean: please don’t, haha)

1 Like