【问题标题】:How to make the circles disappear based on keyboard input?如何根据键盘输入使圆圈消失?
【发布时间】:2017-07-25 14:54:21
【问题描述】:

基于此示例: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);
}

【问题讨论】:

    标签: javascript arrays d3.js slice


    【解决方案1】:

    我花了一段时间才看到你在这里的目的,我的理解可能仍然有点偏差。

    问题

    据我所知,您正在修改数据数组(在这种情况下使用选择菜单),但修改后的数组似乎不会修改您的可视化。本质上,因为“数组天数越来越短......让基于数组值[s]的圆圈消失。”

    更新可视化

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

    circle.data(data);
    

    然后你可以删除旧的项目:

    circle.exit().remove();
    

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

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

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

    改变数组

    在下面的 sn-p 中,我根据数组中的数据附加了一个选择菜单和带有 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');
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"&gt;&lt;/script&gt;

    这里有个问题,每次只去掉最后一个圆圈和菜单项。为什么?想象一个四元素数组,如果你删除了第二项,d3 并不知道你删除了第二项,你可能已经修改了元素 2 和 3,并删除了元素 4。

    由于您的所有项目都附加了它们的增量(它们在数组中的位置),并且这并没有考虑到在移除其他项目时创建的孔,您需要稍微改变方法。

    解决方案

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

    这需要稍微重构您的数据。比如:

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

    由于 id 属性不会改变,这使得设置属性的属性更好。看看下面的sn-p:

    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');
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 我想知道这条线start.property('selected', 'selected');property() 是 javascript 函数还是从哪里获得的?我找不到定义。
    • 看看:github.com/d3/d3-selection#selection_property,它很简短,但可能会有所帮助。
    • 谢谢亚当,你帮了大忙。现在我得到了最后一个问题。我希望小“选择”窗口向我显示 id 而不是值,所以我将其更改为 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.id; }); 现在我要选择,屏幕上显示多少个圆圈。那么,当我想在屏幕上显示 8 个圆圈时,将拼接功能更改为:data.splice(i,data.length - id); 是否正确?
    • 一天中的大部分时间我都只用手机,但稍后再看看。但是,如果您想要更多的受众(其他潜在的回答者可能看不到此评论)并因此可能获得更快的回复,您可以将其作为一个新问题发布。
    • 今晚将深入研究它,同时非常紧张。
    【解决方案2】:

    尝试将您的更新功能更改为:

    function update(nValue) {
    
     days = days.slice(nValue);
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 2011-03-05
      相关资源
      最近更新 更多