javascript - d3/javascript 根据输入过滤数据

标签 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。有谁知道过滤时如何保留国家属性?

谢谢,

最佳答案

严格来说你不需要过滤,你可以只选择你希望可视化的数据属性:

首先,让我们根据您拥有的列制作选择菜单,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 函数将属性名称传递给更新函数(作为参数,或者像我在下面所做的那样,利用回调函数的 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); });

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

关于javascript - d3/javascript 根据输入过滤数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52119854/

相关文章:

javascript - 没有 jQuery 的带有延迟鼠标移出的 js 工具提示

javascript - 了解元素焦点如何与 JavaScript 配合使用

WordPress:the_content 过滤器杀死了画廊短代码

swift - 如何通过随机键值对过滤数组

在列中第一次出现值后删除行及其后续行(使用 dplyr)

javascript - 当我将鼠标悬停在“产品”菜单上时,此代码需要进行哪些更改以提供正确的外观?

javascript - 如何在 Javascript 中解析以下 JSON?

javascript - d3.js v4.9 获取选定元素的计算宽度

javascript - 具有自定义访问器的 D3 geom.hull

javascript - D3.js-动态更新折线图中的轴