保持元素顺序(select .order)与退出转换在d3

Keeping element order (selection.order) with exit transitions in d3

本文关键字:退出 转换 d3 order 元素 顺序 select      更新时间:2023-09-26

我将直接使用小提琴: http://jsfiddle.net/K6Yrw/[点击第二个按钮快速查看效果]


我使用selection.order,因为我需要我的DOM元素以与数据元素相同的顺序存在。

我想添加一个过渡到我的.exit()选择。然而,当与.order()结合时,该过程就失效了。要删除的项被放置在DOM元素列表的开头。

我的猜测:也许是因为order试图获得数据数组中元素的索引-当然它不再存在,因此获得-1作为索引,这意味着它应该排序到DOM元素列表的开头。

如果我不使用order,那么退出转换工作得很好:但是如果我插入数据数组的一部分,当然新的DOM元素只是附加到末尾。

任何提示或帮助非常感谢!

我相信我有办法。问题是d3最终排序的不仅仅是你选择的元素。退出的元素不再是您选择的一部分,d3无意中移动了它们。我修改了现有的d3阶函数,以便它接受一个键函数并跳过当前选择中的任何内容。这样,退出的元素就会保持不变。我的版本需要一个键来检查元素是否在当前选择中。我不确定是否有更好的方法来处理这个问题。

function strictOrder(fnKey){
    fnKey = fnKey || function(d){return d;};
    return function(){
        for (var j = -1, m = this.length; ++j < m; ) {
            for (var group = this[j], i = group.length - 1, next = group[i], node,seen = new d3.set(); --i >= 0; ) {
                node = group[i];
                if (!node)  continue;
                if (next && next !== node.nextSibling && (!node.nextSibling || seen.has(fnKey(node.nextSibling.__data__)))){
                    next.parentNode.insertBefore(node, next);
                }
                seen.add(fnKey(node.__data__));
                next = node;
            }
        }
        return this;
    };
}

查看您的分叉小提琴:http://jsfiddle.net/co8nqopy/1/

也许你可以尝试只运行选择。只在插入项目时订购,而不是在删除项目时订购。

因此,为了纠正这个错误,您可以向方法doD3()添加一个参数,该参数保留是否运行select .order的真/假。因此,在插入项以保持顺序时传递true,在删除项时传递false。

参见:http://jsfiddle.net/K6Yrw/31/

var items = ['apple', 'banana', 'orange', 'aardvark'];
function doD3(order) {
    var selection = d3.select('div.c')
        .selectAll('p')
    .data(items, function(d) { return d; });
    selection
        .enter()
        .append('p')
    .text(function(d) { return d; })
        .style('opacity', 0)
        .transition()
        .style('opacity', 1);
    selection
        .exit()
        .transition()
        .style('opacity', 0)
        .remove();
    if(order) {
        // remove this to see alternative behaviour
        selection
            .order();    
    }    
}
doD3(true);
$('#b1').click(function() {
    items.splice(1, 0, ['kiwi']);
    doD3(true);
});
$('#b2').click(function() {
    items.splice(2, 1);
    doD3(false);
});