如何根据键盘输入使圆圈消失?

时间:2017-03-05 20:43:24

标签: javascript arrays d3.js slice

基于此示例:http://bl.ocks.org/d3noob/10633704我希望在键盘上输入一个数字(一个数字),并在array.slice()的帮助下使圆圈消失。不幸的是,它运作不佳。在我的代码中,我根据数组days的值创建了一些圆圈。使用HTML部分,我可以创建一个按钮,我可以在其中输入数字。对于最后一部分days.slice(nValue),我希望输入数字与slice()函数括号内的数字相同,因此数组days变得更短,并自动让圆圈基于数组的值消失了。但不幸的是,我在这段代码中犯了一个错误。有人可能会这么善良和帮助吗?我正在使用D3来解决这个问题。 感谢

<!DOCTYPE html>
<meta charset="utf-8">
<title>Input (number) test</title>

<p>
  <label for="nValue" 
         style="display: inline-block; width: 120px; text-align: right">
         angle = <span id="nValue-value"></span>
  </label>


  <input type="number" min="0" max="360" step="4" value="0" id="nValue">
</p>

<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var width = 600;
var height = 300;

var svg = d3.select("body")
      .append("svg")
      .attr("width", width)    
      .attr("height", height); 



  var days = [7, 12, 20, 31, 40, 50];
  console.log(days);




  var circle = svg.selectAll("circle")
            .data(days)
            .enter().append("circle")
            .attr("cy", 60)
            .attr("cx", function(d, i) { return i * 100 + 40; })
            .attr("r", function(d) { return Math.sqrt(d); });



  d3.select("#nValue").on("input", function() {
  update(+this.value);
});


// Initial update value 
update(0);




function update(nValue) {

days.slice(nValue);
}

2 个答案:

答案 0 :(得分:2)

我花了一段时间才知道你在这里看到了什么,我可能仍然有点理解。

问题

正如我所看到的那样,您正在修改数据数组(在这种情况下使用选择菜单),但修改后的数组似乎不会修改您的可视化。基本上,随着“数组时间越来越短......让基于数组值[s]的圆圈消失。”

更新可视化

要更新可视化,您需要将新数据绑定到您的选择。在此之后,您可以删除可视化中不需要的元素,添加新元素(与此问题无关)或修改现有元素。单独更改数据数组不会更新可视化。要使可视化使用新信息,您需要将该数据绑定到选择:

circle.data(data);

然后你可以删除旧项目:

circle.exit().remove();

然后您可以修改旧项目的属性:

circle.attr('cx',function(d,i) {...

您的更新功能至少需要更新数据并删除不需要的元素。

更改数组

在下面的代码段中,我根据数组中的数据附加了一个选择菜单和带有d3的圆圈。选择菜单中的项目将删除一个圆圈:

var data = [10,20,30,40,50,60,70,80,90,100];

var color = d3.schemeCategory10; // color array built in

//// Add the select and options:
var select = d3.select('body')
  .append('select')
  .on('change',function() { update(this.value) });
  
var start = select.append('option')
  .html("select: ");
  
var options = select.selectAll('.option')
  .data(data)
  .enter()
  .append('option')
  .attr('class','option')
  .attr('value',function(d,i) { return i; })
  .html(function(d) { return d; });


  
//// Add the circles (and svg)
var svg = d3.selectAll('body')
  .append('svg')
  .attr('width',500)
  .attr('height',200);
  
var circles = svg.selectAll('circle')
  .data(data)
  .enter()
  .append('circle')
  .attr('cx',function(d,i) { return i * 30 + 50; })
  .attr('cy',50)
  .attr('r',10)
  .attr('fill',function(d,i) { return color[i]; });
  
  
// Update everything:
function update(i) {
  data.splice(i,1); // remove that element.
  
  // Update and remove option from the select menu:
  options.data(data).exit().remove();
  
  // Remove that circle:
  circles.data(data).exit().remove(); 
  
  circles.attr('cx',function(d,i) { return i * 30 + 50; })
    .attr('fill',function(d,i) { return color[i]; });
  
  // reset the select menu:
  start.property('selected','selected');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

此处存在问题,每次只删除最后一个圆圈和菜单项。为什么?想象一个四元素数组,如果你删除第二个项目,d3不知道你删除了第二个项目,你可能已经修改了元素二和三并删除了元素四。

由于您的所有项目都附加了它们的增量(它们在数组中的位置),并且这不会考虑在删除其他项目时创建的孔洞,因此您需要稍微更改一下该方法。“ p>

解决方案

不是依赖于数组中项的增量(因为每次从数组中删除另一个元素之前的元素时它都会改变),您可以在数据中使用id属性。

这需要对数据进行一些重组。类似的东西:

var data = [ {id:1,value:1},{id2....

由于id属性不会改变,因此这为设置属性提供了更好的属性。请看下面的代码:

var data = [{id:0,value:10},{id:1,value:20},{id:2,value:23},{id:3,value:40},{id:4,value:50},{id:5,value:60},{id:6,value:70},{id:7,value:77},{id:8,value:86},{id:9,value:90}];

var color = d3.schemeCategory10; // color array built in

//// Add the select and options:
var select = d3.select('body')
  .append('select')
  .on('change',function() { update(this.value); } ); // add an event listener for changes

// append a default value:
var start = select.append('option')
  .html("Select:");
  
var options = select.selectAll('.option')
  .data(data)
  .enter()
  .append('option')
  .attr('class','option')
  .attr('value',function(d,i) { return i; })
  .html(function(d) { return d.value; });
  
  
//// Add the circles (and svg)
var svg = d3.selectAll('body')
  .append('svg')
  .attr('width',500)
  .attr('height',200);
  
var circles = svg.selectAll('circle')
  .data(data)
  .enter()
  .append('circle')
  .attr('cx',function(d) { return d.id * 30 + 50; })
  .attr('cy',50)
  .attr('r',10)
  .attr('fill',function(d) { return color[d.id]; });
  
  
// Update everything:
function update(i) {
  data.splice(i,1); // remove the element selected
  
  // Update and remove option from the select menu:
  options.data(data).exit().remove();
  
  // Remove that circle:
  circles.data(data).exit().remove(); 
  
  // update the options (make sure each option has the correct attributes
  options.attr('value',function(d,i) { return i; })
  .html(function(d) { return d.value; })
  
  // Make sure circles are in the right place and have the right color:
  circles.attr('cx',function(d) { return d.id * 30 + 50; })
    .attr('fill',function(d) { return color[d.id]; });
    
  // reset the default value so the change will work on all entries:
  start.property('selected', 'selected');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

答案 1 :(得分:0)

尝试将更新功能更改为:

function update(nValue) {

 days = days.slice(nValue);

}