score:1

Accepted answer

The reason that your fix works is here:

unitMenu.on('change', function() {

    // find which unit was selected from the dropdown
    var selectedUnit = d3.select(this)
        .select("select")
        .property("value");

    // run update with selected unit
    updateGraph(selectedUnit);

});   

You're attaching the change event listener to the whole div containing the dropdown in your corrected version, whereas before, it was getting attached to the enter selection from your data binding call, which is the array of option elements within the select. Those items do not trigger a change event when you select different elements in the dropdown. Even if they did, this code:

    var selectedUnit = d3.select(this)
        .select("select")
        .property("value");

is searching for a select element within this, which, for an event listener, is the element that triggered the event. If this is an option element, there is no select element to be found within it!

You could also have generated working code by assigning the select element to unitMenu and then altering the code that handles the event:

var unitMenu = d3.select("#dropdown")
.append("select");

unitMenu
.selectAll("option")
    .data(unitOptions)
    .enter()
    .append("option")
    .attr("value", (d) => {return d;})
    .text((d) => {return d;});

[...]

unitMenu.on('change', function() {
    var selectedUnit = d3.select(this)  // this is the select element
        .property("value");

    updateGraph(selectedUnit);
});   

Related Query