【问题标题】:D3.js update with transitionD3.js 更新与过渡
【发布时间】:2017-03-02 09:16:32
【问题描述】:

我正在使用以下代码更新使用 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);});
        });

虽然添加了数据并创建了矩形元素,但数组中最新添加的元素不会发生转换。只有在添加了下一个元素并且该元素的转换没有发生时才会发生。

任何人都可以提供任何可能出现问题的提示吗?

提前谢谢..

【问题讨论】:

    标签: javascript charts css-transitions d3.js


    【解决方案1】:

    由于这是 D3 v4,您必须merge 选择。

    每次您在数据数组中推送一个新值时,您的“输入”选择就会有一个元素。但是,此新元素不会发生转换,因为您使用 bars 调用转换,并且除非您 merge 选择,否则bars 不包含“输入”选择。

    因此,您的“输入”+“更新”选择应该是:

     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);});
    

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多