d3如何补间饼图的内半径

时间:2016-03-14 23:39:34

标签: d3.js svg

我需要将饼图设置为圆环图(或环形图)。 这是我的代码:

  var arc = d3.svg.arc().outerRadius(radius-margin).innerRadius(0)
  var arc2 = d3.svg.arc().outerRadius(radius-margin).innerRadius(60)

  var path = pie_chart.selectAll('path')
    .data(pie(data))
    .enter()
    .append('path')
    .attr('d', arc)
    .attr('fill', function(d, i) {
      return color_scale(d.data.device)
    })
    .transition().attr('d', arc2)

有时它会起作用,但有时却不起作用。我试图将过渡应用于弧但不起作用。

 var arc2 = d3.svg.arc().outerRadius(radius-margin).innerRadius(0).transition().innerRadius(60)

1 个答案:

答案 0 :(得分:4)

我会为此编写自己的arcTween函数来完全控制转换:

function arcTween(d) {
  var i = d3.interpolateNumber(0, radius-70); //<-- radius of 0 to donut
  return function(t) {
    var r = i(t),
        arc = d3.svg.arc()
          .outerRadius(radius - 10)
          .innerRadius(r); //<-- create arc
    return arc(d); //<-- return arc path
  };
}

完整代码:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .arc text {
    font: 10px sans-serif;
    text-anchor: middle;
  }
  
  .arc path {
    stroke: #fff;
  }
</style>

<body>
  <script src="//d3js.org/d3.v3.min.js"></script>
  <script>
    var width = 500,
      height = 500,
      radius = Math.min(width, height) / 2;

    var color = d3.scale.category10();

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

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

    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    var data = [10, 20, 30, 40];

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

    g.append("path")
      .attr("d", arc)
      .style("fill", function(d, i) {
        return color(i);
      })
      .transition()
      .delay(100)
      .duration(5000)
      .attrTween("d", arcTween);
      
    function arcTween(d) {
      var i = d3.interpolateNumber(0, radius-70);
      return function(t) {
        var r = i(t),
            arc = d3.svg.arc()
              .outerRadius(radius - 10)
              .innerRadius(r);
        return arc(d);
      };
    }
      
  </script>
</body>

或者只是让某人头疼:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .arc text {
    font: 10px sans-serif;
    text-anchor: middle;
  }
  
  .arc path {
    stroke: #fff;
  }
</style>

<body>
  <script src="//d3js.org/d3.v3.min.js"></script>
  <script>
    var width = 500,
      height = 500,
      radius = Math.min(width, height) / 2;

    var color = d3.scale.category10();

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

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

    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    var data = [10, 20, 30, 40];

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

    var arcs = g.append("path")
      .attr("d", arc)
      .style("fill", function(d, i) {
        return color(i);
      });
    
    (function repeat() {
      arcs.transition()
        .duration(500)
        .attrTween("d", arcTweenOut)
        .transition()
        .duration(500)
        .attrTween("d", arcTweenIn)
        .each('end', repeat)
    })();
    
    function arcTweenOut(d) {
      var i = d3.interpolateNumber(0, radius-70);
      return function(t) {
        var r = i(t),
            arc = d3.svg.arc()
              .outerRadius(radius - 10)
              .innerRadius(r);
        return arc(d);
      };
    }
    
    function arcTweenIn(d) {
      var i = d3.interpolateNumber(radius-70, 0);
      return function(t) {
        var r = i(t),
            arc = d3.svg.arc()
              .outerRadius(radius - 10)
              .innerRadius(r);
        return arc(d);
      };
    }
      
  </script>
</body>