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