首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >d3:如何正确链接不同选择上的转换

d3:如何正确链接不同选择上的转换
EN

Stack Overflow用户
提问于 2013-06-13 19:53:28
回答 1查看 10.9K关注 0票数 21

我使用的是流行的d3库的V3,基本上希望有三个转换,依次是:第一个转换应用于退出选择,第二个转换应用于更新选择,第三个转换应用于回车选择。它们应该以这样的方式链接:当其中一个选择为空时,其相应的转换将被跳过。即,当没有退出选择时,更新选择应立即开始。到目前为止,我已经编写了这段代码(使用delay函数)。

代码语言:javascript
复制
// 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,但我并不真正理解发生了什么。

此外,不知何故,仅仅编写items.exit().transition().duration(TRANSITION_DURATION).remove()不能与items一起工作,可能是因为它们不是SVG元素,而是div

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-14 13:43:26

好的。这里有两种方法。

首先,您可以使用显式delay,然后使用selection.empty计算它以跳过空转换。(这只是对已有内容的微小修改。)

代码语言:javascript
复制
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会将输入元素合并到更新选择中,而您希望将它们分开;有关详细信息,请参阅Update-only Transition example

或者,您可以使用transition.transition to chain transitionstransition.each将这些链接的过渡应用于现有的选择。在transition.each的上下文中,selection.transition继承现有的转换,而不是创建新的转换。

代码语言:javascript
复制
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将转换应用于选择(而不是使用默认参数派生转换)并不是一个广为人知的特性。

票数 33
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17086415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档