There are a few ways to solve this problem, but I think the easiest is to store the current values in a variable that both the select element change listeners and any code that needs it (e.g. updateSubset
) can access. Here is a simple example:
// all functions in this script can access `current`var current = { colour: 'schemeBlues', size: '30'}// when the select element changes, set the current value of `this.name`// (i.e. either current.colour or current.size) to `this.value`// `this` is the element that triggered the eventfunction changeListener () { current[ this.name ] = this.value // print out current values d3.select('#result') .append('p') .text('Colour: '+ current.colour +'; size: '+ current.size)}// add a select element with `arr` as the option items and `name` as // the select element id and namefunction addCntrl ( arr, name ) { // add a select element var cntrl = d3.select('#controls') .append('select') .attr('name', name ) .attr('id', name ) cntrl.selectAll('option') .data( arr ) .enter() .append( 'option' ) .attr('value', d => d.value ) .text( d => d.name ) // set the selected value to current[name] (i.e. current.colour or current.size) cntrl.property('value', current[name]) cntrl.on('change', changeListener)}function init() { var colours = Object.keys(d3) .filter( function(c){ return (c.indexOf('scheme') !== -1) }) .map( function(c) { return { value: c, name: c.replace('scheme','') .replace(/(\D)(\d)/, '$1 $2') } } ), sizes = [ '10', '20', '30', '40', '50' ].map( e => { return { value: e, name: e } } ) // add select elements to the page addCntrl(colours, 'colour') addCntrl(sizes, 'size')}init()
<script src="http://d3js.org/d3.v5.js"></script><div id="controls"></div><div id="result"></div>
I don't know how your whole script looks, but you could do something similar:
var current = { color: 'blue', size: 'super_massive'}function updateSubset( subset ) { var section_size = current.size, section_color = current.color [ ... ]}function selectChanged() { current[this.name] = this.value; updateSubset( all_data.features )}[ ... ]// make sure that both select elements have their `name` attribute set, then:d3.select('#sizeSection') .on('change', selectChanged)d3.select('#colorSection') .on('change', selectChanged)[ ... ]
or you can also pass in current
if you want to control the scope more tightly:
function updateSubset( subset, opts ) { var section_size = opts.size, section_color = opts.color [ ... ]}[ ... ]function selectChanged() { current[this.name] = this.value; updateSubset( all_data.features, current )}