为什么在单独的函数中应用时转换会闪烁/断断续续(D3)

Why do transitions flicker/stutter when applied in a separate function (D3)

本文关键字:闪烁 断断续续 D3 转换 单独 函数 应用 为什么      更新时间:2023-09-26

我在处理转换,当转换应用于不同函数中的选择时,我注意到一些断断续续和闪烁。但是,如果转换是通过方法链接应用的,它将完全按照规定工作。

下面是简单移动一些文本的小示例(Fiddle)。最左边的第一个字符串在转换开始前神奇地传送到页面上。最右边的第二个字符串从页面的顶部到底部有一个平滑的过渡。

为什么会发生这种"传送"?显然,在一个单独的函数中应用转换与链接它不同,但有办法实现这一点吗?比如说,我想将相同的转换应用于许多不同的对象——从不同的选择中检索——那么有没有一种方法可以将转换降级为其自身的功能而不会出现这种断断续续的情况?

var svg = d3.select('svg');
var textElem = svg.append('text')
    .data(['hello world'])
    .attr('x', 30)
    .attr('y', 100)
    .attr('fill', '#000')
    .attr('id', 'a')
    .text(function (d) {
        return d;
    });
var textElem2 = svg.append('text')
    .data(['some text'])
    .attr('x', 230)
    .attr('y', 100)
    .attr('fill', '#000')
    .attr('id', 'a')
    .text(function (d) {
        return d;
    });
setTimeout(foo, 3000);
function foo() {
    textElem.data(['hello world, again!']);
    applyTextTransitions(textElem);
    textElem.attr({
        x: 30,
        y: 150
    });
    textElem.text(function (d) {
        return d;
    });
    textElem2.data(['some more text!'])
        .transition()
        .duration(1000)
        .style('opacity', 0)
        .transition()
        .duration(1000)
        .style('opacity', 1)
        .attr({
            x: 230,
            y: 150
        })
        .text(function (d) {
            return d;
        });
}
function applyTextTransitions(element) {
    element
        .transition()
        .duration(1000)
        .style('opacity', 0)
        .transition()
        .duration(1000)
        .style('opacity', 1);
}

我还没有用d3,但你打算这么做吗?

applyTextTransitions(textElem, { x: 30, y: 150 }); 
function applyTextTransitions(element, newPos) {
    element
    .transition()
    .duration(1000)
    .style('opacity', 0)
    .transition()
    .duration(1000)
    .attr(newPos)
    .style('opacity', 1)
    .text(function(d){
        return d; 
     }); 
}

https://jsfiddle.net/k8kv4arv/3/

发生"跳转"是因为调用函数等待applyTextTransitions()完成,然后应用新的维度。

我知道我参加聚会迟到了,但是。。。

您遇到的口吃只是因为您调用了一个转换函数applyTextTransition,然后立即更改了元素的位置。

applyTextTransitions(textElem);
textElem.attr({
    x: 30,
    y: 150
});

这就是为什么你会出现不必要的口吃。


此外,重用应用转换的函数的正确D3方式是使用selection.call。这允许您声明一个函数,并使用call方法来调用应用转换的函数。

textElem.call(applyTextTransition);
function applyTextTransition(selection) {
  // perform selection.transition()
}

您现在可以在链接中使用您的函数,并且您不限于仅对当前选择使用该函数。