D3js:鼠标悬停一个元素会改变其他几个元素的不透明度

时间:2014-08-21 20:18:16

标签: javascript css javascript-events d3.js elements

感谢之前的回答,我已经a map and a related graph with 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)

};

这里没问题,the code works fine。我们现在到达图表。他使用了一个在脚本开头调用的.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。< / p>

有人知道我是否可以轻松转换地图部分中的mouseover和mouseout事件,以便同时更改我的图表?

提前致谢。

1 个答案:

答案 0 :(得分: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);
        });

这是a demo

性能问题

这种实施有点慢。您可以通过切换&#34; active&#34;来改善它。等级到要突出显示的栏。

另一个好的尾巴可能是在一个组中收集两种条形,你用id(例如 bureau187 )单独描述。这样,您可以直接在 mouseenter 函数中选择所需的条形图,并使用&#34; active&#34;类。

使用此类,您可以模仿我实施的策略以突出显示某个功能,然后从 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;
}