score:1

Accepted answer

Strictly speaking you don't need to filter, you can just select which property of the data you wish to visualize:

First, let's make the select menu based on the columns you have, d3.csv will produce an array that looks like:

var data = [
  {"country":"US", "value1": 100, "value2": 50},
  {"country":"UK", "value1": 30, "value2": 20},
  {"country":"Germany", "value1": 40, "value2": 30},
  {"country":"France", "value1": 20, "value2": 10}
];

Now we can get the columns, if using d3.csv we can access the columns with data.columns. Since we don't want the country as an option, just the values, we can slice it off with data.columns.slice(1). I just use a javascript object in my snippets, so I use d3.keys(data[0]).slice(1) to achieve the same effect.

Now we can create a drop down based on how many values we have in our dataset with:

// Create a select element
var select = d3.select("body")
  .append("select")
  .on("change", function() {
     // Log value it is changed to:
     console.log(this.value);
  })

// Add an initial option:
select.append("option")
  .html("Select Value:")

// Add the columns as options:
var options = select.selectAll(null)
  .data(values)
  .enter()
  .append("option")
  .text(function(d) { return d; });

Which gives us this:

var data = [
  {"country":"US", "value1": 100, "value2": 50},
  {"country":"UK", "value1": 30, "value2": 20},
  {"country":"Germany", "value1": 40, "value2": 30},
  {"country":"France", "value1": 20, "value2": 10}
];

// Get the columns. 
var values = d3.keys(data[0])
  .slice(1);

// Create a select element
var select = d3.select("body")
  .append("select")
  .on("change", function() {
     console.log(this.value);
  })

// Add an initial option:
select.append("option")
  .html("Select Value:")

// Add the options:
var options = select.selectAll(null)
  .data(values)
  .enter()
  .append("option")
  .text(function(d) { return d; });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

Now we can use that on change function to pass a property name to an update function (either as a parameter or, as I do below, by taking advantage of the fact that the the callback function's this is the element the event is triggered on). That update function will take that property and use it to modify the visualization:

For example:

select.on("change", update)

function update() {
   var property = this.value; // this is the element.

   // .... scale modification eg: scale.domain(d3.extent(data, function(d) { return d[property]; }))
   // .... enter/update/exit cycle       

   // Use property to shape visualization, eg:
   updateSelection.attr("property", function(d) { return scale(d[property]); })

If you need to refine the scales depending on property or change the type of visualization, you can do it in this function. And of course, you still have access to all of the data's properties here so you could still use other properties to modify the visualization (say in a tooltip).

Below I've created a simple visualization, changing the drop down updates the graph (simply though, no scale modification, though to accommodate a selection of the initial option (which doesn't represent a property of the data) I've used d[property] || 0 when scaling values, which removes the visualization gracefully).

var data = [
  {"country":"US", "value1": 100, "value2": 50},
  {"country":"UK", "value1": 30, "value2": 20},
  {"country":"Germany", "value1": 40, "value2": 30},
  {"country":"France", "value1": 20, "value2": 10}
];

// Get the columns. 
var values = d3.keys(data[0])
  .slice(1);

// Create a select element
var select = d3.select("body")
  .append("select")
  .on("change", update)

// Add an initial option:
select.append("option")
  .html("Select Value:")

// Add the options:
var options = select.selectAll(null)
  .data(values)
  .enter()
  .append("option")
  .text(function(d) { return d; });
  

// Create an SVG
var svg = d3.select("body")
  .append("svg")
  .attr("width", 500)
  .attr("height", 400);
  
// Spice it up with some scales:
var x = d3.scaleBand()
  .domain(data.map(function(d) { return d.country; }))
  .range([0,500])
  
var y = d3.scaleLinear()
  .domain([0,100])
  .range([150,0])
  
// Specify an Update function to create and update visualization elements: 
function update() {
  var value = this.value;
  var bars = svg.selectAll("rect")
    .data(data);
    
  bars.enter().append("rect")
    .attr("x", function(d) { return x(d.country); })
    .attr("width", x.bandwidth())
    .attr("y", 150)
    .attr("height",0)
    .merge(bars)    
    .transition()
    .attr("height", function(d) { return 150 - y(d[value] || 0); })
    .attr("y", function(d) { return y(d[value] || 0); });

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>


Related Query

More Query from same tag