简体   繁体   中英

d3 pie sort transition

How would I apply an animated transition when sorting a pie chart? I don't mean updating values, I mean sorting each arc of the pie to move into place the way bars do here .

There are plenty of transition examples for updating using new values of an existing data set (or switching data sets). I can't find anything on how to re-sort (using the same values, same data set).

I'm using this for now which simply redraws the arc by applying the same tween used when initializing the rendering, but it starts each arc from zero.

        .attr('d', arc)
        .transition()
        .duration(1000)
        .attrTween("d", tweenPie);

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

Would I need to store the existing start and end angles somehow and run the tween from those?

I see something kind of like that here , though this example is updating values, not sorting.

Thanks.

Building on the Bostock example here .

  setInterval(change, 2000);

  var sort = false;
  function change() {

    sort = !sort;

    if (sort){
      pie = d3.layout.pie() //<-- pie with default sort
        .value(function(d) {
          return d.value;
        });
    } else {
      pie = d3.layout.pie() //<-- pie with no sort
        .value(function(d) {
          return d.value;
        })
        .sort(null);
    }

    path = path.data(pie); // compute the new angles
    path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
  }

Full code:

 <!DOCTYPE html> <meta charset="utf-8"> <style> body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; margin: auto; position: relative; width: 400px; } text { font: 10px sans-serif; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <body> <script> var width = 400, height = 500, radius = Math.min(width, height) / 2; var color = d3.scale.category20(); var pie = d3.layout.pie() .value(function(d) { return d.value; }) .sort(null); var defaultSort = pie.sort; var arc = d3.svg.arc() .innerRadius(radius - 100) .outerRadius(radius - 20); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var data = [{ value: 1 }, { value: 5 }, { value: 2 }, { value: 6 } ]; var path = svg.datum(data).selectAll("path") .data(pie) .enter().append("path") .attr("fill", function(d, i) { return color(i); }) .attr("d", arc) .each(function(d) { this._current = d; }); // store the initial angles setInterval(change, 2000); var sort = false; function change() { sort = !sort; if (sort){ pie = d3.layout.pie() .value(function(d) { return d.value; }); } else { pie = d3.layout.pie() .value(function(d) { return d.value; }) .sort(null); } path = path.data(pie); // compute the new angles path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs } // Store the displayed angles in _current. // Then, interpolate from _current to the new angles. // During the transition, _current is updated in-place by d3.interpolate. function arcTween(a) { var i = d3.interpolate(this._current, a); this._current = i(0); return function(t) { return arc(i(t)); }; } </script> </body> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM