d3.js同时在两个图表上进行鼠标悬停事件 [英] Mouseover event on two charts at the same time d3.js

查看:81
本文介绍了d3.js同时在两个图表上进行鼠标悬停事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 mouseover a piece of pie, that piece and tooltip will pup up in that pie chart.

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

My question is... when user mouseover a piece of pie, how can I make the popups happen in both of the charts. For example, if user mouseover the green part in the first pie chart, the green parts and tooltips in both charts will show up at the same time.

如何连接两个图表?有人对此有线索吗?谢谢!

How can I make two charts connected? Does anyone have clue about this? Appreciate!!

我在这里找到了类似的问题,并尝试按照Lars的回答更改代码. 影响d3.js中多个单独图表的交互吗? 我分配了一个类名'path',并将d3.select(this)更改为d3.select('.path').但是无论我的鼠标在哪里,都会弹出第一个饼图的紫色部分. 这是我更新的JSbins http://jsbin.com/gozuyekibi/edit?html ,css,js,输出

I found a similar question here and try to change the code follow Lars's answer. Interactions that affect multiple separate charts in d3.js? I assigned a class name 'path', and changed d3.select(this) to d3.select('.path'). But wherever my mouse is, the purple part of first pie chart pops up. Here is my updated 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');                    
      });

推荐答案

首先,为您的工具提示分配一个类,然后清理该CSS.接下来,为每个弧path分配一个类,以便您可以在鼠标悬停时配对路径.然后,概括化您的mouseover以便在两条路径上进行操作:

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>

这篇关于d3.js同时在两个图表上进行鼠标悬停事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆