简体   繁体   English

带for循环的D3链接动画

[英]D3 Chaining Animations with a for loop

I want to chain d3 animations over a for loop. 我想将d3动画链接到for循环上。 What is the best way to achive something like this: 实现这样的最佳方法是什么:

    for (var i=0; i<dat.length-1; i++) {
        var a = function(g,dat,i){
            /*
            g.transition().duration(i * 19)
                .attr("cy", dat[i+1].y1)
                .attr("cx", dat[i+1].x1)
                .attr("r", 10);*/
            console.log("transform " + dat[i+1].x1);
        };

        var t = setTimeout(a(g,dat,i), i*20);
    }

This is of corse not working, since you can not pass objects to setTimeout functions. 这很重要,因为您无法将对象传递给setTimeout函数。

You can use transition.delay() to chain transitions. 您可以使用transition.delay()链接转换。 https://github.com/mbostock/d3/wiki/Transitions#wiki-delay https://github.com/mbostock/d3/wiki/Transitions#wiki-delay

for (var i = 0; i < dat.length - 1; i++) {
    g.transition().duration(20).delay(i * 20)
        .attr("cy", dat[i + 1].y1)
        .attr("cx", dat[i + 1].x1);
}

I found a solution that works for me. 我找到了适合我的解决方案。 I feel it is still ugly code but at least it works. 我觉得它仍然是丑陋的代码,但至少可以正常工作。

First I create an unvisible object for each data in my dataset: 首先,我为数据集中的每个数据创建一个不可见的对象:

g.data(dat) 
.enter()
.append("circle")
.attr("class", function(d,i) { return "default " + d.pn; })
.attr("cx", function(d,i) { return d.x1; })
.attr("cy", function(d,i) { return d.y1; })
.attr("r",  function(d,i) { return d.r; })
.style("opacity", 0);

And then I am going to shedule a transition for each single element: 然后,我将为每个元素提出一个过渡:

        g.each(function(d,i){
            var delay = Math.floor((i+1) / nrOfElements);
            //console.log(delay);
            d3.select(this)
                .transition()
                .delay(delay * speed)
                .duration(speed + DELAY_OFFSET)
                .style("opacity", 100)
                .attr("cx", function(d) { return i<dat.length-1 ? dat[i+1].x1 : dat[i].x1; })
                .attr("cy", function(d) { return i<dat.length-1 ? dat[i+1].y1 : dat[i].y1; })
                .attr("r",  function(d) { return i<dat.length-1 ? dat[i+1].r : dat[i].r; })
                .style("stroke", "blue") // TODO: setAttributes
                .each("end", function() { 
                    // Reset to privious attributes
                    d3.select(this)
                        .attr("cx", function(d) { return dat[i].x1; })
                        .attr("cy", function(d) { return dat[i].y1; })
                        .attr("r",  function(d) { return dat[i].r; })
                        ;

                    if(i<dat.length-nrOfElements) d3.select(this).style("opacity", 0); 
                })
                ;
        });

This seems a huge effort in coding to me for a rather simple requirement ... but at least it is working .. 对我来说,这是一个相当简单的要求,这似乎是一个巨大的努力……但至少它是有效的。

Better solutions are still welcome!! 仍然欢迎更好的解决方案!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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