d3 / javascript根据输入过滤数据

时间:2018-08-31 16:57:44

标签: javascript d3.js filter

对不起,如果我的问题可能很基本,但是我已经教过我自己,并且不了解javascript的基本原理就很难继续学习

为了简化我的问题,假设我有如下数据:

country, value1, value2, 
US, 100, 50,
UK, 30, 20,
Germany, 40, 30,
France, 20, 10

我想创建一个保管箱,其中value1和value2是选项。因此,当用户在下拉框中选择value1选项时,将仅显示value1的可视化。

所以我写了一些伪代码,如下所示,根据输入内容过滤数据。

function update() {
var selected = menu.property("value");
data.filter((d) => return d3.keys(d[0]) === selected; )}

听起来还好吗?还是有什么要解决的?

此外,在过滤数据之后,我需要对数据进行更多操作。因此,我需要国家/地区归因以及value1或value2。有人知道在过滤时如何保留国家/地区归属吗?

谢谢

1 个答案:

答案 0 :(得分:1)

严格来说,您不需要过滤,只需选择要可视化的数据属性即可。

首先,让我们根据您拥有的列进行选择菜单,d3.csv将产生一个类似于以下内容的数组:

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}
];

现在我们可以获取列,如果使用d3.csv,我们可以使用data.columns访问列。由于我们不希望将国家(地区)作为选项,因此可以使用data.columns.slice(1)将其分割。 我只是在摘要中使用了一个javascript对象,所以我使用d3.keys(data[0]).slice(1)来达到相同的效果

现在,我们可以根据以下数据创建一个下拉列表:

// 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; });

哪个给我们的呢?

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>

现在,我们可以使用on change函数将属性名称传递给更新函数(作为参数,或者像我在下面所做的那样,通过利用回调函数的{{1} }是触发事件的元素)。该更新功能将采用该属性,并使用它来修改可视化效果:

例如:

this

如果需要根据属性细化比例或更改可视化类型,可以在此功能中进行。当然,您仍然可以在此处访问所有数据属性,因此仍然可以使用其他属性来修改可视化效果(例如在工具提示中)。

下面,我创建了一个简单的可视化文件,更改了下拉菜单会更新图形(虽然没有缩放比例,但是为了适应初始选项的选择(不代表数据的属性))缩放值时使用了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]); }) ,从而优雅地删除了可视化文件。)

d[property] || 0
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); });

}