d3.js使用exit()和enter()进行子转换

时间:2014-10-17 08:55:02

标签: javascript d3.js

问题简短: 如何在this.selection的子转换中访问整个this.selection.exit()

我正在尝试制作d3.js转换序列。我知道如何使用transition.transition()函数创建序列,但这是我的问题。

序列应为:[删除.exit()个节点]→[移动节点]→[添加.enter()个节点]

代码是:

        this.selection.exit().remove();
        this.selection
            .style("left", this.styleLeft)
            .style("top", this.styleTop)
            .style("width", this.styleWidth)
            .style("height", this.styleHeight);
        this.selection.enter().append("div")
            .attr("class", "node")
            .style("left", this.styleLeft)
            .style("top", this.styleTop)
            .style("width", this.styleWidth)
            .style("height", this.styleHeight);

如果我在上面的每个命令中添加transition(),则所有转换将同时开始。 .delay()似乎无法同时在多个转换中正常工作。

所以我想使用.transition()的子转换,但是如果我将第二个命令应用到第一个命令,我只选择.exit()

编辑1:

示例如何不起作用:

        this.selection.exit().transition()
        .duration(1000).style("opacity", 0).remove();

        this.selection.transition().delay(1010)
            .duration(1000)
            .style("left", this.styleLeft)
            .style("top", this.styleTop)
            .style("width", this.styleWidth)
            .style("height", this.styleHeight)

        this.selection.enter().append("div")
            .attr("class", "node")
            .style("opacity", 0)
            .style("left", this.styleLeft)
            .style("top", this.styleTop)
            .style("width", this.styleWidth)
            .style("height", this.styleHeight)
            .transition()
            .delay(2020)
            .duration(1000)
            .style("opacity", 1);

此处出错:最后一次转换未启动,因此所有新节点都是不透明的。但是如果我禁用第二次转换,它就会起作用。

编辑2:

http://jsfiddle.net/dq6d117g/6/

如果在转换过程中再次调用该函数,则会出现问题。

另外,延迟应该与动画一样长。如果没有动画,延迟应为0.这就是我想使用结束事件的原因。

1 个答案:

答案 0 :(得分:3)

根据Mike Bostock的answer here,您可以使用d3.transition().each()链接预先存在的选项,但是,在我的测试中,它没有跳过不需要的转换,所以我添加了条件以跳过空选择的转换:

http://jsfiddle.net/dq6d117g/8/

var transition=d3.transition().duration(2000);

if (!selection.exit().empty()) transition=transition.each(function(){
    selection.exit()
        .transition()
        .style("opacity", 0)
        .remove();
}).transition();

if (!selection.empty()) transition=transition.each(function(){
    selection.transition()
    .style("height", function (d) {
        return (d.value * 10) + "px";
    });
}).transition();

transition.each(function(){
    selection.enter()
        .append("div")
        .attr("class", "bar")
        .attr("id", function (d) {
            return d;
        })
        .style("opacity", 0)
        .style("height", function (d) {
            return (d.value * 9) + "px";
        })
        .text(function (d) {
            return d.id
        })
        .transition()
        .style("opacity", 1)
        .style("height", function (d) {
            return (d * 10) + "px";
        });
});