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

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

问题描述

我使用的是流行的D3库的V3和基本想有三个转变,其次是对方:第一过渡应适用于退出的选择,第二次更新的选择和第三的输入选择。它们应以这样的方式,当选择之一是空的,其相应的过渡跳过被链接。即当没有退出选择,更新选择应立即启动。到目前为止,我想出了这个code(使用延迟功能)。

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

所有它不允许跳过的过渡和第一第二,我认为还有比延迟更好的办法。我看着 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)一个.remove()不工作项目,可能是因为它们不是SVG元素,但 DIV 秒。

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.

推荐答案

当然。这里有两种方法。

Sure. Here are two ways.

首先,你可以使用一个明确的延迟,然后您再进行计算使用的 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 来的chain过渡 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天全站免登陆