d3.js更新模式无法按预期工作

时间:2016-12-15 19:33:17

标签: javascript d3.js

我在D3 v4中写了一个小灯箱,点击三张图片加载:选中的一个,上一组和下一组。

我将这些图像的引用存储在与general update pattern一起使用的数组中。然后,在单击“上一个”或“下一个”按钮时,将修改数组,以便添加一个图像并在任一端删除一个图像:

[image1, image2, image3]> '下一个'> [image2, image3, image4]

[image1, image2, image3]> 'prev'> [image99, image1, image2]

换句话说,一个图像应该“退出”,两个应该“更新”,一个应该“进入”。在视觉上,它应该是这样的:

Update pattern after clicking 'next'

不幸的是,它不能按设计工作,我不知道为什么。在控制台中,我看到两个'退出',一个'更新'和两个'进入'。为什么呢?

这是我的pen,相关的代码块如下。感谢任何帮助。

d3.selectAll( 'div[role="img"]' ) // image group for lightbox
    .on( "mousedown touchstart", function( d, i, n ) {
        luxBox( d, i, n );
    });

function luxBox( d, idx, n ) {

    var l = n.length,
        j = idx, //selected image in group
        jp = j > 0 ? j - 1 : l - 1, //preceding image in group
        jn = j < l - 1 ? j + 1 : 0; //following image in group

    var imgs = [
        d3.select(n[jp]), //0 
        d3.select(n[j]),  //1
        d3.select(n[jn])  //2
    ];

    function update(data) {

        var t = d3.transition().duration(400);

        var lux = d3.select('#luxbox')
            .attr("class", "show")
            .select('#slider')
            .selectAll('li')
            .data(data, function(d) { return d; }); //join

        lux //exit
            .exit()
            .attr("class", "exit")
            .transition(t)
            .style("opacity", function(d, i) { 
                console.log('exit: i=' + i);
                return 0; 
            })
            .remove();

        lux //update
            .attr("class", "update")
            .transition(t)
            .style("transform", function(d, i) { 
                console.log( 'update: i=' + i );
                return "translateX(" + (i * 100 - 100) + "%)"; 
            });

        lux //enter
            .enter()
            .append('li')
            .attr("class", "enter")
            .style("opacity", 0)
            .style("background-image", function(d) { return d.style('background-image'); })
            .style("transform", function(d, i) { 
                console.log( 'enter: i=' + i );
                return "translateX(" + (i * 100 - 100) + "%)"; 
            })
            //append("h3") // caption
            .transition(t)
            .style("opacity", 1);
    }

    update(imgs);

    d3.select(".next")
        .on("mousedown touchstart", function() { 
            idx < l - 1 ? idx++ : idx = 0; //next index
            console.log( 'index=' + idx );  
            jn = idx < l - 1 ? idx + 1 : 0; //new following image
            imgs.push( d3.select(n[jn]) );
            imgs.shift();
            update( imgs );
        });
    d3.select(".prev")
        .on("mousedown touchstart", function() {
            idx > 0 ? idx-- : idx = l - 1; //prev index
            console.log( 'index=' + idx );
            jp = idx > 0 ? idx - 1 : l - 1; //new preceding image
            imgs.unshift( d3.select(n[jp]) );
            imgs.pop();
            update( imgs );
        });
    d3.select(".close")
        .on("mousedown touchstart", function() {
            d3.select('#luxbox')
                .attr("class", "hide");
            setTimeout( function() {
                d3.selectAll('#slider li').remove();
                console.log('slides removed')
            }, 400 );
        });
}

1 个答案:

答案 0 :(得分:3)

在进一步调查并找到一些great answers后,我通过使用匹配图像选择索引的数据 key 解决了我的问题。

var imgs = [
    { 
        "url": d3.select(n[jp]).select("img").attr("src"),
        "caption": d3.select(n[jp]).select("img").attr("alt"),
        "key": jp
    },
    { 
        "url": d3.select(n[j]).select("img").attr("src"),
        "caption": d3.select(n[j]).select("img").attr("alt"),
        "key": j
    },
    { 
        "url": d3.select(n[jn]).select("img").attr("src"),
        "caption": d3.select(n[jn]).select("img").attr("alt"),
        "key": jn
    }
];

// ...

.data(data, function(d) { return d.key; }); //join