D3 javascript点击一条线来改变线的颜色-改变所有的线
d3 javascript clicking a line to change line color - changes all lines
我有一个力定向图形,想要改变2个节点之间的线的颜色,当我点击这条线。然而,下面的代码改变了所有行的颜色,而不仅仅是我点击的那一行。
我的css为行和点击行:
.link {
fill: none;
stroke: #666;
stroke-width: 2px;
cursor: pointer;
}
.link--clicked {
fill: none;
stroke: red;
stroke-width: 2px;
cursor: pointer;
}
我调用一个函数时,点击行使用:
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; })
.on("click", function(d) { edge_clicked(d); });
function edge_clicked(d) {
d3.select("path").classed("link--clicked", false); //remove color class of any previously clicked link
var clicked = d3.select(this); //select clicked element
path.classed("link--clicked", true); //set class of clicked link
}
我怀疑这与我如何调用路径有关。分类命令,影响所有路径/行,而不仅仅是被点击的行。但是,我不明白所选行的语法。
Gerardo Furtado在他的回答中已经解决了主要缺点,即作用域问题和缺乏使用selectAll
。虽然Gerardo的回答是正确的,但我认为采用不同的方法可能会清理代码和思想。
没有必要使用匿名函数作为click事件的处理程序,它除了调用另一个函数之外什么也不做。直接传入函数edge_clicked
作为事件处理程序将解决作用域问题。
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; })
.on("click", edge_clicked); // Just pass in the handler function
在这种情况下,在处理程序函数中,this
将引用所单击的元素。就我个人而言,我还会为这个函数选择一个不同的实现,它看起来更干净,运行速度也会快一些,因为只需要一个选择而不是两个:
function edge_clicked() {
var clicked = this; // Remember the element clicked upon
d3.selectAll("path").classed("link--clicked", function() {
return clicked === this; // Assign class for clicked element, else unassign class
});
}
这将使用闭包来保存this
的值,即单击的元素,在clicked
中,使其在回调.classed()
时可用。然后,它选择并遍历所有的path
,只将类分配给clicked
元素,而将其取消分配给任何其他元素。
代码中的主要问题是this
的使用。在函数edge_clicked中,this
指向窗口,而不是被单击的元素。
要解决这个问题,首先我们将被点击的元素传递给函数edge_clicked:
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; })
.on("click", function(d) { edge_clicked(this);});
所以,在edge_clicked函数中我们不再需要this
了
现在我们改变函数:
function edge_clicked(elem) {
d3.selectAll(".link").classed("link--clicked", false);//selectAll instead of select
var clicked = d3.select(elem);
clicked.classed("link--clicked", true);//set class of clicked link
}
请注意,我们首先选择所有(不是select
)链接,然后我们只选择被单击的链接。
相关文章:
- 在用Javascript更改背景颜色后:hover don'不要改变颜色
- 如何使用Javascript点击后使形状改变颜色
- 如果我在jquery移动中使用“onclick”,按钮不会改变颜色
- 如何在红绿灯序列中改变颜色
- 按下箭头键时 JS Div 不会改变颜色
- 单击按钮时,背景会改变颜色
- html按钮不会改变颜色
- 当我用鼠标点击身体区域时,那个li标签是如何改变颜色的
- 根据变量onclick改变颜色选择器的值
- 根据值改变颜色
- svg改变颜色属性
- Raphael:如何添加改变颜色的点击动作
- 改变颜色的文本点击使用jQuery
- 根据一天中的时间来改变颜色
- 如何改变颜色时,用户滚动
- 改变颜色的标签和Div周围输入+标签点击
- 如何每秒遍历数组,使h1元素每秒改变颜色
- 为什么我的画布对象在setInterval()被调用后不改变颜色?
- 选择改变颜色图案不会显示
- 避免导航条切换器在选择时改变颜色