如何根据键盘输入使圆圈消失?
How to make the circles disappear based on keyboard input?
基于这个例子: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);
}
尝试将您的更新函数更改为:
function update(nValue) {
days = days.slice(nValue);
}
我花了一段时间才明白你在这里的目的,我的理解可能还有点偏差。
问题
据我所知,您正在修改数据数组(在本例中使用 select 菜单),但修改后的数组似乎并未修改您的可视化。本质上,如 "the array days is getting shorter ... let circles based on the value[s] of the array disappear."
更新可视化
要更新可视化,您需要将新数据绑定到您的 selection。在此之后,您可以删除可视化中不需要的元素、添加新元素(与此问题无关)或修改现有元素。单独更改数据数组不会更新可视化。要让可视化利用新信息,您需要将该数据绑定到 selection:
circle.data(data);
然后您可以删除旧项目:
circle.exit().remove();
然后你可以修改旧项目的属性:
circle.attr('cx',function(d,i) {...
您的更新函数至少需要更新数据并删除不需要的元素。
更改数组
在下面的代码片段中,我根据数组中的数据附加了一个 select 菜单和带有 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 不知道你删除了第二项,你可能修改了元素二和三并删除了元素四。
由于您的所有项目都附加了它们的增量(它们在数组中的位置),并且这不考虑删除其他项目时产生的空洞,您需要稍微改变一下方法。
一个解决方案
而不是依赖数组中项目的增量(因为每次从数组中删除另一个元素之前的元素都会改变),您可以在您的数据。
这需要稍微重组您的数据。类似于:
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>
基于这个例子: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);
}
尝试将您的更新函数更改为:
function update(nValue) {
days = days.slice(nValue);
}
我花了一段时间才明白你在这里的目的,我的理解可能还有点偏差。
问题
据我所知,您正在修改数据数组(在本例中使用 select 菜单),但修改后的数组似乎并未修改您的可视化。本质上,如 "the array days is getting shorter ... let circles based on the value[s] of the array disappear."
更新可视化
要更新可视化,您需要将新数据绑定到您的 selection。在此之后,您可以删除可视化中不需要的元素、添加新元素(与此问题无关)或修改现有元素。单独更改数据数组不会更新可视化。要让可视化利用新信息,您需要将该数据绑定到 selection:
circle.data(data);
然后您可以删除旧项目:
circle.exit().remove();
然后你可以修改旧项目的属性:
circle.attr('cx',function(d,i) {...
您的更新函数至少需要更新数据并删除不需要的元素。
更改数组
在下面的代码片段中,我根据数组中的数据附加了一个 select 菜单和带有 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 不知道你删除了第二项,你可能修改了元素二和三并删除了元素四。
由于您的所有项目都附加了它们的增量(它们在数组中的位置),并且这不考虑删除其他项目时产生的空洞,您需要稍微改变一下方法。
一个解决方案
而不是依赖数组中项目的增量(因为每次从数组中删除另一个元素之前的元素都会改变),您可以在您的数据。
这需要稍微重组您的数据。类似于:
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>