How to increase size of pie segment on hover in d3

2020-06-09 09:38发布

问题:

I created pie chart using d3. How to increase size of pie segment on hover? As you can see, green segment is so small so I want to change it size like red segment. How can I do this?

My code:

var w = 400;
var h = 400;
var r = h/2;
var color = d3.scale.category20c();

var data = [{"label":"Category A", "value":20}, 
                  {"label":"Category B", "value":50}, 
                  {"label":"Category C", "value":30},
           {"label":"Category A", "value":20}, 
                  {"label":"Category B", "value":50}, 
                  {"label":"Category C", "value":30},
           {"label":"Category A", "value":20}, 
                  {"label":"Category B", "value":50}, 
                  {"label":"Category C", "value":5}];


var vis = d3.select('#chart').append("svg:svg").data([data]).attr("width", w).attr("height", h).append("svg:g").attr("transform", "translate(" + r + "," + r + ")");
var pie = d3.layout.pie().value(function(d){return d.value;});

// declare an arc generator function
var arc = d3.svg.arc().outerRadius(r);
var arcOver = d3.svg.arc()
        .outerRadius(r + 9);

// select paths, use arc generator to draw
var arcs = vis.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class", "slice");
arcs.append("svg:path")
    .attr("fill", function(d, i){
        return color(i);
    })
    .attr("d", function (d) {
        // log the result of the arc generator to show how cool it is :)
        console.log(arc(d));
        return arc(d);
    })
     .on("mouseenter", function(d) {
            d3.select(this)
               .attr("stroke","white")
               .transition()
               .duration(1000)
               .attr("d", arcOver)             
               .attr("stroke-width",6);
        })
        .on("mouseleave", function(d) {
            d3.select(this).transition()            
               .attr("d", arc)
               .attr("stroke","none");
        });;

There is example in js fiddle : jsfiddle Thanks.

回答1:

Now this is the right code. Try it..ok

<!DOCTYPE html>
<html>

<head>
  <title>Dsnap - Charts</title>
</head>

<body>
  <div id="wrapper">

  </div>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  <script>
    var canvas = d3.select('#wrapper')
      .append('svg')
      .attr({
        'width': 650,
        'height': 500
      });

    var data = [{
      "label": "one",
      "value": 40
    }, {
      "label": "two",
      "value": 30
    }, {
      "label": "three",
      "value": 30
    }];

    var colors = ['red', 'blue'];

    var colorscale = d3.scale.linear().domain([0, data.length]).range(colors);

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

    var arcOver = d3.svg.arc()
      .innerRadius(0)
      .outerRadius(150 + 10);

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


    var renderarcs = canvas.append('g')
      .attr('transform', 'translate(440,200)')
      .selectAll('.arc')
      .data(pie(data))
      .enter()
      .append('g')
      .attr('class', "arc");

    renderarcs.append('path')
      .attr('d', arc)
      .attr('fill', function(d, i) {
        return colorscale(i);
      })
      .on("mouseover", function(d) {
        d3.select(this).transition()
          .duration(1000)
          .attr("d", arcOver);
      })
      .on("mouseout", function(d) {
        d3.select(this).transition()
          .duration(1000)
          .attr("d", arc);
      });

    renderarcs.append('text')
      .attr('transform', function(d) {
        var c = arc.centroid(d);
        console.log(c);
        return "translate(" + c[0] + "," + c[1] + ")";
      })
      .text(function(d) {
        return d.value + "%";
      });
  </script>
</body>

</html>



回答2:

I just found solution for my problem.

I changed startAngle and endAngle in d3:

.on("mouseenter", function(d) {

         var endAngle = d.endAngle + 0.2;
         var startAngle = d.startAngle - 0.2;

              var arcOver = d3.svg.arc()
    .outerRadius(r + 9).endAngle(endAngle).startAngle(startAngle);

        d3.select(this)
           .attr("stroke","white")
           .transition()
           .duration(1000)
           .attr("d", arcOver)             
           .attr("stroke-width",6);
    })

Working example: jsfiddle