2

我正在尝试使用 d3.js 创建一个动画弧段。我得到了弧线和过渡工作,但是在动画运行时,弧线被扭曲了,我不知道为什么。

这是我到目前为止所拥有的:

jsfiddle

var dataset = {
    apples: [532, 284]
};

var degree = Math.PI/180;

var width = 460,
    height = 300,
    radius = Math.min(width, height) / 2;

var color = d3.scale.category20();

var pie = d3.layout.pie().startAngle(-90*degree).endAngle(90*degree)
    .sort(null);

var arc = d3.svg.arc()
    .innerRadius(radius - 100)
    .outerRadius(radius - 50);

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

var path = svg.selectAll("path")
    .data(pie(dataset.apples))
  .enter().append("path")
    .attr("fill", function(d, i) { return color(i); })
    .attr("d", arc);   


window.setInterval(dummyData, 2000);

function dummyData(){
    var num = Math.round(Math.random() * 100);
    var key = Math.floor(Math.random() * dataset.apples.length);

    dataset.apples[key] = num;

    draw();
};

function draw(){     
    svg.selectAll("path")
        .data(pie(dataset.apples))
    .transition()
    .duration(2500)
        .attr("fill", function(d, i) { return color(i); })
        .attr("d", arc);   
}
4

1 回答 1

1

正如 Richard 解释的那样,您在先前计算的 SVG 路径字符串和新计算的字符串之间进行插值——这会做一些奇怪的事情——而不是在之前的角度和新角度之间进行插值,这正是你想要的。

arc您需要使用您的函数对输入和每个插值映射到 SVG 路径字符串进行插值。为此,您需要将每个先前的数据存储在某处并使用自定义补间函数,您可以在我之前评论的示例中找到该函数。

1. 记住以前的数据(最初):

.each(function(d) { this._current = d; });

2.定义一个自定义补间函数:

function arcTween(a) {
  var i = d3.interpolate(this._current, a);
  this._current = i(0); // Remember previous datum for next time
  return function(t) {
    return arc(i(t));
  };
}

3.使用它:

.attrTween("d", arcTween)

这是它的样子:http: //jsfiddle.net/Qh9X5/18/

于 2013-05-23T16:59:09.330 回答