D3js:鼠标悬停在一个元素上时改变几个其他元素的透明度

4
感谢之前的回答,我已经用D3js制作了地图和相关图表
条形图和地图位于特定的div中,我没有使用相同的数据源,这是我的问题之一。
对于地图,我使用queue.js同时加载多个文件。其中一个文件是.csv文件,其顺序与存储多边形的geojson完全相同。如果我以不同的方式排序.csv文件的数据,则与我的.geojson多边形的对应关系就会出现问题,我的分级地图将变得错误。
下面是与地图交互的多边形的相关代码:
  svg.append("g").attr("class","zones")
    .selectAll("path")
    .data(bureaux.features)   //"bureaux" is a reference to the geojson
    .enter()
      .append("path")
      .attr("class", "bureau")
      .attr("d", path)
      .attr("fill", function(d,i){
          if (progression[i].diff_ries<-16.1){  //"progression" is the reference to my .csv
        return colors[0] // colors is a previous array with the choropleth's colors
      }
      else if (progression[i].diff_ries<-12.6){
        return colors[1]
      }
       else if (progression[i].diff_ries<-9){
        return colors[2]
      }
      else {return colors[3]
      }
    })
    .on('mouseover', tip.show) // tip.show and tip.hide are specific functions of d3.js.tip
    .on('mouseout', tip.hide)

};

没问题,代码运行良好。现在我们来到了图表部分。他在脚本开头使用了一个名为 .json 的数组,像这样

var array=[{"id_bureau":905,"diff_keller":4.05,"diff_ries":-15.02},{etc}];

"

“id_bureau”是我的.geojson,.csv和这个.json数组的共同索引。然后,我使用特定函数对数组进行排序。以下是与图形相关的代码部分:

"
svg2.selectAll(".bar")
.data(array)   
.enter().append("rect")
// I colour on part of the bars like the map
.attr("fill", function(d,i){
          if (array[i].diff_ries<-16.1){
        return colors[0]
      }
      else if (array[i].diff_ries<-12.6){
        return colors[1]
      }
       else if (array[i].diff_ries<-9){
        return colors[2]
      }
      else {return colors[3]
      }
    })
.attr("x", function (d) {
return x(Math.min(0, d.diff_ries));
})
.attr("y", function (d) {
return y(d.id_bureau);
})
.attr("width", function (d) {
return Math.abs(x(d.diff_ries) - x(0));
})
.attr("height", y.rangeBand());

// this part is for the other bars
svg2.selectAll(".bar")
.data(tableau)
.enter().append("rect")
// the others bars are always blue, so I used a simple class
.attr("class", "bar_k")
.attr("x", function (d) {
return x(Math.min(0, d.diff_keller));
})
.attr("y", function (d) {
return y(d.id_bureau);
})
.attr("width", function (d) {
return Math.abs(x(d.diff_keller) - x(0));
})
.attr("height", y.rangeBand());

svg2.append("g")
.attr("class", "x axis")
.call(xAxis);

svg2.append("g")
.attr("class", "y axis")
.append("line")
.attr("x1", x(0))
.attr("x2", x(0))
.attr("y2", height2);

现在,我的目标是当鼠标悬停在一个多边形上时,通过不透明度属性使相应的图表条更加可见(当鼠标移出时,所有图表的不透明度恢复为1)。也许这似乎很明显,但我不知道如何使用“id_bureau”正确地链接地图和图表,因为它们不像在这个问题中那样遵循相同的顺序:Change class of one element when hover over another element d3。有人知道我是否可以轻松地将地图部分的mouseover和mouseout事件转换为同时更改我的图表吗?
1个回答

4

在地图上突出显示一个特征

要聚焦于一个特定的特征,您只需要几行CSS代码:

/* Turn off every features */
#carte:hover .bureau {
  opacity:0.5;
}

/* Turn on the one you are specifically hovering */
#carte:hover .bureau:hover {
  opacity:1;
}

如何在第二个图表中突出显示一条柱形

首先,您需要使用两个类来区分两种类型的柱形:

// First set of bars: .bar_k
svg2.selectAll(".bar_j")
    .data(tableau)
    .enter().append("rect")
    // Important: I use a common class "bar" for both sets
    .attr("class", "bar bar_j")
    // etc...

// Second set of bars: .bar_k
svg2.selectAll(".bar_k")
    .data(tableau)
    .enter().append("rect")
    .attr("class", "bar bar_k")
    // etc...

那么您需要相应地更改mouseenter/mouseleave功能:

svg.append("g").attr("class","zones")
      .selectAll("path")
      .data(bureaux.features)
      .enter()
        // creating paths
        // ...
        // ...
        .on('mouseover', function(d, i) {
          // You have to get the active id to highligth the right bar
          var id = progression[i].id_bureau
          // Then you select every bars (with the common class)
          // to update opacities.
          svg2.selectAll(".bar").style("opacity", function(d) {
            return d.id_bureau == id ? 1 : 0.5;
          });
          tip.show(d,i);
        })
        .on('mouseout',  function(d, i) {
          // To restore the initial states, select every bars and 
          // set the opcitiy to 1
          svg2.selectAll(".bar").style("opacity", 1);
          tip.hide(d,i);
        });

这里有一个演示 (点击链接)

性能问题

这个实现有点慢。你可以通过为想要突出显示的条形图切换一个“active”类来改善它。

另一个好办法是将两种类型的条形图汇集到一个单独的组中,用一个id(例如bureau187)分别描述它们。这样,你就可以直接选择你想要的条形图,在mouseenter函数中打开“active”类。

通过这个类,你可以模仿我实现突出显示功能的策略,并从mouseleave函数中删除 svg2.selectAll(".bar").style("opacity", 1);

/* Turn off every bars */
#carte:hover .bar {
  opacity:0.5;
}

/* Turn on the one you want to highligth */
#carte:hover .bar.active {
  opacity:1;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接