我正在尝试和修改d3.js的this示例,以根据JSON树结构绘制树。这就是树的一部分开头:
我试图对其进行修改,以便点击文字会将相关圈子的颜色更改为红色。
但事实证明这很难,因为它是一个递归函数。在下面的代码段中,我添加了一个功能myFunction
,可以更改圆圈的颜色,我可以通过文本的on-click
功能调用它。我正在通过我刚刚创建的圈子。
function myFunction(d, myCircle) {
myCircle.style("fill", "red");
}
var myCircle = nodeEnter.append("circle")
.attr("r", 1e-6)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeEnter.append("text")
.attr("x", function(d) { return d.children || d._children ? -10 : 10; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
.text(function(d) { return d.name; })
.style("fill-opacity", 1e-6)
.on("click", myFunction(d, myCircle));
当我进行此更改并单击文本" graph"时,看看会发生什么。该节点的所有兄弟姐妹都变红了:
这是plunker of this broken code。你可以亲自试试。
这是因为递归。所有兄弟姐妹的对象'圈子正在发送到myFunction()
。那不是我需要的。但我不知道如何使这项工作正常。请帮我解释一下如何实现此功能。
答案 0 :(得分:1)
不,它不是递归。 当你这样做时:
function myFunction(d, myCircle) {
myCircle.style("fill", "red");
}
此处myCircle是所有圆圈选择,因此当您单击所有打开的节点变为红色时。
你应该像这样解决这个问题:
function myFunction(d) {
//get all the circles
d3.selectAll("circle")[0].forEach(function(e){
//get the data associated with the circle
var d1 = d3.select(e).data()[0];
if (d1.name == d.name){//check if the data's name and one passed is same
d3.select(e).style("fill", "red");//change color fr only that node.
}
})
}
工作代码here
另一种方式
您无需使用myFunction
,只需在点击功能中执行以下操作。
.on("click", function(d) {
d3.select(this.parentNode).select("circle").style("fill", "red")
});
工作代码here