无法在 d3 饼图中一次显示工具提示和 arctween 转换

Unable to display the tooltip and arctween transition ata a time in d3 pie chart

您好,我正在尝试将 arctween 过渡添加到我的饼图中。我能够在我的饼图中显示工具提示和图例,但是当我尝试将 arctween 过渡添加到我的饼图中时,工具提示不起作用。如何使此饼图中的工具提示和 arctween 转换成为可能。

      (function(d3) {
        'use strict';
        var margin = {top: 50, right: 50, bottom: 50, left: 50};
        var width = 800 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;
        var radius = Math.min(width, height) / 3;       
        var legendRectSize = 18;
        var legendSpacing = 4;

       var data = [
      {"IP":"192.168.12.1", "count":20}, 
      {"IP":"76.09.45.34", "count":40}, 
      {"IP":"34.91.23.76", "count":80},
      {"IP":"192.168.19.32", "count":16}, 
      {"IP":"192.168.10.89", "count":50}, 
      {"IP":"192.178.34.07", "count":18},
      {"IP":"192.168.12.98", "count":30}];
    

        var color = d3.scale.category10();

        var svg = d3.select('#chart')
          .append('svg')
          .attr('width', width+margin.left+margin.right)
          .attr('height', height+margin.left+margin.right)
          .append('g')
          .attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')');

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

        var arcOver = d3.svg.arc()
          .innerRadius(0)
          .outerRadius(radius + 5);

        var pie = d3.layout.pie()
      .sort(null)
      .startAngle(1.1*Math.PI)
      .endAngle(3.1*Math.PI)
      .value(function(d) { return d.count; });

        var tooltip = d3.select('#chart')                               
          .append('div')                                                
          .attr('class', 'tooltip');                                    
                      
        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('fill', function(d,i) { 
                return color(d.data.IP); 
            });
          path.on('mouseover', function(d) { 
           d3.select(this).transition()
                    .ease("exp")
                    .duration(3000)
                    .attrTween("d", tweenPie)
                    .duration(200)
                    .attr("d", arcOver)
                    .style('opacity',0.7)

                    function tweenPie(b) {
                      var i = d3.interpolate({startAngle: 1.1*Math.PI, endAngle: 1.1*Math.PI}, b);
                      return function(t) { return arc(i(t)); };
                    } 

            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.IP);                   
            tooltip.select('.count').html(d.data.count);                
            tooltip.select('.percent').html(percent + '%');             
            tooltip.style('display', 'block');                                  
          });                                                           
                
          path.on("mouseout", function(d) {
                d3.select(this).transition()
                    .duration(100)
                    .attr("d", arc)
                    .style('opacity','1');
              tooltip.style('display', 'none'); 
              });                            

  var legend = d3.select("#chart")
    .append("svg")
    .attr("class", "legend")
    .attr("width", radius+50)
    .attr("height", radius * 2)
    .selectAll("g")
    .data(color.domain())
    .enter()
    .append("g")
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

 legend.append('rect')
    .attr('width', legendRectSize)
    .attr('height', legendRectSize)                                   
   .style('fill', color)
   .style('stroke', color);
  
  legend.append('text')
    .attr('x', legendRectSize + legendSpacing)
    .attr('y', legendRectSize - legendSpacing)
    .text(function(d) { return d; });

      })(window.d3);
      #chart {  
        margin-top: 100px;                                              
        position: absolute;  
        margin-right: 50px;
        margin-left: 50px;                                           
      }                                                                 
      .tooltip {                                                        
        background: #eee;                                               
        box-shadow: 0 0 5px #999999;                                    
        color: #900C3F;                                                    
        display: inline-block;                                                  
        font-size: 12px;                                                
        left: 600px;                                                    
        padding: 10px;                                                  
        position: absolute;                                             
        text-align: center;                                             
        top: 95px;                                                      
        width: 100px;                                                    
        z-index: 10;  
        opacity: 1;                                                 
      }                                                                 
      rect {
        stroke-width: 2;
      }
      path {
     stroke: #ffffff;
     stroke-width: 0.5;
   }
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Testing Pie Chart</title>
     <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  </head>
  <body>
    <div id="chart"></div>
  </body>
 </html>

请帮帮我。上面提到的是我已经尝试过的代码。 预先感谢您的帮助。

你想要这样的东西(http://jsbin.com/guqozu/edit?html,js,output):

 .on("mouseover", function(d) {
  var htmlMsg="";
   div.transition()     
   .style("opacity", .9);       
    div.html(
    "IP :"+d.data.IP+""+"<br/>"+
    "Count : " +  d.data.count +"<br/>" + htmlMsg)
    .style("left",  (d3.event.pageX) + "px")
    .style("top",  (d3.event.pageY) + "px");    
    svg.selectAll("path").sort(function (a, b) { 
                  if (a != d) return -1;               
                  else return 1;                             
    });

    var endAngle = d.endAngle + 0.1;
    var arcOver = d3.svg.arc()
                .outerRadius(radius   +10).endAngle(endAngle).startAngle(startAngle);
                        d3.select(this)
                           .attr("stroke","white")
                           .transition()
                           .ease("bounce")
                           .duration(1000)
                           .attr("d", arcOver)             
                           .attr("stroke-width",6);
                    })
                    .on("mouseout", function(d) {
               div.transition()        
                            .duration(500)      
                            .style("opacity", 0); 
                        d3.select(this).transition()            
                           .attr("d", arc)
                           .attr("stroke","none");
                    })
              .transition()
                .ease("bounce")
                .duration(2000)
                .attrTween("d", tweenPie);

var div = d3.select("#toolTip");

var data = [
      {"IP":"192.168.12.1", "count":20}, 
      {"IP":"76.09.45.34", "count":40}, 
      {"IP":"34.91.23.76", "count":80},
      {"IP":"192.168.19.32", "count":16}, 
      {"IP":"192.168.10.89", "count":50}, 
      {"IP":"192.178.34.07", "count":18},
      {"IP":"192.168.12.98", "count":30}];

var width = 300,
 height = 300;
var margin = {top: 15, right: 15, bottom: 20, left: 40},
 radius = Math.min(width, height) / 2 - 10;
var legendRectSize = 18,
    legendSpacing = 4;
   

  var color = d3.scale.category20b();

  var arc = d3.svg.arc()
      .outerRadius(radius);
    
    var arcOver = d3.svg.arc()
          .outerRadius(radius + 10);

  var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d.count; });

    var labelArc = d3.svg.arc()
      .outerRadius(radius - 40)
      .innerRadius(radius - 40);
    
  var svg = d3.select("#chart").append("svg")
      .datum(data)
      .attr("width", width)
      .attr("height", height)
     .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var arcs = svg.selectAll(".arc")
      .data(pie)
     .enter().append("g")
      .attr("class", "arc");
    
   var arcs2 = svg.selectAll(".arc2")
      .data(pie)
     .enter().append("g")
      .attr("class", "arc2");

    
  arcs.append("path")
      .attr("fill", function(d, i) { return color(i); })
      .on("mouseover", function(d) {
    var htmlMsg="";
       div.transition()  
              .style("opacity",0.9);  
          div.html(
           "IP :"+d.data.IP+""+"<br/>"+
           "Count : " +  d.data.count +"<br/>" + htmlMsg)
          .style("left",  (d3.event.pageX) + "px")
             .style("top",  (d3.event.pageY) + "px"); 

      svg.selectAll("path").sort(function (a, b) { 
          if (a != d) return -1;               
         else return 1;                             
      });
    
    var endAngle = d.endAngle + 0.1;
    var startAngle = d.startAngle - 0.1;
    var arcOver = d3.svg.arc()
           .outerRadius(radius + 10).endAngle(endAngle).startAngle(startAngle);
               d3.select(this)
                  .attr("stroke","white")
                  .transition()
                  .ease("bounce")
                  .duration(1000)
                  .attr("d", arcOver)             
                  .attr("stroke-width",6);
           })

      .on("mouseout", function(d) {
             div.transition()        
                .duration(500)      
                .style("opacity", 0); 
              d3.select(this).transition()            
                 .attr("d", arc)
                 .attr("stroke","none");
          })
      .transition()
       .ease("bounce")
       .duration(2000)
       .attrTween("d", tweenPie);

  function tweenPie(b) {
    b.innerRadius = 0;
    var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
    return function(t) { return arc(i(t)); };
  }

        var k=0;
  arcs2.append("text")
  .transition()
      .ease("elastic")
   .duration(2000)
   .delay(function (d, i) {
    return i * 250;
   })
        .attr("x","6")
        .attr("dy", ".35em")
        .text(function(d) { if(d.data.count >0){ k = k+1; return d.data.count;} })
        .attr("transform", function(d) { if (k >1){return "translate(" + labelArc.centroid(d) + ") rotate(" + angle(d) + ")";} else{return "rotate(-360)";} })
        .attr("font-size", "10px");
     

  function type(d) {
    d.count = +d.count;
    return d;
  }
  function angle(d) {
        var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
        return a > 90 ? a - 180 : a;
  }

 var legend = d3.select("#chart")
    .append("svg")
    .attr("class", "legend")
    .attr("width", radius+50)
    .attr("height", radius * 2)
    .selectAll("g")
    .data(color.domain())
    .enter()
    .append("g")
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

 legend.append('rect')
    .attr('width', legendRectSize)
    .attr('height', legendRectSize)                                   
   .style('fill', color)
   .style('stroke', color);
  
  legend.append('text')
    .attr('x', legendRectSize + legendSpacing)
    .attr('y', legendRectSize - legendSpacing)
    .data(data)
    .text(function(d,i) { return d.IP; });
     #chart {  
        margin-top: 100px;                                              
        position: absolute;  
        margin-right: 50px;
        margin-left: 50px;                                           
      }                                                                 
      .tooltip {                                                        
        background: #eee;                                               
        box-shadow: 0 0 5px #999999;                                    
        color: #900C3F;                                                    
        display: inline-block;                                                  
        font-size: 12px;                                                
        left: 600px;                                                    
        padding: 10px;                                                  
        position: absolute;                                             
        text-align: center;                                             
        top: 95px;                                                      
        width: 150px;                                                    
        z-index: 10;  
        opacity: 1;                                                 
    }                                                                 
    rect {
       stroke-width: 2;
    }
    path {
     stroke: #ffffff;
     stroke-width: 0.5;
 }
 div.tooltip {
 position: absolute;
 z-index: 999;
 padding: 10px;
 background: #f4f4f4;
 border: 0px;
 border-radius: 3px;
 pointer-events: none;
 font-size: 11px;
 color: #000;
 line-height: 16px;
 border: 1px solid #d4d4d4;
 }

 .legend{
  margin-left: 300px;
 }
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Testing Pie Chart</title>
     <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
   </head>
 <body>
    <div id="chart"></div>
    <div id="toolTip" class="tooltip" style="opacity: 0;"></div>
    <script type="text/javascript">
      
     </script>
  </body>
 </html>

感谢 SiddP 提出了一些有用的技巧。根据他的代码和我的研究,我在这个饼图中添加了一个图例以及 arctween 和工具提示以使其完整。我希望这可以帮助那些在 D3 饼图上苦苦挣扎的人。 谢谢计算器。 :}