2013-05-23 4 views
2

Я пытаюсь создать анимированный сегмент дуги с d3.js. Я получил дугу и переходный процесс, но пока анимация работает, дуга искажается, и я не могу понять, почему.Проблема с анимацией сегмента дуги 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); 
} 
+0

Вы видели [этот пример] (http://blog.stephenboak.com/2011/08/07/easy-as-a-pie.html)? –

+0

Я думаю, что D3 интерполирует между вами каждый набор точек, поэтому анимация между каждым состоянием, перемещая точки вдоль прямой, а не вдоль радиального, как вам хотелось бы. Для этого вам нужно указать функцию tweening, которая определяет требуемую анимацию перехода. Пример, связанный с Lars, должен показать вам, что вам нужно. –

+0

Пример, связанный странно, относится к функции ('pieTween'), которая никогда не предоставляется. Взгляните на эти, возможно, более полезные примеры: [Обновление диаграммы, II] (http://bl.ocks.org/mbostock/1346410), [Arc Tween (Clock)] (http://bl.ocks.org/mbostock/1098617) и [объяснение, почему это необходимо создателю d3 Майком Бостоком] (http://stackoverflow.com/a/10090745/1798568). – serhalp

ответ

1

Как пояснил Ричард, вы интерполирование между ранее вычисленной строкой SVG путем и вновь вычисленной строкой - которая собирается сделайте некоторые странные вещи - вместо того, чтобы интерполировать между предыдущим углом и новым углом, который вы хотите.

Вам необходимо интерполировать по входу и для каждой интерполированной карты значений, которая соответствует строке пути SVG, используя функцию arc. Чтобы сделать это, вам нужно где-то сохранить каждую предыдущую точку привязки и использовать пользовательскую функцию tweening, которую вы можете найти в примерах в моем предыдущем комментарии.

1. Помните предыдущий геодезическую (изначально):

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

2. Определить пользовательскую функцию Tweening:

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/

+0

Другая проблема заключается в том, что она устанавливает интервал до 2 секунд. А анимация занимает 2,5 секунды. Таким образом, время перехода должно быть изменено, чтобы быть ниже нового времени поступления данных. –