Mouseover event on two charts at the same time d3.js

后端 未结 1 1785
小蘑菇
小蘑菇 2021-01-03 11:36

The code in the link is for two pie charts. http://jsbin.com/vipodidiyo/edit?html,css,js,outputThey are almost the same just different data and positions. When user mouseov

相关标签:
1条回答
  • 2021-01-03 12:08

    First, assign a single class to your tooltips and clean up that css. Next, assign each arc path a class so that your can pair your paths on mouseover. Then generalize your mouseover to operate on both paths:

    .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');
      });
    

    Full code:

    <!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>

    0 讨论(0)
提交回复
热议问题