D3可选转换

D3 Optional Transitions

本文关键字:转换 D3      更新时间:2024-06-13

我有一个D3图表,可以转换绘图点。有时我希望这些是动画过渡,有时我希望它们是即时的。在D3中有没有干的方法来做这种事情?

例如:

    svg.selectAll('g.data-point')
        .data(dataset)
        .transition()
        .duration(transitionTime)
        .attr({
            class: function(d) {
                return getClassesForPoint(d);
            },
            transform: function(d) {
                return ('translate(' + ((d.x) ? xScale(d.x) : xScale(0)) + ', ' + yScale(d.y) + ')');
            }
        });

如果我只想根据一个条件进行动画转换,我是否需要通过If-else结构在没有第3-4行的情况下重复该块,或者有更好的方法吗?链结让我有点累。我已经尝试过给它一个0的持续时间,它仍然会通过动画引擎。

有什么想法吗?

编辑:

事实证明,我的选择器已经失效,正如Lars所提到的,使用持续时间(0)可以很好地工作。然而,我在不同的时候遇到过这种情况,两个链中似乎有足够的通用性,但我不知道如何正确或动态地添加/删除对链的调用。

由于transition对象支持selection对象支持的大多数方法(append等函数除外),因此您可以有条件地选择其中一个方法进行操作:

var selection = svg.selectAll('g.data-point').data(dataset).enter();
if (condition) { selection = selection.transition().duration(transitionTime); }
selection.attr(/* .. */);

我会使用。调用:

function transformationAndSetClass(selection){
   selection.attr({
        class: function(d) {
            return getClassesForPoint(d);
        },
        transform: function(d) {
            return ('translate(' + xScale(d.x ? d.x : 0) + ', ' + yScale(d.y) + ')');
        }
    });
}

然后,当您需要重用这些代码行时:

svg.selectAll('g.data-point')
    .data(dataset)
    .transition()
    .duration(transitionTime)
    .call(transformationAndSetClass)

如果你愿意,你可以使用.each()方法与d3.select(this)配对,对你的选择进行更细粒度的控制:

 svg.selectAll('g.data-point')
    .data(dataset)
    .each(function (d) {
      if (d.someCondition == "something") {
        d3.select(this)
        .transition()
        .duration(1000)
        .attr("transform", "translate(100,100)
      }
      else {
        d3.select(this).attr("transform", "translate(100,100)
      }
 })

显然,它有点冗长。