D3.js更新过渡

Var*_*rma 2 javascript charts css-transitions d3.js d3v4

我正在使用以下代码更新使用d3v4创建的条形图:

d3.select("button.add")
        .on("click", function(){
            dataset.push(Math.floor(Math.random() * 30) + 5);
            xScale.domain(d3.range(dataset.length))
                    .rangeRound([0, w])
                    .padding(0.2);
            yScale.domain([0, d3.max(dataset)]);
            var bars = svg.selectAll("rect")
                            .data(dataset);

            bars.enter()
                .append("rect")
                .attr("class", "bar")
                .attr("x", w)
                .attr("y", function(d){return yScale(d);})
                .attr("width", xScale.bandwidth())
                .attr("height", function(d){return h - yScale(d)})
                .attr("fill", function(d){
                    return 'rgb('+d*3 + ',' + d*6 + ',' + d*9 + ')';
                });

            bars.transition()
                .delay(function(d, i){
                    return(i*1500) / dataset.length;
                })
                .duration(500)
                .ease(d3.easeLinear)
                .attr("x", function(d, i){ return xScale(i);})
                .attr("y", function(d) {return yScale(d);})
                .attr("width", xScale.bandwidth())
                .attr("height", function(d) {return h - yScale(d);});
        });
Run Code Online (Sandbox Code Playgroud)

虽然添加了数据并且还创建了rect元素,但是对于阵列中最新添加的元素不会发生转换.只有在添加下一个元素并且不会发生该元素的转换时才会发生这种情况.

任何人都可以提供任何可能出错的提示吗?

提前致谢..

Ger*_*ado 6

由于这是D3 v4,您将不得不进行merge选择.

每次在数据数组中推送一个新值时,"enter"选择都有一个元素.但是,此新元素不会发生转换,因为bars除非您merge选择,否则使用和调用转换bars不包含"enter"选项.

因此,您的"输入"+"更新"选项应为:

 bars.enter()// <-- this is just the "enter" selection
     .append("rect")
     .attr("class", "bar")
     .attr("x", w)
     .attr("y", function(d){return yScale(d);})
     .attr("width", xScale.bandwidth())
     .attr("height", function(d){return h - yScale(d)})
     .attr("fill", function(d){
         return 'rgb('+d*3 + ',' + d*6 + ',' + d*9 + ')';
      })
     .merge(bars)// <-- merge the selections: from now on, "enter" + "update"
     .transition()
     .delay(function(d, i){
         return(i*1500) / dataset.length;
     })
     .duration(500)
     .ease(d3.easeLinear)
     .attr("x", function(d, i){ return xScale(i);})
     .attr("y", function(d) {return yScale(d);})
     .attr("width", xScale.bandwidth())
     .attr("height", function(d) {return h - yScale(d);});
Run Code Online (Sandbox Code Playgroud)

我知道这是"奇怪的",但如果你停下来想一想,处理更新选择的旧D3 v3方式是错误的,而不是这种新的v4方式.毕竟,bars不包含"输入"选择.

根据迈克博斯托克的说法:

D3 2.0引入了一个更改以解决重复问题:附加到输入选择现在会将输入元素复制到更新选择中.因此,在附加到输入选择之后应用于更新选择的任何操作都将适用于输入和更新元素,并且可以消除重复代码[...]这使得可用性变得更糟.D3 4.0消除了enter.append的魔力.

(来源:https://medium.com/@mbostock/what-makes-software-good-943557f8a488#.293tkrlfo,强调我的)