d3:如何在不同的选择上正确链接转换 [英] d3: How to properly chain transitions on different selections

查看:180
本文介绍了d3:如何在不同的选择上正确链接转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用流行的d3库的V3,基本上想要有三个转换,彼此相邻:第一个转换应该应用到退出选择,第二个到更新选择,第三个到输入选择。它们应当以这样的方式链接,使得当选择之一为空时,跳过其相应的转换。也就是说当没有退出选择时,更新选择应立即开始。到目前为止,我已经提出了这个代码(使用 delay 函数)。

I am using V3 of the popular d3 library and basically want to have three transitions, followed by each other: The first transition should apply to the exit selection, the second to the update selection and the third to the enter selection. They should be chained in such a manner that when one of the selections is empty, its respective transition is skipped. I.e. when there is no exit selection, the update selection should start immediately. So far, I have come up with this code (using the delay function).

// DATA JOIN
var items = d3.select('#data').selectAll('.item');
items = items.data(data, function(d){ 
    return d.twitter_screenname;
});


// EXIT
items.exit().transition().duration(TRANSITION_DURATION).style('opacity', 0).remove();

// UPDATE
// Divs bewegen
items.transition().duration(TRANSITION_DURATION).delay(TRANSITION_DURATION * 1)
    .style('left', function(d, i) {
        return positions[i].left + "px";
    }).style('top', function(d, i) {
        return positions[i].top + "px";
    });

// ENTER
// Divs hinzufügen
var div = items.enter().append('div')
    .attr('class', 'item')
    .style('left', function(d, i) {
        return positions[i].left + "px";
    }).style('top', function(d, i) {
        return positions[i].top + "px";
    });

 div.style('opacity', 0)
    .transition().duration(TRANSITION_DURATION).delay(TRANSITION_DURATION * 2)
    .style('opacity', 1);

首先,它不允许跳过转换,其次我认为方式比 delay 。我看过 http://bl.ocks.org/mbostock/3903818 ,但我没有

First of all it doesn't allow to "skip" transitions and secondly I think there is a better way than delay. I've looked at http://bl.ocks.org/mbostock/3903818 but I did not really understand what is happening.

还有,只是写 items.exit()。transition()。duration(TRANSITION_DURATION).remove )不能使用,可能是因为它们不是SVG元素,而 div s。

Also, somehow just writing items.exit().transition().duration(TRANSITION_DURATION).remove() does not work with the items, probably because they are not SVG elements but divs.

推荐答案

当然。这有两种方法。

首先,您可以使用明确的 delay ,然后您可以使用 selection.empty 来跳过空白转换。 (这只是您已有的一个小修改。)

First, you could use an explicit delay, which you then compute using selection.empty to skip empty transitions. (This is only a minor modification of what you have already.)

var div = d3.select("body").selectAll("div")
    .data(["enter", "update"], function(d) { return d || this.textContent; });

// 2. update
div.transition()
    .duration(duration)
    .delay(!div.exit().empty() * duration)
    .style("background", "orange");

// 3. enter
div.enter().append("div")
    .text(function(d) { return d; })
    .style("opacity", 0)
  .transition()
    .duration(duration)
    .delay((!div.exit().empty() + !div.enter().empty()) * duration)
    .style("background", "green")
    .style("opacity", 1);

// 1. exit
div.exit()
    .style("background", "red")
  .transition()
    .duration(duration)
    .style("opacity", 0)
    .remove();

http ://bl.ocks.org/mbostock/5779682

这里有一个棘手的问题,就是您必须在更新元素上建立转移之前您在输入元素上创建转换;这是因为 enter.append 将输入元素合并到更新选择中,并且希望将它们分开;有关详情,请参阅仅更新转换示例

One tricky thing here is that you have to create the transition on the updating elements before you create the transition on the entering elements; that’s because enter.append merges entering elements into the update selection, and you want to keep them separate; see the Update-only Transition example for details.

,您可以使用 transition.transition 链转换 transition.each 到将这些链接转换应用于现有选择。在transition.each的上下文中,selection.transition继承了现有的转换,而不是创建一个新的转换。

Alternatively, you could use transition.transition to chain transitions, and transition.each to apply these chained transitions to existing selections. Within the context of transition.each, selection.transition inherits the existing transition rather than creating a new one.

var div = d3.select("body").selectAll("div")
    .data(["enter", "update"], function(d) { return d || this.textContent; });

// 1. exit
var exitTransition = d3.transition().duration(750).each(function() {
  div.exit()
      .style("background", "red")
    .transition()
      .style("opacity", 0)
      .remove();
});

// 2. update
var updateTransition = exitTransition.transition().each(function() {
  div.transition()
      .style("background", "orange");
});

// 3. enter
var enterTransition = updateTransition.transition().each(function() {
  div.enter().append("div")
      .text(function(d) { return d; })
      .style("opacity", 0)
    .transition()
      .style("background", "green")
      .style("opacity", 1);
});

http ://bl.ocks.org/mbostock/5779690

我想后者有点更惯用,虽然使用transition.each来应用转换选择(而不是导出具有默认参数的转换)不是广为人知的特征。

I suppose the latter is a bit more idiomatic, although using transition.each to apply transitions to selections (rather than derive transitions with default parameters) isn’t a widely-known feature.

这篇关于d3:如何在不同的选择上正确链接转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆