d3:重复过渡一系列元素?

时间:2016-02-23 05:28:41

标签: javascript d3.js

对于一系列元素,我遇到了重复转换的问题,在这种情况下是一组三行。动画运行一次,但是当它重复时(使用相同的数据),所有三行合并为一行(data中的最后一个数组)。我做错了什么?

(function() {
    var w = 100, h = 100
    var div = d3.select('#sketches').append('div')
    var svg = div.append("svg")
        .attr("width", w)
        .attr("height", h)

    var x = 0, y = 55

    var data = [
        [x, y, x+20, y-40],
        [x+10, y, x+30, y-40],
        [x+20, y, x+40, y-40]
    ];

    (function lines() {
            svg.selectAll('line')
                .data(data).enter().append('line')
                .attr("stroke", "black")
                .attr('x1', function(d) {return d[0]})
                .attr('y1', function(d) {return d[1]})
                .attr('x2', function(d) {return d[2]})
                .attr('y2', function(d) {return d[3]})
                .transition()
                .duration(3000)
                .ease('linear')
                .attr('x1', function(d) {return d[0] + 60})
                .attr('y1', function(d) {return d[1]})
                .attr('x2', function(d) {return d[2] + 60})
                .attr('y2', function(d) {return d[3]})
                .each('end', function(d) {
                    d3.select(this).remove()
                    lines()
                })
    })()
})()
body {
  padding: 1rem;
}
svg {
  background-color: silver;
  stroke: black;
  stroke-width: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<div id="sketches"></div>

1 个答案:

答案 0 :(得分:1)

问题是each函数将为您拥有的每一行启动。实际上你正在做的是每次调用lines()三次。为什么它是yieling一行的输出我不完全确定(仍然在研究它)但由于某种原因,似乎data默认为最后一个数组,所以它只设置绘图基于{{ 1}}。

要修复它,您需要确保data[3]仅在完成删除所有行后调用,因此它只运行一次。我很确定有更好的方法(即某种承诺,所以在lines()运行之后,它会运行一个函数,但你可以做的是设置一个each然后只需每N次运行count,其中N是您要删除的行数。因为您遍历数组lines()并为每个索引附加一行,所以N为data

(我会看看是否有更清洁的方法来做这个,如果我找到方法,我会编辑我的答案,但希望这至少可以帮助你理解这个问题)

data.length
(function() {
    var w = 100, h = 100
    var div = d3.select('#sketches').append('div')
    var svg = div.append("svg")
        .attr("width", w)
        .attr("height", h)

    var x = 0, y = 55

    var data = [
        [x, y, x+20, y-40],
        [x+10, y, x+30, y-40],
        [x+20, y, x+40, y-40]
    ];
    
    var count = 0;
    (function lines() {
            svg.selectAll('line')
                .data(data).enter().append('line')
                .attr("stroke", "black")
                .attr('x1', function(d) {return d[0]})
                .attr('y1', function(d) {return d[1]})
                .attr('x2', function(d) {return d[2]})
                .attr('y2', function(d) {return d[3]})
                .transition()
                .duration(3000)
                .ease('linear')
                .attr('x1', function(d) {return d[0] + 60})
                .attr('y1', function(d) {return d[1]})
                .attr('x2', function(d) {return d[2] + 60})
                .attr('y2', function(d) {return d[3]})
                .each('end', function(d) {
                    d3.select(this).remove()
                    count++;
                    if (count == data.length) {
                      count = 0;
                      lines();
                    }
                })
    })()
})()
body {
  padding: 1rem;
}
svg {
  background-color: silver;
  stroke: black;
  stroke-width: 1;
}