同时在两个图表上的鼠标悬停事件d3.js

时间:2016-01-29 17:14:44

标签: d3.js

链接中的代码用于两个饼图。 http://jsbin.com/vipodidiyo/edit?html,css,js,outputThey几乎相同,只是不同的数据和位置。当用户将鼠标悬停在一块馅饼上时,该碎片和工具提示将在该饼图中显示出来。

我的问题是......当用户将鼠标悬停在一块饼上时,如何在两个图表中都能弹出窗口。例如,如果用户将鼠标悬停在第一个饼图中的绿色部分,则两个图表中的绿色部分和工具提示将同时显示。

如何连接两张图表?有没有人对此有所了解?欣赏!!

更新

我在这里找到了一个类似的问题,并尝试按照Lars的回答更改代码。 Interactions that affect multiple separate charts in d3.js? 我分配了一个班级名称“路径”,并将d3.select(this)更改为d3.select('.path')。但无论我的鼠标在哪里,第一个饼图的紫色部分都会弹出。 这是我更新的JSbins http://jsbin.com/gozuyekibi/edit?html,css,js,output

var path = svg.selectAll('path').
    data(pie(data)).
    enter().
    append('path').
    attr('d', arc).
    attr('class','path').
    //attr('id','pathid').
    attr('fill', function(d,i){
     return color(d.data.label);}). 
   on('mouseover', function(d) {
     d3.select('.path').transition()
      .duration(1000)
      .attr("d", arcHover);     
       var total = d3.sum(data.map(function(d) {
          return d.count;
       }));
       var percent = Math.round(1000 * d.data.count / total) / 10;
        tooltip.select('.label').html(d.data.label); 
        tooltip.select('.count').html(d.data.count); 
        tooltip.select('.percent').html(percent + '%'); 
        tooltip.style('display', 'block');
       }).       
    on('mouseout', function() {
     d3.select('.path').transition()
      .duration(500)
      .attr("d", arc);      
        tooltip.style('display', 'none');                    
      });

1 个答案:

答案 0 :(得分:7)

首先,将单个类分配给工具提示并清理该css。接下来,为每个弧path分配一个类,以便您可以在鼠标悬停时将路径配对。然后概括您的mouseover以在两条路径上运行:

.on('mouseover', function(d0) {

    // apply over to both paths
    d3.selectAll('path.' + d0.data.label).transition()
      .duration(1000)
      .attr("d", arcHover)
      // now loop each of them
      .each(function(d1) {
        // get a sum for the group of paths
        var total = d3.sum(this.parentNode.childNodes, function(d2) {
          return d2.value;
        });
        // and a percent
        var percent = Math.round(1000 * d1.value / total) / 10;

        // find correct tooltip
        var tooltip = d3.select(this.ownerSVGElement.parentNode.childNodes[1]);
        tooltip.select('.label').html(d1.data.label);
        tooltip.select('.count').html(d1.data.count);
        tooltip.select('.percent').html(percent + '%');
        tooltip.style('display', 'block');

      })
  })
  .on('mouseout', function(d) {

      // apply to both paths
      d3.selectAll('path.' + d.data.label).transition()
        .duration(500)
        .attr("d", arc);

      // hide all tooltips
      d3.selectAll('.tooltip').style('display', 'none');
  });

完整代码:



<!DOCTYPE html>
<html>

<head>
  <style>
    #pieChart1 {
      height: 360px;
      position: relative;
      width: 360px;
    }
    
    .tooltip {
      background: #fdd0a2;
      box-shadow: 0 0 5px #999999;
      color: #333;
      display: none;
      left: 300px;
      padding: 10px;
      position: absolute;
      text-align: center;
      width: 80px;
      z-index: 10;
    }
    
    #tooltip1 {
      top: 220px;
    }
    
    #tooltip2 {
      top: 580px;
    }
  </style>
</head>

<body>
  <div id="pieChart1"></div>
  <div id="pieChart2"></div>
  <script src="http://d3js.org/d3.v3.min.js"></script>


  <script>
    var data1 = [{
      label: 'Station1',
      count: 10
    }, {
      label: 'Station2',
      count: 20
    }, {
      label: 'Station3',
      count: 30
    }];
    var data2 = [{
      label: 'Station1',
      count: 15
    }, {
      label: 'Station2',
      count: 80
    }, {
      label: 'Station3',
      count: 20
    }];

    var drawPieChartFunction = function(data, chartId, tooltipName) {

      var margin = {
          top: 20,
          right: 40,
          bottom: 120,
          left: 80
        },
        width = 700 - margin.right - margin.left,
        height = 500 - margin.top - margin.bottom;

      var radius = Math.min(width, height) / 2;
      var donutWidth = 105;
      var legendRectSize = 18;
      var legendSpacing = 4;

      var color = d3.
      scale.
      ordinal().
      range(['#98df8a', '#c5b0d5', '#9edae5']).
      domain(d3.keys(data[0]).filter(function(key) {
        return key === 'label';
      }));

      var svg = d3.
      select(chartId).
      append('svg').
      attr({
        'width': width + margin.right + margin.left,
        'height': height + margin.top + margin.bottom
      }).
      append('g').
      attr('transform', 'translate(' + ((width + margin.right + margin.left) / 2) +
        ',' + ((height + margin.top + margin.bottom) / 2) + ')');

      var arc = d3.svg.arc().
      innerRadius(radius - donutWidth).
      outerRadius(radius);

      var arcHover = d3.svg.arc().
      innerRadius(radius - donutWidth).
      outerRadius(radius + 10);

      var pie = d3.layout.pie().
      value(function(d) {
        return d.count;
      });
      
      var tooltip = d3.select(chartId)
        .append('div')
        .attr('class', 'tooltip')
        .attr('id', tooltipName);
      tooltip.append('div')
        .attr('class', 'label');
      tooltip.append('div')
        .attr('class', 'count');
      tooltip.append('div')
        .attr('class', 'percent');
      
      var path = svg.selectAll('path').
        data(pie(data)).
        enter().
        append('path').
        attr('d', arc).
        attr('class', function(d) {
          return d.data.label;
        }).
        attr('fill', function(d, i) {
          return color(d.data.label);
        }).
        on('mouseover', function(d0) {

          d3.selectAll('path.' + d0.data.label).transition()
            .duration(1000)
            .attr("d", arcHover)
            .each(function(d1) {
              var total = d3.sum(this.parentNode.childNodes, function(d2) {
                return d2.value;
              });
              var percent = Math.round(1000 * d1.value / total) / 10;
              
              // find correct tooltip
              var tooltip = d3.select(this.ownerSVGElement.parentNode.childNodes[1]);
              tooltip.select('.label').html(d1.data.label);
              tooltip.select('.count').html(d1.data.count);
              tooltip.select('.percent').html(percent + '%');
              tooltip.style('display', 'block');
  
            })
      }).
      on('mouseout', function(d) {
        d3.selectAll('path.' + d.data.label).transition()
          .duration(500)
          .attr("d", arc);
        d3.selectAll('.tooltip').style('display', 'none');
      });
      return path;
    };
    drawPieChartFunction(data1, '#pieChart1', 'tooltip1');
    drawPieChartFunction(data2, '#pieChart2', 'tooltip2');
  </script>
</body>

</html>
&#13;
&#13;
&#13;