我想更改d3.js地图中当前所选要素的颜色。但是,我的代码会更改我单击的每个功能的颜色。如何重置地图,以便在单击某个功能时,之前单击的所有其他功能将重置为默认颜色?以下是我的代码。 “点击”功能会发生颜色变化:
function ready(error, us) {
svg.append("g")
.selectAll("path")
.data(topojson.feature(us, us.objects.ecol3_wgs84).features)
.enter()
.append("path")
.attr("transform", "scale(" + SCALE + ")") //scale the map
.attr("class", "region")
.attr("ecoregion", function (d, i) {
return us.objects.ecol3_wgs84.geometries[i].properties.US_L3NAME;
})
.attr("d", path)
.on("mouseover", function (d) {
d3.select("h3").text(d.properties.US_L3NAME);
d3.select(this).attr("class", "region hover");
})
.on("mouseout", function (d) {
d3.select("h3").text("");
d3.select(this).attr("class", "region");
})
.on("click", function (d) {
var name = d.properties.US_L3NAME;
var region = d3.select("#regName");
region.property("value", name);
d3.select(this).style("fill", getColor(name));
});
}
function getColor(n) {
var selectedRegion = "";
selectedRegion = $("#regName").val();
if (n == selectedRegion) {
return 'orange';
}
else {
return '#005DAA';
}
}
答案 0 :(得分:5)
在点击事件中,您可以将所有其他功能重置为默认状态,然后将点击的功能设置为所需的样式:
.on("click", function (d) {
svg.selectAll('path').attr('class','region');
d3.select(this).attr('class','selected');
})
为选定的课程创建课程样式。 据我所知,如果你使用selection.style应用一个样式,它将覆盖你的css样式,这就是为什么我在这里提出一个只使用类的解决方案。但是这给了我一个替代解决方案的想法,只需要很少修改你的代码,见下文
但主要问题是,当您将鼠标移开时,您会将点击的功能重置为默认样式:
.on("mouseout", function (d) {
d3.select("h3").text("");
d3.select(this).attr("class", "region");
})
由于点击必须在鼠标移出之前发生,因此一旦鼠标移动,您将失去点击样式。
将mouseover / mouseoff和click结合起来可能很难在所有情况下获得所需的行为。
你需要:
从点击的功能中删除鼠标输出的事件侦听器,但在不再“点击”或激活后将其放回。
删除所点击功能的鼠标悬停监听器,但在不再“点击”后将其重新放回。否则,鼠标悬停将改变您的样式,一旦您将鼠标悬停在单击的特征上,这在处理小特征或不规则绘制的特征(如生态区域/区域)时很容易。
点击事件发生时很容易删除:
d3.select(this).on('mouseout',null)
在单击下一个功能时添加侦听器会有一些工作。
这样做会稍微改变你的代码。我将在这里展示一个潜在的解决方案,但删除对更改输入框和标题的引用,以便它更清洁:
.on("mouseover", function (d) {
d3.select(this).attr("class", "region hover");
d3.select(this).on("mouseout", function(d) {
d3.select(this).attr("class", "region");
})
})
.on("click", function (d) {
svg.selectAll('path').attr('class','region'); // ensure every other feature is set to default
d3.selectAll('path').on("mouseover", function (d) { // add a mouseover event to every feature in order to get the last one clicked
d3.select(this).attr("class", "region hover");
d3.select(this).on("mouseout", function(d) {
d3.select(this).attr("class", "region"); // add a mouseout event to every feature on mouseover
});
});
d3.select(this).on("mouseout", null); // cancel mouseover out events for the clicked feature.
d3.select(this).on('mouseover',null);
d3.select(this).attr('class','selected');
});
I packaged up an example here, with your geographic features。您可以通过使用鼠标悬停功能的功能来清理它,这部分基本上是重复的。最后,可能有更好的方法来实现这一目标,这只是一个目标。但是,这应该说明如何设置事件监听器,以便它们不会相互冲突,并获得您正在寻找的结果。
更快的解决方案:(参考上文)
您应该能够修改单击功能以从其他单击的元素中去除使用selection.style应用的任何填充样式,然后将其应用于单击的功能:
.on("click", function (d) {
d3.selectAll('path').style('fill',null);
d3.select(this).style("fill","orange")
});
这应该适用于您在上面发布的代码。