我正在尝试在数组中保存选定的圆圈,以便稍后我可以操纵这些圆圈而无需搜索页面上的所有圆圈。我希望能够从不同的功能访问圆圈,而不是创建它们。
// From outer function
var selections = [];
// From inner function A
circles.on("click", function(da){
d3.selectAll("circle").filter(function(db){
var result = da.someProperty == db.someProperty;
var circle = d3.select(this);
if(result) selections.push(circle);
return result;
})
.attr("fill", "red");
});
// From inner function B
selections.forEach(function(circle){
circle.attr("fill", "black"); // Doesn't work
});
有没有办法使用我的选择数组的内容修改圆属性?
答案 0 :(得分:5)
从D3的角度来看,适用于您的方法的一些改进将使您的代码更具可读性和 D3ish 。尝试通过D3' concept of selections来了解它。即使不知道您的整个代码,您问题中发布的代码段也可能会被重构为:
// From outer function
// This will hold the selection in the outer scope.
var selections;
// From inner function A
circles.on("click", function(da){
// Fill in the reference to the selection which is returned by filter().
selections = d3.selectAll("circle").filter(function(db){
return da.someProperty == db.someProperty;
})
.attr("fill", "red");
});
// From inner function B
// No need for an explicit loop here; D3 will take care of that.
selections.attr("fill", "black");
filter()
函数将返回您所选择的选项,而无需摆弄任何辅助数组。您只需在selections
中将对该选择的引用存储在外部范围内。
稍后,当你以某种方式想要对此选择进行操作时,不需要对数组进行显式循环,因为D3会处理这个问题。您可以调用其处理属性,样式,事件处理程序等的方法。有关d3.select()
上提供的所有方法,请参阅API docs。
答案 1 :(得分:2)
在你的selections.forEach(...)中,看一下" circle"实际上是。从我测试过(我必须创建变量"圆圈"提前,这只是d3.selectAll(' circle'),但你应该特别包括您在提示中使用的内容),"圈"在你的函数中,B循环是指一个1单元格的数组,它包含另一个单元格数组,该数组包含一个圆形引用(对于原生HTML / SVG圆,而不是d3包装器)。
将B循环功能的内容更改为
d3.select(circle[0][0]).attr('fill','black');
也许这是一种更优雅,面向d3的方式,但这绝对有效,而且它仍然很简单。
编辑:经过进一步测试后,我实际上并不确定为什么你所做的事情不起作用。一旦我将var circles = d3.selectAll('circle');
添加到开头,假设您在运行之前实际点击了一个圆,则功能B循环正常工作。如果你没有,你就会重复一个空数组。
答案 2 :(得分:0)
这是一个有效的jsfiddle
var jsonCircles = [{
"x_axis": 30,
"y_axis": 30,
"radius": 20,
"color": "green"
}, {
"x_axis": 70,
"y_axis": 70,
"radius": 20,
"color": "purple"
}, {
"x_axis": 110,
"y_axis": 100,
"radius": 20,
"color": "red"
}, {
"x_axis": 150,
"y_axis": 230,
"radius": 70,
"color": "yellow"
}, {
"x_axis": 300,
"y_axis": 100,
"radius": 90,
"color": "grey"
}];
var svgContainer = d3.select("body").append("svg")
.attr("width", 400)
.attr("height", 400);
var circles = svgContainer.selectAll("circle")
.data(jsonCircles)
.enter()
.append("circle");
var circleAttributes = circles.attr("cx", function (d) {
return d.x_axis;
})
.attr("cy", function (d) {
return d.y_axis;
})
.attr("r", function (d) {
return d.radius;
})
.style("fill", function (d) {
return d.color;
});
var selection = [];
d3.selectAll('circle')[0].forEach(function (circle) {
if (circle.r.baseVal.value > 20) {
selection.push(circle);
}
});
alert('We have ' + selection.length + 'circle(s) selected');
selection.forEach(function (circle) {
circle.style.fill = "blue";
});