在d3.js中更改所选地图功能的颜色

时间:2017-02-13 19:45:32

标签: d3.js

我想更改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';
    }
}

1 个答案:

答案 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结合起来可能很难在所有情况下获得所需的行为。

你需要:

  1. 从点击的功能中删除鼠标输出的事件侦听器,但在不再“点击”或激活后将其放回。

  2. 删除所点击功能的鼠标悬停监听器,但在不再“点击”后将其重新放回。否则,鼠标悬停将改变您的样式,一旦您将鼠标悬停在单击的特征上,这在处理小特征或不规则绘制的特征(如生态区域/区域)时很容易。

  3. 点击事件发生时很容易删除:

    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")
       });
    

    这应该适用于您在上面发布的代码。